windmill-components 1.34.0 → 1.35.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 (77) hide show
  1. package/components/AppConnect.svelte +1 -1
  2. package/components/CenteredPage.svelte +2 -2
  3. package/components/EditorBar.svelte +45 -39
  4. package/components/FlowBuilder.svelte +4 -4
  5. package/components/FlowJobResult.svelte +17 -18
  6. package/components/FlowModulesViewer.svelte +97 -0
  7. package/components/FlowModulesViewer.svelte.d.ts +17 -0
  8. package/components/FlowPreview.svelte +35 -34
  9. package/components/FlowPreviewContent.svelte +4 -1
  10. package/components/FlowStatusViewer.svelte +31 -49
  11. package/components/FlowViewer.svelte +60 -159
  12. package/components/FlowViewer.svelte.d.ts +0 -1
  13. package/components/ModuleStep.svelte +1 -1
  14. package/components/Multiselect.svelte +1 -1
  15. package/components/SchemaViewer.svelte +58 -68
  16. package/components/ScriptBuilder.svelte +118 -132
  17. package/components/ScriptEditor.svelte +115 -338
  18. package/components/ScriptEditor.svelte.d.ts +0 -2
  19. package/components/ScriptSchema.svelte +45 -44
  20. package/components/SharedBadge.svelte +1 -1
  21. package/components/{Drawer.svelte → common/drawer/Drawer.svelte} +0 -0
  22. package/components/{Drawer.svelte.d.ts → common/drawer/Drawer.svelte.d.ts} +0 -0
  23. package/components/common/drawer/DrawerContent.svelte +19 -0
  24. package/components/common/drawer/DrawerContent.svelte.d.ts +20 -0
  25. package/components/common/menu/Menu.svelte +57 -0
  26. package/components/common/menu/Menu.svelte.d.ts +23 -0
  27. package/components/common/menu/MenuItem.svelte +9 -0
  28. package/components/common/menu/MenuItem.svelte.d.ts +27 -0
  29. package/components/common/tabs/Tab.svelte +17 -0
  30. package/components/{tabs → common/tabs}/Tab.svelte.d.ts +1 -2
  31. package/components/common/tabs/TabContent.svelte +12 -0
  32. package/components/common/tabs/TabContent.svelte.d.ts +19 -0
  33. package/components/common/tabs/Tabs.svelte +20 -0
  34. package/components/common/tabs/Tabs.svelte.d.ts +24 -0
  35. package/components/flows/FlowModuleHeader.svelte +1 -2
  36. package/components/flows/FlowSettings.svelte +39 -35
  37. package/components/flows/flowState.js +2 -2
  38. package/components/flows/flowStateUtils.js +7 -9
  39. package/components/flows/flowStore.js +24 -0
  40. package/components/flows/utils.d.ts +1 -1
  41. package/components/flows/utils.js +9 -9
  42. package/components/jobs/JobDetail.svelte +176 -0
  43. package/components/jobs/JobDetail.svelte.d.ts +17 -0
  44. package/components/landing/FlowGettingStarted.svelte +95 -0
  45. package/components/landing/FlowGettingStarted.svelte.d.ts +19 -0
  46. package/components/landing/FlowLandingBox.svelte +69 -0
  47. package/components/landing/FlowLandingBox.svelte.d.ts +17 -0
  48. package/components/landing/RessourceGettingStarted.svelte +51 -0
  49. package/components/landing/RessourceGettingStarted.svelte.d.ts +19 -0
  50. package/components/landing/ScriptBox.svelte +81 -0
  51. package/components/landing/ScriptBox.svelte.d.ts +17 -0
  52. package/components/landing/ScriptGettingStarted.svelte +93 -0
  53. package/components/landing/ScriptGettingStarted.svelte.d.ts +19 -0
  54. package/components/script_editor/LogPanel.svelte +172 -0
  55. package/components/script_editor/LogPanel.svelte.d.ts +22 -0
  56. package/components/sidebar/MenuLink.svelte +49 -0
  57. package/components/sidebar/MenuLink.svelte.d.ts +21 -0
  58. package/components/sidebar/SidebarContent.svelte +55 -0
  59. package/components/sidebar/SidebarContent.svelte.d.ts +16 -0
  60. package/components/sidebar/UserMenu.svelte +62 -0
  61. package/components/sidebar/UserMenu.svelte.d.ts +16 -0
  62. package/components/sidebar/WorkspaceMenu.svelte +66 -0
  63. package/components/sidebar/WorkspaceMenu.svelte.d.ts +16 -0
  64. package/gen/models/FlowModule.d.ts +5 -3
  65. package/gen/models/ForloopFlow.d.ts +2 -2
  66. package/logout.js +1 -1
  67. package/package.json +30 -15
  68. package/script_helpers.js +1 -1
  69. package/stores.d.ts +0 -1
  70. package/stores.js +0 -1
  71. package/utils.d.ts +1 -0
  72. package/utils.js +5 -2
  73. package/components/tabs/Tab.svelte +0 -12
  74. package/components/tabs/TabPanel.svelte +0 -11
  75. package/components/tabs/TabPanel.svelte.d.ts +0 -20
  76. package/components/tabs/Tabs.svelte +0 -3
  77. package/components/tabs/Tabs.svelte.d.ts +0 -23
@@ -225,7 +225,7 @@ $: isGoogleSignin =
225
225
  {/if}
226
226
  <PageHeader title="Extra Params" primary={false} />
227
227
  {#if !manual && resource_type != ''}
228
- {#each extra_params as [k, v], i}
228
+ {#each extra_params as [k, v]}
229
229
  <div class="flex flex-row max-w-md">
230
230
  <input type="text" bind:value={k} />
231
231
  <input type="text" bind:value={v} />
@@ -1,5 +1,5 @@
1
- <div class="max-w-screen-lg flex grow w-full h-full xl:-ml-20 mr-2 lg:mr-0">
2
- <div class="grow w-full h-full mt-4">
1
+ <div class="py-6">
2
+ <div class="max-w-6xl mx-auto px-4 sm:px-6 md:px-8">
3
3
  <slot />
4
4
  </div>
5
5
  </div>
@@ -1,9 +1,8 @@
1
1
  <script>import { ResourceService, ScriptService, VariableService } from '../gen';
2
2
  import { getScriptByPath, loadHubScripts, sendUserToast } from '../utils';
3
- import { faSearch } from '@fortawesome/free-solid-svg-icons';
3
+ import { faCode, faCube, faFile, faRotate, faRotateLeft } from '@fortawesome/free-solid-svg-icons';
4
4
  import Icon from 'svelte-awesome';
5
5
  import { hubScripts, workspaceStore } from '../stores';
6
- import { Button } from 'flowbite-svelte';
7
6
  import { Highlight } from 'svelte-highlight';
8
7
  import { python, typescript } from 'svelte-highlight/languages';
9
8
  import ItemPicker from './ItemPicker.svelte';
@@ -157,55 +156,69 @@ async function loadScripts() {
157
156
  </ItemPicker>
158
157
 
159
158
  <ResourceEditor bind:this={resourceEditor} on:refresh={resourcePicker.openModal} />
160
-
161
159
  <VariableEditor bind:this={variableEditor} on:create={variablePicker.openModal} />
162
160
 
163
- <div class="flex flex-row w-full">
164
- <div class="flex flex-row w-full space-x-2 whitespace-nowrap">
165
- <Button
166
- size="xs"
167
- color="alternative"
161
+ <div class="flex divide-x items-center">
162
+ <div>
163
+ <button
164
+ type="button"
165
+ class="mr-1 bg-white rounded-md items-center flex hover:bg-gray-100 font-medium text-xs p-2"
168
166
  on:click={() => {
169
167
  variablePicker.openModal()
170
168
  }}
171
169
  >
172
- <Icon data={faSearch} scale={0.7} class="mr-2" />
173
- Variable picker
174
- </Button>
175
-
176
- <Button
177
- size="xs"
178
- color="alternative"
170
+ <Icon data={faFile} class="h-4 w-4 mr-2" />
171
+ Insert variable
172
+ </button>
173
+ </div>
174
+ <div>
175
+ <button
176
+ type="button"
177
+ class="mx-1 bg-white rounded-md items-center flex hover:bg-gray-100 font-medium text-xs p-2"
179
178
  on:click={() => {
180
179
  resourcePicker.openModal()
181
180
  }}
182
181
  >
183
- <Icon data={faSearch} scale={0.7} class="mr-2" />
184
- Resource picker
185
- </Button>
182
+ <Icon data={faCube} class="h-4 w-4 mr-2" />
183
+ Insert resource
184
+ </button>
185
+ </div>
186
186
 
187
- <Button
188
- size="xs"
189
- color="alternative"
187
+ <div>
188
+ <button
189
+ type="button"
190
+ class="mx-1 bg-white rounded-md items-center flex hover:bg-gray-100 font-medium text-xs p-2"
190
191
  on:click={() => {
191
192
  scriptPicker.openModal()
192
193
  }}
193
194
  >
194
- <Icon data={faSearch} scale={0.7} class="mr-2" />
195
- Script explorer
196
- </Button>
195
+ <Icon data={faCode} class="h-4 w-4 mr-2" />
196
+ Search script
197
+ </button>
197
198
  </div>
198
- <div class="flex flex-row-reverse gap-x-2 w-full">
199
- <Button
200
- size="xs"
201
- class={!websocketAlive.pyright && !websocketAlive.deno && !websocketAlive.black
202
- ? 'bg-red-50'
203
- : ''}
204
- color="alternative"
199
+
200
+ <div>
201
+ <button
202
+ type="button"
203
+ class="mx-1 bg-white rounded-md items-center flex hover:bg-gray-100 font-medium text-xs p-2"
204
+ on:click={() => {
205
+ editor.clearContent()
206
+ }}
207
+ >
208
+ <Icon data={faRotateLeft} class="h-4 w-4 mr-2" />
209
+ Reset content
210
+ </button>
211
+ </div>
212
+ <div>
213
+ <button
214
+ type="button"
215
+ class="ml-1 bg-white rounded-md items-center flex hover:bg-gray-100 font-medium text-xs p-2"
205
216
  on:click={() => {
206
217
  editor.reloadWebsocket()
207
218
  }}
208
219
  >
220
+ <Icon data={faRotate} class="h-4 w-4 mr-2" />
221
+
209
222
  Reload assistants
210
223
  <span class="ml-1">
211
224
  {#if lang == 'deno'}
@@ -216,13 +229,6 @@ async function loadScripts() {
216
229
  <span class={websocketAlive.black ? 'text-green-600' : 'text-red-700'}>Black</span>)
217
230
  {/if}
218
231
  </span>
219
- </Button>
220
- <Button
221
- size="xs"
222
- color="alternative"
223
- on:click={() => {
224
- editor.clearContent()
225
- }}>Reset content</Button
226
- >
232
+ </button>
227
233
  </div>
228
234
  </div>
@@ -1,6 +1,6 @@
1
1
  <script>import { goto } from '$app/navigation';
2
2
  import { page } from '$app/stores';
3
- import { FlowService, Job, ScheduleService } from '../gen';
3
+ import { FlowService, ScheduleService } from '../gen';
4
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';
@@ -8,7 +8,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
+ import Drawer from './common/drawer/Drawer.svelte';
12
12
  import FlowEditor from './FlowEditor.svelte';
13
13
  import FlowPreviewContent from './FlowPreviewContent.svelte';
14
14
  import { flowStateStore, flowStateToFlow } from './flows/flowState';
@@ -133,8 +133,8 @@ onDestroy(() => {
133
133
  });
134
134
  </script>
135
135
 
136
- <div class="flex flex-row w-full h-full justify-between">
137
- <div class={`flex flex-col mb-96 m-auto w-full sm:w-3/4 lg:w-2/3`}>
136
+ <div class="flex flex-row w-full h-full justify-between ">
137
+ <div class={`flex flex-col mb-96 m-auto w-full`}>
138
138
  <!-- Nav between steps-->
139
139
  <div class="justify-between flex flex-row w-full my-4">
140
140
  <Breadcrumb>
@@ -1,24 +1,23 @@
1
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;
2
+ import Tabs from './common/tabs/Tabs.svelte';
3
+ import Tab from './common/tabs/Tab.svelte';
4
+ import TabContent from './common/tabs/TabContent.svelte';
6
5
  export let job;
7
6
  </script>
8
7
 
9
8
  {#if job}
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>
23
- </div>
9
+ <Tabs selected="results">
10
+ <Tab value="results">Results</Tab>
11
+ <Tab value="logs">Logs</Tab>
12
+ <svelte:fragment slot="content">
13
+ <TabContent value="results" class="border p-2 h-36 overflow-y-scroll">
14
+ <DisplayResult result={job.result} />
15
+ </TabContent>
16
+ <TabContent value="logs" class="border p-2 h-36 overflow-y-scroll">
17
+ <div class="text-xs p-4 bg-gray-50 overflow-auto max-h-80 border">
18
+ <pre class="w-full">{job.logs}</pre>
19
+ </div>
20
+ </TabContent>
21
+ </svelte:fragment>
22
+ </Tabs>
24
23
  {/if}
@@ -0,0 +1,97 @@
1
+ <script>import { scriptPathToHref } from '../utils';
2
+ import Highlight from 'svelte-highlight';
3
+ import python from 'svelte-highlight/languages/python';
4
+ import typescript from 'svelte-highlight/languages/typescript';
5
+ import { slide } from 'svelte/transition';
6
+ import InputTransformsViewer from './InputTransformsViewer.svelte';
7
+ import IconedPath from './IconedPath.svelte';
8
+ export let modules;
9
+ let open = {};
10
+ </script>
11
+
12
+ <p class="font-black text-lg my-6 w-full">
13
+ <span>{modules?.length} Step{modules?.length > 1 ? 's' : ''} </span>
14
+ <span class="mt-4" />
15
+ </p>
16
+ <ul class="-mb-8 w-full">
17
+ {#each modules ?? [] as mod, i}
18
+ <li class="w-full">
19
+ <div class="relative pb-8 w-full">
20
+ {#if i < (modules ?? []).length - 1}
21
+ <span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true" />
22
+ {/if}
23
+ <div class="relative flex space-x-3">
24
+ <div>
25
+ <span
26
+ class="h-8 w-8 rounded-full bg-blue-600 flex items-center justify-center ring-8 ring-white text-white"
27
+ >{i + 1}
28
+ </span>
29
+ </div>
30
+ <div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4 w-full">
31
+ <div class="w-full">
32
+ <span class="text-black">{mod?.summary ?? ''}</span>
33
+ <p class="text-sm text-gray-500">
34
+ {#if mod?.value?.type == 'script'}
35
+ <a
36
+ target="_blank"
37
+ href={scriptPathToHref(mod?.value?.path ?? '')}
38
+ class="font-medium text-gray-900"
39
+ >
40
+ <IconedPath path={mod?.value?.path ?? ''} />
41
+ </a>
42
+ {#if mod?.value?.path?.startsWith('hub/')}
43
+ <div>
44
+ <button
45
+ on:click={async () => {
46
+ open[i] = !open[i]
47
+ }}
48
+ class="mb-2 underline text-black"
49
+ >
50
+ View code and inputs {open[i] ? '(-)' : '(+)'}</button
51
+ >
52
+ {#if open[i]}
53
+ <div class="border border-black p-2 bg-gray-50 divide-y">
54
+ <InputTransformsViewer inputTransforms={mod?.input_transforms} />
55
+ <div class="w-full h-full mt-6">
56
+ <iframe
57
+ style="height: 400px;"
58
+ class="w-full h-full text-sm"
59
+ title="embedded script from hub"
60
+ frameborder="0"
61
+ src="https://hub.windmill.dev/embed/script/{mod?.value?.path?.substring(
62
+ 4
63
+ )}"
64
+ />
65
+ </div>
66
+ </div>
67
+ {/if}
68
+ </div>
69
+ {/if}
70
+ {:else if mod?.value?.type == 'rawscript'}
71
+ <button on:click={() => (open[i] = !open[i])} class="mb-2 underline text-black">
72
+ Raw {mod?.value?.language} script {open[i] ? '(-)' : '(+)'}</button
73
+ >
74
+
75
+ {#if open[i]}
76
+ <div transition:slide class="border border-black p-2 bg-gray-50 w-full">
77
+ <InputTransformsViewer inputTransforms={mod?.input_transforms} />
78
+ <Highlight
79
+ language={mod?.value?.language == 'deno' ? typescript : python}
80
+ code={mod?.value?.content}
81
+ />
82
+ </div>
83
+ {/if}
84
+ {:else if mod?.value?.type == 'flow'}
85
+ Flow at path {mod?.value?.path}
86
+ {:else if mod?.value?.type == 'forloopflow'}
87
+ For loop over all the elements of the list returned as a result of step {i}:
88
+ <svelte:self modules={mod.value.modules} />
89
+ {/if}
90
+ </p>
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </li>
96
+ {/each}
97
+ </ul>
@@ -0,0 +1,17 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { FlowModule } from '../gen';
3
+ declare const __propDef: {
4
+ props: {
5
+ modules: FlowModule[];
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export declare type FlowModulesViewerProps = typeof __propDef.props;
13
+ export declare type FlowModulesViewerEvents = typeof __propDef.events;
14
+ export declare type FlowModulesViewerSlots = typeof __propDef.slots;
15
+ export default class FlowModulesViewer extends SvelteComponentTyped<FlowModulesViewerProps, FlowModulesViewerEvents, FlowModulesViewerSlots> {
16
+ }
17
+ export {};
@@ -1,14 +1,14 @@
1
- <script>import { workspaceStore } from '../stores';
2
- import { sendUserToast, truncateRev } from '../utils';
1
+ <script>import { sendUserToast, truncateRev } from '../utils';
3
2
  import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
4
- import { onDestroy } from 'svelte';
5
3
  import Icon from 'svelte-awesome';
6
4
  import { flowStateStore, flowStateToFlow } from './flows/flowState';
7
5
  import { mapJobResultsToFlowState } from './flows/flowStateUtils';
8
6
  import { runFlowPreview } from './flows/utils';
9
7
  import FlowStatusViewer from './FlowStatusViewer.svelte';
10
8
  import RunForm from './RunForm.svelte';
11
- import Tabs from './Tabs.svelte';
9
+ import Tab from './common/tabs/Tab.svelte';
10
+ import TabContent from './common/tabs/TabContent.svelte';
11
+ import Tabs from './common/tabs/Tabs.svelte';
12
12
  export let i;
13
13
  export let flow;
14
14
  export let schema;
@@ -37,14 +37,14 @@ function extractStep(flow) {
37
37
  return localFlow;
38
38
  }
39
39
  function setInputTransformFromArgs(flow, args) {
40
- let input_transform = {};
40
+ let input_transforms = {};
41
41
  Object.entries(args).forEach(([key, value]) => {
42
- input_transform[key] = {
42
+ input_transforms[key] = {
43
43
  type: 'static',
44
44
  value: value
45
45
  };
46
46
  });
47
- flow.value.modules[0].input_transform = input_transform;
47
+ flow.value.modules[0].input_transforms = input_transforms;
48
48
  return flow;
49
49
  }
50
50
  </script>
@@ -65,33 +65,34 @@ function setInputTransformFromArgs(flow, args) {
65
65
 
66
66
  {#if viewPreview}
67
67
  {#if i != flow.value.modules.length}
68
- <Tabs
69
- tabs={[
70
- ['upto', uptoText],
71
- ['justthis', 'preview just this step']
72
- ]}
73
- bind:tab
74
- />
75
- {/if}
76
- <div class="my-2" />
77
- {#if tab == 'upto'}
78
- <RunForm
79
- runnable={truncateFlow(flow)}
80
- runAction={(_, args) => runPreview(args)}
81
- schedulable={false}
82
- buttonText={uptoText}
83
- detailed={false}
84
- bind:args
85
- />
86
- {:else}
87
- <RunForm
88
- runnable={extractStep(flow)}
89
- runAction={(_, args) => runPreview(args)}
90
- schedulable={false}
91
- buttonText="Preview just this step"
92
- detailed={false}
93
- args={stepArgs}
94
- />
68
+ <div class="mt-2">
69
+ <Tabs bind:selected={tab}>
70
+ <Tab value="upto">{uptoText}</Tab>
71
+ <Tab value="justthis">Preview just this step</Tab>
72
+ <svelte:fragment slot="content">
73
+ <TabContent value="upto">
74
+ <RunForm
75
+ runnable={truncateFlow(flow)}
76
+ runAction={(_, args) => runPreview(args)}
77
+ schedulable={false}
78
+ buttonText={uptoText}
79
+ detailed={false}
80
+ bind:args
81
+ />
82
+ </TabContent>
83
+ <TabContent value="justthis">
84
+ <RunForm
85
+ runnable={extractStep(flow)}
86
+ runAction={(_, args) => runPreview(args)}
87
+ schedulable={false}
88
+ buttonText="Preview just this step"
89
+ detailed={false}
90
+ args={stepArgs}
91
+ />
92
+ </TabContent>
93
+ </svelte:fragment>
94
+ </Tabs>
95
+ </div>
95
96
  {/if}
96
97
 
97
98
  {#if jobId}
@@ -72,7 +72,10 @@ onDestroy(() => {
72
72
  {#if jobId}
73
73
  <FlowStatusViewer
74
74
  {jobId}
75
- on:jobsLoaded={(e) => mapJobResultsToFlowState(e.detail, 'upto', steps - 1)}
75
+ on:jobsLoaded={(e) => {
76
+ intervalState = 'done'
77
+ mapJobResultsToFlowState(e.detail, 'upto', steps - 1)
78
+ }}
76
79
  root={true}
77
80
  />
78
81
  {/if}
@@ -1,14 +1,12 @@
1
- <script>import { scriptPathToHref } from '../utils';
2
- import { Job, JobService } from '../gen';
3
- import { arePreviewsReady, workspaceStore } from '../stores';
1
+ <script>import { JobService } from '../gen';
2
+ import { workspaceStore } from '../stores';
4
3
  import FlowJobResult from './FlowJobResult.svelte';
5
- import IconedPath from './IconedPath.svelte';
6
4
  import FlowPreviewStatus from './preview/FlowPreviewStatus.svelte';
7
5
  import { Button } from 'flowbite-svelte';
8
6
  import Icon from 'svelte-awesome';
9
7
  import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
10
- import ProgressBar from './ProgressBar.svelte';
11
8
  import { createEventDispatcher } from 'svelte';
9
+ import { onDestroy } from 'svelte';
12
10
  const dispatch = createEventDispatcher();
13
11
  export let jobId;
14
12
  export let root = false;
@@ -19,20 +17,7 @@ export let jobResult = {
19
17
  loopJobs: []
20
18
  };
21
19
  let forloop_selected = '';
22
- let isReadyIndex = $arePreviewsReady.push(false);
23
- function shouldReset() {
24
- if (jobId != lastJobid) {
25
- lastJobid = jobId;
26
- jobResult = {
27
- job: undefined,
28
- innerJobs: [],
29
- loopJobs: []
30
- };
31
- loadJobInProgress();
32
- }
33
- }
34
- let lastJobid = jobId;
35
- $: jobId && shouldReset();
20
+ let timeout;
36
21
  async function loadJobInProgress() {
37
22
  const job = await JobService.getJob({
38
23
  workspace: $workspaceStore ?? '',
@@ -40,44 +25,41 @@ async function loadJobInProgress() {
40
25
  });
41
26
  jobResult.job = job;
42
27
  jobResult = jobResult;
43
- if (job.type === 'CompletedJob') {
44
- arePreviewsReady.update((isReady) => {
45
- isReady[isReadyIndex - 1] = true;
46
- return isReady;
47
- });
28
+ if (job?.type !== 'CompletedJob') {
29
+ timeout = setTimeout(() => loadJobInProgress(), 500);
48
30
  }
49
- else {
50
- setTimeout(() => loadJobInProgress(), 500);
31
+ else if (root) {
32
+ dispatch('jobsLoaded', jobResult);
51
33
  }
52
34
  }
53
- $: {
54
- if (root) {
55
- if ($arePreviewsReady.every(Boolean) && !(hasModules && $arePreviewsReady.length === 1)) {
56
- arePreviewsReady.update(() => []);
57
- dispatch('jobsLoaded', jobResult);
58
- }
35
+ $: hasModules =
36
+ jobResult.job &&
37
+ Array.isArray(jobResult.job?.raw_flow?.modules) &&
38
+ jobResult.job?.raw_flow?.modules.length > 1;
39
+ function updateJobId() {
40
+ if (jobId !== jobResult.job?.id) {
41
+ loadJobInProgress();
59
42
  }
60
43
  }
61
- $: job = jobResult.job;
62
- $: innerJobs = jobResult.innerJobs;
63
- $: loopJobs = jobResult.loopJobs;
64
- $: hasModules = job && Array.isArray(job?.raw_flow?.modules) && job?.raw_flow?.modules.length > 1;
65
- $: loadJobInProgress();
44
+ $: jobId && updateJobId();
45
+ onDestroy(() => {
46
+ timeout && clearTimeout(timeout);
47
+ });
66
48
  </script>
67
49
 
68
- {#if job}
50
+ {#if jobResult.job}
69
51
  <div class="flow-root w-full space-y-4">
70
52
  <h3 class="text-md leading-6 font-bold text-gray-900 border-b pb-2">Preview results</h3>
71
- <FlowPreviewStatus {job} />
72
- {#if `result` in job}
73
- <FlowJobResult {job} />
74
- {:else if job.logs}
53
+ <FlowPreviewStatus job={jobResult.job} />
54
+ {#if `result` in jobResult.job}
55
+ <FlowJobResult job={jobResult.job} />
56
+ {:else if jobResult.job.logs}
75
57
  <div class="text-xs p-4 bg-gray-50 overflow-auto max-h-80 border">
76
- <pre class="w-full">{job.logs}</pre>
58
+ <pre class="w-full">{jobResult.job.logs}</pre>
77
59
  </div>
78
60
  {/if}
79
61
 
80
- {#if Array.isArray(forloopJobIds) && forloopJobIds?.length > 0 && Array.isArray(loopJobs)}
62
+ {#if Array.isArray(forloopJobIds) && forloopJobIds?.length > 0 && Array.isArray(jobResult.loopJobs)}
81
63
  <h3 class="text-md leading-6 font-bold text-gray-900 border-b mb-4">
82
64
  Loop results ({forloopJobIds.length} items)
83
65
  </h3>
@@ -102,27 +84,27 @@ $: loadJobInProgress();
102
84
  />
103
85
  </Button>
104
86
  <div class="border p-6" class:hidden={forloop_selected != loopJobId}>
105
- <svelte:self jobId={loopJobId} bind:jobResult={loopJobs[j]} />
87
+ <svelte:self jobId={loopJobId} bind:jobResult={jobResult.loopJobs[j]} />
106
88
  </div>
107
89
  {/each}
108
- {:else if hasModules && Array.isArray(innerJobs)}
90
+ {:else if hasModules && Array.isArray(jobResult.innerJobs)}
109
91
  <ul class="w-full">
110
92
  <h3 class="text-md leading-6 font-bold text-gray-900 border-b mb-4 py-2">
111
93
  Detailed results
112
94
  </h3>
113
95
 
114
- {#each job?.flow_status?.modules ?? [] as module, i}
96
+ {#each jobResult.job?.flow_status?.modules ?? [] as module, i}
115
97
  <p class="text-gray-500 mb-6 w-full ">
116
98
  Step
117
99
  <span class="font-medium text-gray-900"> {i + 1} </span> out of
118
- <span class="font-medium text-gray-900">{job?.raw_flow?.modules.length}</span>
100
+ <span class="font-medium text-gray-900">{jobResult.job?.raw_flow?.modules.length}</span>
119
101
  </p>
120
102
 
121
103
  {#if ['InProgress', 'Success', 'Error'].includes(module.type)}
122
104
  <li class="w-full border p-6 space-y-2">
123
105
  <svelte:self
124
106
  jobId={module.job}
125
- bind:jobResult={innerJobs[i]}
107
+ bind:jobResult={jobResult.innerJobs[i]}
126
108
  forloopJobIds={module.forloop_jobs}
127
109
  />
128
110
  </li>