diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index fa97e1cdf2..5ebb4b6cc2 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -381,11 +381,11 @@ ? 'border-2 border-green-500 bg-surface' : '' )} + data-schema-picker > {#if diffStatus && typeof diffStatus === 'object' && diffStatus.diff !== 'same'}
-
-
- {#if typeof selectedCapture == 'string' && selectedCapture == 'WINDMILL_TOO_BIG'} -
- Payload too big to preview but can still be loaded
- {:else if Object.keys(selectedCapture || {}).length > 0} -
- -
- {:else} -
- Select an Input to preview scripts arguments -
- {/if} -
- - - - - -
-
+
+
{#if isRunning} - +
+ +
{:else} -
+
{#if jobId !== undefined && selectedJobStep !== undefined && selectedJobStepIsTopLevel} {#if selectedJobStepType == 'single'}
{/if} -
- - {#if initialPath != ''} - - {/if} -
{#if lastPreviewFlow && JSON.stringify($flowStore) != lastPreviewFlow} @@ -387,17 +321,68 @@
-
+
- {#key renderCount} - - {/key} + { + selectInput(e.detail.payload, e.detail?.type) + }} + {isValid} + {jsonView} + > +
+ +
+ { + jsonEditor?.setCode(JSON.stringify($previewArgs ?? {}, null, '\t')) + refresh() + }} + /> +
+
+ {#if jsonView} +
+ { + if (e.detail) { + $previewArgs = e.detail + } + }} + updateOnBlur={false} + placeholder={`Write args as JSON.

Example:

{
  "foo": "12"
}`} + /> +
+ {:else} + {#key renderCount} +
+ { + savedArgs = $previewArgs + }} + bind:isValid + /> +
+ {/key} + {/if} +
{#if jobId} diff --git a/frontend/src/lib/components/FlowStatusViewerInner.svelte b/frontend/src/lib/components/FlowStatusViewerInner.svelte index a102700fc2..79fafd02ce 100644 --- a/frontend/src/lib/components/FlowStatusViewerInner.svelte +++ b/frontend/src/lib/components/FlowStatusViewerInner.svelte @@ -821,7 +821,7 @@ As a non logged in user, you can only see jobs ran by anonymous users like you {:else if job} -
+
- + { previewOpen = false }} + bind:preventEscape /> @@ -378,6 +367,7 @@ on:schemaChange={() => { resetArgs() }} + bind:isValid >
@@ -470,9 +460,8 @@ }} > { updatePreviewSchemaAndArgs(e.detail ?? undefined) }} @@ -490,12 +479,17 @@
- { - updatePreviewSchemaAndArgs(e.detail ?? undefined) - }} - flowPath={$pathStore} - /> +
+ { + updatePreviewSchemaAndArgs(e.detail ?? undefined) + }} + isFlow={true} + headless={true} + addButton={false} + /> +
{:else if $flowInputEditorState?.selectedTab === 'savedInputs'} { updatePreviewSchemaAndArgs(e.detail ?? undefined) }} @@ -513,6 +508,7 @@ preventEnter = e.detail }} previewArgs={previewArguments} + {isValid} /> {:else if $flowInputEditorState?.selectedTab === 'json'} @@ -522,26 +518,16 @@ }} title="Json payload" > - { preventEnter = true - updatePayloadFromJson(pendingJson) }} on:blur={async () => { preventEnter = false - setTimeout(() => { - if (payloadData) { - updatePayloadFromJson('') - } - }, 100) }} - on:change={(e) => { - updatePayloadFromJson(e.detail.code) + on:select={(e) => { + updatePreviewSchemaAndArgs(e.detail ?? undefined) }} - bind:code={pendingJson} - lang="json" - class="h-full" - placeholder={'Write a JSON payload. The input schema will be inferred.

Example:

{
  "foo": "12"
}'} /> {:else if $flowInputEditorState?.selectedTab === 'firstStepInputs'} @@ -575,7 +561,7 @@ - + diff --git a/frontend/src/lib/components/meltComponents/Popover.svelte b/frontend/src/lib/components/meltComponents/Popover.svelte index ec8618582a..18122ba505 100644 --- a/frontend/src/lib/components/meltComponents/Popover.svelte +++ b/frontend/src/lib/components/meltComponents/Popover.svelte @@ -7,6 +7,8 @@ export let closeButton: boolean = true export let displayArrow: boolean = false export let placement: any = 'bottom' + export let disablePopup: boolean = false + export let openOnHover: boolean = false const { elements: { trigger, content, arrow, close }, @@ -22,7 +24,14 @@ $: sync.open(open, (v) => (open = v)) - diff --git a/frontend/src/lib/components/meltComponents/SideBarTab.svelte b/frontend/src/lib/components/meltComponents/SideBarTab.svelte index 2a13ca4474..5c35d75a3b 100644 --- a/frontend/src/lib/components/meltComponents/SideBarTab.svelte +++ b/frontend/src/lib/components/meltComponents/SideBarTab.svelte @@ -1,4 +1,6 @@
- + {#if hasCloseButton} + + {:else} +
+ {/if} {#if fullMenu}
item.selected) ? 'rounded-md border' : '' + )} > {#each dropdownItems as item}
+
diff --git a/frontend/src/lib/components/schema/SchemaFormDND.svelte b/frontend/src/lib/components/schema/SchemaFormDND.svelte index c29040f75a..7fc90d6c1b 100644 --- a/frontend/src/lib/components/schema/SchemaFormDND.svelte +++ b/frontend/src/lib/components/schema/SchemaFormDND.svelte @@ -19,6 +19,7 @@ export let shouldDispatchChanges: boolean = false export let diff: Record = {} export let nestedClasses = '' + export let isValid: boolean = true const dispatch = createEventDispatcher() const flipDurationMs = 200 @@ -98,6 +99,7 @@ {diff} {nestedParent} {shouldDispatchChanges} + bind:isValid > {#if !disableDnd} diff --git a/frontend/src/lib/components/schema/SchemaPickerRow.svelte b/frontend/src/lib/components/schema/SchemaPickerRow.svelte index af8839a7fc..43abb449f1 100644 --- a/frontend/src/lib/components/schema/SchemaPickerRow.svelte +++ b/frontend/src/lib/components/schema/SchemaPickerRow.svelte @@ -5,7 +5,7 @@ import { twMerge } from 'tailwind-merge' import Cell from '$lib/components/table/Cell.svelte' - export let payloadData: Record + export let payloadData: Record | string export let date: string | undefined export let selected = false export let hovering = false @@ -58,7 +58,7 @@ {formatDateShort(date)} @@ -82,7 +82,15 @@ {JSON.stringify(payloadData)}
- + {#if payloadData === 'WINDMILL_TOO_BIG'} +
+ Payload too big to preview but can still be loaded +
+ {:else} +
+ +
+ {/if}
diff --git a/frontend/src/lib/components/table/DataTable.svelte b/frontend/src/lib/components/table/DataTable.svelte index 7b906e8db7..cd439e0ff9 100644 --- a/frontend/src/lib/components/table/DataTable.svelte +++ b/frontend/src/lib/components/table/DataTable.svelte @@ -31,7 +31,7 @@ let tableHeight: number = 0 const dispatch = createEventDispatcher() let tableContainer: HTMLDivElement - let isLoading = false + export let loading = false setContext('datatable', { size @@ -40,23 +40,19 @@ $: contentHeight = tableHeight - footerHeight function checkScrollStatus() { - if (!infiniteScroll || isLoading) return + if (!infiniteScroll || loading) return const hasScrollbar = tableContainer.scrollHeight > tableContainer.clientHeight if (!hasScrollbar && hasMore) { - isLoading = true dispatch('loadMore') - setTimeout(() => { - isLoading = false - }, 200) } } function handleScroll() { - if (!infiniteScroll || isLoading) { - if (isLoading) { + if (!infiniteScroll || loading) { + if (loading) { const checkAgain = () => { - if (!isLoading) { + if (!loading) { handleScroll() } } @@ -67,15 +63,11 @@ const { scrollTop, scrollHeight, clientHeight } = tableContainer if (scrollHeight - (scrollTop + clientHeight) < 50) { - isLoading = true dispatch('loadMore') - setTimeout(() => { - isLoading = false - }, 1000) } } - $: if (tableContainer && hasMore && !isLoading) { + $: if (tableContainer && hasMore && !loading) { checkScrollStatus() } diff --git a/frontend/src/lib/components/triggers/CaptureTable.svelte b/frontend/src/lib/components/triggers/CaptureTable.svelte index c5cc8bfe03..70596003fc 100644 --- a/frontend/src/lib/components/triggers/CaptureTable.svelte +++ b/frontend/src/lib/components/triggers/CaptureTable.svelte @@ -7,7 +7,6 @@ import CustomPopover from '../CustomPopover.svelte' import { Webhook, Route, Unplug, Mail, Play } from 'lucide-svelte' import KafkaIcon from '$lib/components/icons/KafkaIcon.svelte' - import { isObject } from '$lib/utils' import { createEventDispatcher, onDestroy } from 'svelte' import { type TriggerKind } from '../triggers' import { CaptureService } from '$lib/gen' @@ -15,9 +14,10 @@ import { type CaptureTriggerKind } from '$lib/gen' import CaptureButton from '$lib/components/triggers/CaptureButton.svelte' import InfiniteList from '../InfiniteList.svelte' - import { sendUserToast } from '$lib/utils' + import { isObject, sendUserToast } from '$lib/utils' import SchemaPickerRow from '$lib/components/schema/SchemaPickerRow.svelte' import { clickOutside } from '$lib/utils' + import type { Capture } from '$lib/gen' export let path: string export let hasPreprocessor = false @@ -57,6 +57,11 @@ testWithArgs: any }>() + interface CaptureWithPayload extends Capture { + getFullCapture?: () => Promise + payloadData?: any + } + export async function loadCaptures(refresh: boolean = false) { await infiniteList?.loadData(refresh ? 'refresh' : 'loadMore') } @@ -71,19 +76,36 @@ page, perPage }) - let capturesWithPayload = captures.map((capture) => { - const payload = isObject(capture.payload) ? capture.payload : {} - const triggerExtra = isObject(capture.trigger_extra) ? capture.trigger_extra : {} - return { - ...capture, - payloadData: - testKind === 'preprocessor' - ? { - ...payload, - ...triggerExtra - } - : { ...payload } + + let capturesWithPayload: CaptureWithPayload[] = captures.map((capture) => { + let newCapture: CaptureWithPayload = { ...capture } + if (capture.payload === 'WINDMILL_TOO_BIG') { + newCapture = { + ...capture, + getFullCapture: () => + CaptureService.getCapture({ + workspace: $workspaceStore!, + id: capture.id + }) + } } + const trigger_extra = isObject(capture.trigger_extra) ? capture.trigger_extra : {} + newCapture.payloadData = + testKind === 'preprocessor' + ? capture.payload === 'WINDMILL_TOO_BIG' + ? { + payload: capture.payload, + ...trigger_extra + } + : typeof capture.payload === 'object' + ? { + ...capture.payload, + ...trigger_extra + } + : trigger_extra + : capture.payload + + return newCapture }) return capturesWithPayload } @@ -98,15 +120,33 @@ infiniteList?.setDeleteItemFn(deleteInputFn) } - function handleSelect(capture: any) { + async function handleSelect(capture: any) { if (selected === capture.id) { deselect() } else { + const payloadData = await getPayload(capture) selected = capture.id - dispatch('select', capture.payloadData) + dispatch('select', structuredClone(payloadData)) } } + async function getPayload(capture: any) { + let payloadData = {} + if (capture.getFullCapture) { + const fullCapture = await capture.getFullCapture() + payloadData = + testKind === 'preprocessor' + ? { + ...(typeof fullCapture.payload === 'object' ? fullCapture.payload : {}), + ...(typeof fullCapture.trigger_extra === 'object' ? fullCapture.trigger_extra : {}) + } + : fullCapture.payload + } else { + payloadData = structuredClone(capture.payloadData) + } + return payloadData + } + function deselect() { selected = undefined dispatch('select', undefined) @@ -209,7 +249,7 @@ - + @@ -265,9 +305,10 @@ dropdownItems={[ { label: 'Use as input schema', - onClick: () => { + onClick: async () => { + const payloadData = await getPayload(item) dispatch('updateSchema', { - payloadData: item.payloadData, + payloadData, redirect: true, args: true }) @@ -275,20 +316,23 @@ disabled: !isFlow || testKind !== 'main' } ].filter((item) => !item.disabled)} - on:click={() => { + on:click={async () => { + const payloadData = await getPayload(item) if (isFlow && testKind === 'main') { - dispatch('testWithArgs', item.payloadData) + dispatch('testWithArgs', payloadData) } else { dispatch('applyArgs', { kind: testKind, - args: item.payloadData + args: payloadData }) } }} disabled={testKind === 'preprocessor' && !hasPreprocessor} title={isFlow && testKind === 'main' ? 'Test flow with args' - : 'Apply args to preprocessor'} + : testKind === 'preprocessor' + ? 'Apply args to preprocessor' + : 'Apply args to inputs'} startIcon={isFlow && testKind === 'main' ? { icon: Play } : {}} > {isFlow && testKind === 'main' ? 'Test' : 'Apply args'} diff --git a/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte index f696088a4d..aa26013684 100644 --- a/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte @@ -22,7 +22,7 @@ import { enterpriseLicense, userStore, workspaceStore } from '$lib/stores' import { sendUserToast } from '$lib/toast' import DeployWorkspaceDrawer from '$lib/components/DeployWorkspaceDrawer.svelte' - import SavedInputs from '$lib/components/SavedInputs.svelte' + import SavedInputsV2 from '$lib/components/SavedInputsV2.svelte' import { FolderOpen, Archive, @@ -60,10 +60,12 @@ import json from 'svelte-highlight/languages/json' import { writable } from 'svelte/store' import TriggersBadge from '$lib/components/graph/renderers/triggers/TriggersBadge.svelte' + import InputSelectedBadge from '$lib/components/schema/InputSelectedBadge.svelte' import WebsocketTriggersPanel from '$lib/components/triggers/websocket/WebsocketTriggersPanel.svelte' import KafkaTriggersPanel from '$lib/components/triggers/kafka/KafkaTriggersPanel.svelte' import NatsTriggersPanel from '$lib/components/triggers/nats/NatsTriggersPanel.svelte' import PostgresTriggersPanel from '$lib/components/triggers/postgres/PostgresTriggersPanel.svelte' + import Toggle from '$lib/components/Toggle.svelte' let flow: Flow | undefined let can_write = false @@ -74,6 +76,8 @@ let scheduledForStr: string | undefined = undefined let invisible_to_owner: boolean | undefined = undefined let overrideTag: string | undefined = undefined + let inputSelected: 'saved' | 'history' | undefined = undefined + let jsonView = false const triggersCount = writable(undefined) @@ -430,7 +434,7 @@
-
+
{#if !emptyString(flow?.description)} {/if} @@ -443,20 +447,41 @@ {/if} - +
+
+ + { + runForm?.setCode(JSON.stringify(args ?? {}, null, '\t')) + }} + /> +
+ + +
+
{#if !emptyString(flow.summary)} @@ -499,13 +524,14 @@
- { const nargs = JSON.parse(JSON.stringify(e.detail)) - runForm?.setArgs(nargs) args = nargs }} /> diff --git a/frontend/src/routes/(root)/(logged)/scripts/get/[...hash]/+page.svelte b/frontend/src/routes/(root)/(logged)/scripts/get/[...hash]/+page.svelte index adb7e73203..69457e8abd 100644 --- a/frontend/src/routes/(root)/(logged)/scripts/get/[...hash]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/scripts/get/[...hash]/+page.svelte @@ -18,12 +18,7 @@ } from '$lib/utils' import Tooltip from '$lib/components/Tooltip.svelte' import ShareModal from '$lib/components/ShareModal.svelte' - import { - enterpriseLicense, - hubBaseUrlStore, - userStore, - workspaceStore - } from '$lib/stores' + import { enterpriseLicense, hubBaseUrlStore, userStore, workspaceStore } from '$lib/stores' import { isDeployable, ALL_DEPLOYABLE } from '$lib/utils_deployable' import { onDestroy } from 'svelte' @@ -46,7 +41,7 @@ import { sendUserToast } from '$lib/toast' import DeployWorkspaceDrawer from '$lib/components/DeployWorkspaceDrawer.svelte' - import SavedInputs from '$lib/components/SavedInputs.svelte' + import SavedInputsV2 from '$lib/components/SavedInputsV2.svelte' import WebhooksPanel from '$lib/components/triggers/webhook/WebhooksPanel.svelte' import DetailPageLayout from '$lib/components/details/DetailPageLayout.svelte' import DetailPageHeader from '$lib/components/details/DetailPageHeader.svelte' @@ -92,6 +87,8 @@ import KafkaTriggersPanel from '$lib/components/triggers/kafka/KafkaTriggersPanel.svelte' import NatsTriggersPanel from '$lib/components/triggers/nats/NatsTriggersPanel.svelte' import PostgresTriggersPanel from '$lib/components/triggers/postgres/PostgresTriggersPanel.svelte' + import Toggle from '$lib/components/Toggle.svelte' + import InputSelectedBadge from '$lib/components/schema/InputSelectedBadge.svelte' let script: Script | undefined let topHash: string | undefined @@ -104,6 +101,8 @@ let scheduledForStr: string | undefined = undefined let invisible_to_owner: boolean | undefined = undefined let overrideTag: string | undefined = undefined + let inputSelected: 'saved' | 'history' | undefined = undefined + let jsonView = false $: cliCommand = `wmill script run ${script?.path} -d '${JSON.stringify(args)}'` @@ -599,7 +598,7 @@
-
+
{#if script.lock_error_logs || topHash || script.archived || script.deleted}
{#if script.lock_error_logs} @@ -651,21 +650,41 @@ {/if} - +
+
+ + { + runForm?.setCode(JSON.stringify(args ?? {}, null, '\t')) + }} + /> +
+ + +
{#if !emptyString(script.summary)} @@ -695,14 +714,15 @@ {#if args} - { const nargs = JSON.parse(JSON.stringify(e.detail)) - runForm?.setArgs(nargs) args = nargs }} /> @@ -737,6 +757,7 @@
+