windmill-components 1.28.7 → 1.34.0

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 (119) hide show
  1. package/common.d.ts +3 -0
  2. package/components/AppConnect.svelte +28 -12
  3. package/components/ArgInput.svelte +25 -14
  4. package/components/ArgInput.svelte.d.ts +4 -0
  5. package/components/CenteredPage.svelte +1 -1
  6. package/components/DisplayResult.svelte +3 -3
  7. package/components/Drawer.svelte +108 -0
  8. package/components/Drawer.svelte.d.ts +23 -0
  9. package/components/Editor.svelte +70 -78
  10. package/components/Editor.svelte.d.ts +3 -0
  11. package/components/EditorBar.svelte +23 -10
  12. package/components/FlowBuilder.svelte +39 -33
  13. package/components/FlowEditor.svelte +17 -58
  14. package/components/FlowJobResult.svelte +18 -17
  15. package/components/FlowPreview.svelte +13 -34
  16. package/components/FlowPreview.svelte.d.ts +2 -4
  17. package/components/FlowPreviewContent.svelte +56 -44
  18. package/components/FlowPreviewContent.svelte.d.ts +0 -1
  19. package/components/FlowStatusViewer.svelte +123 -205
  20. package/components/FlowStatusViewer.svelte.d.ts +7 -4
  21. package/components/FlowViewer.svelte +4 -1
  22. package/components/IconedPath.svelte +12 -0
  23. package/components/IconedPath.svelte.d.ts +16 -0
  24. package/components/IconedResourceType.svelte +21 -2
  25. package/components/IconedResourceType.svelte.d.ts +1 -0
  26. package/components/InputTransformForm.svelte +9 -8
  27. package/components/InputTransformForm.svelte.d.ts +1 -1
  28. package/components/InviteGlobalUser.svelte +1 -1
  29. package/components/ItemPicker.svelte +6 -1
  30. package/components/JobStatus.svelte +1 -1
  31. package/components/ModuleStep.svelte +73 -93
  32. package/components/ModuleStep.svelte.d.ts +7 -2
  33. package/components/Path.svelte +62 -40
  34. package/components/Path.svelte.d.ts +2 -0
  35. package/components/ProgressBar.svelte +31 -0
  36. package/components/ProgressBar.svelte.d.ts +17 -0
  37. package/components/ProgressBarPart.svelte +20 -0
  38. package/components/ProgressBarPart.svelte.d.ts +20 -0
  39. package/components/ResourceEditor.svelte +2 -1
  40. package/components/ResourcePicker.svelte +9 -0
  41. package/components/SchemaForm.svelte +9 -4
  42. package/components/SchemaForm.svelte.d.ts +1 -1
  43. package/components/SchemaModal.svelte +20 -3
  44. package/components/ScriptBuilder.svelte +58 -21
  45. package/components/ScriptBuilder.svelte.d.ts +1 -0
  46. package/components/ScriptEditor.svelte +4 -2
  47. package/components/SharedBadge.svelte +8 -3
  48. package/components/VariableEditor.svelte +1 -1
  49. package/components/flows/CopyFirstStepSchema.svelte +4 -3
  50. package/components/flows/DynamicInputHelpBox.svelte +6 -4
  51. package/components/flows/DynamicInputHelpBox.svelte.d.ts +1 -1
  52. package/components/flows/FlowBox.svelte +15 -2
  53. package/components/flows/FlowBox.svelte.d.ts +14 -14
  54. package/components/flows/FlowBoxHeader.svelte +10 -3
  55. package/components/flows/FlowBoxHeader.svelte.d.ts +3 -0
  56. package/components/flows/FlowInput.svelte +14 -12
  57. package/components/flows/FlowInputs.svelte +55 -35
  58. package/components/flows/FlowInputs.svelte.d.ts +3 -1
  59. package/components/flows/FlowModuleHeader.svelte +71 -55
  60. package/components/flows/FlowModuleHeader.svelte.d.ts +6 -6
  61. package/components/flows/FlowSettings.svelte +34 -57
  62. package/components/flows/FlowSettings.svelte.d.ts +0 -1
  63. package/components/flows/FlowTimeline.svelte +169 -0
  64. package/components/flows/FlowTimeline.svelte.d.ts +21 -0
  65. package/components/flows/flowState.d.ts +14 -0
  66. package/components/flows/flowState.js +52 -0
  67. package/components/flows/flowStateUtils.d.ts +37 -0
  68. package/components/flows/flowStateUtils.js +222 -0
  69. package/components/flows/flowStore.d.ts +1 -16
  70. package/components/flows/flowStore.js +7 -208
  71. package/components/flows/pickers/FlowScriptPicker.svelte +5 -9
  72. package/components/flows/pickers/FlowScriptPicker.svelte.d.ts +0 -1
  73. package/components/flows/pickers/PickHubScript.svelte +1 -1
  74. package/components/flows/pickers/PickHubScript.svelte.d.ts +1 -1
  75. package/components/flows/pickers/PickScript.svelte +1 -1
  76. package/components/flows/pickers/PickScript.svelte.d.ts +1 -1
  77. package/components/flows/scheduleUtils.d.ts +7 -0
  78. package/components/flows/scheduleUtils.js +21 -0
  79. package/components/flows/stepOpenedStore.d.ts +1 -0
  80. package/components/flows/stepOpenedStore.js +6 -0
  81. package/components/flows/utils.d.ts +5 -12
  82. package/components/flows/utils.js +40 -112
  83. package/components/icons/DiscordIcon.svelte +16 -0
  84. package/components/icons/DiscordIcon.svelte.d.ts +17 -0
  85. package/components/icons/HttpIcon.svelte +21 -0
  86. package/components/icons/HttpIcon.svelte.d.ts +17 -0
  87. package/components/icons/MastodonIcon.svelte +16 -0
  88. package/components/icons/MastodonIcon.svelte.d.ts +17 -0
  89. package/components/icons/MatrixIcon.svelte +16 -0
  90. package/components/icons/MatrixIcon.svelte.d.ts +17 -0
  91. package/components/icons/S3Icon.svelte +16 -0
  92. package/components/icons/S3Icon.svelte.d.ts +17 -0
  93. package/components/icons/WindmillIcon.svelte +68 -0
  94. package/components/icons/WindmillIcon.svelte.d.ts +17 -0
  95. package/components/preview/FlowPreviewStatus.svelte +28 -0
  96. package/components/preview/FlowPreviewStatus.svelte.d.ts +17 -0
  97. package/components/propertyPicker/ObjectViewer.svelte +13 -13
  98. package/components/propertyPicker/utils.js +3 -2
  99. package/components/tabs/Tab.svelte +12 -0
  100. package/components/tabs/Tab.svelte.d.ts +19 -0
  101. package/components/tabs/TabPanel.svelte +11 -0
  102. package/components/tabs/TabPanel.svelte.d.ts +20 -0
  103. package/components/tabs/Tabs.svelte +3 -0
  104. package/components/tabs/Tabs.svelte.d.ts +23 -0
  105. package/gen/core/OpenAPI.js +1 -1
  106. package/gen/core/request.js +1 -0
  107. package/gen/models/MainArgSignature.d.ts +14 -3
  108. package/gen/services/JobService.d.ts +10 -2
  109. package/gen/services/JobService.js +4 -2
  110. package/gen/services/ScriptService.d.ts +18 -0
  111. package/gen/services/ScriptService.js +30 -0
  112. package/infer.js +47 -24
  113. package/package.json +39 -20
  114. package/script_helpers.d.ts +4 -1
  115. package/script_helpers.js +68 -17
  116. package/stores.d.ts +1 -2
  117. package/stores.js +1 -4
  118. package/utils.d.ts +4 -2
  119. package/utils.js +33 -5
@@ -1,25 +1,27 @@
1
1
  <script>import { goto } from '$app/navigation';
2
2
  import { page } from '$app/stores';
3
- import { FlowService, ScheduleService } from '../gen';
4
- import { clearPreviewResults, previewResults, workspaceStore } from '../stores';
3
+ import { FlowService, Job, ScheduleService } from '../gen';
4
+ import { workspaceStore } from '../stores';
5
5
  import { encodeState, formatCron, loadHubScripts, pathIsEmpty, sendUserToast, setQueryWithoutLoad } from '../utils';
6
6
  import { faPlay } from '@fortawesome/free-solid-svg-icons';
7
7
  import { Breadcrumb, BreadcrumbItem, Button } from 'flowbite-svelte';
8
8
  import { onDestroy, onMount } from 'svelte';
9
9
  import Icon from 'svelte-awesome';
10
10
  import { OFFSET } from './CronInput.svelte';
11
+ import Drawer from './Drawer.svelte';
11
12
  import FlowEditor from './FlowEditor.svelte';
12
13
  import FlowPreviewContent from './FlowPreviewContent.svelte';
13
- import { flowStore, mode } from './flows/flowStore';
14
- import { flowToMode, jobsToResults } from './flows/utils';
14
+ import { flowStateStore, flowStateToFlow } from './flows/flowState';
15
+ import { flowStore } from './flows/flowStore';
16
+ import { cleanInputs } from './flows/utils';
15
17
  import ScriptSchema from './ScriptSchema.svelte';
16
18
  export let initialPath = '';
17
19
  let pathError = '';
18
- let scheduleArgs;
19
- let previewArgs;
20
- let scheduleEnabled;
21
- let scheduleCron;
22
20
  let previewOpen = false;
21
+ let scheduleArgs = {};
22
+ let previewArgs = {};
23
+ let scheduleEnabled = false;
24
+ let scheduleCron = '';
23
25
  $: step = Number($page.url.searchParams.get('step')) || 1;
24
26
  async function createSchedule(path) {
25
27
  await ScheduleService.createSchedule({
@@ -36,7 +38,7 @@ async function createSchedule(path) {
36
38
  });
37
39
  }
38
40
  async function saveFlow() {
39
- const flow = flowToMode($flowStore, $mode);
41
+ const flow = cleanInputs(flowStateToFlow($flowStateStore, $flowStore));
40
42
  if (initialPath === '') {
41
43
  await FlowService.createFlow({
42
44
  workspace: $workspaceStore,
@@ -48,7 +50,7 @@ async function saveFlow() {
48
50
  schema: flow.schema
49
51
  }
50
52
  });
51
- if ($mode == 'pull') {
53
+ if (scheduleEnabled) {
52
54
  await createSchedule(flow.path);
53
55
  }
54
56
  }
@@ -103,28 +105,36 @@ async function saveFlow() {
103
105
  goto(`/flows/get/${$flowStore.path}`);
104
106
  }
105
107
  async function changeStep(step) {
106
- if (step === 2 && previewOpen) {
107
- previewOpen = false;
108
- }
109
108
  goto(`?step=${step}`);
110
109
  }
110
+ flowStateStore.subscribe((flowState) => {
111
+ if (flowState) {
112
+ flowStore.update((flow) => {
113
+ if (flow) {
114
+ return flowStateToFlow(flowState, flow);
115
+ }
116
+ return flow;
117
+ });
118
+ }
119
+ });
111
120
  flowStore.subscribe((flow) => {
112
121
  if (flow) {
113
- setQueryWithoutLoad($page.url, 'state', encodeState(flowToMode(flow, $mode)));
122
+ setQueryWithoutLoad($page.url, 'state', encodeState(flow));
114
123
  }
115
124
  });
116
125
  onMount(() => {
117
126
  loadHubScripts();
118
- clearPreviewResults();
119
127
  });
120
128
  onDestroy(() => {
121
129
  //@ts-ignore
122
130
  $flowStore = undefined;
131
+ //@ts-ignore
132
+ $flowStateStore = undefined;
123
133
  });
124
134
  </script>
125
135
 
126
136
  <div class="flex flex-row w-full h-full justify-between">
127
- <div class={`flex flex-col mb-96 m-auto w-full sm:w-3/4 lg:w-2/3 xl:w-1/2`}>
137
+ <div class={`flex flex-col mb-96 m-auto w-full sm:w-3/4 lg:w-2/3`}>
128
138
  <!-- Nav between steps-->
129
139
  <div class="justify-between flex flex-row w-full my-4">
130
140
  <Breadcrumb>
@@ -157,6 +167,12 @@ onDestroy(() => {
157
167
  </button>
158
168
  {:else}
159
169
  <button class="default-button px-6 self-end" on:click={saveFlow}>Save</button>
170
+ <button
171
+ class="default-button-secondary px-6 max-h-8 mr-2"
172
+ on:click={async () => {
173
+ changeStep(1)
174
+ }}>Back</button
175
+ >
160
176
  {/if}
161
177
  </div>
162
178
  </div>
@@ -169,7 +185,7 @@ onDestroy(() => {
169
185
 
170
186
  <!-- metadata -->
171
187
 
172
- {#if $flowStore}
188
+ {#if $flowStateStore}
173
189
  {#if step === 1}
174
190
  <FlowEditor
175
191
  bind:pathError
@@ -203,20 +219,10 @@ onDestroy(() => {
203
219
  <p>Loading</p>
204
220
  {/if}
205
221
  </div>
206
-
207
- <div class={`relative h-screen w-1/3 ${previewOpen ? '' : 'hidden'}`}>
208
- <div class="absolute top-0 h-full">
209
- {#if $flowStore && step === 1}
210
- <div class="fixed border-l-2 right-0 h-screen w-1/2 sm:w-1/3">
211
- <FlowPreviewContent
212
- bind:args={previewArgs}
213
- on:close={() => (previewOpen = !previewOpen)}
214
- on:change={(e) => {
215
- previewResults.set(jobsToResults(e.detail))
216
- }}
217
- />
218
- </div>
219
- {/if}
220
- </div>
221
- </div>
222
222
  </div>
223
+
224
+ {#if $flowStateStore && $flowStore}
225
+ <Drawer bind:open={previewOpen} size="800px">
226
+ <FlowPreviewContent bind:args={previewArgs} on:close={() => (previewOpen = !previewOpen)} />
227
+ </Drawer>
228
+ {/if}
@@ -1,14 +1,9 @@
1
1
  <script>import { ScheduleService } from '../gen';
2
2
  import { workspaceStore } from '../stores';
3
- import { pathIsEmpty } from '../utils';
4
- import { faPlus } from '@fortawesome/free-solid-svg-icons';
5
- import { Button } from 'flowbite-svelte';
6
- import Icon from 'svelte-awesome';
7
- import FlowInput from './flows/FlowInput.svelte';
8
3
  import FlowSettings from './flows/FlowSettings.svelte';
9
- import { addModule, flowStore, mode } from './flows/flowStore';
10
- import ModuleStep from './ModuleStep.svelte';
11
- import Tooltip from './Tooltip.svelte';
4
+ import { flowStateStore } from './flows/flowState';
5
+ import { flowStore } from './flows/flowStore';
6
+ import FlowTimeline from './flows/FlowTimeline.svelte';
12
7
  export let pathError = '';
13
8
  export let initialPath = '';
14
9
  export let scheduleArgs = {};
@@ -38,59 +33,23 @@ async function loadSchedule() {
38
33
  $: if ($flowStore && $workspaceStore && initialPath != '') {
39
34
  loadSchedule();
40
35
  }
41
- let open = 0;
42
36
  </script>
43
37
 
44
- {#if $flowStore}
45
- <div class="flex space-y-8 flex-col items-center line">
46
- <FlowSettings
47
- bind:pathError
48
- bind:initialPath
49
- bind:scheduleArgs
50
- {previewArgs}
51
- bind:scheduleCron
52
- bind:scheduleEnabled
53
- bind:open
54
- />
55
- <FlowInput />
56
- {#each $flowStore?.value.modules as mod, i}
57
- <ModuleStep bind:open bind:mod bind:args={previewArgs} {i} />
58
- {#if i == 0 && $mode == 'pull'}
59
- <div class="flex justify-center bg-white shadow p-2">
60
- <p>
61
- Starting from here, the flow for loop over items from the 1st step's result right above.
62
- &nbsp; <br />For-loops insertable at other points is not supported yet but coming soon
63
- (See
64
- <a href="https://github.com/windmill-labs/windmill/issues/350">#350</a>.)
65
- </p>
66
- <Tooltip>
67
- This flow being in 'Pull' mode, the rest of the flow will for loop over the list of
68
- items returned by the trigger script right above. Retrieve the item value using
69
- `flow_input._value`
70
- </Tooltip>
71
- </div>
72
- {/if}
73
- {/each}
74
- <Button
75
- disabled={pathIsEmpty($flowStore.path)}
76
- class="blue-button"
77
- on:click={() => {
78
- addModule()
79
- open = $flowStore?.value.modules.length - 1
80
- }}
81
- >
82
- <Icon class="text-white mr-2" data={faPlus} />
83
- Add step {pathIsEmpty($flowStore?.path) ? '(pick a name first!)' : ''}
84
- </Button>
38
+ {#if $flowStateStore}
39
+ <div class="flex space-y-8 flex-col items-center">
40
+ <FlowTimeline bind:args={previewArgs} bind:flowModuleSchemas={$flowStateStore}>
41
+ <div slot="settings">
42
+ <FlowSettings
43
+ bind:pathError
44
+ bind:initialPath
45
+ bind:scheduleArgs
46
+ {previewArgs}
47
+ bind:scheduleCron
48
+ bind:scheduleEnabled
49
+ />
50
+ </div>
51
+ </FlowTimeline>
85
52
  </div>
86
53
  {:else}
87
54
  <h3>Loading flow</h3>
88
55
  {/if}
89
-
90
- <style>
91
- .line {
92
- background-image: linear-gradient(#e5e7eb, #e5e7eb);
93
- background-size: 2px 100%;
94
- background-repeat: no-repeat;
95
- background-position: center center;
96
- }</style>
@@ -1,23 +1,24 @@
1
- <script>import ChevronButton from './ChevronButton.svelte';
2
- import DisplayResult from './DisplayResult.svelte';
1
+ <script>import DisplayResult from './DisplayResult.svelte';
2
+ import Tabs from './tabs/Tabs.svelte';
3
+ import Tab from './tabs/Tab.svelte';
4
+ import TabPanel from './tabs/TabPanel.svelte';
5
+ let value = 0;
3
6
  export let job;
4
7
  </script>
5
8
 
6
9
  {#if job}
7
- <div class="flex flex-col ml-10">
8
- <div>
9
- <ChevronButton text="result" viewOptions={true}>
10
- <div class="text-xs">
11
- <DisplayResult result={job.result} />
12
- </div>
13
- </ChevronButton>
14
- </div>
15
- <div>
16
- <ChevronButton text="logs" viewOptions={true}>
17
- <div class="text-xs p-4 bg-gray-50 overflow-auto max-h-80 border mt-1">
18
- <pre class="w-full">{job.logs}</pre>
19
- </div>
20
- </ChevronButton>
21
- </div>
10
+ <div>
11
+ <Tabs>
12
+ <Tab bind:value index={0}>Results</Tab>
13
+ <Tab bind:value index={1}>Logs</Tab>
14
+ </Tabs>
15
+ <TabPanel bind:value index={0} class="border p-2 h-36 overflow-y-scroll">
16
+ <DisplayResult result={job.result} />
17
+ </TabPanel>
18
+ <TabPanel bind:value index={1} class="border p-2 h-36 overflow-y-scroll">
19
+ <div class="text-xs p-4 bg-gray-50 overflow-auto max-h-80 border">
20
+ <pre class="w-full">{job.logs}</pre>
21
+ </div>
22
+ </TabPanel>
22
23
  </div>
23
24
  {/if}
@@ -1,35 +1,28 @@
1
- <script>import { Job, JobService } from '../gen';
2
- import { workspaceStore } from '../stores';
1
+ <script>import { workspaceStore } from '../stores';
3
2
  import { sendUserToast, truncateRev } from '../utils';
4
3
  import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
5
- import { createEventDispatcher, onDestroy } from 'svelte';
4
+ import { onDestroy } from 'svelte';
6
5
  import Icon from 'svelte-awesome';
7
- import FlowJobResult from './FlowJobResult.svelte';
6
+ import { flowStateStore, flowStateToFlow } from './flows/flowState';
7
+ import { mapJobResultsToFlowState } from './flows/flowStateUtils';
8
8
  import { runFlowPreview } from './flows/utils';
9
9
  import FlowStatusViewer from './FlowStatusViewer.svelte';
10
10
  import RunForm from './RunForm.svelte';
11
11
  import Tabs from './Tabs.svelte';
12
- const dispatch = createEventDispatcher();
13
12
  export let i;
14
13
  export let flow;
15
- export let schemas = [];
14
+ export let schema;
16
15
  export let args = {};
17
16
  let stepArgs = {};
18
17
  let tab = 'upto';
19
18
  let viewPreview = false;
20
- let intervalId;
21
19
  let uptoText = i >= flow.value.modules.length - 1 ? 'Preview whole flow' : 'Preview up to this step';
22
- let job;
23
- let jobs = [];
24
20
  let jobId;
25
- $: dispatch('change', jobs);
26
21
  export async function runPreview(args) {
27
22
  viewPreview = true;
28
- intervalId && clearInterval(intervalId);
23
+ flow = flowStateToFlow($flowStateStore, flow);
29
24
  let newFlow = tab == 'upto' ? truncateFlow(flow) : setInputTransformFromArgs(extractStep(flow), args);
30
25
  jobId = await runFlowPreview(args, newFlow);
31
- jobs = [];
32
- intervalId = setInterval(loadJob, 1000);
33
26
  sendUserToast(`started preview ${truncateRev(jobId, 10)}`);
34
27
  }
35
28
  function truncateFlow(flow) {
@@ -40,7 +33,7 @@ function truncateFlow(flow) {
40
33
  function extractStep(flow) {
41
34
  const localFlow = JSON.parse(JSON.stringify(flow));
42
35
  localFlow.value.modules = flow.value.modules.slice(i, i + 1);
43
- localFlow.schema = schemas[i];
36
+ localFlow.schema = schema;
44
37
  return localFlow;
45
38
  }
46
39
  function setInputTransformFromArgs(flow, args) {
@@ -54,21 +47,6 @@ function setInputTransformFromArgs(flow, args) {
54
47
  flow.value.modules[0].input_transform = input_transform;
55
48
  return flow;
56
49
  }
57
- async function loadJob() {
58
- try {
59
- job = await JobService.getJob({ workspace: $workspaceStore, id: jobId });
60
- if (job?.type == 'CompletedJob') {
61
- //only CompletedJob has success property
62
- clearInterval(intervalId);
63
- }
64
- }
65
- catch (err) {
66
- sendUserToast(err, true);
67
- }
68
- }
69
- onDestroy(() => {
70
- intervalId && clearInterval(intervalId);
71
- });
72
50
  </script>
73
51
 
74
52
  <button
@@ -116,12 +94,13 @@ onDestroy(() => {
116
94
  />
117
95
  {/if}
118
96
 
119
- {#if job}
97
+ {#if jobId}
120
98
  <div class="w-full flex justify-center">
121
- <FlowStatusViewer {job} bind:jobs />
99
+ <FlowStatusViewer
100
+ {jobId}
101
+ on:jobsLoaded={(e) => mapJobResultsToFlowState(e.detail, tab, i)}
102
+ root={true}
103
+ />
122
104
  </div>
123
- {#if `result` in job}
124
- <FlowJobResult {job} />
125
- {/if}
126
105
  {/if}
127
106
  {/if}
@@ -1,17 +1,15 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import type { Schema } from '../common';
3
- import { type Flow } from '../gen';
3
+ import type { Flow } from '../gen';
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  i: number;
7
7
  flow: Flow;
8
- schemas?: Schema[] | undefined;
8
+ schema: Schema;
9
9
  args?: Record<string, any> | undefined;
10
10
  runPreview?: ((args: any) => Promise<void>) | undefined;
11
11
  };
12
12
  events: {
13
- change: CustomEvent<any>;
14
- } & {
15
13
  [evt: string]: CustomEvent<any>;
16
14
  };
17
15
  slots: {};
@@ -1,68 +1,80 @@
1
- <script>import { Job, JobService } from '../gen';
1
+ <script>import { JobService } from '../gen';
2
2
  import { workspaceStore } from '../stores';
3
- import { sendUserToast, truncateRev } from '../utils';
4
- import { faClose } from '@fortawesome/free-solid-svg-icons';
3
+ import { faClose, faPlay } from '@fortawesome/free-solid-svg-icons';
5
4
  import { Button } from 'flowbite-svelte';
6
5
  import { createEventDispatcher, onDestroy } from 'svelte';
7
6
  import Icon from 'svelte-awesome';
8
- import FlowJobResult from './FlowJobResult.svelte';
7
+ import { flowStateStore, flowStateToFlow } from './flows/flowState';
8
+ import { mapJobResultsToFlowState } from './flows/flowStateUtils';
9
9
  import { flowStore } from './flows/flowStore';
10
10
  import { runFlowPreview } from './flows/utils';
11
11
  import FlowStatusViewer from './FlowStatusViewer.svelte';
12
12
  import SchemaForm from './SchemaForm.svelte';
13
- const dispatch = createEventDispatcher();
14
13
  export let args = {};
15
- let intervalId;
16
- let job;
17
- let jobs = [];
18
- let jobId;
14
+ let jobId = undefined;
19
15
  let isValid = false;
20
- $: dispatch('change', jobs);
16
+ let intervalState = 'idle';
17
+ $: newFlow = flowStateToFlow($flowStateStore, $flowStore);
18
+ $: steps = newFlow?.value.modules.length ?? 0;
19
+ const dispatch = createEventDispatcher();
21
20
  export async function runPreview(args) {
22
- intervalId && clearInterval(intervalId);
23
- jobId = await runFlowPreview(args, $flowStore);
24
- jobs = [];
25
- intervalId = setInterval(loadJob, 1000);
26
- sendUserToast(`started preview ${truncateRev(jobId, 10)}`);
27
- }
28
- async function loadJob() {
29
- try {
30
- job = await JobService.getJob({ workspace: $workspaceStore, id: jobId });
31
- if (job?.type == 'CompletedJob') {
32
- clearInterval(intervalId);
33
- }
34
- }
35
- catch (err) {
36
- sendUserToast(err, true);
37
- }
21
+ jobId = await runFlowPreview(args, newFlow);
22
+ intervalState = 'running';
38
23
  }
39
24
  onDestroy(() => {
40
- intervalId && clearInterval(intervalId);
25
+ intervalState = 'done';
41
26
  });
42
27
  </script>
43
28
 
44
- <div class="flex flex-col space-y-4 h-screen bg-white">
45
- <div class="flex flex-col space-y-4 p-6 border-b-2 overflow-y-auto grow">
46
- <div class="flex justify-between">
47
- <h3 class="text-lg leading-6 font-bold text-gray-900">Flow Preview</h3>
29
+ <div class="flex divide-y flex-col space-y-2 h-screen bg-white p-6 w-full">
30
+ <div class="flex justify-between">
31
+ <div class="flex flex-row justify-center items-center">
32
+ <div class="flex justify-center p-2 w-8 h-8 bg-blue-200 rounded-lg mr-2">
33
+ <Icon data={faPlay} scale={1} class="text-blue-500" />
34
+ </div>
48
35
 
49
- <Button color="alternative" on:click={() => dispatch('close')}>
50
- <Icon data={faClose} />
51
- </Button>
36
+ <h3 class="text-lg leading-6 font-bold text-gray-900">Flow preview</h3>
52
37
  </div>
38
+ <Button color="alternative" on:click={() => dispatch('close')}>
39
+ <Icon data={faClose} />
40
+ </Button>
41
+ </div>
42
+ <div class="max-h-80 overflow-y-auto">
53
43
  <SchemaForm schema={$flowStore.schema} bind:isValid bind:args />
54
44
  </div>
55
- <Button disabled={!isValid} class="blue-button mx-4" on:click={() => runPreview(args)} size="md">
56
- Preview
57
- </Button>
45
+ {#if intervalState === 'running'}
46
+ <Button
47
+ disabled={!isValid}
48
+ color="red"
49
+ on:click={async () => {
50
+ intervalState = 'canceled'
51
+ try {
52
+ jobId &&
53
+ (await JobService.cancelQueuedJob({
54
+ workspace: $workspaceStore ?? '',
55
+ id: jobId,
56
+ requestBody: {}
57
+ }))
58
+ } catch {}
59
+ jobId = undefined
60
+ }}
61
+ size="md"
62
+ >
63
+ Cancel
64
+ </Button>
65
+ {:else}
66
+ <Button disabled={!isValid} class="blue-button" on:click={() => runPreview(args)} size="md">
67
+ {`Run${intervalState === 'done' ? ' again' : ''}`}
68
+ </Button>
69
+ {/if}
70
+
58
71
  <div class="h-full overflow-y-auto mb-16 grow">
59
- {#if job}
60
- <div class="w-full">
61
- <FlowStatusViewer {job} bind:jobs />
62
- </div>
63
- {#if `result` in job}
64
- <FlowJobResult {job} />
65
- {/if}
72
+ {#if jobId}
73
+ <FlowStatusViewer
74
+ {jobId}
75
+ on:jobsLoaded={(e) => mapJobResultsToFlowState(e.detail, 'upto', steps - 1)}
76
+ root={true}
77
+ />
66
78
  {/if}
67
79
  </div>
68
80
  </div>
@@ -6,7 +6,6 @@ declare const __propDef: {
6
6
  };
7
7
  events: {
8
8
  close: CustomEvent<any>;
9
- change: CustomEvent<any>;
10
9
  } & {
11
10
  [evt: string]: CustomEvent<any>;
12
11
  };