diff --git a/frontend/src/lib/components/JobLoader.svelte b/frontend/src/lib/components/JobLoader.svelte index 4a2d43ad12..92e2f858be 100644 --- a/frontend/src/lib/components/JobLoader.svelte +++ b/frontend/src/lib/components/JobLoader.svelte @@ -701,7 +701,10 @@ if (previewJobUpdates.completed) { currentEventSource?.close() currentEventSource = undefined - noPingTimeout = undefined + if (noPingTimeout) { + clearTimeout(noPingTimeout) + noPingTimeout = undefined + } isCompleted = true if (onlyResult) { callbacks?.doneResult?.({ diff --git a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte index 51ae40c21a..346dff11c3 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte @@ -235,6 +235,7 @@ bind:loading {componentInput} doOnSuccess={resolvedConfig.onSuccess} + doOnSubmit={resolvedConfig.onSubmit} doOnError={resolvedConfig.onError} {errorHandledByComponent} {id} diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte index 2874422d2f..9751363445 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte @@ -76,6 +76,7 @@ runnableClass?: string runnableStyle?: string doOnSuccess?: SideEffectAction + doOnSubmit?: SideEffectAction doOnError?: SideEffectAction render: boolean recomputeIds?: string[] @@ -112,6 +113,7 @@ runnableClass = '', runnableStyle = '', doOnSuccess = undefined, + doOnSubmit = undefined, doOnError = undefined, render, recomputeIds = [], @@ -191,6 +193,14 @@ ) } + async function handleSubmitSideEffect() { + if (!doOnSubmit) return + + if (doOnSubmit.selected == 'none') return + + await executeSideEffect(doOnSubmit, true) + } + export async function handleSideEffect(success: boolean, errorMessage?: string) { const sideEffect = success ? doOnSuccess : doOnError @@ -201,6 +211,12 @@ if (sideEffect.selected == 'none') return + await executeSideEffect(sideEffect, success, errorMessage) + } + + async function executeSideEffect(sideEffect: SideEffectAction, success: boolean = true, errorMessage?: string) { + if (!sideEffect) return + switch (sideEffect.selected) { case 'setTab': let setTab = sideEffect?.configuration.setTab?.setTab @@ -336,7 +352,9 @@ wrapperClass={runnableClass} wrapperStyle={runnableStyle} {render} - on:started + on:started={(e) => { + handleSubmitSideEffect() + }} on:done on:doneError on:cancel diff --git a/frontend/src/lib/components/apps/editor/component/components.ts b/frontend/src/lib/components/apps/editor/component/components.ts index c36529f2f8..ab9ca96c19 100644 --- a/frontend/src/lib/components/apps/editor/component/components.ts +++ b/frontend/src/lib/components/apps/editor/component/components.ts @@ -640,6 +640,94 @@ const onSuccessClick = { } } as const +const onSubmitClick = { + type: 'oneOf', + tooltip: 'Action to perform on submit (when job ID is obtained)', + selected: 'none', + labels, + configuration: { + none: {}, + gotoUrl: { + url: { + tooltip: 'Go to the given url, absolute or relative', + fieldType: 'text', + type: 'static', + value: '', + placeholder: '/apps/get/foo', + onDemandOnly: true + }, + newTab: { + tooltip: 'Open the url in a new tab', + fieldType: 'boolean', + type: 'static', + value: true + } + }, + setTab: { + setTab: { + type: 'static', + value: [] as Array<{ id: string; index: number }>, + fieldType: 'array', + subFieldType: 'tab-select', + tooltip: 'Set the tabs id and index to go to on submit', + onDemandOnly: true + } + }, + sendToast: { + message: { + tooltip: 'The message of the toast to display', + fieldType: 'text', + type: 'static', + value: '', + placeholder: 'Hello there', + onDemandOnly: true + } + }, + openModal: { + modalId: { + tooltip: 'The id of the modal to open', + fieldType: 'text', + type: 'static', + value: '', + deprecated: true + } + }, + closeModal: { + modalId: { + tooltip: 'The id of the modal to close', + fieldType: 'text', + type: 'static', + value: '', + deprecated: true + } + }, + open: { + id: { + tooltip: 'The id of the modal or the drawer to open', + fieldType: 'text', + type: 'static', + value: '' + } + }, + close: { + id: { + tooltip: 'The id of the modal or the drawer to close', + fieldType: 'text', + type: 'static', + value: '' + } + }, + clearFiles: { + id: { + tooltip: 'The id of s3 file input to clear', + fieldType: 'text', + type: 'static', + value: '' + } + } + } +} as const + const onErrorClick = { type: 'oneOf', tooltip: 'Action to perform on error', @@ -1405,6 +1493,7 @@ export const components = { }, onSuccess: onSuccessClick, + onSubmit: onSubmitClick, onError: onErrorClick, confirmationModal: { type: 'oneOf', @@ -1543,6 +1632,7 @@ export const components = { selectOptions: selectOptions.buttonSizeOptions }, onSuccess: onSuccessClick, + onSubmit: onSubmitClick, onError: onErrorClick } } @@ -1592,6 +1682,7 @@ export const components = { selectOptions: selectOptions.buttonSizeOptions }, onSuccess: onSuccessClick, + onSubmit: onSubmitClick, onError: onErrorClick, disabled: { fieldType: 'boolean', diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte index 9c26dad3c2..3000f6c671 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte @@ -45,6 +45,7 @@ const mapping = { onSuccess: 'On success wizard', + onSubmit: 'On submit wizard', onError: 'On error wizard' }