diff --git a/frontend/package-lock.json b/frontend/package-lock.json index cff0832146334..fc45a149e318b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -86,6 +86,8 @@ "devDependencies": { "@floating-ui/core": "^1.3.1", "@hey-api/openapi-ts": "^0.43.0", + "@melt-ui/pp": "^0.3.2", + "@melt-ui/svelte": "^0.86.2", "@playwright/test": "^1.34.3", "@rgossiaux/svelte-headlessui": "^2.0.0", "@sveltejs/adapter-static": "^3.0.6", @@ -3560,6 +3562,16 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "node_modules/@internationalized/date": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.6.0.tgz", + "integrity": "sha512-+z6ti+CcJnRlLHok/emGEsWQhe7kfSmEW+/6qCzvKY67YPh7YOBfvc7+/+NXq+zJlbArg30tYpqLjNgcAYv2YQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", @@ -3672,6 +3684,58 @@ "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz", "integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==" }, + "node_modules/@melt-ui/pp": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@melt-ui/pp/-/pp-0.3.2.tgz", + "integrity": "sha512-xKkPvaIAFinklLXcQOpwZ8YSpqAFxykjWf8Y/fSJQwsixV/0rcFs07hJ49hJjPy5vItvw5Qa0uOjzFUbXzBypQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^3.0.3", + "magic-string": "^0.30.5" + }, + "peerDependencies": { + "@melt-ui/svelte": ">= 0.29.0", + "svelte": "^3.55.0 || ^4.0.0 || ^5.0.0-next.1" + } + }, + "node_modules/@melt-ui/svelte": { + "version": "0.86.2", + "resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.86.2.tgz", + "integrity": "sha512-wRVN603oIt1aXvx2QRmKqVDJgTScSvr/WJLLokkD8c4QzHgn6pfpPtUKmhV6Dvkk+OY89OG/1Irkd6ouA50Ztw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.3.1", + "@floating-ui/dom": "^1.4.5", + "@internationalized/date": "^3.5.0", + "dequal": "^2.0.3", + "focus-trap": "^7.5.2", + "nanoid": "^5.0.4" + }, + "peerDependencies": { + "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0-next.118" + } + }, + "node_modules/@melt-ui/svelte/node_modules/nanoid": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, "node_modules/@mistralai/mistralai": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.0.tgz", @@ -4323,6 +4387,16 @@ "vite": "^5.0.0" } }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@tailwindcss/forms": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", @@ -7302,6 +7376,16 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/focus-trap": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.2.tgz", + "integrity": "sha512-9FhUxK1hVju2+AiQIDJ5Dd//9R2n2RAfJ0qfhF4IHGHgcoEUTMpbTeG/zbEuwaiYXfuAH6XE0/aCyxDdRM+W5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tabbable": "^6.2.0" + } + }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -12839,6 +12923,13 @@ "node": ">= 10" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true, + "license": "MIT" + }, "node_modules/table": { "version": "6.8.2", "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", @@ -13123,9 +13214,10 @@ "dev": true }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", diff --git a/frontend/package.json b/frontend/package.json index 1bcd76455549b..c3b9a8ef1bbed 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,8 @@ "devDependencies": { "@floating-ui/core": "^1.3.1", "@hey-api/openapi-ts": "^0.43.0", + "@melt-ui/pp": "^0.3.2", + "@melt-ui/svelte": "^0.86.2", "@playwright/test": "^1.34.3", "@rgossiaux/svelte-headlessui": "^2.0.0", "@sveltejs/adapter-static": "^3.0.6", diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index 9edfb332de301..ed9601e95f772 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -95,6 +95,7 @@ | { type: 'hash'; hash: string } | undefined = undefined export let otherArgs: Record = {} + export let lightHeader = false let oneOfSelected: string | undefined = undefined async function updateOneOfSelected(oneOf: SchemaProperty[] | undefined) { @@ -344,6 +345,7 @@ {contentEncoding} {format} {simpleTooltip} + {lightHeader} /> {/if} diff --git a/frontend/src/lib/components/Dev.svelte b/frontend/src/lib/components/Dev.svelte index 22d4f1b22a13c..7f20b6c58f5a0 100644 --- a/frontend/src/lib/components/Dev.svelte +++ b/frontend/src/lib/components/Dev.svelte @@ -489,7 +489,8 @@ selectedTrigger: selectedTriggerStore, triggersCount: triggersCount, simplifiedPoll: writable(false), - defaultValues: writable(undefined) + defaultValues: writable(undefined), + captureOn: writable(undefined) }) setContext('FlowEditorContext', { selectedId: selectedIdStore, diff --git a/frontend/src/lib/components/FieldHeader.svelte b/frontend/src/lib/components/FieldHeader.svelte index 0dea7e0a14f89..2bbbacf1989c5 100644 --- a/frontend/src/lib/components/FieldHeader.svelte +++ b/frontend/src/lib/components/FieldHeader.svelte @@ -14,10 +14,18 @@ export let labelClass: string = '' export let prettify = false export let simpleTooltip: string | undefined = undefined + export let lightHeader = false
- + {#if prettify} {label.replace(/_/g, ' ').split(' ').map(capitalize).join(' ')} {:else} diff --git a/frontend/src/lib/components/FlowBuilder.svelte b/frontend/src/lib/components/FlowBuilder.svelte index af622f661dcd6..5ca09cd87fe94 100644 --- a/frontend/src/lib/components/FlowBuilder.svelte +++ b/frontend/src/lib/components/FlowBuilder.svelte @@ -107,7 +107,7 @@ export let disabledFlowInputs = false export let savedPrimarySchedule: ScheduleTrigger | undefined = undefined export let version: number | undefined = undefined - export let setSavedraftCb: ((cb: () => void) => void) | undefined = undefined + export let setSavedraftCb: ((cb: () => void) => void) | undefined = undefined // Used by multiplayer deploy collision warning let deployedValue: Value | undefined = undefined // Value to diff against @@ -536,7 +536,8 @@ primarySchedule: primaryScheduleStore, triggersCount, simplifiedPoll, - defaultValues: writable(undefined) + defaultValues: writable(undefined), + captureOn: writable(undefined) }) async function loadTriggers() { diff --git a/frontend/src/lib/components/Label.svelte b/frontend/src/lib/components/Label.svelte index 3d53070c6c8c1..dec8f69aae636 100644 --- a/frontend/src/lib/components/Label.svelte +++ b/frontend/src/lib/components/Label.svelte @@ -1,14 +1,25 @@ -
+
-
- {label} - -
+ {#if !headless} +
+ {label} + {#if required} + + {/if} + +
+ {/if}
diff --git a/frontend/src/lib/components/ResourceEditorDrawer.svelte b/frontend/src/lib/components/ResourceEditorDrawer.svelte index b7c80ec840501..c5ee96daa1b22 100644 --- a/frontend/src/lib/components/ResourceEditorDrawer.svelte +++ b/frontend/src/lib/components/ResourceEditorDrawer.svelte @@ -10,7 +10,8 @@ let resource_type: string | undefined = undefined let defaultValues: Record | undefined = undefined - let resourceEditor: { editResource: () => void } | undefined = undefined + let resourceEditor: { editResource: () => void; createResource: () => void } | undefined = + undefined let path: string | undefined = undefined @@ -32,10 +33,17 @@ defaultValues = nDefaultValues drawer.openDrawer?.() } + + let mode: 'edit' | 'new' = newResource ? 'new' : 'edit' + + $: path ? (mode = 'edit') : (mode = 'new') - + {#await import('./ResourceEditor.svelte')} {:then Module} @@ -53,7 +61,11 @@
{:else} diff --git a/frontend/src/lib/components/ScriptEditor.svelte b/frontend/src/lib/components/ScriptEditor.svelte index b307963de5b76..20d15f0f9c214 100644 --- a/frontend/src/lib/components/ScriptEditor.svelte +++ b/frontend/src/lib/components/ScriptEditor.svelte @@ -13,7 +13,7 @@ import EditorBar, { EDITOR_BAR_WIDTH_THRESHOLD } from './EditorBar.svelte' import TestJobLoader from './TestJobLoader.svelte' import JobProgressBar from '$lib/components/jobs/JobProgressBar.svelte' - import { createEventDispatcher, onDestroy, onMount, tick } from 'svelte' + import { createEventDispatcher, onDestroy, onMount } from 'svelte' import { Button } from './common' import SplitPanesWrapper from './splitPanes/SplitPanesWrapper.svelte' import WindmillIcon from './icons/WindmillIcon.svelte' @@ -28,11 +28,7 @@ import Tabs from './common/tabs/Tabs.svelte' import Tab from './common/tabs/Tab.svelte' import { slide } from 'svelte/transition' - import CapturePanel from './triggers/CapturePanel.svelte' - import { - BUN_PREPROCESSOR_MODULE_CODE, - PYTHON_PREPROCESSOR_MODULE_CODE - } from '$lib/script_helpers' + import CaptureTable from '$lib/components/triggers/CaptureTable.svelte' // Exported export let schema: Schema | any = emptySchema() @@ -54,6 +50,10 @@ export let saveToWorkspace = false export let watchChanges = false export let customUi: ScriptEditorWhitelabelCustomUi = {} + export let args: Record = initialArgs + export let selectedTab: 'main' | 'preprocessor' = 'main' + export let hasPreprocessor = false + export let shouldRefreshCaptures = false let jobProgressReset: () => void @@ -75,9 +75,6 @@ let testJobLoader: TestJobLoader - // Test args input - let args: Record = initialArgs - let isValid: boolean = true let scriptProgress = undefined @@ -131,8 +128,6 @@ }) } - let hasPreprocessor = false - export async function inferSchema(code: string, nlang?: SupportedLanguage, resetArgs = false) { let nschema = schema ?? emptySchema() @@ -247,8 +242,9 @@ url.search = '' return `${url}?collab=1` + (edit ? '' : `&path=${path}`) } - let selectedTab: 'main' | 'preprocessor' | 'capture' = 'main' + $: showTabs = hasPreprocessor + $: !hasPreprocessor && (selectedTab = 'main') $: selectedTab && inferSchema(code) let argsRender = 0 @@ -376,136 +372,115 @@
-
- - Main - {#if hasPreprocessor} -
- Preprocessor -
- {/if} - Capture -
-
- {#if selectedTab === 'capture'} - { - selectedTab = e.detail.kind - // TODO: that sucks, but don't know how to avoid it - await tick() - await tick() - args = e.detail.args ?? {} - }} - canHavePreprocessor={lang === 'bun' || lang === 'deno' || lang === 'python3'} - on:addPreprocessor={() => { - const code = editor?.getCode() - if (code) { - const preprocessorCode = - lang === 'python3' - ? PYTHON_PREPROCESSOR_MODULE_CODE - : BUN_PREPROCESSOR_MODULE_CODE - const mainIndex = code.indexOf( - lang === 'python3' ? 'def main' : 'export async function main' - ) - if (mainIndex === -1) { - editor?.setCode(code + preprocessorCode) - } else { - editor?.setCode( - code.slice(0, mainIndex) + - preprocessorCode + - '\n' + - code.slice(mainIndex) + - '\n\n' - ) - } - } - }} - /> - {:else} -
- {#if testIsLoading} - - {:else} - - {/if} -
- - -
-
- {#key argsRender} - - {/key} + {#if showTabs} +
+ + Main + {#if hasPreprocessor} +
+ Preprocessor
+ {/if} +
+
+ {/if} + +
+ {#if testIsLoading} + + {:else} + + {/if} +
+ + +
+
+ {#key argsRender} + + {/key}
- - - - {#if scriptProgress} - - + + + + {#if scriptProgress} + + + {/if} + +
+ - {/if} - - - - {/if} +
+
+
+
+
diff --git a/frontend/src/lib/components/Section.svelte b/frontend/src/lib/components/Section.svelte index cea644eb48e51..1889fc708a8b1 100644 --- a/frontend/src/lib/components/Section.svelte +++ b/frontend/src/lib/components/Section.svelte @@ -10,46 +10,51 @@ export let small: boolean = false export let collapsable: boolean = false - let collapsed: boolean = true + export let collapsed: boolean = true + export let headless: boolean = false
-
-

- {#if collapsable} - + {:else} {label} - - {:else} - {label} - {/if} + {/if} - - {#if tooltip} - {tooltip} - {/if} - {#if eeOnly} - {#if !$enterpriseLicense} -
- - EE only Enterprise Edition only feature -
+ + {#if tooltip} + {tooltip} {/if} + {#if eeOnly} + {#if !$enterpriseLicense} +
+ + EE only Enterprise Edition only feature +
+ {/if} + {/if} +

+ + {#if collapsable && collapsed} + {/if} - - - -
+
+ {/if}
diff --git a/frontend/src/lib/components/Subsection.svelte b/frontend/src/lib/components/Subsection.svelte new file mode 100644 index 0000000000000..a3dd13bde11f0 --- /dev/null +++ b/frontend/src/lib/components/Subsection.svelte @@ -0,0 +1,55 @@ + + +
+ {#if !headless} +
+

+ {#if collapsable} + + {:else} + {label} + {/if} + + + {#if tooltip} + {tooltip} + {/if} + {#if eeOnly} + {#if !$enterpriseLicense} +
+ + EE only Enterprise Edition only feature +
+ {/if} + {/if} +

+ + {#if collapsable && collapsed} + + {/if} +
+ {/if} +
+ +
+
diff --git a/frontend/src/lib/components/common/alert/ConnectionIndicator.svelte b/frontend/src/lib/components/common/alert/ConnectionIndicator.svelte new file mode 100644 index 0000000000000..27b64d7961004 --- /dev/null +++ b/frontend/src/lib/components/common/alert/ConnectionIndicator.svelte @@ -0,0 +1,34 @@ + + +{#if connectionInfo} +
+ {#if connectionInfo.status === 'connected'} + + + + + +
{connectionInfo.message ?? ''}
+
+ {:else} + + + + + + +
{connectionInfo.message ?? ''}
+
+ {/if} +
+{/if} diff --git a/frontend/src/lib/components/common/toggleButton-v2/ToggleButton.svelte b/frontend/src/lib/components/common/toggleButton-v2/ToggleButton.svelte index e5bc62aa889fb..7f903debd8d86 100644 --- a/frontend/src/lib/components/common/toggleButton-v2/ToggleButton.svelte +++ b/frontend/src/lib/components/common/toggleButton-v2/ToggleButton.svelte @@ -48,7 +48,7 @@ {#if icon} diff --git a/frontend/src/lib/components/details/DetailPageLayout.svelte b/frontend/src/lib/components/details/DetailPageLayout.svelte index e9b74666f1417..d951f757411c4 100644 --- a/frontend/src/lib/components/details/DetailPageLayout.svelte +++ b/frontend/src/lib/components/details/DetailPageLayout.svelte @@ -29,7 +29,8 @@ primarySchedule: primaryScheduleStore, triggersCount, simplifiedPoll, - defaultValues: writable(undefined) + defaultValues: writable(undefined), + captureOn: writable(undefined) }) diff --git a/frontend/src/lib/components/details/EmailTriggerConfigSection.svelte b/frontend/src/lib/components/details/EmailTriggerConfigSection.svelte new file mode 100644 index 0000000000000..9f91ea10b1735 --- /dev/null +++ b/frontend/src/lib/components/details/EmailTriggerConfigSection.svelte @@ -0,0 +1,108 @@ + + +{#if SCRIPT_VIEW_SHOW_CREATE_TOKEN_BUTTON} + +{/if} + +{#if !isFlow} +
+
+
Call method
+ + + + +
+
+{/if} + +{#key requestType} + {#key token} + + {/key} +{/key} + + + To trigger the job by email, send an email to the address above. The job will receive two + arguments: `raw_email` containing the raw email as string, and `parsed_email` containing the + parsed email as an object. + diff --git a/frontend/src/lib/components/details/EmailTriggerPanel.svelte b/frontend/src/lib/components/details/EmailTriggerPanel.svelte index defcdf62df660..3edc6840177b3 100644 --- a/frontend/src/lib/components/details/EmailTriggerPanel.svelte +++ b/frontend/src/lib/components/details/EmailTriggerPanel.svelte @@ -1,69 +1,38 @@ @@ -79,65 +48,25 @@ {scopes} /> -
- - Email triggers execute scripts and flows when emails are sent to specific addresses. Each - trigger has its own unique email address that can be used to invoke the script or flow. - - +
{#if loading} {:else} {#if emailDomain} - {#if SCRIPT_VIEW_SHOW_CREATE_TOKEN_BUTTON} - - {/if} - - {#if !isFlow} -
-
-
Call method
- - - - -
-
- {/if} - - {#key requestType} - {#key token} - - {/key} - {/key} - - To trigger the job by email, send an email to the address above. The job will receive two - arguments: `raw_email` containing the raw email as string, and `parsed_email` containing the - parsed email as an object. - + {:else}
diff --git a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte index cd5e9bc4b8824..d432c43d24822 100644 --- a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte +++ b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte @@ -13,6 +13,7 @@ import { dfs } from '../dfs' import FlowPreprocessorModule from './FlowPreprocessorModule.svelte' import type { TriggerContext } from '$lib/components/triggers' + import { insertNewPreprocessorModule } from '../flowStateUtils' export let noEditor = false export let enableAi = false @@ -22,7 +23,7 @@ const { selectedId, flowStore, flowStateStore, flowInputsStore, pathStore, initialPath } = getContext('FlowEditorContext') - const { selectedTrigger, defaultValues } = getContext('TriggerContext') + const { selectedTrigger, defaultValues, captureOn } = getContext('TriggerContext') function checkDup(modules: FlowModule[]): string | undefined { let seenModules: string[] = [] for (const m of modules) { @@ -69,8 +70,16 @@ $selectedId = 'triggers' selectedTrigger.set(ev.detail.kind) defaultValues.set(ev.detail.config) + captureOn.set(true) }} on:applyArgs + on:updateSchema={(e) => { + const { schema, redirect } = e.detail + $flowStore.schema = schema + if (redirect) { + $selectedId = 'Input' + } + }} /> {:else if $selectedId === 'Result'}

The result of the flow will be the result of the last node.

@@ -82,12 +91,22 @@ {:else if $selectedId === 'triggers'} { + await insertNewPreprocessorModule(flowStore, flowStateStore, { + language: 'bun', + subkind: 'preprocessor' + }) + $selectedId = 'preprocessor' + }} currentPath={$pathStore} {initialPath} schema={$flowStore.schema} {noEditor} newItem={newFlow} isFlow={true} + hasPreprocessor={!!$flowStore.value.preprocessor_module} + canHavePreprocessor={true} /> {:else if $selectedId.startsWith('subflow:')}
('FlowEditorContext') let inputLibraryDrawer: Drawer @@ -41,95 +38,63 @@ jsonPayload.closeDrawer() } const yOffset = 191 - - let tabSelected = 'input' {#if !disabled} - - Input form - Capture - - - {#if tabSelected === 'input'} -
-
Copy input's schema from
- - - -
-
- { - $flowStore = $flowStore - }} - /> -
- - { - addProperty?.openDrawer(e.detail) +
+
Copy input's schema from
+ + + + +
+
+ { + $flowStore = $flowStore }} /> - {/if} +
+ + { + addProperty?.openDrawer(e.detail) + }} + on:delete={(e) => { + addProperty?.handleDeleteArgument([e.detail]) + }} + offset={yOffset} + displayWebhookWarning + /> {:else}
diff --git a/frontend/src/lib/components/flows/content/FlowPathViewer.svelte b/frontend/src/lib/components/flows/content/FlowPathViewer.svelte index b80df515ede57..04de37b099e98 100644 --- a/frontend/src/lib/components/flows/content/FlowPathViewer.svelte +++ b/frontend/src/lib/components/flows/content/FlowPathViewer.svelte @@ -22,7 +22,8 @@ selectedTrigger: selectedTriggerStore, triggersCount: triggersCount, simplifiedPoll: writable(false), - defaultValues: writable(undefined) + defaultValues: writable(undefined), + captureOn: writable(undefined) }) async function loadFlow(path: string) { diff --git a/frontend/src/lib/components/meltComponents/Popover.svelte b/frontend/src/lib/components/meltComponents/Popover.svelte new file mode 100644 index 0000000000000..579a0949cb6ef --- /dev/null +++ b/frontend/src/lib/components/meltComponents/Popover.svelte @@ -0,0 +1,50 @@ + + + + +{#if open} +
+ {#if displayArrow} +
+ {/if} + + {#if closeButton} + + {/if} +
+{/if} + + diff --git a/frontend/src/lib/components/scriptEditor/LogPanel.svelte b/frontend/src/lib/components/scriptEditor/LogPanel.svelte index 8b7a59c44d59c..2c1c6ba18c3b0 100644 --- a/frontend/src/lib/components/scriptEditor/LogPanel.svelte +++ b/frontend/src/lib/components/scriptEditor/LogPanel.svelte @@ -37,6 +37,7 @@ export let diffEditor: DiffEditor | undefined = undefined export let args: Record | undefined = undefined export let workspace: string | undefined = undefined + export let showCaptures: boolean = false type DrawerContent = { mode: 'json' | Preview['language'] | 'plain' @@ -87,170 +88,181 @@ - - Logs & Result - History +
+ + Logs & Result + History + {#if showCaptures} + Captures + {/if} - - - {#if selectedTab === 'logs'} - - - {#if previewJob?.is_flow_step == false && previewJob?.flow_status && !(typeof previewJob.flow_status == 'object' && '_metadata' in previewJob.flow_status)} - - - - {/if} - - - - - - {#if previewJob != undefined && 'result' in previewJob} -
-
- - - {#if lang && editor && diffEditor && args && previewJob?.result && typeof previewJob?.result == 'object' && `error` in previewJob?.result && previewJob?.result.error} - + +
+ {#if selectedTab === 'logs'} + + + {#if previewJob?.is_flow_step == false && previewJob?.flow_status && !(typeof previewJob.flow_status == 'object' && '_metadata' in previewJob.flow_status)} + + + + {/if} + + + + + + {#if previewJob != undefined && 'result' in previewJob} +
+
+ + + {#if lang && editor && diffEditor && args && previewJob?.result && typeof previewJob?.result == 'object' && `error` in previewJob?.result && previewJob?.result.error} + + {/if} + + +
+
+ {:else} +
+ + {#if previewIsLoading} + + {:else} + Test to see the result here {/if} - - -
-
- {:else} -
- - {#if previewIsLoading} - - {:else} - Test to see the result here - {/if} - - - The result renderer in Windmill supports rich display rendering, allowing you to - customize the display format of your results. - -
- {/if} - - - - {/if} - {#if selectedTab === 'history'} -
- - - - Id - Created at - Success - Result - Code - Logs - - - - {#each pastPreviews as { id, created_at, success }} - - - {id.substring(30)} - - {displayDate(created_at)} - - {#if success} - - {:else} - - {/if} - - - - - - - - - - - - {/each} - - + + + The result renderer in Windmill supports rich display rendering, allowing you + to customize the display format of your results. + +
+ {/if} + + + + {/if} + {#if selectedTab === 'history'} +
+ + + + Id + Created at + Success + Result + Code + Logs + + + + {#each pastPreviews as { id, created_at, success }} + + + {id.substring(30)} + + {displayDate(created_at)} + + {#if success} + + {:else} + + {/if} + + + + + + + + + + + + {/each} + + +
+ {/if} + {#if selectedTab === 'captures'} + + {/if}
- {/if} - - + + +
diff --git a/frontend/src/lib/components/triggers.ts b/frontend/src/lib/components/triggers.ts index a4447b0795e00..e585c7d989621 100644 --- a/frontend/src/lib/components/triggers.ts +++ b/frontend/src/lib/components/triggers.ts @@ -15,6 +15,7 @@ export type TriggerContext = { triggersCount: Writable simplifiedPoll: Writable defaultValues: Writable | undefined> + captureOn: Writable } export function setScheduledPollSchedule( diff --git a/frontend/src/lib/components/triggers/CaptureButton.svelte b/frontend/src/lib/components/triggers/CaptureButton.svelte new file mode 100644 index 0000000000000..ffc31ef80e9ca --- /dev/null +++ b/frontend/src/lib/components/triggers/CaptureButton.svelte @@ -0,0 +1,87 @@ + + + + + + + +
+ + + + + +
+
+
diff --git a/frontend/src/lib/components/triggers/CapturePanel.svelte b/frontend/src/lib/components/triggers/CapturePanel.svelte deleted file mode 100644 index f7ec31ff9ce1e..0000000000000 --- a/frontend/src/lib/components/triggers/CapturePanel.svelte +++ /dev/null @@ -1,622 +0,0 @@ - - -
-
- - - - - - - - -
- {#if (selected === 'websocket' || selected === 'kafka') && config && active} - {@const serverEnabled = getServerEnabled(config)} -
- {#if serverEnabled} - - - - -
Websocket is connected
-
- {:else} - - - - - -
- Websocket is not connected{config.error ? ': ' + config.error : ''} -
-
- {/if} -
- {/if} - - {#if newItem || cloudDisabled} - -
-
- {#if cloudDisabled} - - {capitalize(selected)} triggers are disabled in the multi-tenant cloud. - - {:else} - {#if selected in schemas} - {#key selected} - - {/key} - {/if} - - {#if selected === 'webhook'} - - - {:else if selected === 'http'} - - - {:else if selected === 'email'} - - {/if} - - - {/if} -
diff --git a/frontend/src/lib/components/triggers/CaptureTable.svelte b/frontend/src/lib/components/triggers/CaptureTable.svelte new file mode 100644 index 0000000000000..b420d4f2014f5 --- /dev/null +++ b/frontend/src/lib/components/triggers/CaptureTable.svelte @@ -0,0 +1,254 @@ + + +{#if selectedCaptures.length > 0 || !hideCapturesWhenEmpty} +
+ {/each} + {/if} +
+ +{/if} diff --git a/frontend/src/lib/components/triggers/CaptureWrapper.svelte b/frontend/src/lib/components/triggers/CaptureWrapper.svelte new file mode 100644 index 0000000000000..e0fa0fdedf672 --- /dev/null +++ b/frontend/src/lib/components/triggers/CaptureWrapper.svelte @@ -0,0 +1,221 @@ + + +
+ {#if cloudDisabled} + + {capitalize(captureType)} triggers are disabled in the multi-tenant cloud. + + {:else} + {#if captureType === 'websocket'} + + {:else if captureType === 'webhook'} + + {:else if captureType === 'http'} + + {:else if captureType === 'email'} + + {:else if captureType === 'kafka'} + + {/if} + + + {/if} +
diff --git a/frontend/src/lib/components/triggers/KafkaTriggerEditorInner.svelte b/frontend/src/lib/components/triggers/KafkaTriggerEditorInner.svelte index 174cdb579f2b8..4696719d8e0b8 100644 --- a/frontend/src/lib/components/triggers/KafkaTriggerEditorInner.svelte +++ b/frontend/src/lib/components/triggers/KafkaTriggerEditorInner.svelte @@ -10,11 +10,10 @@ import { canWrite, emptyString, sendUserToast } from '$lib/utils' import { createEventDispatcher } from 'svelte' import Section from '$lib/components/Section.svelte' - import { Loader2, Save, X, Plus } from 'lucide-svelte' + import { Loader2, Save } from 'lucide-svelte' import Label from '$lib/components/Label.svelte' import Toggle from '../Toggle.svelte' - import { fade } from 'svelte/transition' - import ResourcePicker from '../ResourcePicker.svelte' + import KafkaTriggersConfigSection from './KafkaTriggersConfigSection.svelte' let drawer: Drawer let is_flow: boolean = false @@ -26,15 +25,12 @@ let fixedScriptPath = '' let path: string = '' let pathError = '' - let kafka_resource_path = '' - let group_id = '' - let topics: string[] = [''] - let dirtyGroupId = false let enabled = false let dirtyPath = false let can_write = true let drawerLoading = true let defaultValues: Record | undefined = undefined + let args: Record = {} const dispatch = createEventDispatcher() @@ -48,7 +44,6 @@ itemKind = isFlow ? 'flow' : 'script' edit = true dirtyPath = false - dirtyGroupId = false await loadTrigger() } catch (err) { sendUserToast(`Could not load kafka trigger: ${err}`, true) @@ -68,10 +63,9 @@ is_flow = nis_flow edit = false itemKind = nis_flow ? 'flow' : 'script' - kafka_resource_path = '' - group_id = nDefaultValues?.group_id ?? '' - topics = nDefaultValues?.topics ?? [''] - dirtyGroupId = false + args.kafka_resource_path = nDefaultValues?.kafka_resource_path ?? '' + args.group_id = nDefaultValues?.group_id ?? '' + args.topics = nDefaultValues?.topics ?? [''] initialScriptPath = '' fixedScriptPath = fixedScriptPath_ ?? '' script_path = fixedScriptPath @@ -94,9 +88,9 @@ is_flow = s.is_flow path = s.path - kafka_resource_path = s.kafka_resource_path - group_id = s.group_id - topics = s.topics + args.kafka_resource_path = s.kafka_resource_path + args.group_id = s.group_id + args.topics = s.topics enabled = s.enabled can_write = canWrite(s.path, s.extra_perms, $userStore) @@ -111,9 +105,9 @@ path, script_path, is_flow, - kafka_resource_path, - group_id, - topics + kafka_resource_path: args.kafka_resource_path, + group_id: args.group_id, + topics: args.topics } }) sendUserToast(`Kafka trigger ${path} updated`) @@ -125,9 +119,9 @@ script_path, is_flow, enabled: true, - kafka_resource_path, - group_id, - topics + kafka_resource_path: args.kafka_resource_path, + group_id: args.group_id, + topics: args.topics } }) sendUserToast(`Kafka trigger ${path} created`) @@ -139,12 +133,22 @@ drawer.closeDrawer() } - $: topicsError = topics.some((b) => /[^[a-zA-Z0-9-_.]/.test(b)) ? 'Invalid topics' : '' - $: groupIdError = /[^a-zA-Z0-9-_.]/.test(group_id) ? 'Invalid group ID' : '' + $: topicsError = args.topics?.some((b) => /[^[a-zA-Z0-9-_.]/.test(b)) ? 'Invalid topics' : '' + $: groupIdError = /[^a-zA-Z0-9-_.]/.test(args.group_id) ? 'Invalid group ID' : '' - $: !dirtyGroupId && - path && - (group_id = `windmill_consumer-${$workspaceStore}-${path.replaceAll('/', '__')}`) + function useDefaultValues() { + if (args.kafka_resource_path && args.kafka_resource_path != '') { + return false + } + if (!defaultValues) { + return false + } + return ( + defaultValues.brokers && + defaultValues.brokers.length > 0 && + defaultValues.brokers.some((broker: string) => broker.trim() !== '') + ) + } @@ -180,11 +184,11 @@ startIcon={{ icon: Save }} disabled={pathError != '' || emptyString(script_path) || - emptyString(kafka_resource_path) || - topics.length < 1 || - topics.some((t) => emptyString(t)) || + emptyString(args.kafka_resource_path) || + args.topics.length < 1 || + args.topics.some((t) => emptyString(t)) || topicsError != '' || - emptyString(group_id) || + emptyString(args.group_id) || groupIdError != '' || !can_write} on:click={updateTrigger} @@ -220,85 +224,10 @@
-
-
-
-
- Resource - -
- -
- - - -
-
+

diff --git a/frontend/src/lib/components/triggers/KafkaTriggersConfigSection.svelte b/frontend/src/lib/components/triggers/KafkaTriggersConfigSection.svelte new file mode 100644 index 0000000000000..31296fad7d0ba --- /dev/null +++ b/frontend/src/lib/components/triggers/KafkaTriggersConfigSection.svelte @@ -0,0 +1,212 @@ + + +

+
+
+ + + {#if !staticInputDisabled} + + + + + {/if} + + + {#if selected === 'resource'} + + {:else} + + {/if} + +
+ +
+ + + +
+
+
diff --git a/frontend/src/lib/components/triggers/KafkaTriggersPanel.svelte b/frontend/src/lib/components/triggers/KafkaTriggersPanel.svelte index 83a91ed342bc5..1b84a616407ef 100644 --- a/frontend/src/lib/components/triggers/KafkaTriggersPanel.svelte +++ b/frontend/src/lib/components/triggers/KafkaTriggersPanel.svelte @@ -1,20 +1,22 @@ -
- - Kafka triggers execute scripts and flows in response to messages published to Kafka topics. - +{#if !$enterpriseLicense} + + Kafka triggers are an enterprise only feature. + +{:else if isCloudHosted()} + + Kafka triggers are disabled in the multi-tenant cloud. + +{:else} +
+ { + saveTrigger(path, e.detail.config) + }} + on:applyArgs + on:addPreprocessor + on:refreshCaptures + cloudDisabled={false} + triggerType="kafka" + {isFlow} + {data} + {path} + {isEditor} + {canHavePreprocessor} + {hasPreprocessor} + /> - {#if !$enterpriseLicense} - - Kafka triggers are an enterprise only feature. - - {:else if isCloudHosted()} - - Kafka triggers are disabled in the multi-tenant cloud. - - {:else} -
- {#if newItem} - - Deploy the {isFlow ? 'flow' : 'script'} to add kafka triggers. - - {:else} - - {#if kafkaTriggers} - {#if kafkaTriggers.length == 0} -
No kafka triggers
- {:else} -
- {#each kafkaTriggers as kafkaTrigger (kafkaTrigger.path)} -
-
{kafkaTrigger.path}
-
- {kafkaTrigger.kafka_resource_path} -
-
- -
-
- {/each} -
- {/if} + {#if newItem} + + Deploy the {isFlow ? 'flow' : 'script'} to add kafka triggers. + + {:else if kafkaTriggers} +
+ {#if kafkaTriggers.length == 0} +
No kafka triggers
{:else} - +
+ {#each kafkaTriggers as kafkaTrigger (kafkaTrigger.path)} +
+
{kafkaTrigger.path}
+
+ {kafkaTrigger.kafka_resource_path} +
+
+ +
+
+ {/each} +
{/if} - {/if} -
- {/if} -
+
+ {:else} + + {/if} +
+{/if} diff --git a/frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte b/frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte new file mode 100644 index 0000000000000..a0abd215eecbf --- /dev/null +++ b/frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte @@ -0,0 +1,166 @@ + + +
+ {#if !($userStore?.is_admin || $userStore?.is_super_admin)} + + Route endpoints can only be edited by workspace admins + +
+ {/if} +
+ + + + + + + + + +
+
+ + Full endpoint + + { + currentTarget.select() + }} + /> +
+ +
{dirtyRoutePath ? routeError : ''}
+
+ {#if showCapture} + + {/if} +
+
diff --git a/frontend/src/lib/components/triggers/RouteEditorInner.svelte b/frontend/src/lib/components/triggers/RouteEditorInner.svelte index 3840307373af0..ad7ac6fd1541f 100644 --- a/frontend/src/lib/components/triggers/RouteEditorInner.svelte +++ b/frontend/src/lib/components/triggers/RouteEditorInner.svelte @@ -1,5 +1,5 @@ {#if static_asset_config} @@ -254,76 +223,16 @@
-
- {#if !($userStore?.is_admin || $userStore?.is_super_admin)} - - Route endpoints can only be edited by workspace admins - -
- {/if} -
- - - - - - - - - -
-
- - Full endpoint - - { - currentTarget.select() - }} - /> -
- -
{dirtyRoutePath ? routeError : ''}
-
-
-
+
-
+
-
Request type
- - - - -
-
-
Authentication
- - - - +
+
diff --git a/frontend/src/lib/components/triggers/RoutesPanel.svelte b/frontend/src/lib/components/triggers/RoutesPanel.svelte index 44c0c47a9bf6c..25bdecc3bc043 100644 --- a/frontend/src/lib/components/triggers/RoutesPanel.svelte +++ b/frontend/src/lib/components/triggers/RoutesPanel.svelte @@ -1,19 +1,20 @@ -
- {#if !$simplifiedPoll} - - Webhooks - Schedules - Routes - Websockets - Kafka - Email - {#if isFlow} - Scheduled Poll - {/if} + {#if !$simplifiedPoll} + + Webhooks + Schedules + Routes + Websockets + Kafka + Email + {#if isFlow} + Scheduled Poll + {/if} - - {#if $selectedTrigger === 'webhooks'} -
- -
- {/if} + + {#if $selectedTrigger === 'webhooks'} +
+ +
+ {/if} - {#if $selectedTrigger === 'emails'} -
- -
- {/if} + {#if $selectedTrigger === 'emails'} +
+ +
+ {/if} - {#if $selectedTrigger === 'routes'} -
- -
- {/if} + {#if $selectedTrigger === 'routes'} +
+ +
+ {/if} - {#if $selectedTrigger === 'websockets'} -
- -
- {/if} + {#if $selectedTrigger === 'websockets'} +
+ +
+ {/if} - {#if $selectedTrigger === 'kafka'} -
- -
- {/if} + {#if $selectedTrigger === 'kafka'} +
+ +
+ {/if} - {#if $selectedTrigger === 'schedules'} -
- -
- {/if} + {#if $selectedTrigger === 'schedules'} +
+ +
+ {/if} - {#if $selectedTrigger === 'scheduledPoll'} -
- -
- {/if} -
-
- {:else} -
- -
- {/if} -
+ {#if $selectedTrigger === 'scheduledPoll'} +
+ +
+ {/if} + + + {:else} +
+ +
+ {/if}
diff --git a/frontend/src/lib/components/triggers/TriggersEditorSection.svelte b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte new file mode 100644 index 0000000000000..0c802b42ceb71 --- /dev/null +++ b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte @@ -0,0 +1,145 @@ + + +
+ +
+ {#if isEditor} + + + + + + {/if} + + {#if !noSave} + {@const disabled = newItem || cloudDisabled} + + + + {#if disabled} + {#if newItem} + Deploy the runnable to enable trigger creation + {:else if cloudDisabled} + {capitalize(triggerType)} triggers are disabled in the multi-tenant cloud + {/if} + {:else} + Create new {captureTypeLabels[triggerType]} trigger from prototype + {/if} + + + {/if} +
+
+ + {#if isEditor} + { + const { schema, redirect } = e.detail + $flowStore.schema = schema + if (redirect) { + $selectedId = 'Input' + } + }} + on:saveTrigger + on:refreshCaptures + bind:args + bind:handleCapture + bind:captureActive + {data} + bind:connectionInfo + /> + {:else} + + {/if} +
diff --git a/frontend/src/lib/components/triggers/TriggersWrapper.svelte b/frontend/src/lib/components/triggers/TriggersWrapper.svelte new file mode 100644 index 0000000000000..a2fee7365fa40 --- /dev/null +++ b/frontend/src/lib/components/triggers/TriggersWrapper.svelte @@ -0,0 +1,56 @@ + + +
+ {#if cloudDisabled} + + {capitalize(triggerType)} triggers are disabled in the multi-tenant cloud. + + {:else if triggerType === 'websocket'} + + {:else if triggerType === 'webhook'} + + {:else if triggerType === 'http'} + + {:else if triggerType === 'email'} + + {:else if triggerType === 'kafka'} + + {/if} +
diff --git a/frontend/src/lib/components/triggers/WebhooksConfigSection.svelte b/frontend/src/lib/components/triggers/WebhooksConfigSection.svelte new file mode 100644 index 0000000000000..eb3695c831c37 --- /dev/null +++ b/frontend/src/lib/components/triggers/WebhooksConfigSection.svelte @@ -0,0 +1,454 @@ + + + { + token = e.detail + triggerTokens?.listTokens() + }} + newTokenWorkspace={$workspaceStore} + newTokenLabel={`webhook-${$userStore?.username ?? 'superadmin'}-${generateRandomString(4)}`} + {scopes} +/> + +
+ {#if SCRIPT_VIEW_SHOW_CREATE_TOKEN_BUTTON} + + {/if} + +
+
+
Request type
+ + + + +
+
+
Call method
+ + + {#if !isFlow} + + {/if} + + + +
+
+
Token configuration
+ + + + +
+
+ + +
+ + REST + {#if SCRIPT_VIEW_SHOW_EXAMPLE_CURL} + Curl + {/if} + Fetch + + + {#key token} + +
+ + + {#if requestType !== 'get_path'} + + {/if} + {#key requestType} + {#key tokenType} + + {/key} + {/key} +
+
+ +
+ {#key args} + {#key requestType} + {#key webhookType} + {#key tokenType} + {#key showCapture} +
{ + e.preventDefault() + copyToClipboard(curlCode()) + }} + > + + +
+ {/key} + {/key} + {/key} + {/key} + {/key} +
+
+ + {#key args} + {#key requestType} + {#key webhookType} + {#key tokenType} + {#key token} +
{ + e.preventDefault() + copyToClipboard(fetchCode()) + }} + > + + +
+ {/key}{/key}{/key}{/key} + {/key} +
+ {/key} +
+
+
+ {#if !showCapture} + + {/if} +
diff --git a/frontend/src/lib/components/triggers/WebhooksPanel.svelte b/frontend/src/lib/components/triggers/WebhooksPanel.svelte index 3746ab67cac86..f938bcc1f3667 100644 --- a/frontend/src/lib/components/triggers/WebhooksPanel.svelte +++ b/frontend/src/lib/components/triggers/WebhooksPanel.svelte @@ -1,27 +1,7 @@
- - Webhooks trigger scripts or flows via HTTP requests. Each webhook can be configured to run - synchronously or asynchronously. You can secure webhooks using tokens with specific permissions. - - - { - token = e.detail - triggerTokens?.listTokens() - }} - newTokenWorkspace={$workspaceStore} - newTokenLabel={`webhook-${$userStore?.username ?? 'superadmin'}-${generateRandomString(4)}`} - {scopes} - /> - {#if SCRIPT_VIEW_SHOW_CREATE_TOKEN_BUTTON} - - {/if} - -
-
-
Request type
- - - - -
-
-
Call method
- - - {#if !isFlow} - - {/if} - - - -
-
-
Token configuration
- - - - -
-
- - - - REST - {#if SCRIPT_VIEW_SHOW_EXAMPLE_CURL} - Curl - {/if} - Fetch - - - {#key token} - -
- - - {#if requestType !== 'get_path'} - - {/if} - {#key requestType} - {#key tokenType} - - {/key} - {/key} -
-
- -
- {#key args} - {#key requestType} - {#key webhookType} - {#key tokenType} -
{ - e.preventDefault() - copyToClipboard(curlCode()) - }} - > - - -
- {/key} - {/key} - {/key} - {/key} -
-
- - {#key args} - {#key requestType} - {#key webhookType} - {#key tokenType} - {#key token} -
{ - e.preventDefault() - copyToClipboard(fetchCode()) - }} - > - - -
- {/key}{/key}{/key}{/key} - {/key} -
- {/key} -
-
- -
- - {#if newItem}
@@ -402,4 +32,19 @@ done` {isFlow ? 'flow' : 'script'}. {/if} + +
diff --git a/frontend/src/lib/components/triggers/WebsocketEditorConfigSection.svelte b/frontend/src/lib/components/triggers/WebsocketEditorConfigSection.svelte new file mode 100644 index 0000000000000..49deab7037ca8 --- /dev/null +++ b/frontend/src/lib/components/triggers/WebsocketEditorConfigSection.svelte @@ -0,0 +1,112 @@ + + +
+
+ { + url = ev.detail === 'runnable' ? '$script:' : '' + url_runnable_args = {} + }} + disabled={showCapture} + > + + + +
+ {#if url.startsWith('$')} +
+
+
+
+ Runnable + +
+
+ { + dirtyUrl = true + const { path, itemKind } = ev.detail + url = `$${itemKind}:${path ?? ''}` + }} + /> +
+ {dirtyUrl ? urlError : ''} +
+
+
+ + {#if url.split(':')[1]?.length > 0} + {#if urlRunnableSchema} +

Arguments

+ {#await import('$lib/components/SchemaForm.svelte')} + + {:then Module} + + {/await} + {#if urlRunnableSchema.properties && Object.keys(urlRunnableSchema.properties).length === 0} +
This runnable takes no arguments
+ {/if} + {:else} + + {/if} + {/if} + {:else} +
+ +
+ {/if} +
diff --git a/frontend/src/lib/components/triggers/WebsocketTriggerEditorInner.svelte b/frontend/src/lib/components/triggers/WebsocketTriggerEditorInner.svelte index 51bda8a9edced..5f63050043526 100644 --- a/frontend/src/lib/components/triggers/WebsocketTriggerEditorInner.svelte +++ b/frontend/src/lib/components/triggers/WebsocketTriggerEditorInner.svelte @@ -24,8 +24,7 @@ import { fade } from 'svelte/transition' import JsonEditor from '../apps/editor/settingsPanel/inputEditor/JsonEditor.svelte' import type { Schema } from '$lib/common' - import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte' - import ToggleButton from '../common/toggleButton-v2/ToggleButton.svelte' + import WebsocketEditorConfigSection from './WebsocketEditorConfigSection.svelte' let drawer: Drawer let is_flow: boolean = false @@ -318,92 +317,14 @@
-
-
- { - url = ev.detail === 'runnable' ? '$script:' : '' - url_runnable_args = {} - }} - > - - - -
- {#if url.startsWith('$')} -
-
-
-
- Runnable - -
-
- { - dirtyUrl = true - const { path, itemKind } = ev.detail - url = `$${itemKind}:${path ?? ''}` - }} - /> -
- {dirtyUrl ? urlError : ''} -
-
-
- - {#if url.split(':')[1]?.length > 0} - {#if urlRunnableSchema} -

Arguments

- {#await import('$lib/components/SchemaForm.svelte')} - - {:then Module} - - {/await} - {#if urlRunnableSchema.properties && Object.keys(urlRunnableSchema.properties).length === 0} -
This runnable takes no arguments
- {/if} - {:else} - - {/if} - {/if} - {:else} -
- -
- {/if} -
+

diff --git a/frontend/src/lib/components/triggers/WebsocketTriggersPanel.svelte b/frontend/src/lib/components/triggers/WebsocketTriggersPanel.svelte index 229c08d579029..8dc630ef23322 100644 --- a/frontend/src/lib/components/triggers/WebsocketTriggersPanel.svelte +++ b/frontend/src/lib/components/triggers/WebsocketTriggersPanel.svelte @@ -1,8 +1,6 @@