windmill-components 1.503.3 → 1.503.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/package/components/AppWrapper.svelte +3 -0
  2. package/package/components/Dev.svelte +94 -4
  3. package/package/components/FlowBuilder.svelte +89 -7
  4. package/package/components/FlowPreviewContent.svelte +309 -278
  5. package/package/components/FlowPreviewContent.svelte.d.ts +33 -19
  6. package/package/components/FlowPreviewResult.svelte +74 -0
  7. package/package/components/FlowPreviewResult.svelte.d.ts +21 -0
  8. package/package/components/FlowStatusViewer.svelte +3 -1
  9. package/package/components/FlowStatusViewer.svelte.d.ts +2 -0
  10. package/package/components/FlowStatusViewerInner.svelte +15 -70
  11. package/package/components/FlowStatusWaitingForEvents.svelte +5 -2
  12. package/package/components/FlowStatusWaitingForEvents.svelte.d.ts +1 -0
  13. package/package/components/FlowWrapper.svelte +3 -0
  14. package/package/components/ModuleTest.svelte +26 -24
  15. package/package/components/ScriptWrapper.svelte +3 -0
  16. package/package/components/common/button/Button.svelte +2 -1
  17. package/package/components/common/button/Button.svelte.d.ts +2 -1
  18. package/package/components/flows/FlowEditor.svelte +23 -2
  19. package/package/components/flows/FlowEditor.svelte.d.ts +23 -3
  20. package/package/components/flows/content/FlowEditorPanel.svelte +4 -3
  21. package/package/components/flows/content/FlowEditorPanel.svelte.d.ts +12 -2
  22. package/package/components/flows/content/FlowInput.svelte +2 -2
  23. package/package/components/flows/content/FlowInput.svelte.d.ts +1 -1
  24. package/package/components/flows/content/FlowResult.svelte +35 -0
  25. package/package/components/flows/content/FlowResult.svelte.d.ts +17 -0
  26. package/package/components/flows/header/FlowPreviewButtons.svelte +81 -46
  27. package/package/components/flows/map/FlowGraphPreviewButton.svelte +94 -0
  28. package/package/components/flows/map/FlowGraphPreviewButton.svelte.d.ts +17 -0
  29. package/package/components/flows/map/FlowModuleSchemaItem.svelte +296 -285
  30. package/package/components/flows/map/FlowModuleSchemaItem.svelte.d.ts +6 -0
  31. package/package/components/flows/map/FlowModuleSchemaMap.svelte +20 -1
  32. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +20 -1
  33. package/package/components/flows/map/MapItem.svelte +25 -3
  34. package/package/components/flows/map/MapItem.svelte.d.ts +6 -1
  35. package/package/components/flows/map/VirtualItem.svelte +55 -3
  36. package/package/components/flows/map/VirtualItem.svelte.d.ts +13 -1
  37. package/package/components/flows/map/VirtualItemWrapper.svelte +33 -29
  38. package/package/components/flows/map/VirtualItemWrapper.svelte.d.ts +1 -0
  39. package/package/components/flows/propPicker/OutputPicker.svelte +17 -2
  40. package/package/components/flows/propPicker/OutputPicker.svelte.d.ts +4 -0
  41. package/package/components/flows/propPicker/OutputPickerInner.svelte +2 -2
  42. package/package/components/flows/propPicker/OutputPickerInner.svelte.d.ts +1 -0
  43. package/package/components/flows/types.d.ts +3 -0
  44. package/package/components/flows/utils.d.ts +9 -0
  45. package/package/components/flows/utils.js +39 -0
  46. package/package/components/graph/FlowGraphV2.svelte +27 -4
  47. package/package/components/graph/FlowGraphV2.svelte.d.ts +18 -2
  48. package/package/components/graph/ViewportResizer.svelte +33 -1
  49. package/package/components/graph/ViewportResizer.svelte.d.ts +5 -1
  50. package/package/components/graph/graphBuilder.svelte.d.ts +26 -1
  51. package/package/components/graph/graphBuilder.svelte.js +13 -3
  52. package/package/components/graph/renderers/edges/BaseEdge.svelte +69 -2
  53. package/package/components/graph/renderers/edges/BaseEdge.svelte.d.ts +10 -0
  54. package/package/components/graph/renderers/nodes/InputNode.svelte +19 -1
  55. package/package/components/graph/renderers/nodes/ModuleNode.svelte +17 -2
  56. package/package/components/graph/renderers/nodes/ResultNode.svelte +9 -8
  57. package/package/components/modulesTest.svelte.d.ts +12 -0
  58. package/package/components/modulesTest.svelte.js +8 -0
  59. package/package/components/preview/FlowPreviewStatus.svelte +9 -4
  60. package/package/components/preview/FlowPreviewStatus.svelte.d.ts +6 -18
  61. package/package/components/schema/EditableSchemaSdkWrapper.svelte +3 -0
  62. package/package/utils.js +2 -0
  63. package/package.json +1 -1
  64. package/package/components/flows/header/FlowPreviewButtons.svelte.d.ts +0 -26
@@ -1,6 +1,26 @@
1
1
  import { type Job, type RestartedFrom } from '../gen';
2
2
  import { type Writable } from 'svelte/store';
3
3
  import type { DurationStatus, GraphModuleState } from './graph';
4
+ interface Props {
5
+ previewMode: 'upTo' | 'whole';
6
+ open: boolean;
7
+ preventEscape?: boolean;
8
+ jobId?: string | undefined;
9
+ job?: Job | undefined;
10
+ initial?: boolean;
11
+ selectedJobStep?: string | undefined;
12
+ selectedJobStepIsTopLevel?: boolean | undefined;
13
+ selectedJobStepType?: 'single' | 'forloop' | 'branchall';
14
+ rightColumnSelect?: 'timeline' | 'node_status' | 'node_definition' | 'user_states';
15
+ branchOrIterationN?: number;
16
+ scrollTop?: number;
17
+ localModuleStates?: Writable<Record<string, GraphModuleState>>;
18
+ localDurationStatuses?: Writable<Record<string, DurationStatus>>;
19
+ onRunPreview?: () => void;
20
+ render?: boolean;
21
+ onJobDone?: () => void;
22
+ upToId?: string | undefined;
23
+ }
4
24
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
5
25
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
6
26
  $$bindings?: Bindings;
@@ -14,24 +34,7 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
14
34
  };
15
35
  z_$$bindings?: Bindings;
16
36
  }
17
- declare const FlowPreviewContent: $$__sveltets_2_IsomorphicComponent<{
18
- previewMode: "upTo" | "whole";
19
- open: boolean;
20
- preventEscape?: boolean;
21
- jobId?: string | undefined;
22
- job?: Job | undefined;
23
- selectedJobStep?: string | undefined;
24
- selectedJobStepIsTopLevel?: boolean | undefined;
25
- selectedJobStepType?: "single" | "forloop" | "branchall";
26
- rightColumnSelect?: "timeline" | "node_status" | "node_definition" | "user_states";
27
- branchOrIterationN?: number;
28
- scrollTop?: number;
29
- localModuleStates?: Writable<Record<string, GraphModuleState>>;
30
- localDurationStatuses?: Writable<Record<string, DurationStatus>>;
31
- test?: () => void;
32
- runPreview?: (args: Record<string, any>, restartedFrom: RestartedFrom | undefined) => Promise<void>;
33
- refresh?: () => void;
34
- }, {
37
+ declare const FlowPreviewContent: $$__sveltets_2_IsomorphicComponent<Props, {
35
38
  openTriggers: CustomEvent<any>;
36
39
  close: CustomEvent<any>;
37
40
  } & {
@@ -40,6 +43,17 @@ declare const FlowPreviewContent: $$__sveltets_2_IsomorphicComponent<{
40
43
  test: () => void;
41
44
  runPreview: (args: Record<string, any>, restartedFrom: RestartedFrom | undefined) => Promise<void>;
42
45
  refresh: () => void;
43
- }, string>;
46
+ cancelTest: () => Promise<void>;
47
+ getLocalModuleStates: () => Writable<Record<string, GraphModuleState>>;
48
+ getLocalDurationStatuses: () => Writable<Record<string, DurationStatus>>;
49
+ getSuspendStatus: () => Writable<Record<string, {
50
+ job: Job;
51
+ nb: number;
52
+ }>>;
53
+ getIsRunning: () => boolean;
54
+ getIsOwner: () => boolean;
55
+ getJob: () => Job | undefined;
56
+ flowHasChanged: () => boolean;
57
+ }, "initial" | "preventEscape" | "job" | "jobId" | "scrollTop" | "localDurationStatuses" | "localModuleStates" | "rightColumnSelect" | "previewMode" | "selectedJobStep" | "selectedJobStepIsTopLevel" | "selectedJobStepType" | "branchOrIterationN">;
44
58
  type FlowPreviewContent = InstanceType<typeof FlowPreviewContent>;
45
59
  export default FlowPreviewContent;
@@ -0,0 +1,74 @@
1
+ <script lang="ts">import { Badge, Loader2 } from 'lucide-svelte';
2
+ import FlowJobResult from './FlowJobResult.svelte';
3
+ import FlowPreviewStatus from './preview/FlowPreviewStatus.svelte';
4
+ import FlowStatusWaitingForEvents from './FlowStatusWaitingForEvents.svelte';
5
+ import { emptyString } from '../utils';
6
+ let { job, workspaceId, isOwner, hideFlowResult, hideDownloadLogs, localDurationStatuses, innerModules, suspendStatus, hideJobId, extra } = $props();
7
+ </script>
8
+
9
+ <FlowPreviewStatus {job} {hideJobId} {extra} />
10
+
11
+ {#if !job}
12
+ <div>
13
+ <Loader2 class="animate-spin" />
14
+ </div>
15
+ {:else if `result` in job}
16
+ {#if !hideFlowResult}
17
+ <div class="w-full h-full">
18
+ <FlowJobResult
19
+ workspaceId={job?.workspace_id}
20
+ jobId={job?.id}
21
+ tag={job?.tag}
22
+ loading={job['running'] == true}
23
+ result={job.result}
24
+ logs={job.logs}
25
+ durationStates={localDurationStatuses}
26
+ downloadLogs={!hideDownloadLogs}
27
+ />
28
+ </div>
29
+ {/if}
30
+ {:else if job.flow_status?.modules?.[job?.flow_status?.step]?.type === 'WaitingForEvents'}
31
+ <FlowStatusWaitingForEvents {workspaceId} {job} {isOwner} />
32
+ {:else if $suspendStatus && Object.keys($suspendStatus).length > 0}
33
+ <div class="flex gap-2 flex-col">
34
+ {#each Object.values($suspendStatus) as suspendCount (suspendCount.job.id)}
35
+ <div>
36
+ <div class="text-sm">
37
+ Flow suspended, waiting for {suspendCount.nb} events
38
+ </div>
39
+ <FlowStatusWaitingForEvents job={suspendCount.job} {workspaceId} {isOwner} />
40
+ </div>
41
+ {/each}
42
+ </div>
43
+ {:else if job.logs}
44
+ <div
45
+ class="text-xs p-4 bg-surface-secondary overflow-auto max-h-80 border border-tertiary-inverse"
46
+ >
47
+ <pre class="w-full">{job.logs}</pre>
48
+ </div>
49
+ {:else if innerModules?.length > 0}
50
+ <div class="flex flex-col gap-1">
51
+ {#each innerModules as mod, i (mod.id)}
52
+ {#if mod.type == 'InProgress'}
53
+ {@const rawMod = job.raw_flow?.modules[i]}
54
+
55
+ <div
56
+ ><span class="inline-flex gap-1"
57
+ ><Badge color="indigo">{mod.id}</Badge>
58
+ <span class="font-medium text-primary">
59
+ {#if !emptyString(rawMod?.summary)}
60
+ {rawMod?.summary ?? ''}
61
+ {:else if rawMod?.value.type == 'script'}
62
+ {rawMod.value.path ?? ''}
63
+ {:else if rawMod?.value.type}
64
+ {rawMod?.value.type}
65
+ {/if}
66
+ </span>
67
+
68
+ <Loader2 class="animate-spin" /></span
69
+ ></div
70
+ >
71
+ {/if}
72
+ {/each}
73
+ </div>
74
+ {/if}
@@ -0,0 +1,21 @@
1
+ import type { FlowStatusModule, Job } from '../gen';
2
+ import type { DurationStatus } from './graph';
3
+ import type { Writable } from 'svelte/store';
4
+ interface Props {
5
+ job: Job;
6
+ workspaceId: string | undefined;
7
+ isOwner: boolean;
8
+ hideFlowResult: boolean;
9
+ hideDownloadLogs: boolean;
10
+ localDurationStatuses: Writable<Record<string, DurationStatus>>;
11
+ innerModules: FlowStatusModule[];
12
+ suspendStatus: Writable<Record<string, {
13
+ job: Job;
14
+ nb: number;
15
+ }>>;
16
+ hideJobId?: boolean;
17
+ extra?: import('svelte').Snippet;
18
+ }
19
+ declare const FlowPreviewResult: import("svelte").Component<Props, {}, "">;
20
+ type FlowPreviewResult = ReturnType<typeof FlowPreviewResult>;
21
+ export default FlowPreviewResult;
@@ -20,9 +20,10 @@ export let wideResults = false;
20
20
  export let localModuleStates = writable({});
21
21
  export let localDurationStatuses = writable({});
22
22
  export let job = undefined;
23
+ export let render = true;
24
+ export let suspendStatus = writable({});
23
25
  let lastJobId = jobId;
24
26
  let retryStatus = writable({});
25
- let suspendStatus = writable({});
26
27
  setContext('FlowStatusViewer', {
27
28
  flowStateStore,
28
29
  suspendStatus,
@@ -72,4 +73,5 @@ $: jobId && updateJobId();
72
73
  {isOwner}
73
74
  {wideResults}
74
75
  bind:rightColumnSelect
76
+ {render}
75
77
  />
@@ -33,6 +33,8 @@ declare const FlowStatusViewer: $$__sveltets_2_IsomorphicComponent<{
33
33
  localModuleStates?: Writable<Record<string, GraphModuleState>>;
34
34
  localDurationStatuses?: Writable<Record<string, DurationStatus>>;
35
35
  job?: Job | undefined;
36
+ render?: boolean;
37
+ suspendStatus?: Writable<{}>;
36
38
  }, {
37
39
  start: CustomEvent<any>;
38
40
  done: CustomEvent<any>;
@@ -2,7 +2,6 @@
2
2
  import { workspaceStore } from '../stores';
3
3
  import { base } from '../base';
4
4
  import FlowJobResult from './FlowJobResult.svelte';
5
- import FlowPreviewStatus from './preview/FlowPreviewStatus.svelte';
6
5
  import DisplayResult from './DisplayResult.svelte';
7
6
  import { createEventDispatcher, getContext, tick } from 'svelte';
8
7
  import { onDestroy } from 'svelte';
@@ -10,10 +9,9 @@ import { Badge, Button, Skeleton, Tab } from './common';
10
9
  import Tabs from './common/tabs/Tabs.svelte';
11
10
  import {} from './graph';
12
11
  import ModuleStatus from './ModuleStatus.svelte';
13
- import { emptyString, isScriptPreview, msToSec, truncateRev } from '../utils';
12
+ import { isScriptPreview, msToSec, truncateRev } from '../utils';
14
13
  import JobArgs from './JobArgs.svelte';
15
- import { ChevronDown, Hourglass, Loader2 } from 'lucide-svelte';
16
- import FlowStatusWaitingForEvents from './FlowStatusWaitingForEvents.svelte';
14
+ import { ChevronDown, Hourglass } from 'lucide-svelte';
17
15
  import { deepEqual } from 'fast-equals';
18
16
  import FlowTimeline from './FlowTimeline.svelte';
19
17
  import { dfs } from './flows/dfs';
@@ -22,8 +20,9 @@ import Alert from './common/alert/Alert.svelte';
22
20
  import FlowGraphViewerStep from './FlowGraphViewerStep.svelte';
23
21
  import FlowGraphV2 from './graph/FlowGraphV2.svelte';
24
22
  import { buildPrefix } from './graph/graphBuilder.svelte';
23
+ import FlowPreviewResult from './FlowPreviewResult.svelte';
25
24
  const dispatch = createEventDispatcher();
26
- let { flowStateStore, retryStatus, suspendStatus, hideDownloadInGraph, hideTimeline, hideNodeDefinition, hideDownloadLogs } = getContext('FlowStatusViewer');
25
+ let { flowStateStore, retryStatus, suspendStatus, hideDownloadInGraph, hideTimeline, hideNodeDefinition, hideDownloadLogs, hideJobId } = getContext('FlowStatusViewer');
27
26
  export let jobId;
28
27
  export let initialJob = undefined;
29
28
  export let workspaceId = undefined;
@@ -739,71 +738,17 @@ let subflowsSize = 500;
739
738
  {/if}
740
739
  {:else if render}
741
740
  <div class={'border rounded-md shadow p-2'}>
742
- <FlowPreviewStatus {job} />
743
- {#if !job}
744
- <div>
745
- <Loader2 class="animate-spin" />
746
- </div>
747
- {:else if `result` in job}
748
- {#if !hideFlowResult}
749
- <div class="w-full h-full">
750
- <FlowJobResult
751
- workspaceId={job?.workspace_id}
752
- jobId={job?.id}
753
- tag={job?.tag}
754
- loading={job['running'] == true}
755
- result={job.result}
756
- logs={job.logs}
757
- durationStates={localDurationStatuses}
758
- downloadLogs={!hideDownloadLogs}
759
- />
760
- </div>
761
- {/if}
762
- {:else if job.flow_status?.modules?.[job?.flow_status?.step]?.type === 'WaitingForEvents'}
763
- <FlowStatusWaitingForEvents {workspaceId} {job} {isOwner} />
764
- {:else if $suspendStatus && Object.keys($suspendStatus).length > 0}
765
- <div class="flex gap-2 flex-col">
766
- {#each Object.values($suspendStatus) as suspendCount (suspendCount.job.id)}
767
- <div>
768
- <div class="text-sm">
769
- Flow suspended, waiting for {suspendCount.nb} events
770
- </div>
771
- <FlowStatusWaitingForEvents job={suspendCount.job} {workspaceId} {isOwner} />
772
- </div>
773
- {/each}
774
- </div>
775
- {:else if job.logs}
776
- <div
777
- class="text-xs p-4 bg-surface-secondary overflow-auto max-h-80 border border-tertiary-inverse"
778
- >
779
- <pre class="w-full">{job.logs}</pre>
780
- </div>
781
- {:else if innerModules?.length > 0}
782
- <div class="flex flex-col gap-1">
783
- {#each innerModules as mod, i (mod.id)}
784
- {#if mod.type == 'InProgress'}
785
- {@const rawMod = job.raw_flow?.modules[i]}
786
-
787
- <div
788
- ><span class="inline-flex gap-1"
789
- ><Badge color="indigo">{mod.id}</Badge>
790
- <span class="font-medium text-primary">
791
- {#if !emptyString(rawMod?.summary)}
792
- {rawMod?.summary ?? ''}
793
- {:else if rawMod?.value.type == 'script'}
794
- {rawMod.value.path ?? ''}
795
- {:else if rawMod?.value.type}
796
- {rawMod?.value.type}
797
- {/if}
798
- </span>
799
-
800
- <Loader2 class="animate-spin" /></span
801
- ></div
802
- >
803
- {/if}
804
- {/each}
805
- </div>
806
- {/if}
741
+ <FlowPreviewResult
742
+ {job}
743
+ {workspaceId}
744
+ {isOwner}
745
+ {hideFlowResult}
746
+ {hideDownloadLogs}
747
+ {localDurationStatuses}
748
+ {innerModules}
749
+ {suspendStatus}
750
+ {hideJobId}
751
+ />
807
752
  </div>
808
753
  {/if}
809
754
  {#if render}
@@ -10,6 +10,7 @@ import SchemaForm from './SchemaForm.svelte';
10
10
  export let isOwner;
11
11
  export let workspaceId;
12
12
  export let job;
13
+ export let light = false;
13
14
  let default_payload = {};
14
15
  let resumeUrl = undefined;
15
16
  let cancelUrl = undefined;
@@ -104,9 +105,11 @@ async function continu(approve) {
104
105
  </script>
105
106
 
106
107
  <div class="w-full h-full mt-2 text-sm text-tertiary">
107
- <p>Waiting to be resumed</p>
108
+ {#if !light}
109
+ <p>Waiting to be resumed</p>
110
+ {/if}
108
111
  {#if description != undefined}
109
- <DisplayResult {workspaceId} noControls result={description} language={job?.language}/>
112
+ <DisplayResult {workspaceId} noControls result={description} language={job?.language} />
110
113
  {/if}
111
114
  <div>
112
115
  {#if isOwner || resumeUrl}
@@ -16,6 +16,7 @@ declare const FlowStatusWaitingForEvents: $$__sveltets_2_IsomorphicComponent<{
16
16
  isOwner: boolean;
17
17
  workspaceId: string | undefined;
18
18
  job: Job;
19
+ light?: boolean;
19
20
  }, {
20
21
  [evt: string]: CustomEvent<any>;
21
22
  }, {}, {}, string>;
@@ -2,6 +2,9 @@
2
2
  import FlowBuilder from './FlowBuilder.svelte';
3
3
  let { flowStore: oldFlowStore, disableAi, light, ...props } = $props();
4
4
  let flowStore = $state(oldFlowStore);
5
+ $effect(() => {
6
+ flowStore = oldFlowStore;
7
+ });
5
8
  let trialRender = $state(true);
6
9
  if (light) {
7
10
  setTimeout(() => {
@@ -1,15 +1,11 @@
1
- <script lang="ts" module>"use strict";
2
- let testModulesState = $state({});
3
- </script>
4
-
5
1
  <script lang="ts">import { ScriptService } from '../gen';
6
2
  import { workspaceStore } from '../stores';
7
3
  import { getScriptByPath } from '../scripts';
8
- import { getContext, onMount } from 'svelte';
4
+ import { getContext } from 'svelte';
9
5
  import TestJobLoader from './TestJobLoader.svelte';
10
6
  import { getStepHistoryLoaderContext } from './stepHistoryLoader.svelte';
11
7
  let { mod, testJob = $bindable(undefined), testIsLoading = $bindable(false), noEditor = false, scriptProgress = $bindable(undefined) } = $props();
12
- const { flowStore, flowStateStore, pathStore, testSteps, previewArgs } = getContext('FlowEditorContext');
8
+ const { flowStore, flowStateStore, pathStore, testSteps, previewArgs, modulesTestStates } = getContext('FlowEditorContext');
13
9
  let testJobLoader = $state(undefined);
14
10
  let jobProgressReset = () => { };
15
11
  let stepHistoryLoader = getStepHistoryLoaderContext();
@@ -24,10 +20,13 @@ export async function runTest(args) {
24
20
  // Not defined if JobProgressBar not loaded
25
21
  if (jobProgressReset)
26
22
  jobProgressReset();
27
- testModulesState[mod.id].cancel = async () => {
28
- await testJobLoader?.cancelJob();
29
- testJob = undefined;
30
- };
23
+ if (modulesTestStates.states[mod.id]) {
24
+ modulesTestStates.states[mod.id].cancel = async () => {
25
+ await testJobLoader?.cancelJob();
26
+ modulesTestStates.states[mod.id].testJob = undefined;
27
+ };
28
+ modulesTestStates.runTestCb?.(mod.id);
29
+ }
31
30
  const val = mod.value;
32
31
  // let jobId: string | undefined = undefined
33
32
  if (val.type == 'rawscript') {
@@ -57,21 +56,24 @@ function jobDone() {
57
56
  }
58
57
  stepHistoryLoader?.resetInitial(mod.id);
59
58
  }
60
- testJob = undefined;
59
+ modulesTestStates.states[mod.id].testJob = undefined;
61
60
  }
62
61
  export function cancelJob() {
63
- testModulesState[mod.id]?.cancel?.();
62
+ modulesTestStates.states[mod.id]?.cancel?.();
64
63
  }
65
64
  $effect(() => {
66
- testIsLoading = testModulesState[mod.id]?.loading ?? false;
65
+ // Update testIsLoading to read the state from parent components
66
+ testIsLoading = modulesTestStates.states[mod.id]?.loading ?? false;
67
67
  });
68
- onMount(() => {
69
- const modId = mod.id;
70
- testModulesState[modId] = {
71
- ...(testModulesState[modId] ?? { loading: false, instances: 0 }),
72
- loading: testIsLoading
73
- };
68
+ $effect(() => {
69
+ // Update testJob to read the state from parent components
70
+ testJob = modulesTestStates.states[mod.id]?.testJob;
74
71
  });
72
+ modulesTestStates.states[mod.id] = {
73
+ ...(modulesTestStates.states[mod.id] ?? { loading: false }),
74
+ loading: testIsLoading,
75
+ testJob: testJob
76
+ };
75
77
  </script>
76
78
 
77
79
  <TestJobLoader
@@ -80,16 +82,16 @@ onMount(() => {
80
82
  bind:scriptProgress
81
83
  bind:this={testJobLoader}
82
84
  bind:isLoading={
83
- () => testModulesState[mod.id]?.loading ?? false,
85
+ () => modulesTestStates.states[mod.id]?.loading ?? false,
84
86
  (v) => {
85
87
  let newLoading = v ?? false
86
- if (testModulesState[mod.id]?.loading !== newLoading) {
87
- testModulesState[mod.id] = {
88
- ...(testModulesState[mod.id] ?? {}),
88
+ if (modulesTestStates.states[mod.id]?.loading !== newLoading) {
89
+ modulesTestStates.states[mod.id] = {
90
+ ...(modulesTestStates.states[mod.id] ?? {}),
89
91
  loading: newLoading
90
92
  }
91
93
  }
92
94
  }
93
95
  }
94
- bind:job={testJob}
96
+ bind:job={modulesTestStates.states[mod.id].testJob}
95
97
  />
@@ -2,6 +2,9 @@
2
2
  import AiChatLayout from './copilot/chat/AiChatLayout.svelte';
3
3
  let { script: oldScript, disableAi, ...props } = $props();
4
4
  let script = $state(oldScript);
5
+ $effect(() => {
6
+ script = oldScript;
7
+ });
5
8
  </script>
6
9
 
7
10
  <AiChatLayout noPadding {disableAi}>
@@ -10,7 +10,7 @@ import { createTooltip } from '@melt-ui/svelte';
10
10
  import { conditionalMelt } from '../../../utils';
11
11
  import { createDispatcherIfMounted } from '../../../createDispatcherIfMounted';
12
12
  import { triggerableByAI } from '../../../actions/triggerableByAI.svelte';
13
- let { id = '', aiId = undefined, aiDescription = undefined, size = 'md', spacingSize = size, color = 'blue', variant = 'contained', btnClasses = '', wrapperClasses = '', wrapperStyle = '', disabled = false, href = undefined, target = undefined, iconOnly = false, loadUntilNav = false, clickableWhileLoading = false, element = $bindable(undefined), nonCaptureEvent = false, propagateEvent = false, loading = $bindable(false), title = undefined, style = '', download = undefined, startIcon = undefined, endIcon = undefined, shortCut = undefined, tooltipPopover = undefined, dropdownBtnClasses = '', dropdownItems = undefined, hideDropdown = false, children, tooltip, ...rest } = $props();
13
+ let { id = '', aiId = undefined, aiDescription = undefined, size = 'md', spacingSize = size, color = 'blue', variant = 'contained', btnClasses = '', wrapperClasses = '', wrapperStyle = '', disabled = false, href = undefined, target = undefined, iconOnly = false, loadUntilNav = false, clickableWhileLoading = false, element = $bindable(undefined), nonCaptureEvent = false, propagateEvent = false, loading = $bindable(false), title = undefined, style = '', download = undefined, startIcon = undefined, endIcon = undefined, shortCut = undefined, tooltipPopover = undefined, dropdownBtnClasses = '', dropdownItems = undefined, hideDropdown = false, children, tooltip, dropdownOpen = $bindable(false), ...rest } = $props();
14
14
  function computeDropdowns(menuItems) {
15
15
  const items = typeof menuItems === 'function' ? menuItems() : menuItems;
16
16
  return items.map((item) => ({
@@ -225,6 +225,7 @@ $effect(() => {
225
225
  usePointerDownOutside
226
226
  on:open={() => dispatch('dropdownOpen', true)}
227
227
  on:close={() => dispatch('dropdownOpen', false)}
228
+ bind:open={dropdownOpen}
228
229
  >
229
230
  {#snippet buttonReplacement()}
230
231
  <div
@@ -51,6 +51,7 @@ interface Props {
51
51
  children?: import('svelte').Snippet;
52
52
  tooltip?: import('svelte').Snippet;
53
53
  [key: string]: any;
54
+ dropdownOpen?: boolean;
54
55
  }
55
56
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
56
57
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -73,6 +74,6 @@ declare const Button: $$__sveltets_2_IsomorphicComponent<Props, {
73
74
  }, {}, {
74
75
  focus: () => void;
75
76
  click: () => void;
76
- }, "element" | "loading">;
77
+ }, "element" | "loading" | "dropdownOpen">;
77
78
  type Button = InstanceType<typeof Button>;
78
79
  export default Button;
@@ -9,8 +9,11 @@ import FlowAIChat from '../copilot/chat/flow/FlowAIChat.svelte';
9
9
  import { aiChatManager, AIMode } from '../copilot/chat/AIChatManager.svelte';
10
10
  import { triggerableByAI } from '../../actions/triggerableByAI.svelte';
11
11
  const { flowStore } = getContext('FlowEditorContext');
12
- let { loading, disableStaticInputs = false, disableTutorials = false, disableAi = false, disableSettings = false, disabledFlowInputs = false, smallErrorHandler = false, newFlow = false, savedFlow = undefined, onDeployTrigger = () => { }, onTestUpTo = undefined, onEditInput = undefined, forceTestTab, highlightArg, aiChatOpen, showFlowAiButton, toggleAiChat, onRunPreview = () => { } } = $props();
12
+ let { loading, disableStaticInputs = false, disableTutorials = false, disableAi = false, disableSettings = false, disabledFlowInputs = false, smallErrorHandler = false, newFlow = false, savedFlow = undefined, onDeployTrigger = () => { }, onTestUpTo = undefined, onEditInput = undefined, forceTestTab, highlightArg, localModuleStates = writable({}), aiChatOpen, showFlowAiButton, toggleAiChat, isOwner, onTestFlow, isRunning, onCancelTestFlow, onOpenPreview, onHideJobStatus, individualStepTests = false, job, localDurationStatuses, suspendStatus, showJobStatus, onDelete, flowHasChanged } = $props();
13
13
  let flowModuleSchemaMap = $state();
14
+ export function isNodeVisible(nodeId) {
15
+ return flowModuleSchemaMap?.isNodeVisible(nodeId) ?? false;
16
+ }
14
17
  setContext('PropPickerContext', {
15
18
  flowPropPickerConfig: writable(undefined),
16
19
  pickablePropertiesFiltered: writable(undefined)
@@ -58,9 +61,22 @@ onDestroy(() => {
58
61
  }}
59
62
  {onTestUpTo}
60
63
  {onEditInput}
64
+ {localModuleStates}
61
65
  {aiChatOpen}
62
66
  {showFlowAiButton}
63
67
  {toggleAiChat}
68
+ {isOwner}
69
+ {onTestFlow}
70
+ {isRunning}
71
+ {onCancelTestFlow}
72
+ {onOpenPreview}
73
+ {onHideJobStatus}
74
+ {individualStepTests}
75
+ flowJob={job}
76
+ {showJobStatus}
77
+ {suspendStatus}
78
+ {onDelete}
79
+ {flowHasChanged}
64
80
  />
65
81
  {/if}
66
82
  </div>
@@ -83,7 +99,12 @@ onDestroy(() => {
83
99
  {onDeployTrigger}
84
100
  {forceTestTab}
85
101
  {highlightArg}
86
- {onRunPreview}
102
+ {onTestFlow}
103
+ {job}
104
+ {isOwner}
105
+ {localDurationStatuses}
106
+ {suspendStatus}
107
+ onOpenDetails={onOpenPreview}
87
108
  />
88
109
  {/if}
89
110
  </Pane>
@@ -1,5 +1,7 @@
1
- import type { Flow } from '../../gen';
1
+ import { type Writable } from 'svelte/store';
2
+ import type { Flow, Job } from '../../gen';
2
3
  import type { Trigger } from '../triggers/utils';
4
+ import type { DurationStatus, GraphModuleState } from '../graph';
3
5
  interface Props {
4
6
  loading: boolean;
5
7
  disableStaticInputs?: boolean;
@@ -20,7 +22,23 @@ interface Props {
20
22
  aiChatOpen?: boolean;
21
23
  showFlowAiButton?: boolean;
22
24
  toggleAiChat?: () => void;
23
- onRunPreview?: () => void;
25
+ localModuleStates?: Writable<Record<string, GraphModuleState>>;
26
+ isOwner?: boolean;
27
+ onTestFlow?: () => void;
28
+ isRunning?: boolean;
29
+ onCancelTestFlow?: () => void;
30
+ onOpenPreview?: () => void;
31
+ onHideJobStatus?: () => void;
32
+ individualStepTests?: boolean;
33
+ job?: Job;
34
+ localDurationStatuses?: Writable<Record<string, DurationStatus>>;
35
+ suspendStatus?: Writable<Record<string, {
36
+ job: Job;
37
+ nb: number;
38
+ }>>;
39
+ showJobStatus?: boolean;
40
+ onDelete?: (id: string) => void;
41
+ flowHasChanged?: boolean;
24
42
  }
25
43
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
26
44
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -41,6 +59,8 @@ declare const FlowEditor: $$__sveltets_2_IsomorphicComponent<Props, {
41
59
  testWithArgs: any;
42
60
  } & {
43
61
  [evt: string]: CustomEvent<any>;
44
- }, {}, {}, "">;
62
+ }, {}, {
63
+ isNodeVisible: (nodeId: string) => boolean;
64
+ }, "">;
45
65
  type FlowEditor = InstanceType<typeof FlowEditor>;
46
66
  export default FlowEditor;
@@ -9,7 +9,8 @@ import { insertNewPreprocessorModule } from '../flowStateUtils.svelte';
9
9
  import TriggersEditor from '../../triggers/TriggersEditor.svelte';
10
10
  import { handleSelectTriggerFromKind } from '../../triggers/utils';
11
11
  import { computeMissingInputWarnings } from '../missingInputWarnings';
12
- let { noEditor = false, enableAi = false, newFlow = false, disabledFlowInputs = false, savedFlow = undefined, onDeployTrigger = () => { }, forceTestTab, highlightArg, onRunPreview } = $props();
12
+ import FlowResult from './FlowResult.svelte';
13
+ let { noEditor = false, enableAi = false, newFlow = false, disabledFlowInputs = false, savedFlow = undefined, onDeployTrigger = () => { }, forceTestTab, highlightArg, onTestFlow, job, isOwner, localDurationStatuses, suspendStatus, onOpenDetails } = $props();
13
14
  const { selectedId, flowStore, flowStateStore, flowInputsStore, pathStore, initialPathStore, fakeInitialPath, previewArgs, flowInputEditorState } = getContext('FlowEditorContext');
14
15
  const { showCaptureHint, triggersState, triggersCount } = getContext('TriggerContext');
15
16
  function checkDup(modules) {
@@ -39,10 +40,10 @@ $effect(() => {
39
40
  showCaptureHint.set(true)
40
41
  }}
41
42
  on:applyArgs
42
- {onRunPreview}
43
+ {onTestFlow}
43
44
  />
44
45
  {:else if $selectedId === 'Result'}
45
- <p class="p-4 text-secondary">The result of the flow will be the result of the last node.</p>
46
+ <FlowResult {noEditor} {job} {isOwner} {localDurationStatuses} {suspendStatus} {onOpenDetails} />
46
47
  {:else if $selectedId === 'constants'}
47
48
  <FlowConstants {noEditor} />
48
49
  {:else if $selectedId === 'failure'}
@@ -1,5 +1,7 @@
1
- import type { Flow } from '../../../gen';
1
+ import type { Flow, Job } from '../../../gen';
2
2
  import { type Trigger } from '../../triggers/utils';
3
+ import type { Writable } from 'svelte/store';
4
+ import type { DurationStatus } from '../../graph';
3
5
  interface Props {
4
6
  noEditor?: boolean;
5
7
  enableAi?: boolean;
@@ -11,7 +13,15 @@ interface Props {
11
13
  onDeployTrigger?: (trigger: Trigger) => void;
12
14
  forceTestTab?: Record<string, boolean>;
13
15
  highlightArg?: Record<string, string | undefined>;
14
- onRunPreview?: () => void;
16
+ onTestFlow?: () => void;
17
+ job?: Job;
18
+ isOwner?: boolean;
19
+ localDurationStatuses?: Writable<Record<string, DurationStatus>>;
20
+ suspendStatus?: Writable<Record<string, {
21
+ job: Job;
22
+ nb: number;
23
+ }>>;
24
+ onOpenDetails?: () => void;
15
25
  }
16
26
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
17
27
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -21,7 +21,7 @@ import SideBarTab from '../../meltComponents/SideBarTab.svelte';
21
21
  import CaptureTable from '../../triggers/CaptureTable.svelte';
22
22
  import { isObjectTooBig } from '../../../utils';
23
23
  import { refreshStateStore } from '../../../svelte5Utils.svelte';
24
- let { noEditor, disabled, onRunPreview } = $props();
24
+ let { noEditor, disabled, onTestFlow } = $props();
25
25
  const { flowStore, previewArgs, pathStore, initialPathStore, fakeInitialPath, flowInputEditorState } = getContext('FlowEditorContext');
26
26
  let addPropertyV2 = $state(undefined);
27
27
  let previewSchema = $state(undefined);
@@ -159,7 +159,7 @@ function runPreview() {
159
159
  if (previewArguments) {
160
160
  previewArgs.val = structuredClone($state.snapshot(previewArguments));
161
161
  }
162
- onRunPreview?.();
162
+ onTestFlow?.();
163
163
  }
164
164
  function updatePreviewSchemaAndArgs(payload) {
165
165
  if (isObjectTooBig(payload)) {