From c5b96d7118a3de8b7440175b81bca8a1638fa2ac Mon Sep 17 00:00:00 2001 From: Guilhem Date: Tue, 3 Dec 2024 19:33:23 +0000 Subject: [PATCH 01/42] Move Capture WIP --- frontend/src/lib/components/Section.svelte | 73 +-- .../components/triggers/CaptureWrapper.svelte | 554 ++++++++++++++++++ .../triggers/RouteEditorConfigSection.svelte | 166 ++++++ .../triggers/RouteEditorInner.svelte | 123 +--- .../components/triggers/RoutesPanel.svelte | 102 ++-- .../triggers/TriggersEditorSection.svelte | 105 ++++ frontend/tsconfig.json | 2 +- 7 files changed, 930 insertions(+), 195 deletions(-) create mode 100644 frontend/src/lib/components/triggers/CaptureWrapper.svelte create mode 100644 frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte create mode 100644 frontend/src/lib/components/triggers/TriggersEditorSection.svelte diff --git a/frontend/src/lib/components/Section.svelte b/frontend/src/lib/components/Section.svelte index 43868d170e27b..1889fc708a8b1 100644 --- a/frontend/src/lib/components/Section.svelte +++ b/frontend/src/lib/components/Section.svelte @@ -10,48 +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 collapsable && collapsed} - - {/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..8654986c6a969 --- /dev/null +++ b/frontend/src/lib/components/triggers/CaptureWrapper.svelte @@ -0,0 +1,554 @@ + + +
+ {#if (captureType === 'websocket' || captureType === 'kafka') && config && active} + {@const serverEnabled = getServerEnabled(config)} +
+
+
+ {#if serverEnabled} + + + + +
Websocket is connected
+
+ {:else} + + + + + +
+ Websocket is not connected{config.error ? ': ' + config.error : ''} +
+
+ {/if} +
+
+
+ {/if} + {#if cloudDisabled} + + {capitalize(captureType)} triggers are disabled in the multi-tenant cloud. + + {:else} + {#if captureType in schemas && false} + {#key captureType} + + {/key} + {/if} + + {#if captureType === 'webhook'} + + + {:else if captureType === 'http'} + + {:else if captureType === 'email'} + + {/if} + + {#if captureMode} + + {/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..892020566f092 --- /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 captureMode} + + {/if} +
+
diff --git a/frontend/src/lib/components/triggers/RouteEditorInner.svelte b/frontend/src/lib/components/triggers/RouteEditorInner.svelte index c9e38b1147186..be0c76044d74e 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} @@ -253,76 +222,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 : ''}
-
-
-
+
- import { Button } from '../common' import { userStore, workspaceStore } from '$lib/stores' import { HttpTriggerService, type HttpTrigger } from '$lib/gen' - import { RouteIcon } from 'lucide-svelte' - import Skeleton from '../common/skeleton/Skeleton.svelte' import RouteEditor from './RouteEditor.svelte' import { canWrite } from '$lib/utils' import Alert from '../common/alert/Alert.svelte' import type { TriggerContext } from '../triggers' import { getContext, onMount } from 'svelte' + import Section from '$lib/components/Section.svelte' + import TriggersEditorSection from './TriggersEditorSection.svelte' export let isFlow: boolean export let path: string @@ -58,57 +57,56 @@ bind:this={routeEditor} /> -
- {#if !newItem} - {#if $userStore?.is_admin || $userStore?.is_super_admin} - - {:else} - +
+ { + routeEditor?.openNew(isFlow, path, e.detail.config) + }} + cloudDisabled={false} + captureType="webhook" + {isFlow} + /> +
+ {#if !newItem} + {#if !$userStore?.is_admin && !$userStore?.is_super_admin} + + {/if} {/if} - {/if} - - {#if httpTriggers} - {#if httpTriggers.length == 0} -
No http routes
- {:else} -
- {#each httpTriggers as httpTriggers (httpTriggers.path)} -
-
{httpTriggers.path}
-
- {httpTriggers.http_method.toUpperCase()} /{httpTriggers.route_path} + {#if httpTriggers} + {#if httpTriggers.length == 0} +
No http routes
+ {:else} +
+ {#each httpTriggers as httpTriggers (httpTriggers.path)} +
+
{httpTriggers.path}
+
+ {httpTriggers.http_method.toUpperCase()} /{httpTriggers.route_path} +
+
+ +
-
- -
-
- {/each} -
+ {/each} +
+ {/if} + {:else} + {/if} - {:else} - - {/if} - {#if newItem} - - Deploy the {isFlow ? 'flow' : 'script'} to add http routes. - - {/if} + {#if newItem} + + Deploy the {isFlow ? 'flow' : 'script'} to add http routes. + + {/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..50470583ca818 --- /dev/null +++ b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte @@ -0,0 +1,105 @@ + + +
+ +
+ +
+ {#if captureMode} + + {/if} + + {#if newItem || cloudDisabled} + +
+
+
+ + { + console.log('dbg add preprocessor') + $selectedId = 'preprocessor' + }} + on:updateSchema={(e) => { + const { schema, redirect } = e.detail + $flowStore.schema = schema + if (redirect) { + //tabSelected = 'input' + console.log('dbg redirect') + } + }} + bind:args + {captureMode} + bind:handleCapture + bind:active + /> +
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index c6e52bf449525..85bb4245adfb3 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -31,6 +31,6 @@ "strict": true, "types": [] }, - "include": ["src/**/*.js", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.svelte"], + "include": ["src/**/*.js", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.svelte", "src/lib/components/triggers/TriggersEditorSectionsvelte"], "extends": "./.svelte-kit/tsconfig.json" } From 8f3007db2ef2478bf9a58775cbb804b7ebe7b178 Mon Sep 17 00:00:00 2001 From: Guilhem Date: Wed, 4 Dec 2024 11:34:43 +0000 Subject: [PATCH 02/42] Add capture to webhook and websocket --- frontend/src/lib/components/Label.svelte | 4 +- .../components/triggers/CaptureWrapper.svelte | 30 +- .../components/triggers/RoutesPanel.svelte | 2 +- .../triggers/TriggersEditorSection.svelte | 63 ++- .../triggers/WebhooksConfigSection.svelte | 454 ++++++++++++++++++ .../components/triggers/WebhooksPanel.svelte | 386 +-------------- .../WebsocketEditorConfigSection.svelte | 112 +++++ .../WebsocketTriggerEditorInner.svelte | 97 +--- .../triggers/WebsocketTriggersPanel.svelte | 93 ++-- 9 files changed, 690 insertions(+), 551 deletions(-) create mode 100644 frontend/src/lib/components/triggers/WebhooksConfigSection.svelte create mode 100644 frontend/src/lib/components/triggers/WebsocketEditorConfigSection.svelte diff --git a/frontend/src/lib/components/Label.svelte b/frontend/src/lib/components/Label.svelte index 3d53070c6c8c1..f53a8d9ca24dd 100644 --- a/frontend/src/lib/components/Label.svelte +++ b/frontend/src/lib/components/Label.svelte @@ -1,9 +1,11 @@ -
+
{label} diff --git a/frontend/src/lib/components/triggers/CaptureWrapper.svelte b/frontend/src/lib/components/triggers/CaptureWrapper.svelte index 8654986c6a969..df7877629b477 100644 --- a/frontend/src/lib/components/triggers/CaptureWrapper.svelte +++ b/frontend/src/lib/components/triggers/CaptureWrapper.svelte @@ -28,6 +28,8 @@ import { convert } from '@redocly/json-to-json-schema' import SchemaViewer from '../SchemaViewer.svelte' import RouteEditorConfigSection from './RouteEditorConfigSection.svelte' + import WebsocketEditorConfigSection from './WebsocketEditorConfigSection.svelte' + import WebhooksConfigSection from './WebhooksConfigSection.svelte' export let isFlow: boolean export let path: string @@ -36,8 +38,8 @@ export let captureType: CaptureTriggerKind = 'webhook' export let captureMode = false export let active = false + export let data: any = {} - $: console.log('dbg isFlow', isFlow) const dispatch = createEventDispatcher<{ openTriggers: { kind: TriggerKind @@ -333,7 +335,6 @@ } export async function handleCapture() { - console.log('dbg handleCapture') if (!active) { await setConfig() capture() @@ -392,19 +393,18 @@ {/key} {/if} - {#if captureType === 'webhook'} - - + {#if captureType === 'websocket'} + + {:else if captureType === 'webhook'} + {:else if captureType === 'http'} {:else if captureType === 'email'} diff --git a/frontend/src/lib/components/triggers/RoutesPanel.svelte b/frontend/src/lib/components/triggers/RoutesPanel.svelte index e073b00910646..e0fe43502b884 100644 --- a/frontend/src/lib/components/triggers/RoutesPanel.svelte +++ b/frontend/src/lib/components/triggers/RoutesPanel.svelte @@ -63,7 +63,7 @@ routeEditor?.openNew(isFlow, path, e.detail.config) }} cloudDisabled={false} - captureType="webhook" + captureType="http" {isFlow} />
diff --git a/frontend/src/lib/components/triggers/TriggersEditorSection.svelte b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte index 50470583ca818..12609e6666e25 100644 --- a/frontend/src/lib/components/triggers/TriggersEditorSection.svelte +++ b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte @@ -13,6 +13,16 @@ export let cloudDisabled: boolean export let captureType: CaptureTriggerKind export let isFlow: boolean = false + export let data: any = {} + export let noSave = false + + const captureTypeLabels: Record = { + http: 'Route', + websocket: 'Websocket', + webhook: 'Webhook', + kafka: 'Kafka', + email: 'Email' + } let args: Record = {} let captureMode = false @@ -28,7 +38,7 @@ let handleCapture: (() => Promise) | undefined -
+
@@ -45,34 +55,36 @@ {/if} - {#if newItem || cloudDisabled} - + {#if !noSave} + {#if newItem || cloudDisabled} + +
@@ -81,7 +93,7 @@
diff --git a/frontend/src/lib/components/triggers/WebhooksConfigSection.svelte b/frontend/src/lib/components/triggers/WebhooksConfigSection.svelte new file mode 100644 index 0000000000000..bdf295ed33370 --- /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 captureMode} +
{ + 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 !captureMode} + + {/if} +
diff --git a/frontend/src/lib/components/triggers/WebhooksPanel.svelte b/frontend/src/lib/components/triggers/WebhooksPanel.svelte index eefd785b47e70..78d948791854c 100644 --- a/frontend/src/lib/components/triggers/WebhooksPanel.svelte +++ b/frontend/src/lib/components/triggers/WebhooksPanel.svelte @@ -1,27 +1,7 @@ - { - 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}
@@ -398,4 +30,6 @@ 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..44ce13ee62ac6 --- /dev/null +++ b/frontend/src/lib/components/triggers/WebsocketEditorConfigSection.svelte @@ -0,0 +1,112 @@ + + +
+
+ { + url = ev.detail === 'runnable' ? '$script:' : '' + url_runnable_args = {} + }} + disabled={captureMode} + > + + + +
+ {#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 6afaac01ad6e0..6f777f983ca9f 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 @@ -316,92 +315,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 66fe3252958e2..6ca12cc56963c 100644 --- a/frontend/src/lib/components/triggers/WebsocketTriggersPanel.svelte +++ b/frontend/src/lib/components/triggers/WebsocketTriggersPanel.svelte @@ -1,8 +1,6 @@ + +{#if connectionInfo} +

+ {#if connectionInfo.status === 'connected'} + + + + + +
{connectionInfo.message ?? ''}
+
+ {:else} + + + + + + +
{connectionInfo.message ?? ''}
+
+ {/if} +
+{/if} diff --git a/frontend/src/lib/components/triggers/CaptureWrapper.svelte b/frontend/src/lib/components/triggers/CaptureWrapper.svelte index df7877629b477..eecdb6077d2da 100644 --- a/frontend/src/lib/components/triggers/CaptureWrapper.svelte +++ b/frontend/src/lib/components/triggers/CaptureWrapper.svelte @@ -1,5 +1,5 @@
- {#if (captureType === 'websocket' || captureType === 'kafka') && config && active} - {@const serverEnabled = getServerEnabled(config)} -
-
-
- {#if serverEnabled} - - - - -
Websocket is connected
-
- {:else} - - - - - -
- Websocket is not connected{config.error ? ': ' + config.error : ''} -
-
- {/if} -
-
-
- {/if} {#if cloudDisabled} {capitalize(captureType)} triggers are disabled in the multi-tenant cloud. diff --git a/frontend/src/lib/components/triggers/TriggersEditorSection.svelte b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte index 12609e6666e25..c3af09b8ccd45 100644 --- a/frontend/src/lib/components/triggers/TriggersEditorSection.svelte +++ b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte @@ -9,7 +9,7 @@ import { type CaptureTriggerKind } from '$lib/gen' import type { FlowEditorContext } from '../flows/types' import Toggle from '../Toggle.svelte' - + import ConnectionIndicator from '$lib/components/common/alert/ConnectionIndicator.svelte' export let cloudDisabled: boolean export let captureType: CaptureTriggerKind export let isFlow: boolean = false @@ -27,6 +27,12 @@ let args: Record = {} let captureMode = false let active = false + let connectionInfo: + | { + status: 'connected' | 'disconnected' | 'error' + message?: string + } + | undefined = undefined const dispatch = createEventDispatcher() @@ -43,6 +49,8 @@
+ + {#if captureMode}
From 8019c3a1d0eba8b8f0b04e72e5f3b3799892cca7 Mon Sep 17 00:00:00 2001 From: Guilhem Date: Wed, 4 Dec 2024 14:20:58 +0000 Subject: [PATCH 04/42] change trigger section label --- .../src/lib/components/triggers/TriggersEditorSection.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/lib/components/triggers/TriggersEditorSection.svelte b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte index c3af09b8ccd45..c45a6eacd13c8 100644 --- a/frontend/src/lib/components/triggers/TriggersEditorSection.svelte +++ b/frontend/src/lib/components/triggers/TriggersEditorSection.svelte @@ -44,7 +44,7 @@ let handleCapture: (() => Promise) | undefined -
+
From 124eabb9d4887578b3f68c579b5242de5e9d0c2a Mon Sep 17 00:00:00 2001 From: Guilhem Date: Wed, 4 Dec 2024 17:05:17 +0000 Subject: [PATCH 05/42] Add popover capture picker using melt ui --- frontend/package-lock.json | 98 +++++++- frontend/package.json | 4 +- frontend/src/lib/components/Label.svelte | 11 +- .../components/flows/content/FlowInput.svelte | 10 + .../flows/pickers/InputSchemaPicker.svelte | 68 ++++++ .../components/meltComponents/Popover.svelte | 47 ++++ .../components/triggers/CaptureTable.svelte | 209 +++++++++++++++++ .../components/triggers/CaptureWrapper.svelte | 210 ++---------------- frontend/svelte.config.js | 9 +- 9 files changed, 461 insertions(+), 205 deletions(-) create mode 100644 frontend/src/lib/components/flows/pickers/InputSchemaPicker.svelte create mode 100644 frontend/src/lib/components/meltComponents/Popover.svelte create mode 100644 frontend/src/lib/components/triggers/CaptureTable.svelte diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 539b62be83478..d793dadf12bce 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -85,6 +85,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.0", @@ -3554,6 +3556,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", @@ -3666,6 +3678,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", @@ -4315,6 +4379,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", @@ -7292,6 +7366,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", @@ -12829,6 +12913,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", @@ -13112,9 +13203,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 a6ecec3d4370c..468323f463b80 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.0", @@ -128,8 +130,8 @@ "ol": "^7.4.0", "openai": "^4.57.2", "p-limit": "^6.1.0", - "pdfjs-dist": "4.8.69", "panzoom": "^9.4.3", + "pdfjs-dist": "4.8.69", "quill": "^1.3.7", "rfc4648": "^1.5.3", "svelte-carousel": "^1.0.25", diff --git a/frontend/src/lib/components/Label.svelte b/frontend/src/lib/components/Label.svelte index f53a8d9ca24dd..24acffca29303 100644 --- a/frontend/src/lib/components/Label.svelte +++ b/frontend/src/lib/components/Label.svelte @@ -3,14 +3,17 @@ export let label: string | undefined = undefined export let primary = false export let disabled = false + export let headless = false
-
- {label} - -
+ {#if !headless} +
+ {label} + +
+ {/if}
diff --git a/frontend/src/lib/components/flows/content/FlowInput.svelte b/frontend/src/lib/components/flows/content/FlowInput.svelte index 0834e03ab2127..df13a63ed0239 100644 --- a/frontend/src/lib/components/flows/content/FlowInput.svelte +++ b/frontend/src/lib/components/flows/content/FlowInput.svelte @@ -16,6 +16,8 @@ import Tab from '$lib/components/common/tabs/Tab.svelte' import CapturePanel from '$lib/components/triggers/CapturePanel.svelte' import { insertNewPreprocessorModule } from '../flowStateUtils' + import Popover from '$lib/components/meltComponents/Popover.svelte' + import InputSchemaPicker from '$lib/components/flows/pickers/InputSchemaPicker.svelte' export let noEditor: boolean export let disabled: boolean @@ -55,6 +57,14 @@ {#if tabSelected === 'input'}
Copy input's schema from
+ + + + + + + + + + + + +
+
+
+ +
+
diff --git a/frontend/src/lib/components/meltComponents/Popover.svelte b/frontend/src/lib/components/meltComponents/Popover.svelte new file mode 100644 index 0000000000000..4129971cc8a33 --- /dev/null +++ b/frontend/src/lib/components/meltComponents/Popover.svelte @@ -0,0 +1,47 @@ + + + + +{#if open} +
+
+ + {#if closeButton} + + {/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..4540c017536b0 --- /dev/null +++ b/frontend/src/lib/components/triggers/CaptureTable.svelte @@ -0,0 +1,209 @@ + + + diff --git a/frontend/src/lib/components/triggers/CaptureWrapper.svelte b/frontend/src/lib/components/triggers/CaptureWrapper.svelte index eecdb6077d2da..cd7831b81de43 100644 --- a/frontend/src/lib/components/triggers/CaptureWrapper.svelte +++ b/frontend/src/lib/components/triggers/CaptureWrapper.svelte @@ -1,32 +1,23 @@ diff --git a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte index cd5e9bc4b8824..adb699054a495 100644 --- a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte +++ b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte @@ -22,7 +22,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) { @@ -66,9 +66,11 @@ {noEditor} disabled={disabledFlowInputs} on:openTriggers={(ev) => { + console.log('dbg openTriggers', ev.detail) $selectedId = 'triggers' selectedTrigger.set(ev.detail.kind) defaultValues.set(ev.detail.config) + captureOn.set(true) }} on:applyArgs /> diff --git a/frontend/src/lib/components/flows/content/FlowInput.svelte b/frontend/src/lib/components/flows/content/FlowInput.svelte index df13a63ed0239..97f0009ae59f2 100644 --- a/frontend/src/lib/components/flows/content/FlowInput.svelte +++ b/frontend/src/lib/components/flows/content/FlowInput.svelte @@ -62,7 +62,7 @@ - +
- +
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/CaptureTable.svelte b/frontend/src/lib/components/triggers/CaptureTable.svelte index 4540c017536b0..de0458ceb9acc 100644 --- a/frontend/src/lib/components/triggers/CaptureTable.svelte +++ b/frontend/src/lib/components/triggers/CaptureTable.svelte @@ -1,6 +1,6 @@ + /> + + {/each} + {/if} + + +{/if} diff --git a/frontend/src/lib/components/triggers/CaptureWrapper.svelte b/frontend/src/lib/components/triggers/CaptureWrapper.svelte index cd7831b81de43..69e310892ec70 100644 --- a/frontend/src/lib/components/triggers/CaptureWrapper.svelte +++ b/frontend/src/lib/components/triggers/CaptureWrapper.svelte @@ -23,8 +23,7 @@ export let hasPreprocessor: boolean export let canHavePreprocessor: boolean export let captureType: CaptureTriggerKind = 'webhook' - export let captureMode = false - export let active = false + export let captureActive = false export let data: any = {} export let connectionInfo: | { @@ -217,13 +216,14 @@ return acc }, {}) - if ((captureType === 'websocket' || captureType === 'kafka') && active) { + if ((captureType === 'websocket' || captureType === 'kafka') && captureActive) { const config = captureConfigs[captureType] + console.log('dbg config', config) if (config && config.error) { const serverEnabled = getServerEnabled(config) if (!serverEnabled) { sendUserToast('Capture was stopped because of error: ' + config.error, true) - active = false + captureActive = false } } } @@ -233,10 +233,9 @@ let refreshCaptures: () => Promise async function capture() { - console.log('dbg capture') let i = 0 - active = true - while (active) { + captureActive = true + while (captureActive) { if (i % 3 === 0) { await CaptureService.pingCaptureConfig({ workspace: $workspaceStore!, @@ -253,7 +252,7 @@ } function stopAndSetDefaultArgs() { - active = false + captureActive = false if (captureType in captureConfigs) { const triggerConfig = captureConfigs[captureType].trigger_config args = isObject(triggerConfig) ? triggerConfig : {} @@ -270,7 +269,7 @@ $: captureType && stopAndSetDefaultArgs() onDestroy(() => { - active = false + captureActive = false }) function getServerEnabled(config: CaptureConfig) { @@ -281,11 +280,11 @@ } export async function handleCapture() { - if (!active) { + if (!captureActive) { await setConfig() capture() } else { - active = false + captureActive = false } } @@ -297,9 +296,9 @@ function updateConnectionInfo( captureType: CaptureTriggerKind, config: CaptureConfig | undefined, - active: boolean + captureActive: boolean ) { - if ((captureType === 'websocket' || captureType === 'kafka') && config && active) { + if ((captureType === 'websocket' || captureType === 'kafka') && config && captureActive) { const serverEnabled = getServerEnabled(config) const message = serverEnabled ? 'Websocket is connected' @@ -312,7 +311,7 @@ connectionInfo = undefined } } - $: updateConnectionInfo(captureType, config, active) + $: updateConnectionInfo(captureType, config, captureActive)
@@ -328,7 +327,13 @@ {/if} {#if captureType === 'websocket'} - + {:else if captureType === 'webhook'} {:else if captureType === 'http'} - + {:else if captureType === 'email'} {/if} - {#if captureMode} - - {/if} + {/if}
diff --git a/frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte b/frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte index 892020566f092..31f2cc97e0e5b 100644 --- a/frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte +++ b/frontend/src/lib/components/triggers/RouteEditorConfigSection.svelte @@ -20,7 +20,7 @@ export let can_write: boolean = false export let static_asset_config: { s3: string; storage?: string; filename?: string } | undefined = undefined - export let captureMode = false + export let showCapture = false export let initialRoutePath: string = '' export let isFlow = true export let path: string = '' @@ -69,9 +69,9 @@ $: validateRoute(route_path, http_method) - $: fullRoute = getHttpRoute(route_path, captureMode) + $: fullRoute = getHttpRoute(route_path, showCapture) - $: captureMode && (http_method = 'post') + $: showCapture && (http_method = 'post') export let route_path = '' @@ -119,7 +119,7 @@ disabled={!($userStore?.is_admin || $userStore?.is_super_admin) || !can_write || !!static_asset_config || - captureMode} + showCapture} > @@ -151,7 +151,7 @@ >{dirtyRoutePath ? routeError : ''} - {#if captureMode} + {#if showCapture}