diff --git a/frontend/src/lib/components/InputTransformForm.svelte b/frontend/src/lib/components/InputTransformForm.svelte index 6349e9ad4e..627a3443b0 100644 --- a/frontend/src/lib/components/InputTransformForm.svelte +++ b/frontend/src/lib/components/InputTransformForm.svelte @@ -224,7 +224,7 @@
diff --git a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte index 8d0cb14580..bdfc0eb218 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte @@ -88,7 +88,7 @@ {#if !loading} {:else} - + {/if} diff --git a/frontend/src/lib/components/apps/components/helpers/InputValue.svelte b/frontend/src/lib/components/apps/components/helpers/InputValue.svelte index 25f7f51478..7511e7b0f4 100644 --- a/frontend/src/lib/components/apps/components/helpers/InputValue.svelte +++ b/frontend/src/lib/components/apps/components/helpers/InputValue.svelte @@ -1,6 +1,6 @@ {#if componentInput.type !== 'runnable'} diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte index 4e0d9217d6..7f2235798a 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte @@ -22,7 +22,7 @@ export let result: any = undefined export let forceSchemaDisplay: boolean = false - const { worldStore, runnableComponents, workspace, appPath, mode } = + const { worldStore, runnableComponents, workspace, appPath, isEditor } = getContext('AppEditorContext') onMount(() => { @@ -47,7 +47,30 @@ }, 200) } - $: fields && runnableInputValues && args && autoRefresh && testJobLoader && setDebouncedExecute() + function computeStaticValues() { + return Object.entries(fields ?? {}) + .filter(([k, v]) => v.type == 'static') + .map(([name, field]) => { + return [name, field['value']] + }) + } + + let lazyStaticValues = computeStaticValues() + let currentStaticValues = lazyStaticValues + + $: fields && (currentStaticValues = computeStaticValues()) + $: if (JSON.stringify(currentStaticValues) != JSON.stringify(lazyStaticValues)) { + lazyStaticValues = currentStaticValues + setDebouncedExecute() + } + + $: fields && (lazyStaticValues = computeStaticValues()) + $: runnableInputValues && + extraQueryParams && + args && + autoRefresh && + testJobLoader && + setDebouncedExecute() // Test job internal state let testJob: CompletedJob | undefined = undefined @@ -164,17 +187,18 @@ await testJobLoader?.abstractRun(() => { const nonStaticRunnableInputs = {} const staticRunnableInputs = {} - Object.keys(fields ?? {}).forEach(([k, v]) => { + Object.keys(fields ?? {}).forEach((k) => { let field = fields[k] - if (field.type == 'static') { + if (field?.type == 'static' && fields[k]) { staticRunnableInputs[k] = field.value } else { nonStaticRunnableInputs[k] = runnableInputValues[k] } - }, {}) + }) + const requestBody = { args: { ...nonStaticRunnableInputs, ...args }, - force_viewer_static_fields: $mode == 'preview' ? undefined : staticRunnableInputs + force_viewer_static_fields: !isEditor ? undefined : staticRunnableInputs } if (runnable?.type === 'runnableByName') { diff --git a/frontend/src/lib/components/apps/components/table/AppTable.svelte b/frontend/src/lib/components/apps/components/table/AppTable.svelte index 1bb6d99426..8ddc64e762 100644 --- a/frontend/src/lib/components/apps/components/table/AppTable.svelte +++ b/frontend/src/lib/components/apps/components/table/AppTable.svelte @@ -11,7 +11,6 @@ import { classNames, isObject } from '$lib/utils' import DebouncedInput from '../helpers/DebouncedInput.svelte' import AppTableFooter from './AppTableFooter.svelte' - import RefreshButton from '../helpers/RefreshButton.svelte' import { tableOptions } from './tableOptions' import Alert from '$lib/components/common/alert/Alert.svelte' @@ -20,17 +19,22 @@ export let configuration: Record export let actionButtons: (BaseAppComponent & ButtonComponent)[] - export const staticOutputs: string[] = ['selectedRow', 'loading', 'result'] + export const staticOutputs: string[] = ['selectedRow', 'loading', 'result', 'search'] type T = Record $: result = [] as Array> - let search: 'Runnable' | 'Component' | 'Disabled' | undefined = undefined + let search: 'By Runnable' | 'By Component' | 'Disabled' | undefined = undefined let searchValue = '' let pagination: boolean | undefined = undefined - let page = 1 + + $: setSearch(searchValue) + + function setSearch(srch) { + outputs?.search?.set(srch) + } const options = writable>({ data: [], @@ -79,7 +83,7 @@ return result } return result.filter((row) => - Object.values(row).some((value) => value.toString().includes(searchValue)) + Object.values(row).some((value) => value?.toString()?.includes(searchValue)) ) } @@ -94,11 +98,11 @@ let filteredResult: Array> = [] $: filteredResult && setOptions(filteredResult) - $: extraQueryParams = search === 'Runnable' ? { search: searchValue, page } : { page, search: '' } - $: search === 'Runnable' && (filteredResult = searchInResult(result, searchValue)) - $: (search === 'Runnable' || search === 'Disabled') && (filteredResult = result) + $: search === 'By Component' && (filteredResult = searchInResult(result, searchValue)) + $: (search === 'By Runnable' || search === 'Disabled') && (filteredResult = result) $: outputs = $worldStore?.outputsById[id] as { selectedRow: Output + search: Output } function rerender() { @@ -111,7 +115,7 @@ - + {#if Array.isArray(result) && result.every(isObject)}
{#if search !== 'Disabled'} diff --git a/frontend/src/lib/components/apps/editor/AppEditor.svelte b/frontend/src/lib/components/apps/editor/AppEditor.svelte index 948b4ee92d..b7fdfcea64 100644 --- a/frontend/src/lib/components/apps/editor/AppEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditor.svelte @@ -48,7 +48,8 @@ const summaryStore = writable(summary) const connectingInput = writable({ opened: false, - input: undefined + input: undefined, + hoveredComponent: undefined }) const runnableComponents = writable Promise>>({}) @@ -66,7 +67,8 @@ runnableComponents, appPath: path, workspace: $workspaceStore ?? '', - onchange: () => saveDraft() + onchange: () => saveDraft(), + isEditor: true }) let timeout: NodeJS.Timeout | undefined = undefined @@ -96,6 +98,11 @@ } +{#if $connectingInput.opened} +
+{/if} {#if !$userStore?.operator} {#if initialMode !== 'preview'} @@ -110,15 +117,16 @@ appPath={path} {breakpoint} {policy} + isEditor /> {:else} - + - +
- {/if}
- +
- {#if $connectingInput.opened} -
- {/if}
+
@@ -178,10 +176,7 @@ {#if $connectingInput.opened}
-
diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte index ddd3464f1f..f18d3e8433 100644 --- a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte @@ -12,7 +12,14 @@ import { AppService, Policy } from '$lib/gen' import { userStore, workspaceStore } from '$lib/stores' import { faClipboard, faExternalLink, faSave } from '@fortawesome/free-solid-svg-icons' - import { Eye, Laptop2, Pencil, Smartphone } from 'lucide-svelte' + import { + AlignHorizontalSpaceAround, + Expand, + Eye, + Laptop2, + Pencil, + Smartphone + } from 'lucide-svelte' import { getContext } from 'svelte' import { Icon } from 'svelte-awesome' import { copyToClipboard, sendUserToast } from '../../../utils' @@ -211,11 +218,11 @@ -
+
-
+
@@ -240,12 +247,12 @@ Centered     The max width is 1168px and the content stay centered instead of taking the full page width - Full +
diff --git a/frontend/src/lib/components/apps/editor/AppExportButton.svelte b/frontend/src/lib/components/apps/editor/AppExportButton.svelte index 272a74ef07..fa3559797d 100644 --- a/frontend/src/lib/components/apps/editor/AppExportButton.svelte +++ b/frontend/src/lib/components/apps/editor/AppExportButton.svelte @@ -16,13 +16,7 @@ export let app: App - diff --git a/frontend/src/lib/components/apps/editor/AppPreview.svelte b/frontend/src/lib/components/apps/editor/AppPreview.svelte index db7d6b7335..a2938adf31 100644 --- a/frontend/src/lib/components/apps/editor/AppPreview.svelte +++ b/frontend/src/lib/components/apps/editor/AppPreview.svelte @@ -21,6 +21,7 @@ export let policy: Policy export let summary: string export let workspace: string + export let isEditor: boolean const appStore = writable(app) const worldStore = writable(undefined) @@ -30,7 +31,8 @@ const connectingInput = writable({ opened: false, - input: undefined + input: undefined, + hoveredComponent: undefined }) const runnableComponents = writable Promise>>({}) @@ -48,7 +50,8 @@ runnableComponents, appPath, workspace, - onchange: undefined + onchange: undefined, + isEditor }) let mounted = false @@ -61,7 +64,7 @@ $: width = $breakpoint === 'sm' ? 'max-w-[640px]' : 'w-full ' -
+
{#if $appStore.grid}
diff --git a/frontend/src/lib/components/apps/editor/GridEditor.svelte b/frontend/src/lib/components/apps/editor/GridEditor.svelte index 466021ca7c..7f5e743da4 100644 --- a/frontend/src/lib/components/apps/editor/GridEditor.svelte +++ b/frontend/src/lib/components/apps/editor/GridEditor.svelte @@ -101,15 +101,26 @@ } -
-
+
+

{$summary}

- + {#if !$connectingInput.opened} + + {/if}
{policy.on_behalf_of ? `on behalf of ${policy.on_behalf_of}` : ''}
-
+
+ {#if $connectingInput.opened} + {#if $connectingInput.opened} +
($connectingInput.hoveredComponent = gridComponent.data.id)} + on:pointerleave={() => ($connectingInput.hoveredComponent = undefined)} + class="absolute w-full h-full bg-black border-2 bg-opacity-25 z-20 flex justify-center items-center" + /> + {/if} +
{dataItem.data.id}
+ {/if}
{ - if (x.type == 'static' && !x.value) { - x.value = x.defaultValue - } - }) - if (newData?.componentInput?.type == 'static') { - newData.componentInput.value = newData.componentInput.defaultValue - } + const newItem: GridItem = { data: newData, id: id diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/componentStaticValues.ts b/frontend/src/lib/components/apps/editor/componentsPanel/componentStaticValues.ts index 14666c9c1e..013be9ba50 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/componentStaticValues.ts +++ b/frontend/src/lib/components/apps/editor/componentsPanel/componentStaticValues.ts @@ -5,7 +5,7 @@ const buttonColorOptions = [...BUTTON_COLORS] export const staticValues = { buttonColorOptions, buttonSizeOptions: ['xs', 'sm', 'md', 'lg', 'xl'], - tableSearchOptions: ['Component', 'Runnable', 'Disabled'], + tableSearchOptions: ['By Component', 'By Runnable', 'Disabled'], chartThemeOptions: ['theme1', 'theme2', 'theme3'], textStyleOptions: ['Title', 'Subtitle', 'Body', 'Label', 'Caption'] } as const diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/data.ts b/frontend/src/lib/components/apps/editor/componentsPanel/data.ts index 96ccaa648f..c7dd08e5b3 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/data.ts +++ b/frontend/src/lib/components/apps/editor/componentsPanel/data.ts @@ -14,7 +14,6 @@ const inputs: ComponentSet = { type: 'static', value: 'Type...', fieldType: 'text', - defaultValue: 'Type...' }, }, card: false @@ -45,13 +44,11 @@ const inputs: ComponentSet = { type: 'static', value: '', fieldType: 'date', - defaultValue: '' }, maxDate: { type: 'static', value: '', fieldType: 'date', - defaultValue: '' } }, card: false, @@ -67,7 +64,6 @@ const inputs: ComponentSet = { type: 'static', value: 'Label', fieldType: 'text', - defaultValue: 'Label' } }, card: false @@ -82,10 +78,6 @@ const inputs: ComponentSet = { type: 'static', fieldType: 'array', subFieldType: 'object', - defaultValue: [ - { value: 'foo', label: 'Foo' }, - { value: 'bar', label: 'Bar' } - ], value: [ { value: 'foo', label: 'Foo' }, { value: 'bar', label: 'Bar' } @@ -94,7 +86,6 @@ const inputs: ComponentSet = { itemKey: { type: 'static', fieldType: 'text', - defaultValue: 'value', value: 'value' } }, @@ -116,29 +107,29 @@ const buttons: ComponentSet = { fieldType: 'any', fields: {}, runnable: undefined, - defaultValue: undefined + }, recomputeIds: undefined, configuration: { label: { type: 'static', - value: undefined, + fieldType: 'text', - defaultValue: 'Lorem ipsum' + value: 'Lorem ipsum' }, color: { fieldType: 'select', type: 'static', - value: undefined, + optionValuesKey: 'buttonColorOptions', - defaultValue: 'blue' + value: 'blue' }, size: { fieldType: 'select', type: 'static', - value: undefined, + optionValuesKey: 'buttonSizeOptions', - defaultValue: 'xs' + value: 'xs' } }, @@ -153,7 +144,7 @@ const buttons: ComponentSet = { fieldType: 'any', fields: {}, runnable: undefined, - defaultValue: undefined + }, recomputeIds: undefined, configuration: { @@ -161,21 +152,18 @@ const buttons: ComponentSet = { type: 'static', value: 'Submit', fieldType: 'text', - defaultValue: 'formcomponent' }, color: { fieldType: 'select', type: 'static', value: 'dark', optionValuesKey: 'buttonColorOptions', - defaultValue: 'dark' }, size: { fieldType: 'select', type: 'static', value: 'xs', optionValuesKey: 'buttonSizeOptions', - defaultValue: 'xs' } }, @@ -194,23 +182,23 @@ const display: ComponentSet = { componentInput: { type: 'static', fieldType: 'textarea', - defaultValue: 'Lorem ipsum', - value: undefined + value: 'Lorem ipsum', + }, configuration: { style: { fieldType: 'select', type: 'static', - value: undefined, + optionValuesKey: 'textStyleOptions', - defaultValue: 'Body' + value: 'Body' }, extraStyle: { type: 'static', fieldType: 'text', - defaultValue: '', - value: undefined + value: '', + }, }, @@ -223,22 +211,22 @@ const display: ComponentSet = { search: { fieldType: 'select', type: 'static', - value: undefined, + optionValuesKey: 'tableSearchOptions', - defaultValue: 'Disabled' + value: 'Disabled' }, pagination: { type: 'static', - value: undefined, + fieldType: 'boolean', - defaultValue: false + value: false } }, componentInput: { type: 'static', fieldType: 'array', subFieldType: 'object', - defaultValue: [ + value: [ { id: 1, name: 'Lorem ipsum', @@ -250,7 +238,7 @@ const display: ComponentSet = { age: 42 } ], - value: undefined + }, card: true, actionButtons: [] @@ -261,26 +249,24 @@ const display: ComponentSet = { configuration: { theme: { type: 'static', - value: undefined, + fieldType: 'select', optionValuesKey: 'chartThemeOptions', - defaultValue: 'theme1' + value: 'theme1' }, labels: { type: 'static', value: ['First', 'Second', 'Third'], fieldType: 'array', - subFieldType: 'text', - defaultValue: ['First', 'Second', 'Third'] } }, componentInput: { type: 'static', fieldType: 'array', subFieldType: 'number', - defaultValue: [25, 50, 25], - value: undefined + value: [25, 50, 25], + }, card: true }, @@ -290,25 +276,25 @@ const display: ComponentSet = { configuration: { theme: { type: 'static', - value: undefined, + fieldType: 'select', optionValuesKey: 'chartThemeOptions', - defaultValue: 'theme1' + value: 'theme1' }, labels: { type: 'static', - value: undefined, + fieldType: 'array', subFieldType: 'text', - defaultValue: ['Lorem ipsum', 'Lorem ipsum', 'Lorem ipsum'] + value: ['Lorem ipsum', 'Lorem ipsum', 'Lorem ipsum'] } }, componentInput: { type: 'static', fieldType: 'array', subFieldType: 'number', - defaultValue: [25, 50, 25], - value: undefined + value: [25, 50, 25], + }, card: true }, @@ -318,8 +304,8 @@ const display: ComponentSet = { componentInput: { type: 'static', fieldType: 'object', - defaultValue: { "foo": 42 }, - value: undefined + value: { "foo": 42 }, + }, configuration: {}, card: false diff --git a/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte b/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte index c8135c2b19..903bd9a6e9 100644 --- a/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte +++ b/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte @@ -19,7 +19,8 @@ path }, type: 'connected' - } + }, + hoveredComponent: undefined } } } @@ -36,10 +37,14 @@ -
+
{#each Object.entries($staticOutputs) as [componentId, outputs] (componentId)} {#if outputs.length > 0 && $worldStore?.outputsById[componentId]} -
+
@@ -194,6 +195,7 @@ size="sm" color="blue" startIcon={{ icon: faMousePointer }} + btnClasses="truncate" > Select a script or flow diff --git a/frontend/src/lib/components/apps/inputType.ts b/frontend/src/lib/components/apps/inputType.ts index 97772b68e0..9912fc126e 100644 --- a/frontend/src/lib/components/apps/inputType.ts +++ b/frontend/src/lib/components/apps/inputType.ts @@ -84,7 +84,6 @@ type AppInputSpec = ( type InputConfiguration = { fieldType: T - defaultValue: U subFieldType?: V format?: string | undefined } diff --git a/frontend/src/lib/components/apps/types.ts b/frontend/src/lib/components/apps/types.ts index 5a78d76529..f7bd79fec9 100644 --- a/frontend/src/lib/components/apps/types.ts +++ b/frontend/src/lib/components/apps/types.ts @@ -122,6 +122,7 @@ export type ConnectingInput = { opened: boolean input?: ConnectedInput sourceName?: string + hoveredComponent: string | undefined } export type AppEditorContext = { @@ -137,7 +138,8 @@ export type AppEditorContext = { runnableComponents: Writable Promise>> appPath: string, workspace: string, - onchange: (() => void) | undefined + onchange: (() => void) | undefined, + isEditor: boolean } export type EditorMode = 'dnd' | 'preview' diff --git a/frontend/src/lib/components/apps/utils.ts b/frontend/src/lib/components/apps/utils.ts index 5c53e3832c..32e2dc3008 100644 --- a/frontend/src/lib/components/apps/utils.ts +++ b/frontend/src/lib/components/apps/utils.ts @@ -58,8 +58,7 @@ export function schemaToInputsSpec(schema: Schema): Record {/if}

- Inline new {kind == 'script' ? 'common' : kind} script + Inline new {kind == 'script' ? 'action' : kind} script Embed a script directly inside a flow instead of saving the script into your workspace for reuse. You can always save an inline script to your workspace later. diff --git a/frontend/src/lib/components/flows/propPicker/PropPickerWrapper.svelte b/frontend/src/lib/components/flows/propPicker/PropPickerWrapper.svelte index cdf3423a72..529f63e545 100644 --- a/frontend/src/lib/components/flows/propPicker/PropPickerWrapper.svelte +++ b/frontend/src/lib/components/flows/propPicker/PropPickerWrapper.svelte @@ -19,6 +19,7 @@ - - - - - - {#if result} - { - dispatch('select', detail) - if ($propPickerConfig?.onSelect(detail)) { - propPickerConfig.set(undefined) - } - }} - /> - {:else if pickableProperties} - { - dispatch('select', detail) - if ($propPickerConfig?.onSelect(detail)) { - propPickerConfig.set(undefined) - } - }} - /> - {/if} - - +
propPickerConfig.set(undefined)} +> + + + + + + {#if result} + { + dispatch('select', detail) + if ($propPickerConfig?.onSelect(detail)) { + propPickerConfig.set(undefined) + } + }} + /> + {:else if pickableProperties} + { + dispatch('select', detail) + if ($propPickerConfig?.onSelect(detail)) { + propPickerConfig.set(undefined) + } + }} + /> + {/if} + + +
diff --git a/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte b/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte index 03dd0c83e4..b7f8676a68 100644 --- a/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte +++ b/frontend/src/lib/components/propertyPicker/ObjectViewer.svelte @@ -117,8 +117,10 @@ {#if !isLast && collapsed} , {/if} -{:else} +{:else if topBrackets} {openBracket}{closeBracket} +{:else} + No items {/if}