From b33735d8cccba22dd5559fe0f8b5d55f655f41fc Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 27 Feb 2026 16:06:51 +0100 Subject: [PATCH] refactor: add callback props alongside createEventDispatcher for svelte 5 migration Co-Authored-By: Claude Opus 4.6 --- .../lib/components/AppConnectDrawer.svelte | 5 +- .../src/lib/components/AppConnectInner.svelte | 12 +- frontend/src/lib/components/ArgEnum.svelte | 10 +- frontend/src/lib/components/ArgInput.svelte | 59 ++++- .../lib/components/AssignableTagsInner.svelte | 5 +- .../ChangeInstanceUsernameInner.svelte | 18 +- .../lib/components/ContentSearchInner.svelte | 9 +- .../components/ContentSearchInnerItem.svelte | 4 +- .../lib/components/DarkModeObserver.svelte | 7 +- frontend/src/lib/components/DateInput.svelte | 6 +- .../src/lib/components/DateTimeInput.svelte | 10 +- .../src/lib/components/DeployButton.svelte | 9 +- .../src/lib/components/DeployWorkspace.svelte | 19 +- .../src/lib/components/DisplayResult.svelte | 6 +- .../components/DisplayResultControlBar.svelte | 6 +- .../lib/components/EditableSchemaForm.svelte | 8 +- frontend/src/lib/components/Editor.svelte | 20 +- frontend/src/lib/components/EditorBar.svelte | 18 +- .../src/lib/components/FlowGraphViewer.svelte | 41 ++-- .../components/FlowHistoryJobPicker.svelte | 12 +- .../FlowLoopIterationPreview.svelte | 6 +- .../lib/components/FlowPreviewContent.svelte | 9 +- .../src/lib/components/FolderEditor.svelte | 4 +- .../components/GitRepoPopoverPicker.svelte | 4 +- .../components/GitRepoResourcePicker.svelte | 10 +- .../src/lib/components/GroupEditor.svelte | 4 +- .../src/lib/components/HistoricInputs.svelte | 10 +- .../src/lib/components/InfiniteList.svelte | 12 +- .../lib/components/InputTransformForm.svelte | 9 +- .../lib/components/InstanceGroupEditor.svelte | 32 +-- .../lib/components/InstanceNameEditor.svelte | 214 +++++++++--------- .../src/lib/components/InstanceSetting.svelte | 5 +- .../lib/components/InstanceSettings.svelte | 6 +- .../lib/components/InviteGlobalUser.svelte | 6 +- frontend/src/lib/components/JsonEditor.svelte | 13 +- frontend/src/lib/components/JsonInputs.svelte | 14 +- frontend/src/lib/components/Path.svelte | 5 +- .../src/lib/components/RadioButton.svelte | 21 +- .../src/lib/components/ResourceEditor.svelte | 11 +- .../lib/components/ResourceTypePicker.svelte | 9 +- .../lib/components/S3FilePickerInner.svelte | 5 +- .../src/lib/components/S3ObjectPicker.svelte | 8 +- .../lib/components/SaveInputsButton.svelte | 19 +- .../lib/components/SavedInputsPicker.svelte | 10 +- .../src/lib/components/SavedInputsV2.svelte | 6 +- frontend/src/lib/components/SchemaForm.svelte | 42 +++- .../components/SchemaFormWithArgPicker.svelte | 7 +- .../src/lib/components/ScriptEditor.svelte | 8 +- .../src/lib/components/ScriptPicker.svelte | 5 +- .../components/ScriptVersionHistory.svelte | 11 +- .../src/lib/components/SimpleEditor.svelte | 12 +- .../src/lib/components/TemplateEditor.svelte | 12 +- frontend/src/lib/components/Toggle.svelte | 5 +- .../src/lib/components/UserSettings.svelte | 5 +- .../src/lib/components/WorkerGroup.svelte | 7 +- .../src/lib/components/WorkerTagSelect.svelte | 8 +- .../display/dbtable/DeleteRow.svelte | 4 +- .../display/dbtable/InsertRowRunnable.svelte | 4 +- .../table/AppAggridExplorerTable.svelte | 18 +- .../table/AppAggridTableActions.svelte | 12 +- .../components/display/table/AppCell.svelte | 6 +- .../apps/components/helpers/InputValue.svelte | 6 +- .../helpers/RunnableComponent.svelte | 31 ++- .../apps/editor/AppJobsDrawer.svelte | 13 +- .../apps/editor/ComponentHeader.svelte | 21 +- .../apps/editor/DecisionTreeDebug.svelte | 11 +- .../apps/editor/DeploymentHistory.svelte | 7 +- .../apps/editor/GridEditorMenu.svelte | 16 +- .../components/apps/editor/GridViewer.svelte | 17 +- .../apps/editor/RecomputeAllButton.svelte | 8 +- .../components/apps/editor/TabsDebug.svelte | 6 +- .../editor/componentsPanel/CssProperty.svelte | 13 +- .../componentsPanel/CustomComponentRow.svelte | 5 +- .../editor/componentsPanel/GroupRow.svelte | 5 +- .../editor/componentsPanel/ListItem.svelte | 5 +- .../editor/componentsPanel/NameEditor.svelte | 5 +- .../componentsPanel/ThemeNameEditor.svelte | 4 +- .../editor/componentsPanel/ThemeRow.svelte | 12 +- .../EmptyInlineScript.svelte | 10 +- .../InlineScriptEditor.svelte | 9 +- .../InlineScriptEditorPanel.svelte | 5 +- .../InlineScriptHiddenRunnable.svelte | 13 +- .../InlineScriptRunnableByPath.svelte | 22 +- .../ArrayStaticInputEditor.svelte | 5 +- .../ComponentInputTypeEditor.svelte | 9 +- .../settingsPanel/InputsSpecEditor.svelte | 8 +- .../settingsPanel/InputsSpecsEditor.svelte | 6 +- .../settingsPanel/QuickAddColumn.svelte | 5 +- .../InsertDecisionTreeNode.svelte | 12 +- .../inputEditor/ColorInput.svelte | 4 +- .../mainInput/InlineScriptList.svelte | 5 +- .../mainInput/RunnableSelector.svelte | 32 ++- .../mainInput/WorkspaceFlowList.svelte | 5 +- .../mainInput/WorkspaceScriptList.svelte | 5 +- .../shared/ScriptRunConfiguration.svelte | 6 +- .../lib/components/common/CloseButton.svelte | 13 +- .../components/common/button/Button.svelte | 10 +- .../components/common/button/UndoRedo.svelte | 12 +- .../clearableInput/ClearableInput.svelte | 27 ++- .../DraftTriggersConfirmationModal.svelte | 17 +- .../components/common/drawer/Drawer.svelte | 13 +- .../common/drawer/DrawerContent.svelte | 5 +- .../common/fileUpload/FileUpload.svelte | 13 +- .../common/fileUpload/FileUploadModal.svelte | 18 +- .../lib/components/common/menu/Menu.svelte | 8 +- .../lib/components/common/modal/Modal.svelte | 9 +- .../components/common/stepper/Stepper.svelte | 19 +- .../lib/components/common/table/AppRow.svelte | 9 +- .../components/common/table/FlowRow.svelte | 7 +- .../components/common/table/ScriptRow.svelte | 8 +- .../src/lib/components/common/tabs/Tab.svelte | 5 +- .../lib/components/common/tabs/Tabs.svelte | 5 +- .../copilot/FlowCopilotInputsModal.svelte | 15 +- .../lib/components/copilot/IteratorGen.svelte | 13 +- .../components/copilot/PredicateGen.svelte | 10 +- .../components/copilot/StepGenQuick.svelte | 6 +- .../components/copilot/StepInputGen.svelte | 11 +- .../details/DetailPageHeader.svelte | 5 +- .../lib/components/display/PdfViewer.svelte | 8 +- .../flows/common/FlowCardHeader.svelte | 12 +- .../flows/content/FlowInputEditor.svelte | 4 +- .../flows/content/FlowInputs.svelte | 10 +- .../flows/content/FlowInputsFlow.svelte | 4 +- .../flows/content/FlowInputsQuick.svelte | 29 ++- .../flows/content/FlowModuleHeader.svelte | 78 +++++-- .../content/FlowModuleWorkerTagSelect.svelte | 6 +- .../flows/content/GenAiQuick.svelte | 14 +- .../flows/header/FlowPreviewButtons.svelte | 5 +- .../flows/map/FlowErrorHandlerItem.svelte | 9 +- .../flows/map/FlowModuleSchemaItem.svelte | 24 +- .../flows/map/FlowModuleSchemaMap.svelte | 17 +- .../flows/map/InsertModuleInner.svelte | 31 ++- .../lib/components/flows/map/MapItem.svelte | 11 +- .../flows/map/VirtualItemWrapper.svelte | 5 +- .../pickers/FlowScriptPickerQuick.svelte | 17 +- .../flows/pickers/FlowToplevelNode.svelte | 8 +- .../flows/pickers/PickHubApp.svelte | 11 +- .../flows/pickers/PickHubFlow.svelte | 11 +- .../flows/pickers/PickHubScript.svelte | 5 +- .../flows/pickers/PickHubScriptQuick.svelte | 5 +- .../pickers/WorkspaceScriptPicker.svelte | 5 +- .../pickers/WorkspaceScriptPickerQuick.svelte | 10 +- .../flows/propPicker/PropPickerWrapper.svelte | 6 +- .../flows/propPicker/StepHistory.svelte | 7 +- .../renderers/triggers/TriggersWrapper.svelte | 8 +- frontend/src/lib/components/home/Item.svelte | 23 +- .../components/home/ListFiltersQuick.svelte | 22 +- .../propertyPicker/ObjectViewer.svelte | 5 +- .../raw_apps/RawAppEditorHeader.svelte | 8 +- .../raw_apps/RawAppInlineScriptEditor.svelte | 6 +- .../RawAppInlineScriptRunnable.svelte | 14 +- .../lib/components/runs/JobRunsPreview.svelte | 11 +- .../src/lib/components/runs/RunRow.svelte | 40 +++- .../src/lib/components/runs/RunsTable.svelte | 9 +- .../lib/components/schema/AddProperty.svelte | 8 +- .../schema/AddPropertyFormV2.svelte | 10 +- .../schema/EditableSchemaDrawer.svelte | 6 +- .../schema/FlowPropertyEditor.svelte | 5 +- .../components/schema/PropertyEditor.svelte | 16 +- .../schema/RunningJobSchemaPicker.svelte | 65 +++--- .../components/schema/SchemaFormDND.svelte | 5 +- .../lib/components/sidebar/MenuButton.svelte | 16 +- .../src/lib/components/table/DataTable.svelte | 13 +- .../components/triggers/CaptureButton.svelte | 7 +- .../components/triggers/CaptureSection.svelte | 36 ++- .../components/triggers/CaptureTable.svelte | 28 ++- .../components/triggers/TriggersEditor.svelte | 5 +- .../nats/NatsTriggersConfigSection.svelte | 5 +- .../lib/components/tutorials/Tutorial.svelte | 21 +- .../tutorials/TutorialControls.svelte | 15 +- .../components/wizards/AgChartWizard.svelte | 4 +- .../components/wizards/ChartJSWizard.svelte | 8 +- .../components/wizards/PlotlyWizard.svelte | 8 +- 173 files changed, 1724 insertions(+), 561 deletions(-) diff --git a/frontend/src/lib/components/AppConnectDrawer.svelte b/frontend/src/lib/components/AppConnectDrawer.svelte index 2a1498d055..ef52111c3b 100644 --- a/frontend/src/lib/components/AppConnectDrawer.svelte +++ b/frontend/src/lib/components/AppConnectDrawer.svelte @@ -1,5 +1,4 @@ @@ -20,6 +21,7 @@ {href} onclick={() => { dispatch('close') + onclose?.() }} > {title} diff --git a/frontend/src/lib/components/DarkModeObserver.svelte b/frontend/src/lib/components/DarkModeObserver.svelte index 30d0d78091..24e60d1ace 100644 --- a/frontend/src/lib/components/DarkModeObserver.svelte +++ b/frontend/src/lib/components/DarkModeObserver.svelte @@ -36,10 +36,13 @@ import { onMount, onDestroy } from 'svelte' import { createEventDispatcher } from 'svelte' - let { darkMode = $bindable(false) }: { darkMode?: boolean } = $props() + let { + darkMode = $bindable(false), + onchange = undefined + }: { darkMode?: boolean; onchange?: (...args: any[]) => any } = $props() const dispatch = createEventDispatcher() let isDarkMode = useIsDarkMode({ - onChange: (newDarkMode) => dispatch('change', newDarkMode) + onChange: (newDarkMode) => (dispatch('change', newDarkMode), onchange?.(newDarkMode)) }) $effect(() => { if (darkMode !== isDarkMode.val) { diff --git a/frontend/src/lib/components/DateInput.svelte b/frontend/src/lib/components/DateInput.svelte index d634a149ae..2f4c10d01d 100644 --- a/frontend/src/lib/components/DateInput.svelte +++ b/frontend/src/lib/components/DateInput.svelte @@ -12,6 +12,7 @@ maxDate?: string | undefined dateFormat?: string | undefined disabled?: boolean + onchange?: (...args: any[]) => any } let { @@ -20,7 +21,8 @@ minDate = undefined, maxDate = undefined, dateFormat = 'dd-MM-yyyy', - disabled = false + disabled = false, + onchange = undefined }: Props = $props() const defaultDateFormat = 'dd-MM-yyyy' @@ -60,6 +62,7 @@ const parsedDate = format(dateFromValue, getFormat()) value = parsedDate dispatch('change', value) + onchange?.(value) } catch (error) { console.error('Failed to parse date:', error) } @@ -91,6 +94,7 @@ } else { value = null dispatch('change', value) + onchange?.(value) } }} /> diff --git a/frontend/src/lib/components/DateTimeInput.svelte b/frontend/src/lib/components/DateTimeInput.svelte index ba3a848ff9..d047779082 100644 --- a/frontend/src/lib/components/DateTimeInput.svelte +++ b/frontend/src/lib/components/DateTimeInput.svelte @@ -25,6 +25,8 @@ * 'local' will use the local timezone of the user */ timezone?: 'naive' | 'local' + onchange?: (...args: any[]) => any + onclear?: (...args: any[]) => any } let { @@ -36,7 +38,9 @@ maxDate = undefined, disabled = undefined, inputClass = undefined, - timezone = 'local' + timezone = 'local', + onchange = undefined, + onclear = undefined }: Props = $props() let date: string | undefined = $state(undefined) @@ -80,6 +84,7 @@ if (date === '' && value) { value = null dispatchIfMounted('change', value) + onchange?.(value) return } @@ -89,6 +94,7 @@ if (newDate.getFullYear() < 1900) return value = newDate.toISOString() dispatchIfMounted('change', value) + onchange?.(value) } } @@ -114,6 +120,7 @@ newDate.setMinutes(newDate.getMinutes() + mins) value = newDate.toISOString() dispatch('change', value) + onchange?.(value) } let randomId = 'datetarget-' + Math.random().toString(36).substring(7) @@ -189,6 +196,7 @@ on:click={() => { value = null dispatch('clear') + onclear?.() }} > {/if} diff --git a/frontend/src/lib/components/DeployButton.svelte b/frontend/src/lib/components/DeployButton.svelte index 16ccc04cd2..ec5be21392 100644 --- a/frontend/src/lib/components/DeployButton.svelte +++ b/frontend/src/lib/components/DeployButton.svelte @@ -7,7 +7,8 @@ loading = false, loadingSave = false, newFlow = false, - dropdownItems = [] + dropdownItems = [], + onsave = undefined }: { loading?: boolean loadingSave?: boolean @@ -16,6 +17,7 @@ label: string onClick: () => void }> + onsave?: (...args: any[]) => any } = $props() const dispatch = createEventDispatcher() @@ -32,7 +34,7 @@ variant="accent" unifiedSize="md" startIcon={{ icon: Save }} - on:click={() => dispatch('save')} + on:click={() => (dispatch('save'), onsave?.())} dropdownItems={!newFlow ? dropdownItems : undefined} tooltipPopover={{ placement: 'bottom-end', @@ -66,6 +68,7 @@ onkeydown={async (e) => { if (e.key === 'Enter') { dispatch('save', deploymentMsg) + onsave?.(deploymentMsg) } }} bind:this={msgInput} @@ -73,7 +76,7 @@ - diff --git a/frontend/src/lib/components/EditableSchemaForm.svelte b/frontend/src/lib/components/EditableSchemaForm.svelte index 02b3ad7304..d564461c49 100644 --- a/frontend/src/lib/components/EditableSchemaForm.svelte +++ b/frontend/src/lib/components/EditableSchemaForm.svelte @@ -81,6 +81,8 @@ extraTab?: import('svelte').Snippet schemaFormClassName?: string onChange?: (args: Record) => void + oneditPanelSizeChanged?: (...args: any[]) => any + ondelete?: (...args: any[]) => any } let { @@ -117,7 +119,9 @@ runButton, extraTab, schemaFormClassName = undefined, - onChange = undefined + onChange = undefined, + oneditPanelSizeChanged = undefined, + ondelete = undefined }: Props = $props() $effect.pre(() => { @@ -322,6 +326,7 @@ editPanelSize = editSize inputPanelSize = inputSize dispatch('editPanelSizeChanged', editSize) + oneditPanelSizeChanged?.(editSize) } let panelButtonWidth: number = $state(0) @@ -647,6 +652,7 @@ aria-label="Clear" onclick={() => { dispatch('delete', argName) + ondelete?.(argName) }} > diff --git a/frontend/src/lib/components/Editor.svelte b/frontend/src/lib/components/Editor.svelte index 46a30ffc16..8c18430a5d 100644 --- a/frontend/src/lib/components/Editor.svelte +++ b/frontend/src/lib/components/Editor.svelte @@ -144,6 +144,12 @@ preparedAssetsSqlQueries?: InferAssetsSqlQueryDetails[] | undefined // To execute preview scripts with the right worker group customTag?: string + onchange?: (...args: any[]) => any + onsaveDraft?: (...args: any[]) => any + onblur?: (...args: any[]) => any + onfocus?: (...args: any[]) => any + ontoggleTestPanel?: (...args: any[]) => any + onataReady?: (...args: any[]) => any } let { @@ -174,7 +180,13 @@ enablePreprocessorSnippet = false, rawAppRunnableKey = undefined, preparedAssetsSqlQueries, - customTag + customTag, + onchange = undefined, + onsaveDraft = undefined, + onblur = undefined, + onfocus = undefined, + ontoggleTestPanel = undefined, + onataReady = undefined }: Props = $props() $effect.pre(() => { @@ -395,6 +407,7 @@ } code = ncode dispatch('change', ncode) + onchange?.(ncode) } export function append(code: string): void { @@ -1237,6 +1250,7 @@ function saveDraft() { dispatch('saveDraft', code) + onsaveDraft?.(code) } let vimDisposable: IDisposable | undefined = $state(undefined) @@ -1450,6 +1464,7 @@ editor?.onDidBlurEditorText(() => { dispatch('blur') + onblur?.() }) editor?.onDidChangeCursorPosition((event) => { @@ -1458,6 +1473,7 @@ editor?.onDidFocusEditorText(() => { dispatch('focus') + onfocus?.() // for escape we use onkeydown instead of addCommand because addCommand on escape specifically prevents default behavior (like autocomplete cancellation) editor?.onKeyDown((e) => { @@ -1526,6 +1542,7 @@ editor?.addCommand(KeyMod.CtrlCmd | KeyCode.KeyU, function () { dispatch('toggleTestPanel') + ontoggleTestPanel?.() }) if ( @@ -1705,6 +1722,7 @@ ata?.(code ?? '') } dispatch('ataReady') + onataReady?.() } } diff --git a/frontend/src/lib/components/EditorBar.svelte b/frontend/src/lib/components/EditorBar.svelte index 3dfc25e127..18ba5ba64d 100644 --- a/frontend/src/lib/components/EditorBar.svelte +++ b/frontend/src/lib/components/EditorBar.svelte @@ -94,6 +94,9 @@ right?: import('svelte').Snippet openAiChat?: boolean moduleId?: string + ontoggleCollabMode?: (...args: any[]) => any + oncollabPopup?: (...args: any[]) => any + oncreateScriptFromInlineScript?: (...args: any[]) => any } let { @@ -116,7 +119,10 @@ showHistoryDrawer = $bindable(false), right, openAiChat = false, - moduleId = undefined + moduleId = undefined, + ontoggleCollabMode = undefined, + oncollabPopup = undefined, + oncreateScriptFromInlineScript = undefined }: Props = $props() let contextualVariablePicker: ItemPicker | undefined = $state() @@ -1054,7 +1060,7 @@ JsonNode ${windmillPathToCamelCaseName(path)} = JsonNode.Parse(await client.GetS options={{ right: '' }} size="xs" checked={collabLive} - on:change={() => dispatch('toggleCollabMode')} + on:change={() => (dispatch('toggleCollabMode'), ontoggleCollabMode?.())} /> {#snippet text()} @@ -1066,7 +1072,8 @@ JsonNode ${windmillPathToCamelCaseName(path)} = JsonNode.Parse(await client.GetS (dispatch('collabPopup'), oncollabPopup?.())} + >
{#each collabUsers as user} @@ -1125,7 +1132,10 @@ JsonNode ${windmillPathToCamelCaseName(path)} = JsonNode.Parse(await client.GetS unifiedSize="sm" variant="subtle" startIcon={{ icon: Save }} - on:click={() => dispatch('createScriptFromInlineScript')} + on:click={() => ( + dispatch('createScriptFromInlineScript'), + oncreateScriptFromInlineScript?.() + )} iconOnly={false} > Save to workspace diff --git a/frontend/src/lib/components/FlowGraphViewer.svelte b/frontend/src/lib/components/FlowGraphViewer.svelte index f4b3b1cc97..6e2793206f 100644 --- a/frontend/src/lib/components/FlowGraphViewer.svelte +++ b/frontend/src/lib/components/FlowGraphViewer.svelte @@ -9,24 +9,25 @@ import { dfs } from './flows/dfs' import { workspaceStore } from '$lib/stores' - interface Props { flow: { - summary: string - description?: string - value: FlowValue - schema?: any - path?: string - }; - overflowAuto?: boolean; - noSide?: boolean; - download?: boolean; - noGraph?: boolean; - triggerNode?: boolean; - stepDetail?: FlowModule | string | undefined; - workspace?: string | undefined; - minHeight?: number; - noBorder?: boolean; + summary: string + description?: string + value: FlowValue + schema?: any + path?: string + } + overflowAuto?: boolean + noSide?: boolean + download?: boolean + noGraph?: boolean + triggerNode?: boolean + stepDetail?: FlowModule | string | undefined + workspace?: string | undefined + minHeight?: number + noBorder?: boolean + ontriggerDetail?: (...args: any[]) => any + onselect?: (...args: any[]) => any } let { @@ -39,8 +40,10 @@ stepDetail = $bindable(undefined), workspace = $workspaceStore, minHeight = 400, - noBorder = false - }: Props = $props(); + noBorder = false, + ontriggerDetail = undefined, + onselect = undefined + }: Props = $props() const dispatch = createEventDispatcher() @@ -67,6 +70,7 @@ onSelect={(nodeId) => { if (nodeId === 'Trigger') { dispatch('triggerDetail') + ontriggerDetail?.() return } else if (nodeId === 'failure') { stepDetail = flow?.value?.failure_module @@ -77,6 +81,7 @@ } stepDetail = stepDetail ?? nodeId dispatch('select', stepDetail) + onselect?.(stepDetail) }} />
diff --git a/frontend/src/lib/components/FlowHistoryJobPicker.svelte b/frontend/src/lib/components/FlowHistoryJobPicker.svelte index 3a703d8bd7..80fbfc83e3 100644 --- a/frontend/src/lib/components/FlowHistoryJobPicker.svelte +++ b/frontend/src/lib/components/FlowHistoryJobPicker.svelte @@ -12,13 +12,19 @@ selected?: string | undefined selectInitial?: boolean loading?: boolean + onselect?: (...args: any[]) => any + onnohistory?: (...args: any[]) => any + onunselect?: (...args: any[]) => any } let { path, selected = undefined, selectInitial = false, - loading = $bindable(false) + loading = $bindable(false), + onselect = undefined, + onnohistory = undefined, + onunselect = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -33,9 +39,11 @@ if (jobs.length > 0) { if (selectInitial) { dispatch('select', { jobId: jobs[0].id, initial: true }) + onselect?.({ jobId: jobs[0].id, initial: true }) } } else { dispatch('nohistory') + onnohistory?.() } loading = false } @@ -55,8 +63,10 @@ on:select={(e) => { if (e.detail) { dispatch('select', { jobId: e.detail?.jobId, initial: false }) + onselect?.({ jobId: e.detail?.jobId, initial: false }) } else { dispatch('unselect') + onunselect?.() } }} {selected} diff --git a/frontend/src/lib/components/FlowLoopIterationPreview.svelte b/frontend/src/lib/components/FlowLoopIterationPreview.svelte index f92072b5fd..e1c29d8fcd 100644 --- a/frontend/src/lib/components/FlowLoopIterationPreview.svelte +++ b/frontend/src/lib/components/FlowLoopIterationPreview.svelte @@ -18,6 +18,7 @@ modules: FlowModule[] previewArgs?: Record whileLoop?: boolean + onclose?: (...args: any[]) => any } let { @@ -26,7 +27,8 @@ job = $bindable(undefined), modules, previewArgs = $bindable({}), - whileLoop = false + whileLoop = false, + onclose = undefined }: Props = $props() export const forloopSchema: Schema = { @@ -112,7 +114,7 @@
| undefined + onselect?: (...args: any[]) => any } let { @@ -26,7 +27,8 @@ showAuthor = false, placement = 'top-end', limitPayloadSize = false, - searchArgs = undefined + searchArgs = undefined, + onselect = undefined }: Props = $props() let historicList: HistoricList | undefined = $state(undefined) @@ -44,11 +46,16 @@ if (data.payloadData === 'WINDMILL_TOO_BIG') { const fullPayload = await data.getFullPayload?.() dispatch('select', { args: fullPayload, jobId: data.id }) + onselect?.({ args: fullPayload, jobId: data.id }) } else { dispatch('select', { args: structuredClone($state.snapshot(data.payloadData)), jobId: data.id }) + onselect?.({ + args: structuredClone($state.snapshot(data.payloadData)), + jobId: data.id + }) } } @@ -84,6 +91,7 @@ selected = undefined if (dispatchEvent) { dispatch('select', undefined) + onselect?.(undefined) } } diff --git a/frontend/src/lib/components/InfiniteList.svelte b/frontend/src/lib/components/InfiniteList.svelte index d4b5a05f9a..382b0b901e 100644 --- a/frontend/src/lib/components/InfiniteList.svelte +++ b/frontend/src/lib/components/InfiniteList.svelte @@ -22,6 +22,8 @@ extra_row?: import('svelte').Snippet<[any]> children?: import('svelte').Snippet<[any]> empty?: import('svelte').Snippet<[any]> + onerror?: (...args: any[]) => any + onselect?: (...args: any[]) => any } let { @@ -43,7 +45,9 @@ columns, extra_row, children, - empty + empty, + onerror = undefined, + onselect = undefined }: Props = $props() const perPage = 20 @@ -125,6 +129,7 @@ if (hasAlreadyFailed) return hasAlreadyFailed = true dispatch('error', { type: 'load', error: err }) + onerror?.({ type: 'load', error: err }) } finally { loading = false loadingMore = false @@ -145,6 +150,7 @@ }, 100) } catch (err) { dispatch('error', { type: 'delete', error: err }) + onerror?.({ type: 'delete', error: err }) } } @@ -178,7 +184,7 @@ {#if extra_row} dispatch('select', 'extraRow')} + onclick={() => (dispatch('select', 'extraRow'), onselect?.('extraRow'))} class={twMerge( extraRowClasses.class, selectedItemId === 'extraRow' ? extraRowClasses.bgSelected : extraRowClasses.bgHover, @@ -195,7 +201,7 @@ {@render customRow?.({ item, hover })} {:else} dispatch('select', item)} + onclick={() => (dispatch('select', item), onselect?.(item))} class={twMerge( selectedItemId === item.id ? 'bg-surface-selected' : 'hover:bg-surface-hover', 'cursor-pointer rounded-md', diff --git a/frontend/src/lib/components/InputTransformForm.svelte b/frontend/src/lib/components/InputTransformForm.svelte index 98bb3035de..9d9c0f58e9 100644 --- a/frontend/src/lib/components/InputTransformForm.svelte +++ b/frontend/src/lib/components/InputTransformForm.svelte @@ -68,6 +68,7 @@ allowedAiTransforms?: string[] | undefined s3StorageConfigured?: boolean chatInputEnabled?: boolean + onchange?: (...args: any[]) => any } let { @@ -95,7 +96,8 @@ isAgentTool = false, allowedAiTransforms = isAgentTool ? undefined : [], s3StorageConfigured = true, - chatInputEnabled = false + chatInputEnabled = false, + onchange = undefined }: Props = $props() let monaco: SimpleEditor | undefined = $state(undefined) @@ -300,6 +302,7 @@ // Dispatch change dispatch('change', { argName, arg }) + onchange?.({ argName, arg }) } async function switchToJsAndConnect(onPath: (path: string) => void) { @@ -579,6 +582,7 @@ focusProp?.(argName, (path) => { connectProperty(path) dispatch('change', { argName }) + onchange?.({ argName }) return true }) } @@ -774,6 +778,7 @@ fontSize={12} on:change={() => { dispatch('change', { argName, arg }) + onchange?.({ argName, arg }) }} loadAsync class="bg-surface-input" @@ -792,6 +797,7 @@ shouldDispatchChanges on:change={() => { dispatch('change', { argName, arg }) + onchange?.({ argName, arg }) }} label={argName} bind:editor={monaco} @@ -867,6 +873,7 @@ }} on:change={() => { dispatch('change', { argName, arg }) + onchange?.({ argName, arg }) }} autoHeight loadAsync diff --git a/frontend/src/lib/components/InstanceGroupEditor.svelte b/frontend/src/lib/components/InstanceGroupEditor.svelte index 860b41de68..ac9ee8606f 100644 --- a/frontend/src/lib/components/InstanceGroupEditor.svelte +++ b/frontend/src/lib/components/InstanceGroupEditor.svelte @@ -1,5 +1,4 @@
@@ -58,6 +57,7 @@ requestBody: { new_summary: instance_group?.summary ?? '' } }) dispatch('update') + onupdate?.() sendUserToast('New summary saved') }}>Save Summary @@ -81,6 +81,7 @@ requestBody: { email: email } }) dispatch('update') + onupdate?.() sendUserToast('User added') loadInstanceGroup() }} @@ -97,26 +98,27 @@ {/snippet} {#snippet body()} - + {#each members as { member_email }} {member_email} remove {/each} - {/snippet} + {/snippet} {:else}
diff --git a/frontend/src/lib/components/InstanceNameEditor.svelte b/frontend/src/lib/components/InstanceNameEditor.svelte index e6060d98a5..ea4464b177 100644 --- a/frontend/src/lib/components/InstanceNameEditor.svelte +++ b/frontend/src/lib/components/InstanceNameEditor.svelte @@ -1,7 +1,7 @@ @@ -60,115 +66,111 @@ closeButton > {#snippet trigger()} - - - + {/snippet} {#snippet content()} - -
- {#if automateUsernameCreation && username} - - {/if} - +
{/snippet} diff --git a/frontend/src/lib/components/InstanceSetting.svelte b/frontend/src/lib/components/InstanceSetting.svelte index 1780bc1d80..307098350a 100644 --- a/frontend/src/lib/components/InstanceSetting.svelte +++ b/frontend/src/lib/components/InstanceSetting.svelte @@ -36,6 +36,7 @@ openSmtpSettings?: () => void oauths?: Record warning?: string + oncloseDrawer?: (...args: any[]) => any } let { @@ -45,7 +46,8 @@ loading = true, openSmtpSettings, oauths, - warning + warning, + oncloseDrawer = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -523,6 +525,7 @@ on:click={() => { isCriticalAlertsUIOpen.set(true) dispatch('closeDrawer') + oncloseDrawer?.() }} > Show critical alerts diff --git a/frontend/src/lib/components/InstanceSettings.svelte b/frontend/src/lib/components/InstanceSettings.svelte index 10f65061bf..4dd6289c7c 100644 --- a/frontend/src/lib/components/InstanceSettings.svelte +++ b/frontend/src/lib/components/InstanceSettings.svelte @@ -30,6 +30,7 @@ quickSetup?: boolean yamlMode?: boolean hasUnsavedChanges?: boolean + onsaved?: (...args: any[]) => any } let { @@ -40,7 +41,8 @@ onNavigateToTab, quickSetup = false, yamlMode = $bindable(false), - hasUnsavedChanges = $bindable(false) + hasUnsavedChanges = $bindable(false), + onsaved = undefined }: Props = $props() let values: Writable> = writable({}) @@ -229,6 +231,7 @@ } else { sendUserToast('Settings updated') dispatch('saved') + onsaved?.() } } @@ -571,6 +574,7 @@ } else { sendUserToast('Settings updated') dispatch('saved') + onsaved?.() } } diff --git a/frontend/src/lib/components/InviteGlobalUser.svelte b/frontend/src/lib/components/InviteGlobalUser.svelte index f1a9c16a55..0b5d8ca7b4 100644 --- a/frontend/src/lib/components/InviteGlobalUser.svelte +++ b/frontend/src/lib/components/InviteGlobalUser.svelte @@ -9,10 +9,11 @@ import { globalEmailInvite } from '$lib/stores' interface Props { - close?: (() => void) | undefined; + close?: (() => void) | undefined + onnew?: (...args: any[]) => any } - let { close = undefined }: Props = $props(); + let { close = undefined, onnew = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -35,6 +36,7 @@ $globalEmailInvite = '' password = generateRandomString(10) dispatch('new') + onnew?.() close?.() } diff --git a/frontend/src/lib/components/JsonEditor.svelte b/frontend/src/lib/components/JsonEditor.svelte index 07db17b9c9..a7e679d556 100644 --- a/frontend/src/lib/components/JsonEditor.svelte +++ b/frontend/src/lib/components/JsonEditor.svelte @@ -18,6 +18,9 @@ class?: string | undefined disabled?: boolean fixedOverflowWidgets?: boolean + onchangeValue?: (...args: any[]) => any + onfocus?: (...args: any[]) => any + onblur?: (...args: any[]) => any } let { @@ -29,7 +32,10 @@ loadAsync = false, class: clazz = undefined, disabled = false, - fixedOverflowWidgets = true + fixedOverflowWidgets = true, + onchangeValue = undefined, + onfocus = undefined, + onblur = undefined }: Props = $props() let tooBig = $derived(code && code?.length > 1000000) @@ -47,6 +53,7 @@ value = JSON.parse(code ?? '') } dispatchIfMounted('changeValue', value) + onchangeValue?.(value) error = '' } catch (e) { error = e.message @@ -75,8 +82,8 @@ (dispatch('focus'), (focused = true))} - on:blur={() => (dispatch('blur'), (focused = false))} + on:focus={() => ((dispatch('focus'), onfocus?.()), (focused = true))} + on:blur={() => ((dispatch('blur'), onblur?.()), (focused = false))} bind:this={editor} on:change autoHeight diff --git a/frontend/src/lib/components/JsonInputs.svelte b/frontend/src/lib/components/JsonInputs.svelte index d336ad2d46..49769e189f 100644 --- a/frontend/src/lib/components/JsonInputs.svelte +++ b/frontend/src/lib/components/JsonInputs.svelte @@ -8,12 +8,18 @@ updateOnBlur?: boolean placeholder?: string selected?: boolean + onselect?: (...args: any[]) => any + onfocus?: (...args: any[]) => any + onblur?: (...args: any[]) => any } let { updateOnBlur = true, placeholder = 'Write a JSON payload. The input schema will be inferred.

Example:

{
  "foo": "12"
}', - selected = false + selected = false, + onselect = undefined, + onfocus = undefined, + onblur = undefined }: Props = $props() let pendingJson = $state('') @@ -23,13 +29,16 @@ function updatePayloadFromJson(jsonInput: string) { if (jsonInput === undefined || jsonInput === null || jsonInput.trim() === '') { dispatch('select', undefined) + onselect?.(undefined) return } try { const parsed = JSON.parse(jsonInput) dispatch('select', parsed) + onselect?.(parsed) } catch (error) { dispatch('select', undefined) + onselect?.(undefined) } } @@ -40,6 +49,7 @@ export function resetSelected(dispatchEvent?: boolean) { if (dispatchEvent) { dispatch('select', undefined) + onselect?.(undefined) } } @@ -62,12 +72,14 @@ on:focus={() => { if (updateOnBlur) { dispatch('focus') + onfocus?.() updatePayloadFromJson(pendingJson) } }} on:blur={async () => { if (updateOnBlur) { dispatch('blur') + onblur?.() } }} on:change={(e) => { diff --git a/frontend/src/lib/components/Path.svelte b/frontend/src/lib/components/Path.svelte index 85ca9c4271..9a2990c018 100644 --- a/frontend/src/lib/components/Path.svelte +++ b/frontend/src/lib/components/Path.svelte @@ -72,6 +72,7 @@ hideFullPath?: boolean size?: 'sm' | 'md' drawerOffset?: number + onenter?: (...args: any[]) => any } let { @@ -89,7 +90,8 @@ disableEditing = false, hideFullPath = false, size = 'md', - drawerOffset = 0 + drawerOffset = 0, + onenter = undefined }: Props = $props() $effect.pre(() => { @@ -133,6 +135,7 @@ if (key === 'Enter') { event.preventDefault() dispatch('enter') + onenter?.() } } diff --git a/frontend/src/lib/components/RadioButton.svelte b/frontend/src/lib/components/RadioButton.svelte index c7e5dc8dce..7025f80343 100644 --- a/frontend/src/lib/components/RadioButton.svelte +++ b/frontend/src/lib/components/RadioButton.svelte @@ -1,14 +1,14 @@ @@ -39,7 +40,7 @@ class="sr-only" bind:group={value} aria-labelledby="memory-option-0-label" - onclick={() => dispatch('change', val)} + onclick={() => (dispatch('change', val), onchange?.(val))} />

{#if typeof label !== 'string'} diff --git a/frontend/src/lib/components/ResourceEditor.svelte b/frontend/src/lib/components/ResourceEditor.svelte index 8ca1ecd85e..0517f24e66 100644 --- a/frontend/src/lib/components/ResourceEditor.svelte +++ b/frontend/src/lib/components/ResourceEditor.svelte @@ -1,5 +1,4 @@ diff --git a/frontend/src/lib/components/SavedInputsPicker.svelte b/frontend/src/lib/components/SavedInputsPicker.svelte index 057a405ac4..bba06fef67 100644 --- a/frontend/src/lib/components/SavedInputsPicker.svelte +++ b/frontend/src/lib/components/SavedInputsPicker.svelte @@ -21,6 +21,8 @@ noButton?: boolean jsonView?: boolean limitPayloadSize?: boolean + onselect?: (...args: any[]) => any + onisEditing?: (...args: any[]) => any } let { @@ -30,7 +32,9 @@ isValid = false, noButton = false, jsonView = false, - limitPayloadSize = false + limitPayloadSize = false, + onselect = undefined, + onisEditing = undefined }: Props = $props() interface EditableInput extends Input { @@ -136,9 +140,11 @@ if (input.payloadData === 'WINDMILL_TOO_BIG') { const fullPayload = await input.getFullPayload?.() dispatch('select', fullPayload) + onselect?.(fullPayload) } else { selectedArgs = structuredClone($state.snapshot(input.payloadData) ?? {}) dispatch('select', selectedArgs) + onselect?.(selectedArgs) } } } @@ -170,6 +176,7 @@ function setEditing(input: EditableInput | null) { isEditing = input dispatch('isEditing', !!input) + onisEditing?.(!!input) } function handleError(error: { type: string; error: any }) { @@ -189,6 +196,7 @@ selectedArgs = undefined if (dispatchEvent) { dispatch('select', undefined) + onselect?.(undefined) } } diff --git a/frontend/src/lib/components/SavedInputsV2.svelte b/frontend/src/lib/components/SavedInputsV2.svelte index 7823a7caaf..525365af38 100644 --- a/frontend/src/lib/components/SavedInputsV2.svelte +++ b/frontend/src/lib/components/SavedInputsV2.svelte @@ -24,6 +24,7 @@ // Are the current Inputs valid and able to be saved? isValid: boolean args: object + onselected_args?: (...args: any[]) => any } let { @@ -34,7 +35,8 @@ jsonView = false, schema, isValid, - args + args, + onselected_args = undefined }: Props = $props() export function resetSelected() { @@ -59,9 +61,11 @@ } inputSelected = type dispatch('selected_args', selected_args) + onselected_args?.(selected_args) } else if (savedArgs) { inputSelected = type dispatch('selected_args', savedArgs) + onselected_args?.(savedArgs) } } diff --git a/frontend/src/lib/components/SchemaForm.svelte b/frontend/src/lib/components/SchemaForm.svelte index cb8828286c..9894bfa61e 100644 --- a/frontend/src/lib/components/SchemaForm.svelte +++ b/frontend/src/lib/components/SchemaForm.svelte @@ -72,6 +72,12 @@ workspace?: string | undefined chatInputEnabled?: boolean actions?: import('svelte').Snippet<[{ item: { id: string; value: string } }]> | undefined + onchange?: (...args: any[]) => any + onclick?: (...args: any[]) => any + onnestedChange?: (...args: any[]) => any + onacceptChange?: (...args: any[]) => any + onrejectChange?: (...args: any[]) => any + onkeydownCmdEnter?: (...args: any[]) => any } let { @@ -114,7 +120,13 @@ computeS3ForceViewerPolicies = undefined, workspace = undefined, chatInputEnabled = false, - actions: actions_render = undefined + actions: actions_render = undefined, + onchange = undefined, + onclick = undefined, + onnestedChange = undefined, + onacceptChange = undefined, + onrejectChange = undefined, + onkeydownCmdEnter = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -188,6 +200,7 @@ if (!deepEqual(keys, nkeys)) { keys = nkeys dispatch('change') + onchange?.() } } // let missingKeys = keys.filter((x) => args && !(x in args)) @@ -360,6 +373,7 @@ class="flex flex-row items-center {largeGap ? 'pb-4' : 'pb-2'} " onclick={() => { dispatch('click', argName) + onclick?.(argName) }} > {#if args && typeof args == 'object' && prop} @@ -371,13 +385,21 @@ {lightHeaderFont} on:change={() => { dispatch('change') + onchange?.() }} on:nestedChange={() => { dispatch('nestedChange') + onnestedChange?.() }} - on:acceptChange={(e) => dispatch('acceptChange', e.detail)} - on:rejectChange={(e) => dispatch('rejectChange', e.detail)} - on:keydownCmdEnter={() => dispatch('keydownCmdEnter')} + on:acceptChange={(e) => ( + dispatch('acceptChange', e.detail), + onacceptChange?.(e.detail) + )} + on:rejectChange={(e) => ( + dispatch('rejectChange', e.detail), + onrejectChange?.(e.detail) + )} + on:keydownCmdEnter={() => (dispatch('keydownCmdEnter'), onkeydownCmdEnter?.())} {disablePortal} {resourceTypes} {prettifyHeader} @@ -398,17 +420,19 @@ customErrorMessage={prop?.customErrorMessage} bind:properties={ () => prop?.properties, - (v) => { if (prop) prop.properties = v } + (v) => { + if (prop) prop.properties = v + } } bind:order={ () => prop?.order, - (v) => { if (prop) prop.order = v } + (v) => { + if (prop) prop.order = v + } } nestedRequired={prop?.required} itemsType={prop?.items} - disabled={disabledArgs.includes(argName) || - disabled || - prop?.disabled} + disabled={disabledArgs.includes(argName) || disabled || prop?.disabled} {compact} {variableEditor} {itemPicker} diff --git a/frontend/src/lib/components/SchemaFormWithArgPicker.svelte b/frontend/src/lib/components/SchemaFormWithArgPicker.svelte index f1f7bae6e9..28363afe4e 100644 --- a/frontend/src/lib/components/SchemaFormWithArgPicker.svelte +++ b/frontend/src/lib/components/SchemaFormWithArgPicker.svelte @@ -19,6 +19,7 @@ isValid?: boolean jsonView?: boolean children?: import('svelte').Snippet + onselect?: (...args: any[]) => any } let { @@ -28,7 +29,8 @@ previewArgs, isValid = true, jsonView = false, - children + children, + onselect = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -142,6 +144,7 @@ {runnableType} on:select={(e) => { dispatch('select', { payload: e.detail?.args, type: 'history' }) + onselect?.({ payload: e.detail?.args, type: 'history' }) }} /> @@ -155,6 +158,7 @@ bind:this={savedInputsPicker} on:select={(e) => { dispatch('select', { payload: e.detail, type: 'saved' }) + onselect?.({ payload: e.detail, type: 'saved' }) }} {jsonView} /> @@ -173,6 +177,7 @@ path={stablePathForCaptures} on:select={(e) => { dispatch('select', { payload: e.detail, type: 'captures' }) + onselect?.({ payload: e.detail, type: 'captures' }) }} bind:this={captureTable} isFlow={true} diff --git a/frontend/src/lib/components/ScriptEditor.svelte b/frontend/src/lib/components/ScriptEditor.svelte index 4659abc0ac..391365b2c9 100644 --- a/frontend/src/lib/components/ScriptEditor.svelte +++ b/frontend/src/lib/components/ScriptEditor.svelte @@ -119,6 +119,8 @@ assets?: AssetWithAltAccessType[] editor_bar_right?: import('svelte').Snippet enablePreprocessorSnippet?: boolean + onchange?: (...args: any[]) => any + onformat?: (...args: any[]) => any } let { @@ -150,7 +152,9 @@ disableAi = false, assets = $bindable(), editor_bar_right, - enablePreprocessorSnippet = false + enablePreprocessorSnippet = false, + onchange = undefined, + onformat = undefined }: Props = $props() let initialArgs = structuredClone($state.snapshot(args)) @@ -187,6 +191,7 @@ watchChanges && (code != undefined || schema != undefined) && dispatch('change', { code, schema }) + onchange?.({ code, schema }) }) watch( @@ -1407,6 +1412,7 @@ console.error('Could not save last_save to local storage', e) } dispatch('format') + onformat?.() }} class="flex flex-1 h-full !overflow-visible" scriptLang={lang} diff --git a/frontend/src/lib/components/ScriptPicker.svelte b/frontend/src/lib/components/ScriptPicker.svelte index 5fa0618edd..d04f4b2cd7 100644 --- a/frontend/src/lib/components/ScriptPicker.svelte +++ b/frontend/src/lib/components/ScriptPicker.svelte @@ -30,6 +30,7 @@ allowEdit?: boolean allowView?: boolean clearable?: boolean + onselect?: (...args: any[]) => any } let { @@ -42,7 +43,8 @@ allowRefresh = false, allowEdit = true, allowView = true, - clearable = false + clearable = false, + onselect = undefined }: Props = $props() let items: { value: string; label: string }[] = $state([]) @@ -130,6 +132,7 @@ (path) => { scriptPath = path dispatch('select', { path, itemKind }) + onselect?.({ path, itemKind }) } } class="grow shrink max-w-full" diff --git a/frontend/src/lib/components/ScriptVersionHistory.svelte b/frontend/src/lib/components/ScriptVersionHistory.svelte index 4d053fc433..eaafb2fe2f 100644 --- a/frontend/src/lib/components/ScriptVersionHistory.svelte +++ b/frontend/src/lib/components/ScriptVersionHistory.svelte @@ -13,7 +13,15 @@ const dispatch = createEventDispatcher() - let { openDetails = false, scriptPath }: { openDetails?: boolean; scriptPath: string } = $props() + let { + openDetails = false, + scriptPath, + onopenDetails = undefined + }: { + openDetails?: boolean + scriptPath: string + onopenDetails?: (...args: any[]) => any + } = $props() let deploymentMsgUpdateMode = $state(false) let deploymentMsgUpdate: string | undefined = $state() @@ -102,6 +110,7 @@ {#if hasErrors} - {/if} diff --git a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte index e717205670..ffa2974123 100644 --- a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte +++ b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte @@ -28,6 +28,11 @@ errorHandledByComponent?: boolean fullHeight?: boolean componentContainerWidth: number + onmouseover?: (...args: any[]) => any + onfillHeight?: (...args: any[]) => any + onlock?: (...args: any[]) => any + onexpand?: (...args: any[]) => any + ontriggerInlineEditor?: (...args: any[]) => any } let { @@ -40,7 +45,12 @@ inlineEditorOpened = false, errorHandledByComponent = false, fullHeight = false, - componentContainerWidth + componentContainerWidth, + onmouseover = undefined, + onfillHeight = undefined, + onlock = undefined, + onexpand = undefined, + ontriggerInlineEditor = undefined }: Props = $props() const DECISION_TREE_THRESHOLD = 300 @@ -130,6 +140,7 @@ onmouseover={stopPropagation(() => { hoverHeader = true dispatch('mouseover') + onmouseover?.() })} onmouseleave={stopPropagation(() => { hoverHeader = false @@ -163,7 +174,7 @@ ? 'bg-blue-300 text-blue-800' : 'text-white hover:bg-blue-400 hover:text-white' )} - onclick={() => dispatch('fillHeight')} + onclick={() => (dispatch('fillHeight'), onfillHeight?.())} onpointerdown={stopPropagation(bubble('pointerdown'))} > @@ -175,7 +186,7 @@ 'px-1 py-0.5 text-2xs font-bold rounded cursor-pointer w-fit h-full', locked ? 'bg-blue-300 text-blue-800' : 'text-white hover:bg-blue-400 hover:text-white' )} - onclick={() => dispatch('lock')} + onclick={() => (dispatch('lock'), onlock?.())} onpointerdown={stopPropagation(bubble('pointerdown'))} > {#if locked} @@ -190,7 +201,7 @@ class={twMerge( 'px-1 py-0.5 text-2xs font-bold rounded cursor-pointer w-fit h-full text-white hover:bg-blue-400 hover:text-white' )} - onclick={() => dispatch('expand')} + onclick={() => (dispatch('expand'), onexpand?.())} onpointerdown={stopPropagation(bubble('pointerdown'))} > @@ -217,7 +228,7 @@ ? 'bg-blue-300 text-blue-800' : 'text-blue-600 hover:bg-blue-300 hover:text-blue-800' )} - onclick={() => dispatch('triggerInlineEditor')} + onclick={() => (dispatch('triggerInlineEditor'), ontriggerInlineEditor?.())} onpointerdown={stopPropagation(bubble('pointerdown'))} > diff --git a/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte b/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte index bf70dafd61..7d259a728f 100644 --- a/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte +++ b/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte @@ -15,9 +15,16 @@ id: string isSmall?: boolean componentIsDebugging?: boolean + ontriggerInlineEditor?: (...args: any[]) => any } - let { nodes = [], id, isSmall = false, componentIsDebugging = $bindable(false) }: Props = $props() + let { + nodes = [], + id, + isSmall = false, + componentIsDebugging = $bindable(false), + ontriggerInlineEditor = undefined + }: Props = $props() $effect(() => { componentIsDebugging = isDebugging($debuggingComponents, id) @@ -119,7 +126,7 @@ ? ' hover:bg-red-300 hover:text-red-800' : 'text-blue-600 hover:bg-blue-300 hover:text-blue-800' )} - onclick={() => dispatch('triggerInlineEditor')} + onclick={() => (dispatch('triggerInlineEditor'), ontriggerInlineEditor?.())} onpointerdown={stopPropagation(bubble('pointerdown'))} > {#if componentIsDebugging} diff --git a/frontend/src/lib/components/apps/editor/DeploymentHistory.svelte b/frontend/src/lib/components/apps/editor/DeploymentHistory.svelte index 95bf74acf8..16523a1c1b 100644 --- a/frontend/src/lib/components/apps/editor/DeploymentHistory.svelte +++ b/frontend/src/lib/components/apps/editor/DeploymentHistory.svelte @@ -14,9 +14,10 @@ interface Props { appPath: string | undefined + onrestore?: (...args: any[]) => any } - let { appPath }: Props = $props() + let { appPath, onrestore = undefined }: Props = $props() let loading: boolean = $state(false) let versions: AppHistory[] = $state([]) @@ -186,7 +187,9 @@ > Restore as fork -

diff --git a/frontend/src/lib/components/apps/editor/GridEditorMenu.svelte b/frontend/src/lib/components/apps/editor/GridEditorMenu.svelte index 5180b322a8..a9ad5e9538 100644 --- a/frontend/src/lib/components/apps/editor/GridEditorMenu.svelte +++ b/frontend/src/lib/components/apps/editor/GridEditorMenu.svelte @@ -71,9 +71,20 @@ fullHeight?: boolean id: string children?: import('svelte').Snippet + onfillHeight?: (...args: any[]) => any + onexpand?: (...args: any[]) => any + onlock?: (...args: any[]) => any } - let { locked = false, fullHeight = false, id, children }: Props = $props() + let { + locked = false, + fullHeight = false, + id, + children, + onfillHeight = undefined, + onexpand = undefined, + onlock = undefined + }: Props = $props() const { selectedComponent, focusedGrid, componentControl, app } = getContext( 'AppViewerContext' @@ -116,6 +127,7 @@ label: () => (fullHeight ? 'Undo fill height' : 'Fill height'), onClick: () => { dispatch('fillHeight') + onfillHeight?.() }, icon: ArrowDownFromLine, tooltip: { @@ -127,6 +139,7 @@ label: () => 'Expand', onClick: () => { dispatch('expand') + onexpand?.() }, icon: Expand, tooltip: { @@ -138,6 +151,7 @@ label: () => (locked ? 'Unlock' : 'Lock'), onClick: () => { dispatch('lock') + onlock?.() }, icon: Anchor, tooltip: { diff --git a/frontend/src/lib/components/apps/editor/GridViewer.svelte b/frontend/src/lib/components/apps/editor/GridViewer.svelte index fc540c6cf0..214c632b70 100644 --- a/frontend/src/lib/components/apps/editor/GridViewer.svelte +++ b/frontend/src/lib/components/apps/editor/GridViewer.svelte @@ -29,6 +29,8 @@ containerWidth?: number | undefined parentWidth?: number | undefined children?: import('svelte').Snippet<[any]> + onresize?: (...args: any[]) => any + onmount?: (...args: any[]) => any } let { @@ -41,7 +43,9 @@ allIdsInPath = undefined, containerWidth = $bindable(undefined), parentWidth = undefined, - children + children, + onresize = undefined, + onmount = undefined }: Props = $props() const cols = columnConfiguration @@ -71,6 +75,12 @@ yPerPx, width: containerWidth }) + onresize?.({ + cols: getComputedCols, + xPerPx, + yPerPx, + width: containerWidth + }) }, throttleUpdate) onMount(() => { @@ -99,6 +109,11 @@ xPerPx, yPerPx // same as rowHeight }) + onmount?.({ + cols: getComputedCols, + xPerPx, + yPerPx // same as rowHeight + }) } else { onResize() } diff --git a/frontend/src/lib/components/apps/editor/RecomputeAllButton.svelte b/frontend/src/lib/components/apps/editor/RecomputeAllButton.svelte index bed52c94e9..ead7b0f253 100644 --- a/frontend/src/lib/components/apps/editor/RecomputeAllButton.svelte +++ b/frontend/src/lib/components/apps/editor/RecomputeAllButton.svelte @@ -12,6 +12,7 @@ refreshing?: string[] progress?: number loading?: boolean | undefined + onsetInter?: (...args: any[]) => any } let { @@ -19,7 +20,8 @@ interval = undefined, refreshing = [], progress = 100, - loading = false + loading = false, + onsetInter = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -27,11 +29,11 @@ const items = [ { displayName: 'Once', - action: () => dispatch('setInter', undefined) + action: () => (dispatch('setInter', undefined), onsetInter?.(undefined)) }, ...[1, 2, 3, 4, 5, 6].map((i) => ({ displayName: `Every ${i * 5} seconds`, - action: () => dispatch('setInter', i * 5000) + action: () => (dispatch('setInter', i * 5000), onsetInter?.(i * 5000)) })) ] diff --git a/frontend/src/lib/components/apps/editor/TabsDebug.svelte b/frontend/src/lib/components/apps/editor/TabsDebug.svelte index 8d99fd8397..6bf0c0e616 100644 --- a/frontend/src/lib/components/apps/editor/TabsDebug.svelte +++ b/frontend/src/lib/components/apps/editor/TabsDebug.svelte @@ -17,6 +17,7 @@ isConditionalDebugMode?: boolean isSmall?: boolean isManuallySelected?: boolean + ontriggerInlineEditor?: (...args: any[]) => any } let { @@ -24,7 +25,8 @@ id, isConditionalDebugMode = false, isSmall = false, - isManuallySelected = $bindable(false) + isManuallySelected = $bindable(false), + ontriggerInlineEditor = undefined }: Props = $props() let selected: number | null = $state(null) @@ -68,7 +70,7 @@ ? 'hover:bg-red-200 hover:text-red-800' : 'text-blue-600 hover:bg-blue-300 hover:text-blue-800' )} - onclick={() => dispatch('triggerInlineEditor')} + onclick={() => (dispatch('triggerInlineEditor'), ontriggerInlineEditor?.())} onpointerdown={stopPropagation(bubble('pointerdown'))} > {#if isManuallySelected} diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte index 640b9b155c..894c76b693 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/CssProperty.svelte @@ -33,6 +33,9 @@ overriden?: boolean overridding?: boolean wmClass?: string | undefined + onchange?: (...args: any[]) => any + onleft?: (...args: any[]) => any + onright?: (...args: any[]) => any } let { @@ -47,7 +50,10 @@ shouldDisplayRight = false, overriden = false, overridding = false, - wmClass = undefined + wmClass = undefined, + onchange = undefined, + onleft = undefined, + onright = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -58,6 +64,7 @@ if (deepEqual(prevValue, value)) return prevValue = structuredClone($state.snapshot(value)) dispatch('change', value) + onchange?.(value) }) function toggleQuickMenu() { @@ -93,7 +100,7 @@ size="xs2" iconOnly startIcon={{ icon: MoveLeft }} - on:click={() => dispatch('left')} + on:click={() => (dispatch('left'), onleft?.())} /> {#snippet text()} {'Copy for this component'} @@ -107,7 +114,7 @@ size="xs2" iconOnly startIcon={{ icon: MoveRight }} - on:click={() => dispatch('right')} + on:click={() => (dispatch('right'), onright?.())} /> {#snippet text()} Copy for every {componentType ? ccomponents[componentType].name : 'component'} diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentRow.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentRow.svelte index 3835c191b6..f9976e3719 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentRow.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentRow.svelte @@ -14,9 +14,10 @@ name: string path: string } + onreload?: (...args: any[]) => any } - let { row }: Props = $props() + let { row, onreload = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -28,6 +29,7 @@ }) } dispatch('reload') + onreload?.() sendUserToast('Component deleted:\n' + row.name) } @@ -49,6 +51,7 @@ } }) dispatch('reload') + onreload?.() sendUserToast('Component name updated:\n' + name) } diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/GroupRow.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/GroupRow.svelte index f59cdbfc7f..1b6db58407 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/GroupRow.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/GroupRow.svelte @@ -13,9 +13,10 @@ name: string path: string } + onreloadGroups?: (...args: any[]) => any } - let { row }: Props = $props() + let { row, onreloadGroups = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -24,6 +25,7 @@ await deleteGroup($workspaceStore, row.path) } dispatch('reloadGroups') + onreloadGroups?.() sendUserToast('Group deleted:\n' + row.name) } @@ -54,6 +56,7 @@ } }) dispatch('reloadGroups') + onreloadGroups?.() sendUserToast('Group name updated:\n' + e.detail.name) }} diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/ListItem.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/ListItem.svelte index 0a4834c53c..076fe208f6 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/ListItem.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/ListItem.svelte @@ -20,6 +20,7 @@ subtitle?: string | undefined titleSlot?: import('svelte').Snippet children?: import('svelte').Snippet + onopen?: (...args: any[]) => any } let { @@ -34,7 +35,8 @@ documentationLink = undefined, subtitle = undefined, titleSlot, - children + children, + onopen = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -46,6 +48,7 @@ $effect(() => { dispatch('open', isOpen ?? false) + onopen?.(isOpen ?? false) }) onMount(() => { diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte index 6263bc8026..3fbd0f0356 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte @@ -10,9 +10,10 @@ name: string path: string } + onupdate?: (...args: any[]) => any } - let { kind, row }: Props = $props() + let { kind, row, onupdate = undefined }: Props = $props() let editedName = $state(row.name) @@ -20,6 +21,7 @@ function onkeydown(e) { if (e.key === 'Enter') { dispatch('update', { path: row.path, name: editedName }) + onupdate?.({ path: row.path, name: editedName }) } } @@ -42,6 +44,7 @@ size="xs" on:click={() => { dispatch('update', { path: row.path, name: editedName }) + onupdate?.({ path: row.path, name: editedName }) close() }} > diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/ThemeNameEditor.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/ThemeNameEditor.svelte index cb1793b252..679c5f3c76 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/ThemeNameEditor.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/ThemeNameEditor.svelte @@ -12,9 +12,10 @@ name: string path: string } + onreloadThemes?: (...args: any[]) => any } - let { row }: Props = $props() + let { row, onreloadThemes = undefined }: Props = $props() let editedName = $state(row.name) @@ -49,6 +50,7 @@ } }) dispatch('reloadThemes') + onreloadThemes?.() close() sendUserToast('Theme name updated:\n' + editedName) }} diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/ThemeRow.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/ThemeRow.svelte index f5e26488b6..05a56a8e06 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/ThemeRow.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/ThemeRow.svelte @@ -22,9 +22,16 @@ name: string path: string } + onreloadThemes?: (...args: any[]) => any + onsetCodeTab?: (...args: any[]) => any } - let { previewThemePath = $bindable(undefined), row }: Props = $props() + let { + previewThemePath = $bindable(undefined), + row, + onreloadThemes = undefined, + onsetCodeTab = undefined + }: Props = $props() const { previewTheme, app } = getContext('AppViewerContext') @@ -80,6 +87,7 @@ } dispatch('reloadThemes') + onreloadThemes?.() } async function toggleDelete() { @@ -88,6 +96,7 @@ await deleteTheme($workspaceStore, row.path) } dispatch('reloadThemes') + onreloadThemes?.() sendUserToast('Theme deleted:\n' + row.name) } @@ -120,6 +129,7 @@ } dispatch('setCodeTab') + onsetCodeTab?.() } function stopPreview() { diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte index edaefe947a..f0b9c302b9 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte @@ -25,13 +25,17 @@ showScriptPicker?: boolean rawApps?: boolean unusedInlineScripts: { name: string; inlineScript: InlineScript }[] + onnew?: (...args: any[]) => any + ondelete?: (...args: any[]) => any } let { componentType = undefined, showScriptPicker = false, rawApps = false, - unusedInlineScripts + unusedInlineScripts, + onnew = undefined, + ondelete = undefined }: Props = $props() let tab = $state('workspacescripts') @@ -75,6 +79,7 @@ schema } dispatch('new', newInlineScript) + onnew?.(newInlineScript) } async function pickScript(path: string) { @@ -147,7 +152,7 @@
diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte index 802d51116f..38df7630b3 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte @@ -46,6 +46,8 @@ transformer?: boolean componentType?: string | undefined editor?: Editor | undefined + oncreateScriptFromInlineScript?: (...args: any[]) => any + ondelete?: (...args: any[]) => any } let { @@ -57,7 +59,9 @@ syncFields = false, transformer = false, componentType = undefined, - editor = $bindable(undefined) + editor = $bindable(undefined), + oncreateScriptFromInlineScript = undefined, + ondelete = undefined }: Props = $props() let diffEditor: DiffEditor | undefined = $state() let simpleEditor: SimpleEditor | undefined = $state() @@ -221,6 +225,7 @@ bind:inlineScript on:createScriptFromInlineScript={() => { dispatch('createScriptFromInlineScript') + oncreateScriptFromInlineScript?.() drawerIsOpen = false }} /> @@ -280,7 +285,7 @@ variant="subtle" destructive aria-label="Delete" - on:click={() => dispatch('delete')} + on:click={() => (dispatch('delete'), ondelete?.())} endIcon={{ icon: Trash2 }} iconOnly /> diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte index ba3a3b2654..f8831a0b34 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte @@ -14,6 +14,7 @@ componentType: string id: string transformer: boolean + oncreateScriptFromInlineScript?: (...args: any[]) => any } let { @@ -21,7 +22,8 @@ defaultUserInput = false, componentType, id, - transformer + transformer, + oncreateScriptFromInlineScript = undefined }: Props = $props() const { app } = getContext('AppViewerContext') @@ -70,6 +72,7 @@ on:createScriptFromInlineScript={() => { if (componentInput?.type == 'runnable' && isRunnableByName(componentInput.runnable)) { dispatch('createScriptFromInlineScript', componentInput?.runnable) + oncreateScriptFromInlineScript?.(componentInput?.runnable) } }} {defaultUserInput} diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptHiddenRunnable.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptHiddenRunnable.svelte index 70562ec9d3..045525b8eb 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptHiddenRunnable.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptHiddenRunnable.svelte @@ -15,9 +15,15 @@ runnable: HiddenRunnable id: string transformer: boolean + oncreateScriptFromInlineScript?: (...args: any[]) => any } - let { runnable = $bindable(), id, transformer }: Props = $props() + let { + runnable = $bindable(), + id, + transformer, + oncreateScriptFromInlineScript = undefined + }: Props = $props() const { runnableComponents, app } = getContext('AppViewerContext') async function fork(nrunnable: Runnable) { @@ -60,7 +66,10 @@ {/if} {:else if isRunnableByName(runnable) && runnable.inlineScript} dispatch('createScriptFromInlineScript', runnable)} + on:createScriptFromInlineScript={() => ( + dispatch('createScriptFromInlineScript', runnable), + oncreateScriptFromInlineScript?.(runnable) + )} {id} bind:inlineScript={runnable.inlineScript} bind:name={runnable.name} diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte index 5d6ddf7b93..f1ab74a80b 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte @@ -36,13 +36,18 @@ interface Props { runnable: RunnableByPath fields: - | Record + | Record< + string, + StaticAppInput | ConnectedAppInput | RowAppInput | UserAppInput | CtxAppInput + > | undefined id: string rawApps?: boolean isLoading?: boolean onRun?: any onCancel?: any + onfork?: (...args: any[]) => any + ondelete?: (...args: any[]) => any } let { @@ -52,7 +57,9 @@ rawApps = false, isLoading = false, onRun = async () => {}, - onCancel = async () => {} + onCancel = async () => {}, + onfork = undefined, + ondelete = undefined }: Props = $props() const viewerContext = getContext('AppViewerContext') @@ -118,6 +125,16 @@ path } }) + onfork?.({ + type: 'inline', + name: path, + inlineScript: { + content, + language, + schema, + path + } + }) } async function openScriptEditor(path: string) { @@ -227,6 +244,7 @@ startIcon={{ icon: Trash }} on:click={() => { dispatch('delete') + ondelete?.() }} > Clear diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte index edea934b57..3f1be7817a 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte @@ -19,13 +19,15 @@ subFieldType?: InputType | undefined selectOptions?: StaticOptions['selectOptions'] | undefined id: string | undefined + ondeleteArrayItem?: (...args: any[]) => any } let { componentInput = $bindable(), subFieldType = undefined, selectOptions = undefined, - id + id, + ondeleteArrayItem = undefined }: Props = $props() const appContext = getContext('AppViewerContext') @@ -223,6 +225,7 @@ items = items componentInput.value = componentInput.value dispatch('deleteArrayItem', { index }) + ondeleteArrayItem?.({ index }) } } diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentInputTypeEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentInputTypeEditor.svelte index 609f58fd7d..245e24807c 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentInputTypeEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentInputTypeEditor.svelte @@ -13,9 +13,15 @@ componentInput: AppInput disableStatic?: boolean evalV2editor: EvalV2InputEditor | undefined + onselect?: (...args: any[]) => any } - let { componentInput = $bindable(), disableStatic = false, evalV2editor }: Props = $props() + let { + componentInput = $bindable(), + disableStatic = false, + evalV2editor, + onselect = undefined + }: Props = $props() const { onchange, connectingInput, app } = getContext('AppViewerContext') @@ -66,6 +72,7 @@ onConnect: () => {} } dispatch('select', true) + onselect?.(true) }} openConnection={() => { $connectingInput = { diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte index 7992159fc1..7897e411a4 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte @@ -58,6 +58,8 @@ markdownTooltip?: string | undefined securedContext?: boolean disabled?: boolean + oncloseConnection?: (...args: any[]) => any + onopenConnection?: (...args: any[]) => any } let { @@ -87,7 +89,9 @@ showOnDemandOnlyToggle = true, documentationLink = undefined, markdownTooltip = undefined, - securedContext = false + securedContext = false, + oncloseConnection = undefined, + onopenConnection = undefined }: Props = $props() $effect.pre(() => { @@ -140,6 +144,7 @@ function closeConnection() { dispatch('closeConnection') + oncloseConnection?.() $connectingInput = { opened: false, hoveredComponent: undefined, @@ -150,6 +155,7 @@ function openConnection() { dispatch('openConnection') + onopenConnection?.() $connectingInput = { opened: true, input: undefined, diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte index 19dd309bec..729cc41741 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte @@ -21,6 +21,7 @@ showOnDemandOnlyToggle?: boolean securedContext?: boolean overridenByComponent?: string[] + ondelete?: (...args: any[]) => any } let { @@ -36,7 +37,8 @@ recomputeOnInputChanged = true, showOnDemandOnlyToggle = false, securedContext = false, - overridenByComponent = [] + overridenByComponent = [], + ondelete = undefined }: Props = $props() let finalInputSpecsConfiguration = $derived(inputSpecsConfiguration ?? inputSpecs) @@ -104,7 +106,7 @@ /> {#if deletable}
- dispatch('delete', k)} /> + (dispatch('delete', k), ondelete?.(k))} />
{/if} {/if} diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/QuickAddColumn.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/QuickAddColumn.svelte index 7bc4978ce5..47a919f52d 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/QuickAddColumn.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/QuickAddColumn.svelte @@ -9,9 +9,10 @@ interface Props { columns?: string[] id: string | undefined + onadd?: (...args: any[]) => any } - let { columns = [], id }: Props = $props() + let { columns = [], id, onadd = undefined }: Props = $props() let remainingColumns: string[] = $state([]) @@ -64,7 +65,7 @@
{#each remainingColumns as column}
diff --git a/frontend/src/lib/components/common/CloseButton.svelte b/frontend/src/lib/components/common/CloseButton.svelte index d7d0a58a7b..5616ecb7d3 100644 --- a/frontend/src/lib/components/common/CloseButton.svelte +++ b/frontend/src/lib/components/common/CloseButton.svelte @@ -11,15 +11,24 @@ class?: string id?: string | undefined onClick?: () => void | undefined | any + onclose?: (...args: any[]) => any } - let { noBg = false, small = false, Icon, class: className, id, onClick }: Props = $props() + let { + noBg = false, + small = false, + Icon, + class: className, + id, + onClick, + onclose = undefined + }: Props = $props() const dispatch = createEventDispatcher() - {/snippet} + {/snippet} diff --git a/frontend/src/lib/components/copilot/IteratorGen.svelte b/frontend/src/lib/components/copilot/IteratorGen.svelte index b9015eb2b1..4b3aa2d97c 100644 --- a/frontend/src/lib/components/copilot/IteratorGen.svelte +++ b/frontend/src/lib/components/copilot/IteratorGen.svelte @@ -22,9 +22,17 @@ focused?: boolean arg: InputTransform | any pickableProperties?: PickableProperties | undefined + onsetExpr?: (...args: any[]) => any + onshowExpr?: (...args: any[]) => any } - let { focused = false, arg, pickableProperties = undefined }: Props = $props() + let { + focused = false, + arg, + pickableProperties = undefined, + onsetExpr = undefined, + onshowExpr = undefined + }: Props = $props() let btnFocused = $state(false) @@ -94,6 +102,7 @@ Only output the expression, do not explain or discuss.` if (!loading && generatedContent) { event.preventDefault() dispatch('setExpr', generatedContent) + onsetExpr?.(generatedContent) generatedContent = '' } } else { @@ -141,6 +150,7 @@ Only output the expression, do not explain or discuss.` $effect(() => { dispatch('showExpr', generatedContent) + onshowExpr?.(generatedContent) }) let out = $state(true) // hack to prevent regenerating answer when accepting the answer due to mouseenter on new icon @@ -160,6 +170,7 @@ Only output the expression, do not explain or discuss.` on:click={() => { if (!loading && generatedContent.length > 0) { dispatch('setExpr', generatedContent) + onsetExpr?.(generatedContent) generatedContent = '' } }} diff --git a/frontend/src/lib/components/copilot/PredicateGen.svelte b/frontend/src/lib/components/copilot/PredicateGen.svelte index c49edb70a8..3d8d8335b0 100644 --- a/frontend/src/lib/components/copilot/PredicateGen.svelte +++ b/frontend/src/lib/components/copilot/PredicateGen.svelte @@ -18,9 +18,15 @@ let loading = $state(false) interface Props { pickableProperties?: PickableProperties | undefined + onsetExpr?: (...args: any[]) => any + onupdateSummary?: (...args: any[]) => any } - let { pickableProperties = undefined }: Props = $props() + let { + pickableProperties = undefined, + onsetExpr = undefined, + onupdateSummary = undefined + }: Props = $props() let instructions = $state('') let instructionsField: HTMLInputElement | undefined = $state(undefined) @@ -77,7 +83,9 @@ Only return the expression without any wrapper. Do not explain or discuss.` ) dispatch('setExpr', result) + onsetExpr?.(result) dispatch('updateSummary', instructions) + onupdateSummary?.(instructions) } catch (err) { if (!abortController.signal.aborted) { sendUserToast('Could not generate predicate: ' + err, true) diff --git a/frontend/src/lib/components/copilot/StepGenQuick.svelte b/frontend/src/lib/components/copilot/StepGenQuick.svelte index d09e554240..d1bb1f3ecf 100644 --- a/frontend/src/lib/components/copilot/StepGenQuick.svelte +++ b/frontend/src/lib/components/copilot/StepGenQuick.svelte @@ -16,6 +16,7 @@ preFilter: string disableAi?: boolean filteredItems?: (Script & { marked?: string })[] | (Item & { marked?: string })[] + onescape?: (...args: any[]) => any } let { @@ -24,7 +25,8 @@ loading = false, preFilter, disableAi = false, - filteredItems = $bindable([]) + filteredItems = $bindable([]), + onescape = undefined }: Props = $props() let prefilteredItems = $derived(scripts ?? []) @@ -74,7 +76,7 @@ inputProps={{ type: 'text', onkeydown: (e) => { - if (e.key === 'Escape') dispatch('escape') + if (e.key === 'Escape') (dispatch('escape'), onescape?.()) }, placeholder: `Search ${trigger ? 'triggers' : 'scripts'} ${disableAi ? '' : 'or AI gen'}` }} diff --git a/frontend/src/lib/components/copilot/StepInputGen.svelte b/frontend/src/lib/components/copilot/StepInputGen.svelte index 7358ef4c5a..bc5ffc5c8f 100644 --- a/frontend/src/lib/components/copilot/StepInputGen.svelte +++ b/frontend/src/lib/components/copilot/StepInputGen.svelte @@ -1,5 +1,4 @@ diff --git a/frontend/src/lib/components/flows/content/FlowInputs.svelte b/frontend/src/lib/components/flows/content/FlowInputs.svelte index 7452527103..5cdf0a269a 100644 --- a/frontend/src/lib/components/flows/content/FlowInputs.svelte +++ b/frontend/src/lib/components/flows/content/FlowInputs.svelte @@ -26,6 +26,7 @@ shouldDisableTriggerScripts?: boolean noEditor: boolean summary?: string | undefined + onnew?: (...args: any[]) => any } let { @@ -33,7 +34,8 @@ preprocessorModule, shouldDisableTriggerScripts = false, noEditor, - summary = $bindable(undefined) + summary = $bindable(undefined), + onnew = undefined }: Props = $props() const dispatch = createEventDispatcher() @@ -282,6 +284,12 @@ subkind: lang == 'docker' ? 'docker' : preprocessorModule ? 'preprocessor' : 'flow', summary }) + onnew?.({ + language: lang == 'docker' ? 'bash' : lang, + kind, + subkind: lang == 'docker' ? 'docker' : preprocessorModule ? 'preprocessor' : 'flow', + summary + }) }} /> {/if} diff --git a/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte b/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte index 9f16d95bab..c15fe36c16 100644 --- a/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte +++ b/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte @@ -11,9 +11,10 @@ import { fade } from 'svelte/transition' interface Props { children?: import('svelte').Snippet + onpick?: (...args: any[]) => any } - let { children }: Props = $props() + let { children, onpick = undefined }: Props = $props() // export let failureModule: boolean const dispatch = createEventDispatcher() @@ -90,6 +91,7 @@ class="p-4 gap-1 flex flex-row grow hover:bg-surface-hover bg-surface transition-all text-primary" onclick={() => { dispatch('pick', { path }) + onpick?.({ path }) }} >
diff --git a/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte b/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte index a05177b7f2..e08932c3be 100644 --- a/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte +++ b/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte @@ -51,6 +51,7 @@ selectedKind?: 'script' | 'flow' | 'approval' | 'trigger' | 'preprocessor' | 'failure' displayPath?: boolean refreshCount?: number + onnew?: (...args: any[]) => any } let { @@ -64,7 +65,8 @@ kind, selectedKind = kind, displayPath = false, - refreshCount = 0 + refreshCount = 0, + onnew = undefined }: Props = $props() if ($workspaceStore && cachedOwners?.[$workspaceStore]) { @@ -133,6 +135,16 @@ instructions: funcDesc } }) + onnew?.({ + kind: selectedKind, + inlineScript: { + language: lang, + kind: selectedKind, + subkind: 'flow', + summary, + instructions: funcDesc + } + }) } let openScriptSettings = $state(false) @@ -353,6 +365,7 @@ { dispatch('new', { kind }) + onnew?.({ kind }) }} {label} selected={selectedByKeyboard === i} @@ -433,6 +446,20 @@ summary } }) + onnew?.({ + kind: selectedKind, + inlineScript: { + language: lang == 'docker' ? 'bash' : lang, + kind: selectedKind, + subkind: + lang == 'docker' + ? 'docker' + : selectedKind == 'preprocessor' + ? 'preprocessor' + : 'flow', + summary + } + }) }} /> {/each} diff --git a/frontend/src/lib/components/flows/content/FlowModuleHeader.svelte b/frontend/src/lib/components/flows/content/FlowModuleHeader.svelte index bb8490be5f..e21adf9a84 100644 --- a/frontend/src/lib/components/flows/content/FlowModuleHeader.svelte +++ b/frontend/src/lib/components/flows/content/FlowModuleHeader.svelte @@ -25,10 +25,36 @@ interface Props { module: FlowModule tag: string | undefined + ontoggleRetry?: (...args: any[]) => any + ontoggleConcurrency?: (...args: any[]) => any + ontoggleCache?: (...args: any[]) => any + ontoggleStopAfterIf?: (...args: any[]) => any + ontoggleSuspend?: (...args: any[]) => any + ontoggleSleep?: (...args: any[]) => any + ontogglePin?: (...args: any[]) => any + onreload?: (...args: any[]) => any + ontagChange?: (...args: any[]) => any + onfork?: (...args: any[]) => any + oncreateScriptFromInlineScript?: (...args: any[]) => any } - let { module, tag }: Props = $props() - const { scriptEditorDrawer, flowEditorDrawer } = getContext('FlowEditorContext') + let { + module, + tag, + ontoggleRetry = undefined, + ontoggleConcurrency = undefined, + ontoggleCache = undefined, + ontoggleStopAfterIf = undefined, + ontoggleSuspend = undefined, + ontoggleSleep = undefined, + ontogglePin = undefined, + onreload = undefined, + ontagChange = undefined, + onfork = undefined, + oncreateScriptFromInlineScript = undefined + }: Props = $props() + const { scriptEditorDrawer, flowEditorDrawer } = + getContext('FlowEditorContext') const dispatch = createEventDispatcher() let customUi: undefined | FlowBuilderWhitelabelCustomUi = getContext('customUi') @@ -40,7 +66,11 @@
{#if module.value.type === 'script' || module.value.type === 'rawscript' || module.value.type == 'flow'} {#if module.retry?.constant || module.retry?.exponential} - dispatch('toggleRetry')}> + (dispatch('toggleRetry'), ontoggleRetry?.())} + > {#snippet text()} Retries @@ -51,7 +81,7 @@ dispatch('toggleConcurrency')} + onClick={() => (dispatch('toggleConcurrency'), ontoggleConcurrency?.())} > {#snippet text()} @@ -60,7 +90,11 @@ {/if} {#if module.cache_ttl != undefined} - dispatch('toggleCache')}> + (dispatch('toggleCache'), ontoggleCache?.())} + > {#snippet text()} Cache @@ -71,7 +105,7 @@ dispatch('toggleStopAfterIf')} + onClick={() => (dispatch('toggleStopAfterIf'), ontoggleStopAfterIf?.())} > {#snippet text()} @@ -80,7 +114,11 @@ {/if} {#if module.suspend} - dispatch('toggleSuspend')}> + (dispatch('toggleSuspend'), ontoggleSuspend?.())} + > {#snippet text()} Suspend @@ -88,7 +126,11 @@ {/if} {#if module.sleep} - dispatch('toggleSleep')}> + (dispatch('toggleSleep'), ontoggleSleep?.())} + > {#snippet text()} Sleep @@ -96,7 +138,11 @@ {/if} {#if module.mock?.enabled} - dispatch('togglePin')}> + (dispatch('togglePin'), ontogglePin?.())} + > {#snippet text()} This step is pinned @@ -114,6 +160,7 @@ const hash = module.value.hash ?? (await getLatestHashForScript(module.value.path)) $scriptEditorDrawer?.openDrawer(hash, () => { dispatch('reload') + onreload?.() sendUserToast('Script has been updated') }) } @@ -132,14 +179,14 @@ noLabel={customUi?.tagSelectNoLabel} nullTag={tag} tag={module.value.tag_override} - on:change={(e) => dispatch('tagChange', e.detail)} + on:change={(e) => (dispatch('tagChange', e.detail), ontagChange?.(e.detail))} /> {/if} {#if customUi?.scriptFork != false} (dispatch('move'), onmove?.())} + size="xs" + destructive>Cancel move
{/if} diff --git a/frontend/src/lib/components/flows/map/VirtualItemWrapper.svelte b/frontend/src/lib/components/flows/map/VirtualItemWrapper.svelte index 798116b47d..7c796e6509 100644 --- a/frontend/src/lib/components/flows/map/VirtualItemWrapper.svelte +++ b/frontend/src/lib/components/flows/map/VirtualItemWrapper.svelte @@ -15,6 +15,7 @@ className?: string previewButton?: import('svelte').Snippet colorClasses: FlowNodeColorClasses + onselect?: (...args: any[]) => any } let { @@ -25,7 +26,8 @@ children, className, previewButton, - colorClasses + colorClasses, + onselect = undefined }: Props = $props() const dispatch = createEventDispatcher<{ @@ -55,6 +57,7 @@ onpointerdown={() => { if (selectable) { dispatch('select', id || label || '') + onselect?.(id || label || '') } }} onmouseenter={() => { diff --git a/frontend/src/lib/components/flows/pickers/FlowScriptPickerQuick.svelte b/frontend/src/lib/components/flows/pickers/FlowScriptPickerQuick.svelte index e93512d456..f7b81f4073 100644 --- a/frontend/src/lib/components/flows/pickers/FlowScriptPickerQuick.svelte +++ b/frontend/src/lib/components/flows/pickers/FlowScriptPickerQuick.svelte @@ -6,11 +6,12 @@ import { createEventDispatcher } from 'svelte' interface Props { - label: string; - lang?: SupportedLanguage | 'docker' | 'javascript' | undefined; - selected?: boolean; - eeRestricted: boolean; - enterpriseLangs?: string[]; + label: string + lang?: SupportedLanguage | 'docker' | 'javascript' | undefined + selected?: boolean + eeRestricted: boolean + enterpriseLangs?: string[] + onclick?: (...args: any[]) => any } let { @@ -18,8 +19,9 @@ lang = undefined, selected = false, eeRestricted, - enterpriseLangs = [] - }: Props = $props(); + enterpriseLangs = [], + onclick = undefined + }: Props = $props() const dispatch = createEventDispatcher() function handleKeydown(event: KeyboardEvent & { currentTarget: EventTarget & Window }) { @@ -37,6 +39,7 @@ return } dispatch('click') + onclick?.() } diff --git a/frontend/src/lib/components/flows/pickers/FlowToplevelNode.svelte b/frontend/src/lib/components/flows/pickers/FlowToplevelNode.svelte index 1b0e6ae58a..5a969aaedd 100644 --- a/frontend/src/lib/components/flows/pickers/FlowToplevelNode.svelte +++ b/frontend/src/lib/components/flows/pickers/FlowToplevelNode.svelte @@ -3,11 +3,12 @@ import TopLevelNode from './TopLevelNode.svelte' interface Props { - label: string; - selected?: boolean; + label: string + selected?: boolean + onclick?: (...args: any[]) => any } - let { label, selected = false }: Props = $props(); + let { label, selected = false, onclick = undefined }: Props = $props() const dispatch = createEventDispatcher() function handleKeydown(event: KeyboardEvent & { currentTarget: EventTarget & Window }) { if (selected && event.key === 'Enter') { @@ -18,6 +19,7 @@ function click() { dispatch('click') + onclick?.() } diff --git a/frontend/src/lib/components/flows/pickers/PickHubApp.svelte b/frontend/src/lib/components/flows/pickers/PickHubApp.svelte index 7f534a924a..079c66cb5b 100644 --- a/frontend/src/lib/components/flows/pickers/PickHubApp.svelte +++ b/frontend/src/lib/components/flows/pickers/PickHubApp.svelte @@ -13,9 +13,16 @@ syncQuery?: boolean children?: import('svelte').Snippet size?: ButtonType.UnifiedSize + onpick?: (...args: any[]) => any } - let { filter = $bindable(''), syncQuery = false, children, size = 'md' }: Props = $props() + let { + filter = $bindable(''), + syncQuery = false, + children, + size = 'md', + onpick = undefined + }: Props = $props() type Item = { apps: string[]; summary: string; path: string } let hubApps: any[] | undefined = $state(undefined) @@ -63,7 +70,7 @@