mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 00:02:23 +00:00
feat(frontend): Add support for object editor + fix wording (#1004)
This commit is contained in:
@@ -116,7 +116,7 @@
|
||||
timeoutModel && clearTimeout(timeoutModel)
|
||||
timeoutModel = setTimeout(() => {
|
||||
code = getCode()
|
||||
dispatch('change')
|
||||
dispatch('change', { code })
|
||||
}, 200)
|
||||
})
|
||||
|
||||
|
||||
@@ -36,32 +36,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
let searchConfiguration: 'Frontend' | 'Backend' | 'Disabled' = 'Disabled'
|
||||
let paginationEnabled: boolean | undefined = undefined
|
||||
let search: 'Frontend' | 'Backend' | 'Disabled' = 'Disabled'
|
||||
let pagination: boolean | undefined = undefined
|
||||
|
||||
let page = 1
|
||||
let search = ''
|
||||
let searchValue = ''
|
||||
|
||||
let result: Array<Record<string, any>> = []
|
||||
$: headers = Object.keys(result[0] || {}) || []
|
||||
|
||||
const extraQueryParams = { search, page }
|
||||
const extraQueryParams = { search: searchValue, page }
|
||||
|
||||
export const reservedKeys: string[] = Object.keys(extraQueryParams)
|
||||
|
||||
$: (searchConfiguration === 'Frontend' || searchConfiguration === 'Backend') &&
|
||||
(extraQueryParams.search = search)
|
||||
$: (search === 'Frontend' || search === 'Backend') && (extraQueryParams.search = searchValue)
|
||||
</script>
|
||||
|
||||
<InputValue input={configuration.searchConfiguration} bind:value={searchConfiguration} />
|
||||
<InputValue input={configuration.paginationEnabled} bind:value={paginationEnabled} />
|
||||
<InputValue input={configuration.search} bind:value={search} />
|
||||
<InputValue input={configuration.pagination} bind:value={pagination} />
|
||||
|
||||
<RunnableWrapper bind:componentInput {id} bind:result extraQueryParams={{ search, page }}>
|
||||
<RunnableWrapper
|
||||
bind:componentInput
|
||||
{id}
|
||||
bind:result
|
||||
extraQueryParams={{ search: searchValue, page }}
|
||||
>
|
||||
<div class="gap-2 flex flex-col mt-2">
|
||||
{#if searchConfiguration !== 'Disabled'}
|
||||
{#if search !== 'Disabled'}
|
||||
<div>
|
||||
<div>
|
||||
<DebouncedInput placeholder="Search..." bind:value={search} />
|
||||
<DebouncedInput placeholder="Search..." bind:value={searchValue} />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -117,7 +121,7 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{#if paginationEnabled}
|
||||
{#if pagination}
|
||||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
on:click={() => {
|
||||
|
||||
@@ -122,14 +122,14 @@ const dataDisplay: ComponentSet = {
|
||||
id: 'tablecomponent',
|
||||
type: 'tablecomponent',
|
||||
configuration: {
|
||||
searchConfiguration: {
|
||||
search: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
value: 'Disabled',
|
||||
optionValuesKey: 'tableSearchOptions',
|
||||
defaultValue: 'Disabled'
|
||||
},
|
||||
paginationEnabled: {
|
||||
pagination: {
|
||||
type: 'static',
|
||||
value: false,
|
||||
fieldType: 'boolean',
|
||||
|
||||
@@ -132,46 +132,50 @@
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="w-full border rounded-sm">
|
||||
{#each $app.inlineScripts ? Object.entries($app.inlineScripts) : [] as [key, value], index}
|
||||
<div
|
||||
class={classNames(
|
||||
'flex justify-between flex-row w-full items-center p-2',
|
||||
index % 2 === 0 ? 'bg-gray-100' : 'bg-white'
|
||||
)}
|
||||
>
|
||||
<span class="text-xs">{key}</span>
|
||||
<div class="flex gap-2">
|
||||
<Button
|
||||
size="xs"
|
||||
color="light"
|
||||
variant="border"
|
||||
iconOnly
|
||||
startIcon={{ icon: faEdit }}
|
||||
on:click={() => {
|
||||
if (value) {
|
||||
selectedScript = value
|
||||
scriptEditorDrawer.openDrawer && scriptEditorDrawer.openDrawer()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
size="xs"
|
||||
color="red"
|
||||
variant="border"
|
||||
iconOnly
|
||||
startIcon={{ icon: faTrash }}
|
||||
on:click={() => {
|
||||
if ($app.inlineScripts[key]) {
|
||||
delete $app.inlineScripts[key]
|
||||
$app = $app
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{#if $app.inlineScripts && Object.keys($app.inlineScripts).length > 0}
|
||||
<div class="w-full border rounded-sm">
|
||||
{#each $app.inlineScripts ? Object.entries($app.inlineScripts) : [] as [key, value], index}
|
||||
<div
|
||||
class={classNames(
|
||||
'flex justify-between flex-row w-full items-center p-2',
|
||||
index % 2 === 0 ? 'bg-gray-100' : 'bg-white'
|
||||
)}
|
||||
>
|
||||
<span class="text-xs">{key}</span>
|
||||
<div class="flex gap-2">
|
||||
<Button
|
||||
size="xs"
|
||||
color="light"
|
||||
variant="border"
|
||||
iconOnly
|
||||
startIcon={{ icon: faEdit }}
|
||||
on:click={() => {
|
||||
if (value) {
|
||||
selectedScript = value
|
||||
scriptEditorDrawer.openDrawer && scriptEditorDrawer.openDrawer()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
size="xs"
|
||||
color="red"
|
||||
variant="border"
|
||||
iconOnly
|
||||
startIcon={{ icon: faTrash }}
|
||||
on:click={() => {
|
||||
if ($app.inlineScripts[key]) {
|
||||
delete $app.inlineScripts[key]
|
||||
$app = $app
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-sm text-gray-500">No inline scripts</div>
|
||||
{/if}
|
||||
</PanelSection>
|
||||
|
||||
<PanelSection title="Outputs">
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
import { Plus } from 'svelte-lucide'
|
||||
import StaticInputEditor from './StaticInputEditor.svelte'
|
||||
import ConnectedInputEditor from './ConnectedInputEditor.svelte'
|
||||
import { sanitizeInputSpec } from '../../utils'
|
||||
|
||||
export let component: AppComponent | undefined
|
||||
export let onDelete: (() => void) | undefined = undefined
|
||||
@@ -73,7 +72,7 @@
|
||||
Connect
|
||||
</ToggleButton>
|
||||
<ToggleButton position="right" value="runnable" startIcon={{ icon: faCode }} size="xs">
|
||||
Script
|
||||
Computed
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import type { AppInput } from '../../inputType'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import { faPlus } from '@fortawesome/free-solid-svg-icons'
|
||||
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
|
||||
|
||||
export let componentInput: AppInput | undefined
|
||||
export let canHide: boolean = false
|
||||
@@ -32,7 +33,18 @@
|
||||
<div class="flex gap-2 flex-col mt-2">
|
||||
{#if componentInput.value}
|
||||
{#each componentInput.value as value, index}
|
||||
<input bind:value={componentInput.value[index]} />
|
||||
<div class="border rounded-sm">
|
||||
<SimpleEditor
|
||||
lang="json"
|
||||
code={JSON.stringify(componentInput.value[index], null, 2)}
|
||||
class="few-lines-editor"
|
||||
on:change={(e) => {
|
||||
if (componentInput?.type === 'static' && componentInput.value) {
|
||||
componentInput.value[index] = JSON.parse(e.detail.code)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
<Button
|
||||
size="xs"
|
||||
@@ -44,7 +56,7 @@
|
||||
componentInput.type === 'static' &&
|
||||
componentInput.value
|
||||
) {
|
||||
componentInput.value.push('')
|
||||
componentInput.value.push({})
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
{#if components.length > 0}
|
||||
<div class="w-full">
|
||||
<Alert title="Special argument" size="xs">
|
||||
A "row" argument is automatically added to the script. It contains the row data.
|
||||
The row is passed as an argument to the runnable.
|
||||
</Alert>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -98,7 +98,7 @@
|
||||
on:keypress
|
||||
>
|
||||
<div>
|
||||
<TableActionLabel componentInput={component.componentInput} />
|
||||
<TableActionLabel componentInput={component.configuration.label} />
|
||||
</div>
|
||||
<Badge color="dark-blue">
|
||||
Component: {component.id}
|
||||
|
||||
Reference in New Issue
Block a user