mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-08 16:03:27 +00:00
fix(frontend): fix table bindings
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import { loadIcon } from '../icon'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { goto } from '$app/navigation'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
@@ -32,7 +33,8 @@
|
||||
let runnableComponent: RunnableComponent
|
||||
let disabled: boolean | undefined = undefined
|
||||
let fillContainer: boolean | undefined = undefined
|
||||
let goto: string | undefined = undefined
|
||||
let gotoUrl: string | undefined = undefined
|
||||
let gotoNewTab: boolean | undefined = undefined
|
||||
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
@@ -87,7 +89,7 @@
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.label} bind:value={labelValue} />
|
||||
<InputValue {id} input={configuration.goto} bind:value={goto} />
|
||||
<InputValue {id} input={configuration.goto} bind:value={gotoUrl} />
|
||||
<InputValue {id} input={configuration.color} bind:value={color} />
|
||||
<InputValue {id} input={configuration.size} bind:value={size} />
|
||||
<InputValue {id} input={configuration.beforeIcon} bind:value={beforeIcon} />
|
||||
@@ -101,6 +103,7 @@
|
||||
bind:error={errors.disabled}
|
||||
/>
|
||||
<InputValue {id} input={configuration.fillContainer} bind:value={fillContainer} />
|
||||
<InputValue {id} input={configuration.gotoNewTab} bind:value={gotoNewTab} />
|
||||
|
||||
<RunnableWrapper
|
||||
flexWrap
|
||||
@@ -109,7 +112,8 @@
|
||||
{id}
|
||||
{extraQueryParams}
|
||||
autoRefresh={false}
|
||||
{goto}
|
||||
goto={gotoUrl}
|
||||
{gotoNewTab}
|
||||
>
|
||||
<AlignWrapper {noWFull} {horizontalAlignment} {verticalAlignment}>
|
||||
{#if errorsMessage}
|
||||
@@ -134,7 +138,18 @@
|
||||
e?.stopPropagation()
|
||||
e?.preventDefault()
|
||||
ownClick = true
|
||||
await runnableComponent?.runComponent()
|
||||
|
||||
if (!runnableComponent) {
|
||||
if (gotoUrl) {
|
||||
if (gotoNewTab) {
|
||||
window.open(gotoUrl, '_blank')
|
||||
} else {
|
||||
goto(gotoUrl)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await runnableComponent?.runComponent()
|
||||
}
|
||||
|
||||
if (recomputeIds) {
|
||||
recomputeIds.forEach((id) => {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
export let wrapperStyle = ''
|
||||
export let initializing: boolean | undefined = undefined
|
||||
export let gotoUrl: string | undefined = undefined
|
||||
export let gotoNewTab: boolean | undefined = undefined
|
||||
|
||||
const {
|
||||
worldStore,
|
||||
@@ -241,7 +242,13 @@
|
||||
delete $errorByComponent[previousJobId]
|
||||
$errorByComponent = $errorByComponent
|
||||
}
|
||||
gotoUrl && gotoUrl != '' && result?.error == undefined && goto(gotoUrl)
|
||||
if (gotoUrl && gotoUrl != '' && result?.error == undefined) {
|
||||
if (gotoNewTab) {
|
||||
window.open(gotoUrl, '_blank')
|
||||
} else {
|
||||
goto(gotoUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
export let runnableClass = ''
|
||||
export let runnableStyle = ''
|
||||
export let goto: string | undefined = undefined
|
||||
export let gotoNewTab: boolean | undefined = undefined
|
||||
|
||||
const { staticExporter, noBackend } = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
@@ -43,6 +44,7 @@
|
||||
{:else if componentInput.type === 'runnable' && isRunnableDefined()}
|
||||
<RunnableComponent
|
||||
gotoUrl={goto}
|
||||
{gotoNewTab}
|
||||
{flexWrap}
|
||||
bind:this={runnableComponent}
|
||||
fields={componentInput.fields}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppEditorContext, GridItem } from '../types'
|
||||
import ComponentPanel from './settingsPanel/ComponentPanel.svelte'
|
||||
|
||||
const { selectedComponent } = getContext<AppEditorContext>('AppEditorContext')
|
||||
export let gridItems: GridItem[]
|
||||
export let parent: string | undefined
|
||||
</script>
|
||||
|
||||
{#each gridItems as gridItem, i (gridItem?.data?.id ?? i)}
|
||||
{#if gridItem?.data?.id === $selectedComponent}
|
||||
<ComponentPanel {parent} bind:component={gridItem.data} />
|
||||
{:else if gridItem?.data?.type === 'tablecomponent'}
|
||||
{#each gridItem.data.actionButtons as actionButton (actionButton.id)}
|
||||
{#if actionButton.id === $selectedComponent}
|
||||
<ComponentPanel
|
||||
parent={undefined}
|
||||
noGrid
|
||||
rowColumns
|
||||
bind:component={actionButton}
|
||||
duplicateMoveAllowed={false}
|
||||
onDelete={() => {
|
||||
gridItem.data.actionButtons = gridItem.data.actionButtons.filter(
|
||||
(c) => c.id !== actionButton.id
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -1,31 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppEditorContext } from '../types'
|
||||
import GridPanel from './GridPanel.svelte'
|
||||
import PanelSection from './settingsPanel/common/PanelSection.svelte'
|
||||
import ComponentPanel from './settingsPanel/ComponentPanel.svelte'
|
||||
import InputsSpecsEditor from './settingsPanel/InputsSpecsEditor.svelte'
|
||||
import TablePanel from './TablePanel.svelte'
|
||||
|
||||
const { selectedComponent, app } = getContext<AppEditorContext>('AppEditorContext')
|
||||
</script>
|
||||
|
||||
{#each $app.grid as gridItem (gridItem?.data?.id)}
|
||||
{#if gridItem?.data?.id === $selectedComponent}
|
||||
<ComponentPanel parent={undefined} bind:component={gridItem.data} />
|
||||
{:else if gridItem?.data?.type === 'tablecomponent'}
|
||||
<TablePanel bind:component={gridItem.data} />
|
||||
{/if}
|
||||
{/each}
|
||||
{#if $app.grid}
|
||||
<GridPanel parent={undefined} bind:gridItems={$app.grid} />
|
||||
{/if}
|
||||
|
||||
{#if $app.subgrids}
|
||||
{#each Object.keys($app.subgrids ?? {}) as key (key)}
|
||||
{#each $app.subgrids[key] as gridItem (gridItem?.data?.id)}
|
||||
{#if gridItem?.data?.id === $selectedComponent}
|
||||
<ComponentPanel parent={key} bind:component={gridItem.data} />
|
||||
{:else if gridItem?.data?.type === 'tablecomponent'}
|
||||
<TablePanel bind:component={gridItem.data} />
|
||||
{/if}
|
||||
{/each}
|
||||
<GridPanel parent={key} bind:gridItems={$app.subgrids[key]} />
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppEditorContext } from '../types'
|
||||
import type { TableComponent } from './component'
|
||||
import ComponentPanel from './settingsPanel/ComponentPanel.svelte'
|
||||
|
||||
export let component: TableComponent
|
||||
const { selectedComponent } = getContext<AppEditorContext>('AppEditorContext')
|
||||
</script>
|
||||
|
||||
{#each component.actionButtons as actionButton (actionButton.id)}
|
||||
{#if actionButton.id === $selectedComponent}
|
||||
<ComponentPanel
|
||||
parent={undefined}
|
||||
noGrid
|
||||
rowColumns
|
||||
bind:component={actionButton}
|
||||
onDelete={() => {
|
||||
component.actionButtons = component.actionButtons.filter((c) => c.id !== actionButton.id)
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -104,7 +104,6 @@ export type AppComponent = BaseAppComponent &
|
||||
| HtmlComponent
|
||||
| TableComponent
|
||||
| TextComponent
|
||||
| TableComponent
|
||||
| ButtonComponent
|
||||
| PieChartComponent
|
||||
| ScatterChartComponent
|
||||
@@ -285,6 +284,12 @@ export const components: Record<AppComponent['type'], AppComponentConfig> = {
|
||||
type: 'static',
|
||||
value: ''
|
||||
},
|
||||
gotoNewTab: {
|
||||
tooltip: 'Go to create a new tab',
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
value: true
|
||||
},
|
||||
beforeIcon: {
|
||||
type: 'static',
|
||||
value: undefined,
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
function getComponentNameById(componentId: string) {
|
||||
const component = findGridItem($app, componentId)
|
||||
|
||||
if (component?.data.type) {
|
||||
if (component?.data?.type) {
|
||||
return components[component?.data.type].name
|
||||
} else if (componentId == 'ctx') {
|
||||
return 'Context'
|
||||
|
||||
+7
-7
@@ -26,11 +26,11 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#each $app.grid as gridItem (gridItem?.data?.id)}
|
||||
{#if gridItem?.data?.id === selectedScriptComponentId}
|
||||
{#each $app.grid as gridItem, index (gridItem?.data?.id ?? index)}
|
||||
{#if gridItem?.data?.id && gridItem.data.id === selectedScriptComponentId}
|
||||
<InlineScriptEditorPanel
|
||||
defaultUserInput={gridItem.data.type == 'formcomponent' ||
|
||||
gridItem.data.type == 'buttonformcomponent'}
|
||||
defaultUserInput={gridItem?.data?.type == 'formcomponent' ||
|
||||
gridItem?.data?.type == 'buttonformcomponent'}
|
||||
id={gridItem.data.id}
|
||||
bind:componentInput={gridItem.data.componentInput}
|
||||
/>
|
||||
@@ -51,10 +51,10 @@
|
||||
{#if $app.subgrids}
|
||||
{#each Object.keys($app.subgrids ?? {}) as key (key)}
|
||||
{#each $app.subgrids[key] as gridItem (gridItem?.data?.id)}
|
||||
{#if gridItem?.data?.id === selectedScriptComponentId}
|
||||
{#if gridItem?.data?.id && gridItem.data.id === selectedScriptComponentId}
|
||||
<InlineScriptEditorPanel
|
||||
defaultUserInput={gridItem.data.type == 'formcomponent' ||
|
||||
gridItem.data.type == 'buttonformcomponent'}
|
||||
defaultUserInput={gridItem.data?.type == 'formcomponent' ||
|
||||
gridItem.data?.type == 'buttonformcomponent'}
|
||||
id={gridItem.data.id}
|
||||
bind:componentInput={gridItem.data.componentInput}
|
||||
/>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
export let onDelete: (() => void) | undefined = undefined
|
||||
export let parent: string | undefined
|
||||
export let noGrid = false
|
||||
export let duplicateMoveAllowed = true
|
||||
|
||||
const {
|
||||
app,
|
||||
@@ -204,24 +205,26 @@
|
||||
</PanelSection>
|
||||
{/if}
|
||||
|
||||
<PanelSection title="Duplicate">
|
||||
<Button
|
||||
size="xs"
|
||||
color="dark"
|
||||
startIcon={{ icon: faCopy }}
|
||||
on:click={() => {
|
||||
if (component) {
|
||||
duplicateElement(component.id)
|
||||
}
|
||||
}}
|
||||
>
|
||||
Duplicate component: {component.id}
|
||||
</Button>
|
||||
</PanelSection>
|
||||
{#if duplicateMoveAllowed}
|
||||
<PanelSection title="Duplicate">
|
||||
<Button
|
||||
size="xs"
|
||||
color="dark"
|
||||
startIcon={{ icon: faCopy }}
|
||||
on:click={() => {
|
||||
if (component) {
|
||||
duplicateElement(component.id)
|
||||
}
|
||||
}}
|
||||
>
|
||||
Duplicate component: {component.id}
|
||||
</Button>
|
||||
</PanelSection>
|
||||
|
||||
<PanelSection title="Move to other grid">
|
||||
<MoveToOtherGrid bind:component {parent} />
|
||||
</PanelSection>
|
||||
<PanelSection title="Move to other grid">
|
||||
<MoveToOtherGrid bind:component {parent} />
|
||||
</PanelSection>
|
||||
{/if}
|
||||
|
||||
<PanelSection title="Danger zone">
|
||||
<Button
|
||||
|
||||
@@ -44,6 +44,30 @@
|
||||
fieldType: 'boolean',
|
||||
type: 'eval',
|
||||
expr: 'false'
|
||||
},
|
||||
goto: {
|
||||
tooltip: 'Go to an url on success if not empty',
|
||||
fieldType: 'text',
|
||||
type: 'static',
|
||||
value: ''
|
||||
},
|
||||
gotoNewTab: {
|
||||
tooltip: 'Go to create a new tab',
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
value: true
|
||||
},
|
||||
beforeIcon: {
|
||||
type: 'static',
|
||||
value: undefined,
|
||||
fieldType: 'icon-select',
|
||||
onlyStatic: true
|
||||
},
|
||||
afterIcon: {
|
||||
type: 'static',
|
||||
value: undefined,
|
||||
fieldType: 'icon-select',
|
||||
onlyStatic: true
|
||||
}
|
||||
},
|
||||
componentInput: {
|
||||
@@ -54,6 +78,9 @@
|
||||
value: undefined
|
||||
},
|
||||
recomputeIds: undefined,
|
||||
customCss: {
|
||||
button: { style: '', class: '' }
|
||||
} as const,
|
||||
card: false
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user