windmill-components 1.389.3 → 1.394.3

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 (158) hide show
  1. package/package/assets/app.css +4 -3
  2. package/package/components/AppConnectInner.svelte +18 -10
  3. package/package/components/ArgInfo.svelte +1 -1
  4. package/package/components/ArgInput.svelte +22 -2
  5. package/package/components/AutheliaSetting.svelte +1 -0
  6. package/package/components/AuthentikSetting.svelte +1 -0
  7. package/package/components/BoundedInputNumber +0 -0
  8. package/package/components/CliHelpBox.svelte +2 -2
  9. package/package/components/DateInput.svelte +1 -0
  10. package/package/components/DisplayResult.svelte +39 -31
  11. package/package/components/Editor.svelte +0 -21
  12. package/package/components/ErrorOrRecoveryHandler.svelte +7 -1
  13. package/package/components/ErrorOrRecoveryHandler.svelte.d.ts +1 -1
  14. package/package/components/FlowBuilder.svelte +2 -2
  15. package/package/components/FlowGraphViewerStep.svelte +22 -0
  16. package/package/components/FlowJobResult.svelte +1 -0
  17. package/package/components/FlowMetadata.svelte +3 -2
  18. package/package/components/FlowStatusViewer.svelte +2 -0
  19. package/package/components/FlowStatusViewer.svelte.d.ts +2 -0
  20. package/package/components/FlowStatusViewerInner.svelte +10 -5
  21. package/package/components/FlowStatusViewerInner.svelte.d.ts +1 -0
  22. package/package/components/FolderEditor.svelte +1 -1
  23. package/package/components/IdEditorInput.svelte +82 -0
  24. package/package/components/IdEditorInput.svelte.d.ts +26 -0
  25. package/package/components/InputTransformForm.svelte +10 -10
  26. package/package/components/InputTransformForm.svelte.d.ts +4 -1
  27. package/package/components/InputTransformSchemaForm.svelte.d.ts +3 -1
  28. package/package/components/InstanceSettings.svelte +73 -12
  29. package/package/components/ItemPicker.svelte +1 -0
  30. package/package/components/KanidmSetting.svelte +1 -0
  31. package/package/components/KeycloakSetting.svelte +1 -0
  32. package/package/components/LightweightArgInput.svelte +2 -0
  33. package/package/components/LogViewer.svelte +206 -0
  34. package/package/components/ModulePreview.svelte.d.ts +3 -1
  35. package/package/components/ModulePreviewForm.svelte +2 -2
  36. package/package/components/ModulePreviewForm.svelte.d.ts +4 -1
  37. package/package/components/OAuthSetting.svelte +11 -10
  38. package/package/components/ObjectStoreConfigSettings.svelte +6 -6
  39. package/package/components/OktaSetting.svelte +1 -0
  40. package/package/components/Password.svelte +30 -35
  41. package/package/components/RunChart.svelte +16 -0
  42. package/package/components/RunChart.svelte.d.ts +2 -0
  43. package/package/components/SavedInputs.svelte +4 -4
  44. package/package/components/ScheduleEditorInner.svelte +145 -2
  45. package/package/components/SchemaForm.svelte +1 -2
  46. package/package/components/ScriptBuilder.svelte +1 -0
  47. package/package/components/TestConnection.svelte +24 -6
  48. package/package/components/TestJobLoader.svelte +2 -0
  49. package/package/components/ZitadelSetting.svelte +1 -0
  50. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte +0 -1
  51. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte.d.ts +1 -2
  52. package/package/components/apps/components/display/table/AppAggridInfiniteTableEe.svelte +0 -2
  53. package/package/components/apps/components/display/table/AppAggridInfiniteTableEe.svelte.d.ts +1 -2
  54. package/package/components/apps/components/display/table/AppAggridTable.svelte +6 -2
  55. package/package/components/apps/components/inputs/AppSelect.svelte +18 -17
  56. package/package/components/apps/editor/AppEditor.svelte +1 -1
  57. package/package/components/apps/editor/AppPreview.svelte +3 -6
  58. package/package/components/apps/editor/AppReportsDrawer.svelte +17 -5
  59. package/package/components/apps/editor/DeploymentHistory.svelte +1 -0
  60. package/package/components/apps/editor/component/Component.svelte +0 -2
  61. package/package/components/apps/editor/componentsPanel/themeUtils.js +18 -7
  62. package/package/components/apps/editor/contextPanel/SubGridOutput.svelte +1 -0
  63. package/package/components/apps/editor/contextPanel/components/IdEditor.svelte +13 -67
  64. package/package/components/apps/editor/contextPanel/components/IdEditor.svelte.d.ts +1 -2
  65. package/package/components/apps/editor/settingsPanel/ComponentPanel.svelte +0 -1
  66. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphEditor.svelte +0 -1
  67. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphEditor.svelte.d.ts +0 -1
  68. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphNode.svelte +1 -1
  69. package/package/components/apps/editor/settingsPanel/decisionTree/InsertDecisionTreeNode.svelte +2 -2
  70. package/package/components/apps/editor/settingsPanel/inputEditor/IconSelectInput.svelte +1 -0
  71. package/package/components/apps/svelte-select/lib/Select.svelte +1 -0
  72. package/package/components/build_workers.js +24 -18
  73. package/package/components/common/button/Button.svelte +3 -4
  74. package/package/components/common/button/model.d.ts +1 -1
  75. package/package/components/common/button/model.js +6 -0
  76. package/package/components/common/clearableInput/ClearableInput.svelte +1 -0
  77. package/package/components/common/menu/MenuItem.svelte +1 -0
  78. package/package/components/common/modal/AlwaysMountedModal.svelte +1 -0
  79. package/package/components/common/stepper/Stepper.svelte +1 -0
  80. package/package/components/copilot/StepInputsGen.svelte +2 -2
  81. package/package/components/copilot/StepInputsGen.svelte.d.ts +3 -1
  82. package/package/components/copilot/lib.js +2 -2
  83. package/package/components/details/ClipboardPanel.svelte +1 -0
  84. package/package/components/flows/content/DynamicInputHelpBox.svelte +4 -1
  85. package/package/components/flows/content/FlowConstants.svelte +3 -3
  86. package/package/components/flows/content/FlowEditorPanel.svelte +1 -1
  87. package/package/components/flows/content/FlowModuleComponent.svelte +2 -2
  88. package/package/components/flows/content/FlowModuleHeader.svelte +5 -45
  89. package/package/components/flows/content/FlowModuleWorkerTagSelect.svelte +47 -0
  90. package/package/components/flows/content/FlowModuleWorkerTagSelect.svelte.d.ts +16 -0
  91. package/package/components/flows/content/FlowSettings.svelte +1 -0
  92. package/package/components/flows/flowModuleNextId.js +1 -1
  93. package/package/components/flows/flowState.d.ts +1 -1
  94. package/package/components/flows/flowStateUtils.d.ts +1 -1
  95. package/package/components/flows/flowStateUtils.js +1 -1
  96. package/package/components/flows/flowStore.d.ts +1 -0
  97. package/package/components/flows/flowStore.js +5 -0
  98. package/package/components/flows/map/FlowJobsMenu.svelte +0 -1
  99. package/package/components/flows/map/FlowJobsMenu.svelte.d.ts +0 -1
  100. package/package/components/flows/map/FlowModuleSchemaItem.svelte +103 -19
  101. package/package/components/flows/map/FlowModuleSchemaItem.svelte.d.ts +1 -0
  102. package/package/components/flows/map/FlowModuleSchemaMap.svelte +31 -1
  103. package/package/components/flows/map/InsertModuleButton.svelte +5 -5
  104. package/package/components/flows/map/InsertTriggerButton.svelte +2 -2
  105. package/package/components/flows/map/MapItem.svelte +4 -0
  106. package/package/components/flows/map/MapItem.svelte.d.ts +1 -0
  107. package/package/components/flows/map/VirtualItem.svelte +15 -7
  108. package/package/components/flows/map/VirtualItem.svelte.d.ts +2 -1
  109. package/package/components/flows/previousResults.js +1 -1
  110. package/package/components/flows/utils.d.ts +3 -3
  111. package/package/components/flows/utils.js +2 -2
  112. package/package/components/graph/FlowGraphV2.svelte +4 -0
  113. package/package/components/graph/FlowGraphV2.svelte.d.ts +1 -0
  114. package/package/components/graph/graphBuilder.d.ts +1 -0
  115. package/package/components/graph/graphBuilder.js +2 -4
  116. package/package/components/graph/renderers/edges/BaseEdge.svelte +2 -2
  117. package/package/components/graph/renderers/nodes/BranchAllStart.svelte +2 -1
  118. package/package/components/graph/renderers/nodes/BranchOneStart.svelte +3 -3
  119. package/package/components/graph/renderers/nodes/BranchOneStart.svelte.d.ts +1 -0
  120. package/package/components/graph/renderers/nodes/InputNode.svelte +2 -2
  121. package/package/components/graph/renderers/nodes/ModuleNode.svelte +6 -2
  122. package/package/components/graph/util.d.ts +1 -1
  123. package/package/components/graph/util.js +7 -2
  124. package/package/components/icons/AzureIcon.svelte +1 -1
  125. package/package/components/icons/FunkwhaleIcon.svelte +1 -19
  126. package/package/components/icons/JumpCloudIcon.svelte +12 -0
  127. package/package/components/icons/JumpCloudIcon.svelte.d.ts +17 -0
  128. package/package/components/icons/KeycloakIcon.svelte +20 -0
  129. package/package/components/icons/KeycloakIcon.svelte.d.ts +17 -0
  130. package/package/components/icons/MailchimpIcon.svelte +1 -1
  131. package/package/components/icons/ZitadelIcon.svelte +76 -0
  132. package/package/components/icons/ZitadelIcon.svelte.d.ts +17 -0
  133. package/package/components/icons/index.d.ts +7 -1
  134. package/package/components/icons/index.js +8 -2
  135. package/package/components/instanceSettings.d.ts +1 -1
  136. package/package/components/instanceSettings.js +24 -15
  137. package/package/components/runs/JobLoader.svelte +17 -6
  138. package/package/components/runs/JobLoader.svelte.d.ts +2 -0
  139. package/package/components/runs/RunRow.svelte +7 -7
  140. package/package/components/runs/RunsFilter.svelte +8 -1
  141. package/package/components/runs/RunsTable.svelte +30 -8
  142. package/package/components/runs/RunsTable.svelte.d.ts +2 -0
  143. package/package/components/schema/PropertyEditor.svelte +0 -5
  144. package/package/components/settings/WorkspaceUserSettings.svelte +1 -1
  145. package/package/components/sidebar/MenuLink.svelte +2 -1
  146. package/package/components/sidebar/WorkspaceMenu.svelte +4 -1
  147. package/package/components/sidebar/changelogs.js +30 -0
  148. package/package/components/tutorials/FlowBuilderTutorialsForLoop.svelte +2 -2
  149. package/package/gen/core/OpenAPI.js +1 -1
  150. package/package/gen/schemas.gen.d.ts +21 -0
  151. package/package/gen/schemas.gen.js +21 -0
  152. package/package/gen/services.gen.d.ts +11 -12
  153. package/package/gen/services.gen.js +19 -24
  154. package/package/gen/types.gen.d.ts +62 -37
  155. package/package/hub.d.ts +1 -0
  156. package/package/hubPaths.json +11 -8
  157. package/package.json +4 -4
  158. package/package/windmill_fetch.d.ts.txt +0 -16966
@@ -12,9 +12,10 @@
12
12
 
13
13
  /* Chrome, Edge, and Safari */
14
14
  *::-webkit-scrollbar {
15
- width: 3px;
16
- height: 3px;
15
+ width: 5px;
16
+ height: 5px;
17
17
  }
18
+
18
19
  /*
19
20
  *::-webkit-scrollbar-track {
20
21
  @apply bg-tertiary;
@@ -23,7 +24,7 @@
23
24
 
24
25
  *::-webkit-scrollbar-thumb {
25
26
  @apply bg-tertiary-inverse dark:bg-tertiary;
26
- border-radius: 10px;
27
+ border-radius: 3px;
27
28
  }
28
29
 
29
30
  @font-face {
@@ -39,14 +39,18 @@ let connects = undefined;
39
39
  let connectsManual = undefined;
40
40
  let args = {};
41
41
  let renderDescription = true;
42
- $: linkedSecretCandidates = apiTokenApps[resourceType]?.linkedSecret
43
- ? [apiTokenApps[resourceType]?.linkedSecret]
44
- : args != undefined
45
- ? Object.keys(args).filter((x) => ['token', 'secret', 'key', 'pass', 'private'].some((y) => x.toLowerCase().includes(y)))
46
- : undefined;
47
- $: linkedSecret =
48
- forceSecretValue(resourceType) ??
49
- linkedSecretCandidates?.sort((ua, ub) => linkedSecretValue(ub) - linkedSecretValue(ua))?.[0];
42
+ function computeCandidates(resourceType, argsKeys) {
43
+ return apiTokenApps[resourceType]?.linkedSecret
44
+ ? [apiTokenApps[resourceType]?.linkedSecret]
45
+ : argsKeys.filter((x) => ['token', 'secret', 'key', 'pass', 'private'].some((y) => x.toLowerCase().includes(y)));
46
+ }
47
+ let linkedSecret = undefined;
48
+ let linkedSecretCandidates = undefined;
49
+ function computeLinkedSecret(resourceType, argsKeys) {
50
+ linkedSecretCandidates = computeCandidates(resourceType, argsKeys);
51
+ return (forceSecretValue(resourceType) ??
52
+ linkedSecretCandidates?.sort((ua, ub) => linkedSecretValue(ub) - linkedSecretValue(ua))?.[0]);
53
+ }
50
54
  let scopes = [];
51
55
  let extra_params = [];
52
56
  let path;
@@ -162,9 +166,14 @@ async function getResourceTypeInfo() {
162
166
  workspace: $workspaceStore,
163
167
  path: resourceType
164
168
  });
169
+ const newArgsKeys = Object.keys(resourceTypeInfo?.schema?.['properties'] ?? {}) ?? [];
170
+ if (!linkedSecret) {
171
+ linkedSecret = computeLinkedSecret(resourceType, newArgsKeys);
172
+ }
165
173
  }
166
174
  export async function next() {
167
175
  if (step == 1) {
176
+ linkedSecret = undefined;
168
177
  if (manual) {
169
178
  getResourceTypeInfo();
170
179
  args = {};
@@ -290,7 +299,6 @@ let editScopes = false;
290
299
  bind:filteredItems={filteredConnectsManual}
291
300
  f={(x) => x[0]}
292
301
  />
293
-
294
302
  {#if step == 1}
295
303
  <div class="w-12/12 pb-2 flex flex-row my-1 gap-1">
296
304
  <input
@@ -456,7 +464,7 @@ let editScopes = false;
456
464
  <div class="mt-12">
457
465
  {#key resourceTypeInfo}
458
466
  <ApiConnectForm
459
- {linkedSecret}
467
+ bind:linkedSecret
460
468
  {linkedSecretCandidates}
461
469
  {resourceType}
462
470
  {resourceTypeInfo}
@@ -48,7 +48,7 @@ async function getVariable(path) {
48
48
 
49
49
  {#if value == undefined || value == null}
50
50
  <span class="text-tertiary">null</span>
51
- {:else if value == '<function call>'}
51
+ {:else if value === '<function call>'}
52
52
  {'<function call>'}<Tooltip
53
53
  >The arg was none and the default argument of the script is a function call, hence the actual
54
54
  value used for this arg was the output of the script's function call for this arg</Tooltip
@@ -174,7 +174,23 @@ function validateInput(pattern, v, required) {
174
174
  valid && (valid = false);
175
175
  }
176
176
  else {
177
- if (pattern && !testRegex(pattern, v)) {
177
+ if (inputCat == 'number' && typeof v === 'number') {
178
+ let min = extra['min'];
179
+ let max = extra['max'];
180
+ if (min != undefined && typeof min == 'number' && v < min) {
181
+ error = `Should be greater than or equal to ${min}`;
182
+ valid && (valid = false);
183
+ }
184
+ else if (max != undefined && typeof max == 'number' && v > max) {
185
+ error = `Should be less than or equal to ${max}`;
186
+ valid && (valid = false);
187
+ }
188
+ else {
189
+ error = '';
190
+ !valid && (valid = true);
191
+ }
192
+ }
193
+ else if (pattern && !testRegex(pattern, v)) {
178
194
  if (!emptyString(customErrorMessage)) {
179
195
  error = customErrorMessage ?? '';
180
196
  }
@@ -773,7 +789,9 @@ $: shouldDispatchChanges && debounced(value);
773
789
  <div class="flex flex-col w-full">
774
790
  <div class="flex flex-row w-full items-center justify-between relative">
775
791
  {#if password || extra?.['password'] == true}
776
- {#if onlyMaskPassword}
792
+ {#if value && typeof value == 'string' && value?.startsWith('$var:')}
793
+ <input type="text" bind:value />
794
+ {:else if onlyMaskPassword}
777
795
  <Password
778
796
  {disabled}
779
797
  bind:password={value}
@@ -862,4 +880,6 @@ $: shouldDispatchChanges && debounced(value);
862
880
  /* Firefox */
863
881
  input[type='number'] {
864
882
  -moz-appearance: textfield !important;
883
+ -webkit-appearance: textfield !important;
884
+ appearance: textfield !important;
865
885
  }</style>
@@ -25,6 +25,7 @@ function changeOrg(org) {
25
25
  </script>
26
26
 
27
27
  <div class="flex flex-col gap-1">
28
+ <!-- svelte-ignore a11y-label-has-associated-control -->
28
29
  <label class="text-sm font-medium text-primary flex gap-4 items-center"
29
30
  ><div class="w-[120px]"><IconedResourceType name={'authelia'} after={true} /></div><Toggle
30
31
  checked={enabled}
@@ -25,6 +25,7 @@ function changeOrg(org) {
25
25
  </script>
26
26
 
27
27
  <div class="flex flex-col gap-1">
28
+ <!-- svelte-ignore a11y-label-has-associated-control -->
28
29
  <label class="text-sm font-medium text-primary flex gap-4 items-center"
29
30
  ><div class="w-[120px]"><IconedResourceType name={'authentik'} after={true} /></div><Toggle
30
31
  checked={enabled}
File without changes
@@ -9,8 +9,8 @@ $: url = `${$page.url.protocol}//${$page.url.hostname}/`;
9
9
  <div class="text-sm" role="alert" id="dynamic-input-help-box">
10
10
  <ul class="pl-0 pt-2 list-decimal list-inside flex flex-col gap-2">
11
11
  <li>
12
- Install the latest wmill CLI from deno.land:
13
- <ClipboardPanel content={'deno install -q -A https://deno.land/x/wmill/main.ts'} />
12
+ Install the latest wmill CLI from npm:
13
+ <ClipboardPanel content={'npm install -g windmill-cli'} />
14
14
  </li>
15
15
 
16
16
  <li>
@@ -58,6 +58,7 @@ let randomId = 'datetarget-' + Math.random().toString(36).substring(7);
58
58
  </script>
59
59
 
60
60
  <div class="flex flex-row gap-1 items-center w-full" id={randomId} on:pointerdown on:focus>
61
+ <!-- svelte-ignore a11y-autofocus -->
61
62
  <input
62
63
  type="date"
63
64
  bind:value={date}
@@ -69,7 +69,7 @@ let is_render_all = false;
69
69
  let download_as_csv = false;
70
70
  function inferResultKind(result) {
71
71
  try {
72
- if (result == 'WINDMILL_TOO_BIG') {
72
+ if (result === 'WINDMILL_TOO_BIG') {
73
73
  largeObject = true;
74
74
  return 'json';
75
75
  }
@@ -86,7 +86,7 @@ function inferResultKind(result) {
86
86
  return 'plain';
87
87
  }
88
88
  try {
89
- let keys = result && typeof result == 'object' ? Object.keys(result) : [];
89
+ let keys = result && typeof result === 'object' ? Object.keys(result) : [];
90
90
  is_render_all =
91
91
  keys.length == 1 && keys.includes('render_all') && Array.isArray(result['render_all']);
92
92
  // Check if the result is an image
@@ -136,20 +136,20 @@ function inferResultKind(result) {
136
136
  return 'json';
137
137
  }
138
138
  if (keys.length != 0) {
139
- if (keys.length == 1 && keys[0] == 'html') {
139
+ if (keys.length == 1 && keys[0] === 'html') {
140
140
  return 'html';
141
141
  }
142
- else if (keys.length == 1 && keys[0] == 'map') {
142
+ else if (keys.length == 1 && keys[0] === 'map') {
143
143
  return 'map';
144
144
  }
145
- else if (keys.length == 1 && keys[0] == 'file') {
145
+ else if (keys.length == 1 && keys[0] === 'file') {
146
146
  return 'file';
147
147
  }
148
148
  else if (keys.includes('windmill_content_type') &&
149
149
  result['windmill_content_type'].startsWith('text/')) {
150
150
  return 'plain';
151
151
  }
152
- else if (keys.length == 1 && keys[0] == 'error') {
152
+ else if (keys.length == 1 && keys[0] === 'error') {
153
153
  return 'error';
154
154
  }
155
155
  else if (keys.length === 2 && keys.includes('file') && keys.includes('filename')) {
@@ -203,11 +203,17 @@ function toJsonStr(result) {
203
203
  }
204
204
  }
205
205
  function contentOrRootString(obj) {
206
+ if (obj == undefined || obj == null) {
207
+ return '';
208
+ }
206
209
  if (typeof obj === 'string') {
207
210
  return obj;
208
211
  }
212
+ else if (typeof obj === 'object') {
213
+ return obj?.['content'];
214
+ }
209
215
  else {
210
- return obj.content;
216
+ return '';
211
217
  }
212
218
  }
213
219
  function handleArrayOfObjectsHeaders(json) {
@@ -308,7 +314,7 @@ let seeS3PreviewFileFromList = '';
308
314
  />
309
315
  {/each}</div
310
316
  >
311
- {:else if resultKind == 'nondisplayable'}<div class="text-red-400">Non displayable object</div
317
+ {:else if resultKind === 'nondisplayable'}<div class="text-red-400">Non displayable object</div
312
318
  >{:else}<div
313
319
  class="inline-highlight relative grow {['plain', 'markdown'].includes(resultKind ?? '')
314
320
  ? ''
@@ -366,16 +372,16 @@ let seeS3PreviewFileFromList = '';
366
372
  {/if}
367
373
  </div>
368
374
  </div><div class="grow"
369
- >{#if !forceJson && resultKind == 'table-col'}
375
+ >{#if !forceJson && resultKind === 'table-col'}
370
376
  {@const data = 'table-col' in result ? result['table-col'] : result}
371
377
  <AutoDataTable objects={objectOfArraysToObjects(data)} />
372
- {:else if !forceJson && resultKind == 'table-row'}
378
+ {:else if !forceJson && resultKind === 'table-row'}
373
379
  {@const data = 'table-row' in result ? result['table-row'] : result}
374
380
  <AutoDataTable objects={arrayOfRowsToObjects(data)} />
375
- {:else if !forceJson && resultKind == 'table-row-object'}
381
+ {:else if !forceJson && resultKind === 'table-row-object'}
376
382
  {@const data = 'table-row-object' in result ? result['table-row-object'] : result}
377
383
  <AutoDataTable objects={handleArrayOfObjectsHeaders(data)} />
378
- {:else if !forceJson && resultKind == 'html'}
384
+ {:else if !forceJson && resultKind === 'html'}
379
385
  <div class="h-full">
380
386
  {#if !requireHtmlApproval || enableHtml}
381
387
  {@html result.html}
@@ -403,7 +409,7 @@ let seeS3PreviewFileFromList = '';
403
409
  </div>
404
410
  {/if}
405
411
  </div>
406
- {:else if !forceJson && resultKind == 'map'}
412
+ {:else if !forceJson && resultKind === 'map'}
407
413
  <div class="h-full">
408
414
  <MapResult
409
415
  lat={result.map.lat}
@@ -412,7 +418,7 @@ let seeS3PreviewFileFromList = '';
412
418
  markers={result.map.markers}
413
419
  />
414
420
  </div>
415
- {:else if !forceJson && resultKind == 'png'}
421
+ {:else if !forceJson && resultKind === 'png'}
416
422
  <div class="h-full">
417
423
  <img
418
424
  alt="png rendered"
@@ -420,7 +426,7 @@ let seeS3PreviewFileFromList = '';
420
426
  src="data:image/png;base64,{contentOrRootString(result.png)}"
421
427
  />
422
428
  </div>
423
- {:else if !forceJson && resultKind == 'jpeg'}
429
+ {:else if !forceJson && resultKind === 'jpeg'}
424
430
  <div class="h-full">
425
431
  <img
426
432
  alt="jpeg rendered"
@@ -428,13 +434,13 @@ let seeS3PreviewFileFromList = '';
428
434
  src="data:image/jpeg;base64,{contentOrRootString(result.jpeg)}"
429
435
  />
430
436
  </div>
431
- {:else if !forceJson && resultKind == 'svg'}
437
+ {:else if !forceJson && resultKind === 'svg'}
432
438
  <div
433
439
  ><a download="windmill.svg" href="data:text/plain;base64,{btoa(result.svg)}">Download</a
434
440
  >
435
441
  </div>
436
442
  <div class="h-full overflow-auto">{@html result.svg} </div>
437
- {:else if !forceJson && resultKind == 'gif'}
443
+ {:else if !forceJson && resultKind === 'gif'}
438
444
  <div class="h-full">
439
445
  <img
440
446
  alt="gif rendered"
@@ -442,12 +448,12 @@ let seeS3PreviewFileFromList = '';
442
448
  src="data:image/gif;base64,{contentOrRootString(result.gif)}"
443
449
  />
444
450
  </div>
445
- {:else if !forceJson && resultKind == 'plain'}<div class="h-full text-2xs"
446
- ><pre>{typeof result == 'string' ? result : result?.['result']}</pre>{#if !noControls}
451
+ {:else if !forceJson && resultKind === 'plain'}<div class="h-full text-2xs"
452
+ ><pre>{typeof result === 'string' ? result : result?.['result']}</pre>{#if !noControls}
447
453
  <div class="flex">
448
454
  <Button
449
455
  on:click={() =>
450
- copyToClipboard(typeof result == 'string' ? result : result?.['result'])}
456
+ copyToClipboard(typeof result === 'string' ? result : result?.['result'])}
451
457
  color="light"
452
458
  size="xs"
453
459
  >
@@ -456,7 +462,7 @@ let seeS3PreviewFileFromList = '';
456
462
  </div>
457
463
  {/if}
458
464
  </div>
459
- {:else if !forceJson && resultKind == 'file'}
465
+ {:else if !forceJson && resultKind === 'file'}
460
466
  <div>
461
467
  <a
462
468
  download={result.filename ?? result.file?.filename ?? 'windmill.file'}
@@ -464,7 +470,7 @@ let seeS3PreviewFileFromList = '';
464
470
  >Download</a
465
471
  >
466
472
  </div>
467
- {:else if !forceJson && resultKind == 'error' && result?.error}
473
+ {:else if !forceJson && resultKind === 'error' && result?.error}
468
474
  <div class="flex flex-col items-start">
469
475
  <span class="text-red-500 pt-2 font-semibold !text-xs whitespace-pre-wrap"
470
476
  >{#if result.error.name || result.error.message}{result.error.name}: {result.error
@@ -475,7 +481,7 @@ let seeS3PreviewFileFromList = '';
475
481
  >
476
482
  <slot />
477
483
  </div>
478
- {#if language == 'bun'}
484
+ {#if language === 'bun'}
479
485
  <div class="pt-20" />
480
486
  <Alert size="xs" type="info" title="Seeing an odd error?">
481
487
  Bun script are bundled for performance reasons. If you see an odd error that doesn't
@@ -484,7 +490,9 @@ let seeS3PreviewFileFromList = '';
484
490
  team.
485
491
  </Alert>
486
492
  {/if}
487
- {:else if !forceJson && resultKind == 'approval'}<div class="flex flex-col gap-3 mt-2 mx-4">
493
+ {:else if !forceJson && resultKind === 'approval'}<div
494
+ class="flex flex-col gap-3 mt-2 mx-4"
495
+ >
488
496
  <Button
489
497
  color="green"
490
498
  variant="border"
@@ -505,9 +513,9 @@ let seeS3PreviewFileFromList = '';
505
513
  ></div
506
514
  >
507
515
  </div>
508
- {:else if !forceJson && resultKind == 's3object'}
516
+ {:else if !forceJson && resultKind === 's3object'}
509
517
  <div
510
- class="h-full w-full {typeof result?.s3 == 'string' && result?.s3?.endsWith('.parquet')
518
+ class="h-full w-full {typeof result?.s3 === 'string' && result?.s3?.endsWith('.parquet')
511
519
  ? 'h-min-[600px]'
512
520
  : ''}"
513
521
  >
@@ -577,7 +585,7 @@ let seeS3PreviewFileFromList = '';
577
585
  {/if}
578
586
  {/if}
579
587
  </div>
580
- {:else if !forceJson && resultKind == 's3object-list'}
588
+ {:else if !forceJson && resultKind === 's3object-list'}
581
589
  <div class="h-full w-full">
582
590
  <div class="flex flex-col gap-2">
583
591
  <Toggle
@@ -646,12 +654,12 @@ let seeS3PreviewFileFromList = '';
646
654
  {/each}
647
655
  </div>
648
656
  </div>
649
- {:else if !forceJson && resultKind == 'markdown'}
657
+ {:else if !forceJson && resultKind === 'markdown'}
650
658
  <div class="prose-xs dark:prose-invert !list-disc !list-outside">
651
659
  <Markdown md={result?.md ?? result?.markdown} />
652
660
  </div>
653
661
  {:else if largeObject}
654
- {#if result && typeof result == 'object' && 'file' in result}
662
+ {#if result && typeof result === 'object' && 'file' in result}
655
663
  <div
656
664
  ><a
657
665
  download={result.filename ?? result.file?.filename ?? 'windmill.file'}
@@ -692,7 +700,7 @@ let seeS3PreviewFileFromList = '';
692
700
  <ObjectViewer json={result} />
693
701
  {/if}
694
702
  {/if}
695
- {:else if typeof result == 'string' && result.length > 0}
703
+ {:else if typeof result === 'string' && result.length > 0}
696
704
  <pre class="text-sm">{result}</pre>{#if !noControls}<div class="flex">
697
705
  <Button on:click={() => copyToClipboard(result)} color="light" size="xs">
698
706
  <div class="flex gap-2 items-center">Copy <ClipboardCopy size={12} /> </div>
@@ -707,7 +715,7 @@ let seeS3PreviewFileFromList = '';
707
715
  />
708
716
  {/if}
709
717
  </div>
710
- {:else if typeof result == 'string' && resultKind == 'plain'}
718
+ {:else if typeof result === 'string' && resultKind === 'plain'}
711
719
  <div class="h-full text-xs">
712
720
  <pre>{result}</pre>
713
721
  {#if !noControls}
@@ -4,7 +4,6 @@
4
4
  import '@codingame/monaco-vscode-standalone-languages'
5
5
  import '@codingame/monaco-vscode-standalone-typescript-language-features'
6
6
  import processStdContent from '../process.d.ts.txt?raw'
7
- import windmillFetchContent from '../windmill_fetch.d.ts.txt?raw'
8
7
 
9
8
  languages.typescript.typescriptDefaults.addExtraLib(processStdContent, 'process.d.ts')
10
9
 
@@ -968,26 +967,6 @@ async function loadMonaco() {
968
967
  async function setTypescriptExtraLibs() {
969
968
  if (lang === 'typescript' && scriptLang != 'deno') {
970
969
  const hostname = getHostname();
971
- // const stdLib = { content: libStdContent, filePath: 'es6.d.ts' }
972
- if (scriptLang == 'bun' || scriptLang == 'bunnative') {
973
- // const processLib = { content: processStdContent, filePath: 'process.d.ts' }
974
- // const domLib = { content: domContent, filePath: 'dom.d.ts' }
975
- // languages.typescript.typescriptDefaults.setExtraLibs([stdLib, domLib, processLib])
976
- }
977
- else {
978
- // const denoFetch = { content: denoFetchContent, filePath: 'deno_fetch.d.ts' }
979
- // languages.typescript.typescriptDefaults.setExtraLibs([stdLib, denoFetch])
980
- let localContent = windmillFetchContent;
981
- let p = '/tmp/monaco/windmill.d.ts';
982
- let nuri = mUri.parse(p);
983
- let localModel = meditor.getModel(nuri);
984
- if (localModel) {
985
- localModel.setValue(localContent);
986
- }
987
- else {
988
- meditor.createModel(localContent, 'typescript', nuri);
989
- }
990
- }
991
970
  if (scriptLang == 'bun' && ata == undefined) {
992
971
  const addLibraryToRuntime = async (code, _path) => {
993
972
  const path = 'file://' + _path;
@@ -11,6 +11,7 @@ import { CheckCircle2, Loader2, RotateCw, XCircle } from 'lucide-svelte';
11
11
  import { hubPaths } from '../hub';
12
12
  const slackRecoveryHandler = hubPaths.slackRecoveryHandler;
13
13
  const slackHandlerScriptPath = hubPaths.slackErrorHandler;
14
+ const slackSuccessHandler = hubPaths.slackSuccessHandler;
14
15
  export let errorOrRecovery;
15
16
  export let isEditable;
16
17
  export let slackToggleText = 'Enable';
@@ -116,9 +117,12 @@ function isSlackHandler(scriptPath) {
116
117
  return (scriptPath.startsWith('hub/') &&
117
118
  scriptPath.endsWith('/workspace-or-schedule-error-handler-slack'));
118
119
  }
119
- else {
120
+ else if (errorOrRecovery == 'recovery') {
120
121
  return (scriptPath.startsWith('hub/') && scriptPath.endsWith('/schedule-recovery-handler-slack'));
121
122
  }
123
+ else {
124
+ return scriptPath.startsWith('hub/') && scriptPath.endsWith('/schedule-success-handler-slack');
125
+ }
122
126
  }
123
127
  $: {
124
128
  if ($workspaceStore) {
@@ -232,6 +236,8 @@ $: handlerPath &&
232
236
  handlerPath = slackHandlerScriptPath
233
237
  } else if (e.detail && errorOrRecovery === 'recovery') {
234
238
  handlerPath = slackRecoveryHandler
239
+ } else if (e.detail && errorOrRecovery === 'success') {
240
+ handlerPath = slackSuccessHandler
235
241
  } else {
236
242
  handlerPath = undefined
237
243
  }
@@ -1,7 +1,7 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
- errorOrRecovery: 'error' | 'recovery';
4
+ errorOrRecovery: 'error' | 'recovery' | 'success';
5
5
  isEditable: boolean;
6
6
  slackToggleText?: string | undefined;
7
7
  showScriptHelpText?: boolean | undefined;
@@ -715,13 +715,13 @@ async function genFlow(idx, flowModules, stepOnly = false) {
715
715
  Object.keys(flowModule.value.input_transforms).forEach((key) => {
716
716
  if (key !== 'prev_output') {
717
717
  const schema = $flowStateStore[module.id].schema;
718
- const schemaProperty = Object.entries(schema.properties).find((x) => x[0] === key)?.[1];
718
+ const schemaProperty = Object.entries(schema?.properties ?? {}).find((x) => x[0] === key)?.[1];
719
719
  const snakeKey = snakeCase(key);
720
720
  if (schemaProperty &&
721
721
  (!$flowStore.schema || !(snakeKey in $flowStore.schema.properties ?? {})) // prevent overriding flow inputs
722
722
  ) {
723
723
  copilotFlowInputs[snakeKey] = schemaProperty;
724
- if (schema.required.includes(snakeKey)) {
724
+ if (schema?.required.includes(snakeKey)) {
725
725
  copilotFlowRequiredInputs.push(snakeKey);
726
726
  }
727
727
  }
@@ -117,6 +117,8 @@ let codeViewer;
117
117
  Run one branch
118
118
  {:else if stepDetail.value.type == 'flow'}
119
119
  Inner flow
120
+ {:else if stepDetail.value.type == 'whileloopflow'}
121
+ While loop
120
122
  {:else}
121
123
  Anonymous step
122
124
  {/if}
@@ -206,6 +208,26 @@ let codeViewer;
206
208
  </span>
207
209
  {/if}
208
210
  </div>
211
+ {:else if stepDetail.value.type == 'whileloopflow'}
212
+ <div>
213
+ {#if stepDetail.stop_after_if}
214
+ <p class="font-medium text-secondary pb-2 pt-4">Stop after if expr:: </p>
215
+ <span class="text-xs">
216
+ <Highlight language={typescript} code={cleanExpr(stepDetail.stop_after_if?.expr)} />
217
+ </span>
218
+ {/if}
219
+ </div>
220
+ <div>
221
+ {#if stepDetail.stop_after_all_iters_if}
222
+ <p class="font-medium text-secondary pb-2 pt-4">Stop after all iters if expr:: </p>
223
+ <span class="text-xs">
224
+ <Highlight
225
+ language={typescript}
226
+ code={cleanExpr(stepDetail.stop_after_all_iters_if?.expr)}
227
+ />
228
+ </span>
229
+ {/if}
230
+ </div>
209
231
  {:else if stepDetail.value.type == 'branchall'}
210
232
  <p class="font-medium text-secondary text-center pt-4 pb-8">
211
233
  All branches will run, regardless of the inputs
@@ -32,6 +32,7 @@ async function diffJobId() {
32
32
  let logOffset = 0;
33
33
  async function getLogs() {
34
34
  if (jobId) {
35
+ console.log('getLogs');
35
36
  const getUpdate = await JobService.getJobUpdates({
36
37
  workspace: workspaceId ?? $workspaceStore,
37
38
  id: jobId,
@@ -49,10 +49,10 @@ export let scheduleEditor;
49
49
  {#if job.is_flow_step}
50
50
  <div class="flex flex-row gap-2 items-center text-sm">
51
51
  <BarsStaggered size={SMALL_ICON_SIZE} class="text-secondary min-w-3.5" />
52
- <span class="whitespace-nowrap">
52
+ <span class="whitespace-nowrap text-sm">
53
53
  Step of flow
54
54
  <a href={`${base}/run/${job.parent_job}?workspace=${$workspaceStore}`}>
55
- {job.parent_job}
55
+ {truncateRev(job.parent_job, 18)}
56
56
  </a>
57
57
  </span>
58
58
  </div>
@@ -72,6 +72,7 @@ export let scheduleEditor;
72
72
  <Calendar size={SMALL_ICON_SIZE} class="text-secondary min-w-3.5" />
73
73
  <span class="whitespace-nowrap">
74
74
  Schedule:
75
+ <!-- svelte-ignore a11y-invalid-attribute -->
75
76
  <a
76
77
  href="#"
77
78
  class="break-words text-blue-600 font-normal"
@@ -4,6 +4,7 @@ import { createEventDispatcher, setContext } from 'svelte';
4
4
  import { isOwner as loadIsOwner } from '../utils';
5
5
  import { userStore, workspaceStore } from '../stores';
6
6
  export let jobId;
7
+ export let initialJob = undefined;
7
8
  export let workspaceId = undefined;
8
9
  export let flowStateStore = writable({});
9
10
  export let selectedJobStep = undefined;
@@ -56,6 +57,7 @@ $: jobId && updateJobId();
56
57
  bind:selectedNode={selectedJobStep}
57
58
  on:start
58
59
  on:done
60
+ {initialJob}
59
61
  {jobId}
60
62
  {workspaceId}
61
63
  {isOwner}
@@ -1,9 +1,11 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import { type Writable } from 'svelte/store';
3
3
  import type { FlowState } from './flows/flowState';
4
+ import type { Job } from '../gen';
4
5
  declare const __propDef: {
5
6
  props: {
6
7
  jobId: string;
8
+ initialJob?: Job | undefined;
7
9
  workspaceId?: string | undefined;
8
10
  flowStateStore?: Writable<FlowState> | undefined;
9
11
  selectedJobStep?: string | undefined;
@@ -24,6 +24,7 @@ import FlowGraphV2 from './graph/FlowGraphV2.svelte';
24
24
  const dispatch = createEventDispatcher();
25
25
  let { flowStateStore, retryStatus, suspendStatus, hideDownloadInGraph, hideTimeline, hideNodeDefinition } = getContext('FlowStatusViewer');
26
26
  export let jobId;
27
+ export let initialJob = undefined;
27
28
  export let workspaceId = undefined;
28
29
  export let flowJobIds = undefined;
29
30
  //only useful when forloops are optimized and the job doesn't contain the mod id anymore
@@ -204,11 +205,15 @@ async function loadJobInProgress() {
204
205
  dispatch('start');
205
206
  if (jobId != '00000000-0000-0000-0000-000000000000') {
206
207
  try {
207
- const newJob = await JobService.getJob({
208
- workspace: workspaceId ?? $workspaceStore ?? '',
209
- id: jobId ?? '',
210
- noLogs: true
211
- });
208
+ const newJob = jobId == initialJob?.id &&
209
+ initialJob?.id != undefined &&
210
+ initialJob?.type === 'CompletedJob'
211
+ ? initialJob
212
+ : await JobService.getJob({
213
+ workspace: workspaceId ?? $workspaceStore ?? '',
214
+ id: jobId ?? '',
215
+ noLogs: true
216
+ });
212
217
  if (!deepEqual(job, newJob)) {
213
218
  job = newJob;
214
219
  job?.flow_status && updateStatus(job?.flow_status);
@@ -5,6 +5,7 @@ import { type Writable } from 'svelte/store';
5
5
  declare const __propDef: {
6
6
  props: {
7
7
  jobId: string;
8
+ initialJob?: Job | undefined;
8
9
  workspaceId?: string | undefined;
9
10
  flowJobIds?: {
10
11
  moduleId: string;
@@ -199,7 +199,7 @@ async function updateFolder() {
199
199
  size="sm"
200
200
  on:click={addToFolder}
201
201
  >
202
- Grant permission to folder
202
+ Grant
203
203
  </Button>
204
204
  </div>
205
205
  {/if}