windmill-components 1.379.4 → 1.382.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 (199) hide show
  1. package/package/base.d.ts +1 -1
  2. package/package/base.js +1 -1
  3. package/package/components/ArgInput.svelte +33 -3
  4. package/package/components/DisplayResult.svelte +17 -5
  5. package/package/components/EditorBar.svelte +48 -38
  6. package/package/components/EditorBar.svelte.d.ts +2 -0
  7. package/package/components/ErrorOrRecoveryHandler.svelte +3 -2
  8. package/package/components/FlowBuilder.svelte +18 -12
  9. package/package/components/FlowBuilder.svelte.d.ts +3 -2
  10. package/package/components/FlowGraphViewer.svelte +6 -5
  11. package/package/components/FlowJobResult.svelte +4 -2
  12. package/package/components/FlowJobResult.svelte.d.ts +2 -0
  13. package/package/components/FlowStatusViewer.svelte +7 -1
  14. package/package/components/FlowStatusViewer.svelte.d.ts +3 -0
  15. package/package/components/FlowStatusViewerInner.svelte +29 -11
  16. package/package/components/FlowViewer.svelte +3 -1
  17. package/package/components/FlowViewer.svelte.d.ts +1 -0
  18. package/package/components/HighlightCode.svelte +2 -2
  19. package/package/components/ModulePreviewForm.svelte +1 -1
  20. package/package/components/ObjectResourceInput.svelte +7 -2
  21. package/package/components/ObjectResourceInput.svelte.d.ts +2 -0
  22. package/package/components/ResourcePicker.svelte +60 -48
  23. package/package/components/ScriptBuilder.svelte +42 -36
  24. package/package/components/ScriptBuilder.svelte.d.ts +2 -0
  25. package/package/components/ScriptEditor.svelte +3 -1
  26. package/package/components/ScriptEditor.svelte.d.ts +2 -0
  27. package/package/components/ScriptVersionHistory.svelte +63 -7
  28. package/package/components/apps/components/display/AppText.svelte +8 -3
  29. package/package/components/apps/components/display/dbtable/DbExplorerCount.svelte +3 -2
  30. package/package/components/apps/components/display/table/AppAggridExplorerTable.svelte +22 -5
  31. package/package/components/apps/components/display/table/AppAggridTable.svelte +14 -5
  32. package/package/components/apps/components/display/table/AppAggridTableActions.svelte +23 -8
  33. package/package/components/apps/components/display/table/AppAggridTableActions.svelte.d.ts +5 -3
  34. package/package/components/apps/components/display/table/utils.js +8 -7
  35. package/package/components/apps/components/helpers/RunnableComponent.svelte +13 -1
  36. package/package/components/apps/components/helpers/eval.js +31 -25
  37. package/package/components/apps/components/inputs/AppSelect.svelte +45 -29
  38. package/package/components/apps/editor/AppEditorHeader.svelte +1 -0
  39. package/package/components/apps/editor/AppReportsDrawer.svelte +4 -3
  40. package/package/components/apps/editor/component/components.d.ts +7 -1
  41. package/package/components/apps/editor/component/components.js +6 -0
  42. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphEditor.svelte +0 -1
  43. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphHeader.svelte +55 -45
  44. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphHeader.svelte.d.ts +7 -9
  45. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphNode.svelte +66 -59
  46. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphNode.svelte.d.ts +9 -11
  47. package/package/components/apps/editor/settingsPanel/decisionTree/DecisionTreePreview.svelte +213 -254
  48. package/package/components/apps/editor/settingsPanel/decisionTree/DecisionTreePreview.svelte.d.ts +0 -1
  49. package/package/components/apps/editor/settingsPanel/decisionTree/nodeHelpers.d.ts +1 -1
  50. package/package/components/apps/editor/settingsPanel/decisionTree/nodeHelpers.js +2 -6
  51. package/package/components/custom_ui.d.ts +35 -1
  52. package/package/components/details/DetailPageDetailPanel.svelte +9 -1
  53. package/package/components/details/DetailPageDetailPanel.svelte.d.ts +2 -1
  54. package/package/components/details/DetailPageLayout.svelte +2 -0
  55. package/package/components/details/DetailPageLayout.svelte.d.ts +3 -0
  56. package/package/components/details/EmailTriggerPanel.svelte +128 -0
  57. package/package/components/details/EmailTriggerPanel.svelte.d.ts +20 -0
  58. package/package/components/details/WebhooksPanel.svelte +10 -71
  59. package/package/components/flows/FlowHistory.svelte +1 -0
  60. package/package/components/flows/content/FlowInputs.svelte +0 -1
  61. package/package/components/flows/content/FlowModuleComponent.svelte +8 -2
  62. package/package/components/flows/content/FlowModuleEarlyStop.svelte +193 -66
  63. package/package/components/flows/content/FlowModuleHeader.svelte +1 -1
  64. package/package/components/flows/content/FlowModuleScript.svelte +33 -3
  65. package/package/components/flows/content/FlowModuleScript.svelte.d.ts +2 -0
  66. package/package/components/flows/content/FlowModuleSuspend.svelte +15 -0
  67. package/package/components/flows/content/FlowSettings.svelte +26 -15
  68. package/package/components/flows/flowExplorer.js +3 -0
  69. package/package/components/flows/flowInfers.js +1 -1
  70. package/package/components/flows/map/FlowJobsMenu.svelte +39 -44
  71. package/package/components/flows/map/FlowModuleSchemaItem.svelte +1 -2
  72. package/package/components/flows/map/FlowModuleSchemaMap.svelte +4 -3
  73. package/package/components/flows/map/InsertModuleButton.svelte +16 -9
  74. package/package/components/flows/map/MapItem.svelte +4 -98
  75. package/package/components/flows/map/MapItem.svelte.d.ts +0 -5
  76. package/package/components/flows/map/VirtualItem.svelte +6 -159
  77. package/package/components/flows/map/VirtualItem.svelte.d.ts +0 -15
  78. package/package/components/flows/propPicker/PropPickerWrapper.svelte +2 -0
  79. package/package/components/flows/propPicker/PropPickerWrapper.svelte.d.ts +1 -0
  80. package/package/components/flows/types.d.ts +2 -0
  81. package/package/components/graph/FlowGraphV2.svelte +256 -0
  82. package/package/components/graph/{FlowGraph.svelte.d.ts → FlowGraphV2.svelte.d.ts} +8 -8
  83. package/package/components/graph/graphBuilder.d.ts +15 -0
  84. package/package/components/graph/graphBuilder.js +337 -0
  85. package/package/components/graph/index.d.ts +0 -1
  86. package/package/components/graph/index.js +0 -1
  87. package/package/components/graph/model.d.ts +4 -8
  88. package/package/components/graph/renderers/edges/BaseEdge.svelte +109 -0
  89. package/package/components/graph/renderers/edges/BaseEdge.svelte.d.ts +35 -0
  90. package/package/components/graph/renderers/edges/DataflowEdge.svelte +37 -0
  91. package/package/components/graph/renderers/edges/DataflowEdge.svelte.d.ts +29 -0
  92. package/package/components/graph/renderers/edges/EmptyEdge.svelte +22 -0
  93. package/package/components/graph/renderers/edges/EmptyEdge.svelte.d.ts +23 -0
  94. package/package/components/graph/renderers/nodes/BranchAllStart.svelte +44 -0
  95. package/package/components/graph/renderers/nodes/BranchAllStart.svelte.d.ts +29 -0
  96. package/package/components/graph/renderers/nodes/BranchOneStart.svelte +41 -0
  97. package/package/components/graph/renderers/nodes/BranchOneStart.svelte.d.ts +29 -0
  98. package/package/components/graph/renderers/nodes/ForLoopEndNode.svelte +19 -0
  99. package/package/components/graph/renderers/nodes/ForLoopEndNode.svelte.d.ts +24 -0
  100. package/package/components/graph/renderers/nodes/ForLoopStartNode.svelte +20 -0
  101. package/package/components/graph/renderers/nodes/ForLoopStartNode.svelte.d.ts +25 -0
  102. package/package/components/graph/renderers/nodes/InputNode.svelte +74 -0
  103. package/package/components/graph/renderers/nodes/InputNode.svelte.d.ts +23 -0
  104. package/package/components/graph/renderers/nodes/ModuleNode.svelte +71 -0
  105. package/package/components/graph/renderers/nodes/ModuleNode.svelte.d.ts +41 -0
  106. package/package/components/graph/renderers/nodes/NoBranchNode.svelte +20 -0
  107. package/package/components/graph/renderers/nodes/NoBranchNode.svelte.d.ts +27 -0
  108. package/package/components/graph/renderers/nodes/NodeWrapper.svelte +21 -0
  109. package/package/components/graph/renderers/nodes/NodeWrapper.svelte.d.ts +22 -0
  110. package/package/components/graph/renderers/nodes/ResultNode.svelte +24 -0
  111. package/package/components/graph/renderers/nodes/ResultNode.svelte.d.ts +22 -0
  112. package/package/components/graph/renderers/nodes/branchAllEndNode.svelte +19 -0
  113. package/package/components/graph/renderers/nodes/branchAllEndNode.svelte.d.ts +26 -0
  114. package/package/components/graph/renderers/nodes/branchOneEndNode.svelte +19 -0
  115. package/package/components/graph/renderers/nodes/branchOneEndNode.svelte.d.ts +24 -0
  116. package/package/components/graph/renderers/utils.d.ts +8 -0
  117. package/package/components/graph/renderers/utils.js +26 -0
  118. package/package/components/graph/util.d.ts +1 -2
  119. package/package/components/graph/util.js +2 -8
  120. package/package/components/propertyPicker/PropPickerResult.svelte +6 -1
  121. package/package/components/propertyPicker/PropPickerResult.svelte.d.ts +1 -0
  122. package/package/components/runs/RunsFilter.svelte +15 -17
  123. package/package/components/sidebar/changelogs.js +5 -0
  124. package/package/gen/core/OpenAPI.js +1 -1
  125. package/package/gen/schemas.gen.d.ts +3 -0
  126. package/package/gen/schemas.gen.js +3 -0
  127. package/package/gen/services.gen.d.ts +22 -3
  128. package/package/gen/services.gen.js +38 -2
  129. package/package/gen/types.gen.d.ts +69 -6
  130. package/package/hub.d.ts +11 -0
  131. package/package/hub.js +2 -0
  132. package/package/hubPaths.json +9 -0
  133. package/package/init_scripts/python_failure_module.d.ts +1 -1
  134. package/package/init_scripts/python_failure_module.js +4 -3
  135. package/package/script_helpers.d.ts +2 -2
  136. package/package/script_helpers.js +11 -9
  137. package/package.json +2 -1
  138. package/package/components/graph/FlowGraph.svelte +0 -614
  139. package/package/components/graph/svelvet/LICENSE +0 -21
  140. package/package/components/graph/svelvet/container/README.md +0 -7
  141. package/package/components/graph/svelvet/container/controllers/middleware.d.ts +0 -11
  142. package/package/components/graph/svelvet/container/controllers/middleware.js +0 -87
  143. package/package/components/graph/svelvet/container/models/index.d.ts +0 -0
  144. package/package/components/graph/svelvet/container/models/index.js +0 -1
  145. package/package/components/graph/svelvet/container/views/GraphView.svelte +0 -262
  146. package/package/components/graph/svelvet/container/views/GraphView.svelte.d.ts +0 -26
  147. package/package/components/graph/svelvet/container/views/Svelvet.svelte +0 -121
  148. package/package/components/graph/svelvet/container/views/Svelvet.svelte.d.ts +0 -36
  149. package/package/components/graph/svelvet/customCss/controllers/getCss.d.ts +0 -2
  150. package/package/components/graph/svelvet/customCss/controllers/getCss.js +0 -46
  151. package/package/components/graph/svelvet/d3/controllers/d3.d.ts +0 -5
  152. package/package/components/graph/svelvet/d3/controllers/d3.js +0 -59
  153. package/package/components/graph/svelvet/edges/controllers/anchorCbDev.d.ts +0 -4
  154. package/package/components/graph/svelvet/edges/controllers/anchorCbDev.js +0 -92
  155. package/package/components/graph/svelvet/edges/controllers/anchorCbUser.d.ts +0 -57
  156. package/package/components/graph/svelvet/edges/controllers/anchorCbUser.js +0 -73
  157. package/package/components/graph/svelvet/edges/controllers/util.d.ts +0 -37
  158. package/package/components/graph/svelvet/edges/controllers/util.js +0 -71
  159. package/package/components/graph/svelvet/edges/models/Anchor.d.ts +0 -48
  160. package/package/components/graph/svelvet/edges/models/Anchor.js +0 -122
  161. package/package/components/graph/svelvet/edges/models/Edge.d.ts +0 -48
  162. package/package/components/graph/svelvet/edges/models/Edge.js +0 -109
  163. package/package/components/graph/svelvet/edges/types/types.d.ts +0 -18
  164. package/package/components/graph/svelvet/edges/types/types.js +0 -1
  165. package/package/components/graph/svelvet/edges/views/Edges/BaseEdge.svelte +0 -104
  166. package/package/components/graph/svelvet/edges/views/Edges/BaseEdge.svelte.d.ts +0 -18
  167. package/package/components/graph/svelvet/edges/views/Edges/EdgeText.svelte +0 -42
  168. package/package/components/graph/svelvet/edges/views/Edges/EdgeText.svelte.d.ts +0 -17
  169. package/package/components/graph/svelvet/edges/views/Edges/SimpleBezierEdge.svelte +0 -151
  170. package/package/components/graph/svelvet/edges/views/Edges/SimpleBezierEdge.svelte.d.ts +0 -17
  171. package/package/components/graph/svelvet/edges/views/Edges/SmoothStepEdge.svelte +0 -157
  172. package/package/components/graph/svelvet/edges/views/Edges/SmoothStepEdge.svelte.d.ts +0 -60
  173. package/package/components/graph/svelvet/edges/views/Edges/StepEdge.svelte +0 -8
  174. package/package/components/graph/svelvet/edges/views/Edges/StepEdge.svelte.d.ts +0 -25
  175. package/package/components/graph/svelvet/edges/views/Edges/types.d.ts +0 -52
  176. package/package/components/graph/svelvet/edges/views/Edges/types.js +0 -1
  177. package/package/components/graph/svelvet/edges/views/Edges/utils.d.ts +0 -33
  178. package/package/components/graph/svelvet/edges/views/Edges/utils.js +0 -31
  179. package/package/components/graph/svelvet/nodes/controllers/util.d.ts +0 -9
  180. package/package/components/graph/svelvet/nodes/controllers/util.js +0 -13
  181. package/package/components/graph/svelvet/nodes/models/Node.d.ts +0 -74
  182. package/package/components/graph/svelvet/nodes/models/Node.js +0 -156
  183. package/package/components/graph/svelvet/nodes/views/Node.svelte +0 -84
  184. package/package/components/graph/svelvet/nodes/views/Node.svelte.d.ts +0 -21
  185. package/package/components/graph/svelvet/store/controllers/storeApi.d.ts +0 -25
  186. package/package/components/graph/svelvet/store/controllers/storeApi.js +0 -91
  187. package/package/components/graph/svelvet/store/controllers/userApi.d.ts +0 -3
  188. package/package/components/graph/svelvet/store/controllers/userApi.js +0 -18
  189. package/package/components/graph/svelvet/store/controllers/util.d.ts +0 -24
  190. package/package/components/graph/svelvet/store/controllers/util.js +0 -148
  191. package/package/components/graph/svelvet/store/models/store.d.ts +0 -13
  192. package/package/components/graph/svelvet/store/models/store.js +0 -12
  193. package/package/components/graph/svelvet/store/types/types.d.ts +0 -127
  194. package/package/components/graph/svelvet/store/types/types.js +0 -1
  195. package/package/components/graph/svelvet/types/README.md +0 -3
  196. package/package/components/graph/svelvet/types/index.d.ts +0 -2
  197. package/package/components/graph/svelvet/types/index.js +0 -1
  198. package/package/components/graph/svelvet/types/types.d.ts +0 -50
  199. package/package/components/graph/svelvet/types/types.js +0 -18
@@ -16,6 +16,9 @@ declare const __propDef: {
16
16
  webhooks: {
17
17
  slot: string;
18
18
  };
19
+ email: {
20
+ slot: string;
21
+ };
19
22
  schedule: {
20
23
  slot: string;
21
24
  };
@@ -0,0 +1,128 @@
1
+ <script>import Tooltip from '../Tooltip.svelte';
2
+ import { enterpriseLicense, userStore, workspaceStore } from '../../stores';
3
+ import { Button } from '../common';
4
+ import { SCRIPT_VIEW_SHOW_CREATE_TOKEN_BUTTON } from '../../consts';
5
+ import UserSettings from '../UserSettings.svelte';
6
+ import ClipboardPanel from './ClipboardPanel.svelte';
7
+ import { generateRandomString } from '../../utils';
8
+ import HighlightTheme from '../HighlightTheme.svelte';
9
+ import Alert from '../common/alert/Alert.svelte';
10
+ import { SettingService } from '../../gen';
11
+ import { base32 } from 'rfc4648';
12
+ import ToggleButton from '../common/toggleButton-v2/ToggleButton.svelte';
13
+ import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte';
14
+ import { AlertTriangle } from 'lucide-svelte';
15
+ import Skeleton from '../common/skeleton/Skeleton.svelte';
16
+ let userSettings;
17
+ export let token;
18
+ export let scopes = [];
19
+ export let isFlow = false;
20
+ export let hash = undefined;
21
+ export let path;
22
+ let emailDomain = null;
23
+ let loading = true;
24
+ async function getEmailDomain() {
25
+ emailDomain =
26
+ (await SettingService.getGlobal({
27
+ key: 'email_domain'
28
+ })) ?? null;
29
+ loading = false;
30
+ }
31
+ getEmailDomain();
32
+ let requestType = 'path';
33
+ function emailAddress() {
34
+ const pathOrHash = requestType === 'hash' ? hash : path.replaceAll('/', '.');
35
+ const plainPrefix = `${$workspaceStore}+${(requestType === 'hash' ? 'hash.' : isFlow ? 'flow.' : '') + pathOrHash}+${token}`;
36
+ const encodedPrefix = base32
37
+ .stringify(new TextEncoder().encode(plainPrefix), {
38
+ pad: false
39
+ })
40
+ .toLowerCase();
41
+ return `${pathOrHash}+${encodedPrefix}@${emailDomain}`;
42
+ }
43
+ </script>
44
+
45
+ <HighlightTheme />
46
+
47
+ <UserSettings
48
+ bind:this={userSettings}
49
+ on:tokenCreated={(e) => {
50
+ token = e.detail
51
+ }}
52
+ newTokenLabel={`${$userStore?.username ?? 'superadmin'}-${generateRandomString(4)}`}
53
+ {scopes}
54
+ />
55
+
56
+ <div class="p-2 flex flex-col w-full gap-4">
57
+ {#if loading}
58
+ <Skeleton layout={[[18]]} />
59
+ {:else}
60
+ {#if emailDomain}
61
+ {#if SCRIPT_VIEW_SHOW_CREATE_TOKEN_BUTTON}
62
+ <div class="my-2">
63
+ <div class="flex flex-row justify-between gap-2">
64
+ <input
65
+ bind:value={token}
66
+ placeholder="paste your token here once created to alter examples below"
67
+ class="!text-xs"
68
+ />
69
+ <Button size="xs" color="light" variant="border" on:click={userSettings.openDrawer}>
70
+ Create an Email-specific Token
71
+ <Tooltip light>
72
+ The token will have a scope such that it can only be used to trigger this script. It
73
+ is safe to share as it cannot be used to impersonate you.
74
+ </Tooltip>
75
+ </Button>
76
+ </div>
77
+ {#if token === 'TOKEN_TO_CREATE'}
78
+ <div class="flex flex-row gap-1 text-xs text-red-500 items-center mt-1">
79
+ <AlertTriangle size="12" />
80
+ Create/input a valid token before copying the email address below
81
+ </div>
82
+ {/if}
83
+ </div>
84
+ {/if}
85
+
86
+ {#if !isFlow}
87
+ <div class="flex flex-col gap-2">
88
+ <div class="flex flex-row justify-between">
89
+ <div class="text-xs font-semibold flex flex-row items-center">Call method</div>
90
+ <ToggleButtonGroup class="h-[30px] w-auto" bind:selected={requestType}>
91
+ <ToggleButton label="By path" value="path" />
92
+ <ToggleButton label="By hash" value="hash" />
93
+ </ToggleButtonGroup>
94
+ </div>
95
+ </div>
96
+ {/if}
97
+ <div class="flex flex-col gap-4">
98
+ {#key requestType}
99
+ {#key token}
100
+ <div class="flex flex-col gap-2">
101
+ <ClipboardPanel title="Email address" content={emailAddress()} />
102
+ </div>
103
+ {/key}
104
+ {/key}
105
+ <Alert title="Email trigger" size="xs">
106
+ To trigger the job by email, send an email to the address above. The job will receive two
107
+ arguments: `raw_email` containing the raw email as string, and `parsed_email` containing
108
+ the parsed email as an object.
109
+ </Alert>
110
+ </div>
111
+ {:else}
112
+ <div>
113
+ <Alert title="Email triggers are disabled" size="xs" type="warning">
114
+ Ask an instance superadmin to setup the instance for email triggering (<a
115
+ target="_blank"
116
+ href="https://windmill.dev/docs/advanced/email_triggers">docs</a
117
+ >) and to set the email domain in the instance settings.
118
+ </Alert>
119
+ </div>
120
+ {/if}
121
+
122
+ {#if !$enterpriseLicense}
123
+ <Alert title="Community Edition limitations" type="warning" size="xs">
124
+ Email triggers on Windmill Community Edition are limited to 100 emails per day.
125
+ </Alert>
126
+ {/if}
127
+ {/if}
128
+ </div>
@@ -0,0 +1,20 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ token: string;
5
+ scopes?: string[] | undefined;
6
+ isFlow?: boolean | undefined;
7
+ hash?: string | undefined;
8
+ path: string;
9
+ };
10
+ events: {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ };
15
+ export type EmailTriggerPanelProps = typeof __propDef.props;
16
+ export type EmailTriggerPanelEvents = typeof __propDef.events;
17
+ export type EmailTriggerPanelSlots = typeof __propDef.slots;
18
+ export default class EmailTriggerPanel extends SvelteComponent<EmailTriggerPanelProps, EmailTriggerPanelEvents, EmailTriggerPanelSlots> {
19
+ }
20
+ export {};
@@ -13,10 +13,7 @@ import { typescript } from 'svelte-highlight/languages';
13
13
  import ClipboardPanel from './ClipboardPanel.svelte';
14
14
  import { copyToClipboard, generateRandomString } from '../../utils';
15
15
  import HighlightTheme from '../HighlightTheme.svelte';
16
- import Alert from '../common/alert/Alert.svelte';
17
- import { SettingService } from '../../gen';
18
16
  import { base } from '../../base';
19
- import { base32 } from 'rfc4648';
20
17
  let userSettings;
21
18
  export let token;
22
19
  export let args;
@@ -26,14 +23,6 @@ export let hash = undefined;
26
23
  export let path;
27
24
  let selectedTab = 'rest';
28
25
  let webhooks;
29
- let emailDomain = null;
30
- async function getEmailDomain() {
31
- emailDomain =
32
- (await SettingService.getGlobal({
33
- key: 'email_domain'
34
- })) ?? null;
35
- }
36
- getEmailDomain();
37
26
  $: webhooks = isFlow ? computeFlowWebhooks(path) : computeScriptWebhooks(hash, path);
38
27
  function computeScriptWebhooks(hash, path) {
39
28
  let webhookBase = `${$page.url.origin}${base}/api/w/${$workspaceStore}/jobs`;
@@ -50,9 +39,9 @@ function computeScriptWebhooks(hash, path) {
50
39
  };
51
40
  }
52
41
  function computeFlowWebhooks(path) {
53
- let base = `${$page.url.origin}/api/w/${$workspaceStore}/jobs`;
54
- let urlAsync = `${base}/run/f/${path}`;
55
- let urlSync = `${base}/run_wait_result/f/${path}`;
42
+ let webhooksBase = `${$page.url.origin}${base}/api/w/${$workspaceStore}/jobs`;
43
+ let urlAsync = `${webhooksBase}/run/f/${path}`;
44
+ let urlSync = `${webhooksBase}/run_wait_result/f/${path}`;
56
45
  return {
57
46
  async: {
58
47
  path: urlAsync
@@ -70,9 +59,6 @@ $: if (webhookType === 'async' && requestType === 'get_path') {
70
59
  // Request type is not supported for async webhooks
71
60
  requestType = 'hash';
72
61
  }
73
- $: if (webhookType === 'sync' && selectedTab === 'email') {
74
- webhookType = 'async';
75
- }
76
62
  $: url =
77
63
  webhooks[webhookType][requestType] +
78
64
  (tokenType === 'query'
@@ -92,16 +78,6 @@ function headers() {
92
78
  }
93
79
  return headers;
94
80
  }
95
- function emailAddress() {
96
- const pathOrHash = requestType === 'hash' ? hash : path.replaceAll('/', '.');
97
- const plainPrefix = `${$workspaceStore}+${(requestType === 'hash' ? 'hash.' : isFlow ? 'flow.' : '') + pathOrHash}+${token}`;
98
- const encodedPrefix = base32
99
- .stringify(new TextEncoder().encode(plainPrefix), {
100
- pad: false
101
- })
102
- .toLowerCase();
103
- return `${pathOrHash}+${encodedPrefix}@${emailDomain}`;
104
- }
105
81
  function fetchCode() {
106
82
  if (webhookType === 'sync') {
107
83
  return `
@@ -238,7 +214,6 @@ done`}`;
238
214
  label="Sync"
239
215
  value="sync"
240
216
  tooltip="Triggers the execution, wait for the job to complete and return it as a response."
241
- disabled={selectedTab === 'email'}
242
217
  />
243
218
  </ToggleButtonGroup>
244
219
  </div>
@@ -269,15 +244,13 @@ done`}`;
269
244
  />
270
245
  </ToggleButtonGroup>
271
246
  </div>
272
- {#if selectedTab !== 'email'}
273
- <div class="flex flex-row justify-between">
274
- <div class="text-xs font-semibold flex flex-row items-center">Token configuration</div>
275
- <ToggleButtonGroup class="h-[30px] w-auto" bind:selected={tokenType}>
276
- <ToggleButton label="Token in Headers" value="headers" />
277
- <ToggleButton label="Token in Query" value="query" />
278
- </ToggleButtonGroup>
279
- </div>
280
- {/if}
247
+ <div class="flex flex-row justify-between">
248
+ <div class="text-xs font-semibold flex flex-row items-center">Token configuration</div>
249
+ <ToggleButtonGroup class="h-[30px] w-auto" bind:selected={tokenType}>
250
+ <ToggleButton label="Token in Headers" value="headers" />
251
+ <ToggleButton label="Token in Query" value="query" />
252
+ </ToggleButtonGroup>
253
+ </div>
281
254
  </div>
282
255
  <!-- svelte-ignore a11y-click-events-have-key-events -->
283
256
  <!-- svelte-ignore a11y-no-static-element-interactions -->
@@ -287,7 +260,6 @@ done`}`;
287
260
  <Tab value="curl" size="xs">Curl</Tab>
288
261
  {/if}
289
262
  <Tab value="fetch" size="xs">Fetch</Tab>
290
- <Tab value="email" size="xs">Email</Tab>
291
263
 
292
264
  <svelte:fragment slot="content">
293
265
  {#key token}
@@ -346,39 +318,6 @@ done`}`;
346
318
  {/key}{/key}{/key}{/key}
347
319
  {/key}
348
320
  </TabContent>
349
- <TabContent value="email">
350
- {#if emailDomain}
351
- <div class="flex flex-col gap-4">
352
- {#key args}
353
- {#key requestType}
354
- {#key webhookType}
355
- {#key tokenType}
356
- {#key token}
357
- <div class="flex flex-col gap-2">
358
- <ClipboardPanel title="Email address" content={emailAddress()} />
359
- </div>
360
- {/key}
361
- {/key}
362
- {/key}
363
- {/key}
364
- {/key}
365
- <Alert title="Email triggers" size="xs">
366
- To trigger the job by email, send an email to the address above. The job will
367
- receive two arguments: `raw_email` containing the raw email as string, and
368
- `parsed_email` containing the parsed email as an object.
369
- </Alert>
370
- </div>
371
- {:else}
372
- <div>
373
- <Alert title="Email triggers are disabled" size="xs" kind="danger">
374
- Ask an instance superadmin to setup the instance for email triggering (<a
375
- target="_blank"
376
- href="https://windmill.dev/docs/advanced/email_triggers">docs</a
377
- >) and to set the email domain in the instance settings.
378
- </Alert>
379
- </div>
380
- {/if}
381
- </TabContent>
382
321
  {/key}
383
322
  </svelte:fragment>
384
323
  </Tabs>
@@ -79,6 +79,7 @@ $: selectedVersion !== undefined && loadFlow(selectedVersion.id);
79
79
  on:close={() => {
80
80
  drawer?.closeDrawer()
81
81
  }}
82
+ noPadding
82
83
  >
83
84
  <Splitpanes class="!overflow-visible">
84
85
  <Pane size={20}>
@@ -209,7 +209,6 @@ let customUi = getContext('customUi');
209
209
  return
210
210
  }
211
211
  }
212
- console.log(lang, kind)
213
212
  dispatch('new', {
214
213
  language: lang == 'docker' ? 'bash' : lang,
215
214
  kind,
@@ -41,7 +41,7 @@ import { loadSchemaFromModule } from '../flowInfers';
41
41
  import { computeFlowStepWarning, initFlowStepWarnings } from '../utils';
42
42
  import { debounce } from '../../../utils';
43
43
  import { dfs } from '../dfs';
44
- const { selectedId, previewArgs, flowStateStore, flowStore, pathStore, saveDraft, flowInputsStore } = getContext('FlowEditorContext');
44
+ const { selectedId, previewArgs, flowStateStore, flowStore, pathStore, saveDraft, flowInputsStore, customUi } = getContext('FlowEditorContext');
45
45
  export let flowModule;
46
46
  export let failureModule = false;
47
47
  export let parentModule = undefined;
@@ -216,6 +216,7 @@ function setFlowInput(argName) {
216
216
  {#if flowModule.value.type === 'rawscript' && !noEditor}
217
217
  <div class="border-b-2 shadow-sm px-1">
218
218
  <EditorBar
219
+ customUi={customUi?.editorBar}
219
220
  {validCode}
220
221
  {editor}
221
222
  {diffEditor}
@@ -353,7 +354,12 @@ function setFlowInput(argName) {
353
354
  {#if !$selectedId.includes('failure')}
354
355
  <Tab value="runtime">Runtime</Tab>
355
356
  <Tab value="cache" active={Boolean(flowModule.cache_ttl)}>Cache</Tab>
356
- <Tab value="early-stop" active={Boolean(flowModule.stop_after_if)}>
357
+ <Tab
358
+ value="early-stop"
359
+ active={Boolean(
360
+ flowModule.stop_after_if || flowModule.stop_after_all_iters_if
361
+ )}
362
+ >
357
363
  Early Stop
358
364
  </Tab>
359
365
  <Tab value="suspend" active={Boolean(flowModule.suspend)}>Suspend</Tab>
@@ -6,84 +6,211 @@ import { getContext } from 'svelte';
6
6
  import { NEVER_TESTED_THIS_FAR } from '../models';
7
7
  import Section from '../../Section.svelte';
8
8
  import { getStepPropPicker } from '../previousResults';
9
+ import { dfs } from '../previousResults';
9
10
  const { flowStateStore, flowStore, previewArgs } = getContext('FlowEditorContext');
10
11
  export let flowModule;
11
12
  let editor = undefined;
12
13
  $: stepPropPicker = getStepPropPicker($flowStateStore, undefined, undefined, flowModule.id, $flowStore, $previewArgs, false);
14
+ function checkIfParentLoop(flowStore) {
15
+ const flow = JSON.parse(JSON.stringify(flowStore));
16
+ const parents = dfs(flowModule.id, flow, true);
17
+ for (const parent of parents.slice(1)) {
18
+ if (parent.value.type === 'forloopflow' || parent.value.type === 'whileloopflow') {
19
+ return parent.id;
20
+ }
21
+ }
22
+ return null;
23
+ }
24
+ $: isLoop = flowModule.value.type === 'forloopflow' || flowModule.value.type === 'whileloopflow';
25
+ $: isBranchAll = flowModule.value.type === 'branchall';
13
26
  $: isStopAfterIfEnabled = Boolean(flowModule.stop_after_if);
27
+ $: isStopAfterAllIterationsEnabled = Boolean(flowModule.stop_after_all_iters_if);
14
28
  $: result = $flowStateStore[flowModule.id]?.previewResult ?? NEVER_TESTED_THIS_FAR;
29
+ $: parentLoopId = checkIfParentLoop($flowStore);
15
30
  </script>
16
31
 
17
32
  <div class="flex flex-col items-start space-y-2 {$$props.class}">
18
- <Section label="Early stop/Break" class="w-full">
19
- <svelte:fragment slot="header">
20
- <Tooltip documentationLink="https://www.windmill.dev/docs/flows/early_stop">
21
- If defined, at the end of the step, the predicate expression will be evaluated to decide if
22
- the flow should stop early.
23
- </Tooltip>
24
- </svelte:fragment>
33
+ {#if !isBranchAll}
34
+ <Section
35
+ label={(isLoop
36
+ ? 'Break loop'
37
+ : parentLoopId
38
+ ? 'Break parent loop module ' + parentLoopId
39
+ : 'Stop flow early') + (isLoop ? ' (evaluated after each iteration)' : '')}
40
+ class="w-full"
41
+ >
42
+ <svelte:fragment slot="header">
43
+ <Tooltip documentationLink="https://www.windmill.dev/docs/flows/early_stop">
44
+ If defined, at the end of the step, the predicate expression will be evaluated to decide
45
+ if the flow should stop early or break if inside a for/while loop.
46
+ </Tooltip>
47
+ </svelte:fragment>
25
48
 
26
- <Toggle
27
- checked={isStopAfterIfEnabled}
28
- on:change={() => {
29
- if (isStopAfterIfEnabled && flowModule.stop_after_if) {
30
- flowModule.stop_after_if = undefined
31
- } else {
32
- flowModule.stop_after_if = {
33
- expr: 'result == undefined',
34
- skip_if_stopped: false
49
+ <Toggle
50
+ checked={isStopAfterIfEnabled}
51
+ on:change={() => {
52
+ if (isStopAfterIfEnabled && flowModule.stop_after_if) {
53
+ flowModule.stop_after_if = undefined
54
+ } else {
55
+ flowModule.stop_after_if = {
56
+ expr: 'result == undefined',
57
+ skip_if_stopped: false
58
+ }
35
59
  }
36
- }
37
- }}
38
- options={{
39
- right: 'Early stop or Break if condition met'
40
- }}
41
- />
60
+ }}
61
+ options={{
62
+ right: isLoop
63
+ ? 'Break loop'
64
+ : parentLoopId
65
+ ? 'Break parent loop module'
66
+ : 'Stop flow' + ' if condition met'
67
+ }}
68
+ />
69
+
70
+ <div
71
+ class="w-full border p-2 flex flex-col {flowModule.stop_after_if
72
+ ? ''
73
+ : 'bg-surface-secondary'}"
74
+ >
75
+ {#if flowModule.stop_after_if}
76
+ {@const earlyStopResult = isLoop
77
+ ? Array.isArray(result) && result.length > 0
78
+ ? result[result.length - 1]
79
+ : result === NEVER_TESTED_THIS_FAR
80
+ ? result
81
+ : undefined
82
+ : result}
83
+ {#if !parentLoopId && !isLoop}
84
+ <Toggle
85
+ size="xs"
86
+ bind:checked={flowModule.stop_after_if.skip_if_stopped}
87
+ options={{
88
+ right: 'Label flow as "skipped" if stopped'
89
+ }}
90
+ />
91
+ {/if}
92
+ <span class="mt-2 text-xs font-bold">Stop condition expression</span>
93
+ <div class="border w-full">
94
+ <PropPickerWrapper
95
+ notSelectable
96
+ flow_input={stepPropPicker.pickableProperties.flow_input}
97
+ pickableProperties={undefined}
98
+ result={earlyStopResult}
99
+ extraResults={isLoop ? { all_iters: result } : undefined}
100
+ on:select={({ detail }) => {
101
+ editor?.insertAtCursor(detail)
102
+ editor?.focus()
103
+ }}
104
+ >
105
+ <SimpleEditor
106
+ bind:this={editor}
107
+ lang="javascript"
108
+ bind:code={flowModule.stop_after_if.expr}
109
+ class="few-lines-editor"
110
+ extraLib={`declare const result = ${JSON.stringify(earlyStopResult)};` +
111
+ (isLoop ? `\ndeclare const all_iters = ${JSON.stringify(result)};` : '')}
112
+ />
113
+ </PropPickerWrapper>
114
+ </div>
115
+ {:else}
116
+ {#if !parentLoopId && !isLoop}
117
+ <Toggle
118
+ disabled
119
+ size="xs"
120
+ options={{
121
+ right: 'Label flow as "skipped" if stopped'
122
+ }}
123
+ />
124
+ {/if}
125
+ <span class="mt-2 text-xs font-bold">Stop condition expression</span>
126
+ <textarea disabled rows="3" class="min-h-[80px]" />
127
+ {/if}
128
+ </div>
129
+ </Section>
130
+ {/if}
42
131
 
43
- <div
44
- class="w-full border p-2 flex flex-col {flowModule.stop_after_if
45
- ? ''
46
- : 'bg-surface-secondary'}"
132
+ {#if isLoop || isBranchAll}
133
+ <Section
134
+ label={(parentLoopId ? 'Break parent loop module ' + parentLoopId : 'Stop flow early') +
135
+ (isBranchAll
136
+ ? ' (evaluated after all branches have been run)'
137
+ : ' (evaluated after all iterations)')}
138
+ class="w-full"
47
139
  >
48
- {#if flowModule.stop_after_if}
49
- <Toggle
50
- size="xs"
51
- bind:checked={flowModule.stop_after_if.skip_if_stopped}
52
- options={{
53
- right: 'Label flow as "skipped" if stopped'
54
- }}
55
- />
56
- <span class="mt-2 text-xs font-bold">Stop condition expression</span>
57
- <div class="border w-full">
58
- <PropPickerWrapper
59
- notSelectable
60
- flow_input={stepPropPicker.pickableProperties.flow_input}
61
- pickableProperties={undefined}
62
- {result}
63
- on:select={({ detail }) => {
64
- editor?.insertAtCursor(detail)
65
- editor?.focus()
66
- }}
67
- >
68
- <SimpleEditor
69
- bind:this={editor}
70
- lang="javascript"
71
- bind:code={flowModule.stop_after_if.expr}
72
- class="few-lines-editor"
73
- extraLib={`declare const result = ${JSON.stringify(result)};`}
140
+ <svelte:fragment slot="header">
141
+ <Tooltip documentationLink="https://www.windmill.dev/docs/flows/early_stop">
142
+ If defined, at the end of the step, the predicate expression will be evaluated to decide
143
+ if the flow should stop early or break if inside a for/while loop.
144
+ </Tooltip>
145
+ </svelte:fragment>
146
+
147
+ <Toggle
148
+ checked={isStopAfterAllIterationsEnabled}
149
+ on:change={() => {
150
+ if (isStopAfterAllIterationsEnabled && flowModule.stop_after_all_iters_if) {
151
+ flowModule.stop_after_all_iters_if = undefined
152
+ } else {
153
+ flowModule.stop_after_all_iters_if = {
154
+ expr: 'result == undefined',
155
+ skip_if_stopped: false
156
+ }
157
+ }
158
+ }}
159
+ options={{
160
+ right: (parentLoopId ? 'Break parent loop module' : 'Stop flow') + ' if condition met'
161
+ }}
162
+ />
163
+
164
+ <div
165
+ class="w-full border p-2 flex flex-col {flowModule.stop_after_all_iters_if
166
+ ? ''
167
+ : 'bg-surface-secondary'}"
168
+ >
169
+ {#if flowModule.stop_after_all_iters_if}
170
+ {#if !parentLoopId}
171
+ <Toggle
172
+ size="xs"
173
+ bind:checked={flowModule.stop_after_all_iters_if.skip_if_stopped}
174
+ options={{
175
+ right: 'Label flow as "skipped" if stopped'
176
+ }}
177
+ />
178
+ {/if}
179
+ <span class="mt-2 text-xs font-bold">Stop condition expression</span>
180
+ <div class="border w-full">
181
+ <PropPickerWrapper
182
+ notSelectable
183
+ flow_input={stepPropPicker.pickableProperties.flow_input}
184
+ pickableProperties={undefined}
185
+ {result}
186
+ on:select={({ detail }) => {
187
+ editor?.insertAtCursor(detail)
188
+ editor?.focus()
189
+ }}
190
+ >
191
+ <SimpleEditor
192
+ bind:this={editor}
193
+ lang="javascript"
194
+ bind:code={flowModule.stop_after_all_iters_if.expr}
195
+ class="few-lines-editor"
196
+ extraLib={`declare const result = ${JSON.stringify(result)};`}
197
+ />
198
+ </PropPickerWrapper>
199
+ </div>
200
+ {:else}
201
+ {#if !parentLoopId}
202
+ <Toggle
203
+ disabled
204
+ size="xs"
205
+ options={{
206
+ right: 'Label flow as "skipped" if stopped'
207
+ }}
74
208
  />
75
- </PropPickerWrapper>
76
- </div>
77
- {:else}
78
- <Toggle
79
- disabled
80
- size="xs"
81
- options={{
82
- right: 'Label flow as "skipped" if stopped'
83
- }}
84
- /> <span class="mt-2 text-xs font-bold">Stop condition expression</span>
85
- <textarea disabled rows="3" class="min-h-[80px]" />
86
- {/if}
87
- </div>
88
- </Section>
209
+ {/if}
210
+ <span class="mt-2 text-xs font-bold">Stop condition expression</span>
211
+ <textarea disabled rows="3" class="min-h-[80px]" />
212
+ {/if}
213
+ </div>
214
+ </Section>
215
+ {/if}
89
216
  </div>
@@ -51,7 +51,7 @@ $: moduleRetry = module.retry?.constant || module.retry?.exponential;
51
51
  <svelte:fragment slot="text">Cache</svelte:fragment>
52
52
  </Popover>
53
53
  {/if}
54
- {#if module.stop_after_if}
54
+ {#if module.stop_after_if || module.stop_after_all_iters_if}
55
55
  <Popover
56
56
  placement="bottom"
57
57
  class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"