windmill-components 1.503.3 → 1.503.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/components/AppWrapper.svelte +3 -0
- package/package/components/Dev.svelte +94 -4
- package/package/components/FlowBuilder.svelte +89 -7
- package/package/components/FlowPreviewContent.svelte +309 -278
- package/package/components/FlowPreviewContent.svelte.d.ts +33 -19
- package/package/components/FlowPreviewResult.svelte +74 -0
- package/package/components/FlowPreviewResult.svelte.d.ts +21 -0
- package/package/components/FlowStatusViewer.svelte +3 -1
- package/package/components/FlowStatusViewer.svelte.d.ts +2 -0
- package/package/components/FlowStatusViewerInner.svelte +15 -70
- package/package/components/FlowStatusWaitingForEvents.svelte +5 -2
- package/package/components/FlowStatusWaitingForEvents.svelte.d.ts +1 -0
- package/package/components/FlowWrapper.svelte +3 -0
- package/package/components/ModuleTest.svelte +26 -24
- package/package/components/ScriptWrapper.svelte +3 -0
- package/package/components/common/button/Button.svelte +2 -1
- package/package/components/common/button/Button.svelte.d.ts +2 -1
- package/package/components/flows/FlowEditor.svelte +23 -2
- package/package/components/flows/FlowEditor.svelte.d.ts +23 -3
- package/package/components/flows/content/FlowEditorPanel.svelte +4 -3
- package/package/components/flows/content/FlowEditorPanel.svelte.d.ts +12 -2
- package/package/components/flows/content/FlowInput.svelte +2 -2
- package/package/components/flows/content/FlowInput.svelte.d.ts +1 -1
- package/package/components/flows/content/FlowResult.svelte +35 -0
- package/package/components/flows/content/FlowResult.svelte.d.ts +17 -0
- package/package/components/flows/header/FlowPreviewButtons.svelte +81 -46
- package/package/components/flows/map/FlowGraphPreviewButton.svelte +94 -0
- package/package/components/flows/map/FlowGraphPreviewButton.svelte.d.ts +17 -0
- package/package/components/flows/map/FlowModuleSchemaItem.svelte +296 -285
- package/package/components/flows/map/FlowModuleSchemaItem.svelte.d.ts +6 -0
- package/package/components/flows/map/FlowModuleSchemaMap.svelte +20 -1
- package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +20 -1
- package/package/components/flows/map/MapItem.svelte +25 -3
- package/package/components/flows/map/MapItem.svelte.d.ts +6 -1
- package/package/components/flows/map/VirtualItem.svelte +55 -3
- package/package/components/flows/map/VirtualItem.svelte.d.ts +13 -1
- package/package/components/flows/map/VirtualItemWrapper.svelte +33 -29
- package/package/components/flows/map/VirtualItemWrapper.svelte.d.ts +1 -0
- package/package/components/flows/propPicker/OutputPicker.svelte +17 -2
- package/package/components/flows/propPicker/OutputPicker.svelte.d.ts +4 -0
- package/package/components/flows/propPicker/OutputPickerInner.svelte +2 -2
- package/package/components/flows/propPicker/OutputPickerInner.svelte.d.ts +1 -0
- package/package/components/flows/types.d.ts +3 -0
- package/package/components/flows/utils.d.ts +9 -0
- package/package/components/flows/utils.js +39 -0
- package/package/components/graph/FlowGraphV2.svelte +27 -4
- package/package/components/graph/FlowGraphV2.svelte.d.ts +18 -2
- package/package/components/graph/ViewportResizer.svelte +33 -1
- package/package/components/graph/ViewportResizer.svelte.d.ts +5 -1
- package/package/components/graph/graphBuilder.svelte.d.ts +26 -1
- package/package/components/graph/graphBuilder.svelte.js +13 -3
- package/package/components/graph/renderers/edges/BaseEdge.svelte +69 -2
- package/package/components/graph/renderers/edges/BaseEdge.svelte.d.ts +10 -0
- package/package/components/graph/renderers/nodes/InputNode.svelte +19 -1
- package/package/components/graph/renderers/nodes/ModuleNode.svelte +17 -2
- package/package/components/graph/renderers/nodes/ResultNode.svelte +9 -8
- package/package/components/modulesTest.svelte.d.ts +12 -0
- package/package/components/modulesTest.svelte.js +8 -0
- package/package/components/preview/FlowPreviewStatus.svelte +9 -4
- package/package/components/preview/FlowPreviewStatus.svelte.d.ts +6 -18
- package/package/components/schema/EditableSchemaSdkWrapper.svelte +3 -0
- package/package/utils.js +2 -0
- package/package.json +1 -1
- package/package/components/flows/header/FlowPreviewButtons.svelte.d.ts +0 -26
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
1
|
+
<script lang="ts">import { run, stopPropagation } from 'svelte/legacy';
|
|
2
|
+
import { JobService } from '../gen';
|
|
2
3
|
import { workspaceStore } from '../stores';
|
|
3
4
|
import { Badge, Button } from './common';
|
|
4
5
|
import Popover from './meltComponents/Popover.svelte';
|
|
@@ -20,36 +21,26 @@ import { writable } from 'svelte/store';
|
|
|
20
21
|
import { getStepHistoryLoaderContext } from './stepHistoryLoader.svelte';
|
|
21
22
|
import { aiChatManager } from './copilot/chat/AIChatManager.svelte';
|
|
22
23
|
import { stateSnapshot } from '../svelte5Utils.svelte';
|
|
23
|
-
|
|
24
|
-
export let open;
|
|
25
|
-
export let preventEscape = false;
|
|
26
|
-
export let jobId = undefined;
|
|
27
|
-
export let job = undefined;
|
|
28
|
-
export let selectedJobStep = undefined;
|
|
29
|
-
export let selectedJobStepIsTopLevel = undefined;
|
|
30
|
-
export let selectedJobStepType = 'single';
|
|
31
|
-
export let rightColumnSelect = 'timeline';
|
|
32
|
-
export let branchOrIterationN = 0;
|
|
33
|
-
export let scrollTop = 0;
|
|
34
|
-
export let localModuleStates = writable({});
|
|
35
|
-
export let localDurationStatuses = writable({});
|
|
24
|
+
let { previewMode = $bindable(), open, preventEscape = $bindable(false), jobId = $bindable(undefined), job = $bindable(undefined), initial = $bindable(false), selectedJobStep = $bindable(undefined), selectedJobStepIsTopLevel = $bindable(undefined), selectedJobStepType = $bindable('single'), rightColumnSelect = $bindable('timeline'), branchOrIterationN = $bindable(0), scrollTop = $bindable(0), localModuleStates = $bindable(writable({})), localDurationStatuses = $bindable(writable({})), onRunPreview, render = false, onJobDone, upToId = undefined } = $props();
|
|
36
25
|
let restartBranchNames = [];
|
|
37
|
-
let isRunning = false;
|
|
38
|
-
let
|
|
39
|
-
let
|
|
40
|
-
let
|
|
41
|
-
let
|
|
42
|
-
let
|
|
26
|
+
let isRunning = $state(false);
|
|
27
|
+
let jsonView = $state(false);
|
|
28
|
+
let jsonEditor = $state(undefined);
|
|
29
|
+
let schemaHeight = $state(0);
|
|
30
|
+
let isValid = $state(true);
|
|
31
|
+
let suspendStatus = $state(writable({}));
|
|
32
|
+
let isOwner = $state(false);
|
|
43
33
|
export function test() {
|
|
44
34
|
renderCount++;
|
|
45
35
|
runPreview(previewArgs.val, undefined);
|
|
46
36
|
}
|
|
47
|
-
const { selectedId, previewArgs, flowStateStore, flowStore, pathStore, initialPathStore, fakeInitialPath, customUi, executionCount } = getContext('FlowEditorContext');
|
|
37
|
+
const { selectedId, previewArgs, flowStateStore, flowStore, pathStore, initialPathStore, fakeInitialPath, customUi, executionCount } = $state(getContext('FlowEditorContext'));
|
|
48
38
|
const dispatch = createEventDispatcher();
|
|
39
|
+
let renderCount = $state(0);
|
|
40
|
+
let schemaFormWithArgPicker = $state(undefined);
|
|
41
|
+
let currentJobId = $state(undefined);
|
|
49
42
|
let stepHistoryLoader = getStepHistoryLoaderContext();
|
|
50
|
-
let
|
|
51
|
-
let schemaFormWithArgPicker = undefined;
|
|
52
|
-
let currentJobId = undefined;
|
|
43
|
+
let flowProgressBar = $state(undefined);
|
|
53
44
|
function extractFlow(previewMode) {
|
|
54
45
|
const previewFlow = aiChatManager.flowAiChatHelpers?.getPreviewFlow();
|
|
55
46
|
if (previewMode === 'whole') {
|
|
@@ -58,21 +49,21 @@ function extractFlow(previewMode) {
|
|
|
58
49
|
else {
|
|
59
50
|
const flow = previewFlow ?? stateSnapshot(flowStore).val;
|
|
60
51
|
const idOrders = dfs(flow.value.modules, (x) => x.id);
|
|
61
|
-
let upToIndex = idOrders.indexOf($selectedId);
|
|
52
|
+
let upToIndex = idOrders.indexOf(upToId ?? $selectedId);
|
|
62
53
|
if (upToIndex != -1) {
|
|
63
54
|
flow.value.modules = sliceModules(flow.value.modules, upToIndex, idOrders);
|
|
64
55
|
}
|
|
65
56
|
return flow;
|
|
66
57
|
}
|
|
67
58
|
}
|
|
68
|
-
let lastPreviewFlow = undefined;
|
|
59
|
+
let lastPreviewFlow = $state(undefined);
|
|
69
60
|
export async function runPreview(args, restartedFrom) {
|
|
70
61
|
if (stepHistoryLoader?.flowJobInitial) {
|
|
71
62
|
stepHistoryLoader?.setFlowJobInitial(false);
|
|
72
63
|
}
|
|
73
64
|
try {
|
|
74
65
|
lastPreviewFlow = JSON.stringify(flowStore.val);
|
|
75
|
-
|
|
66
|
+
flowProgressBar?.reset();
|
|
76
67
|
const newFlow = extractFlow(previewMode);
|
|
77
68
|
jobId = await runFlowPreview(args, newFlow, $pathStore, restartedFrom);
|
|
78
69
|
isRunning = true;
|
|
@@ -80,6 +71,7 @@ export async function runPreview(args, restartedFrom) {
|
|
|
80
71
|
savedArgs = previewArgs.val;
|
|
81
72
|
inputSelected = undefined;
|
|
82
73
|
}
|
|
74
|
+
onRunPreview?.();
|
|
83
75
|
}
|
|
84
76
|
catch (e) {
|
|
85
77
|
sendUserToast('Could not run preview', true, undefined, e.toString());
|
|
@@ -129,8 +121,8 @@ function onSelectedJobStepChange() {
|
|
|
129
121
|
}
|
|
130
122
|
}
|
|
131
123
|
}
|
|
132
|
-
let savedArgs = previewArgs.val;
|
|
133
|
-
let inputSelected = undefined;
|
|
124
|
+
let savedArgs = $state(previewArgs.val);
|
|
125
|
+
let inputSelected = $state(undefined);
|
|
134
126
|
async function selectInput(input, type) {
|
|
135
127
|
if (!input) {
|
|
136
128
|
previewArgs.val = savedArgs;
|
|
@@ -149,293 +141,327 @@ async function selectInput(input, type) {
|
|
|
149
141
|
export function refresh() {
|
|
150
142
|
renderCount++;
|
|
151
143
|
}
|
|
152
|
-
$: if (job?.type === 'CompletedJob') {
|
|
153
|
-
isRunning = false;
|
|
154
|
-
}
|
|
155
|
-
$: selectedJobStep !== undefined && onSelectedJobStepChange();
|
|
156
144
|
let scrollableDiv = undefined;
|
|
157
145
|
function handleScroll() {
|
|
158
146
|
scrollTop = scrollableDiv?.scrollTop ?? 0;
|
|
159
147
|
}
|
|
160
|
-
$: scrollableDiv && onScrollableDivChange();
|
|
161
148
|
function onScrollableDivChange() {
|
|
162
149
|
if (scrollTop != 0 && scrollableDiv) {
|
|
163
150
|
scrollableDiv.scrollTop = scrollTop;
|
|
164
151
|
}
|
|
165
152
|
}
|
|
153
|
+
run(() => {
|
|
154
|
+
selectedJobStep !== undefined && onSelectedJobStepChange();
|
|
155
|
+
});
|
|
156
|
+
run(() => {
|
|
157
|
+
scrollableDiv && onScrollableDivChange();
|
|
158
|
+
});
|
|
159
|
+
export async function cancelTest() {
|
|
160
|
+
isRunning = false;
|
|
161
|
+
try {
|
|
162
|
+
jobId &&
|
|
163
|
+
(await JobService.cancelQueuedJob({
|
|
164
|
+
workspace: $workspaceStore ?? '',
|
|
165
|
+
id: jobId,
|
|
166
|
+
requestBody: {}
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
catch { }
|
|
170
|
+
}
|
|
171
|
+
export function getLocalModuleStates() {
|
|
172
|
+
return localModuleStates;
|
|
173
|
+
}
|
|
174
|
+
export function getLocalDurationStatuses() {
|
|
175
|
+
return localDurationStatuses;
|
|
176
|
+
}
|
|
177
|
+
export function getSuspendStatus() {
|
|
178
|
+
return suspendStatus;
|
|
179
|
+
}
|
|
180
|
+
export function getIsRunning() {
|
|
181
|
+
return isRunning;
|
|
182
|
+
}
|
|
183
|
+
export function getIsOwner() {
|
|
184
|
+
return isOwner;
|
|
185
|
+
}
|
|
186
|
+
export function getJob() {
|
|
187
|
+
return job;
|
|
188
|
+
}
|
|
189
|
+
export function flowHasChanged() {
|
|
190
|
+
return !!lastPreviewFlow && JSON.stringify(flowStore.val) != lastPreviewFlow;
|
|
191
|
+
}
|
|
166
192
|
</script>
|
|
167
193
|
|
|
168
|
-
<svelte:window
|
|
194
|
+
<svelte:window onkeydown={onKeyDown} />
|
|
169
195
|
|
|
170
196
|
<div class="flex flex-col space-y-2 h-screen bg-surface px-4 py-2 w-full" id="flow-preview-content">
|
|
171
|
-
|
|
172
|
-
<div class="w-
|
|
173
|
-
<
|
|
174
|
-
on:click={() => dispatch('close')}
|
|
175
|
-
startIcon={{ icon: X }}
|
|
176
|
-
iconOnly
|
|
177
|
-
size="sm"
|
|
178
|
-
color="light"
|
|
179
|
-
btnClasses="hover:bg-surface-hover bg-surface-secondaryw-8 h-8 rounded-full p-0"
|
|
180
|
-
/>
|
|
181
|
-
</div>
|
|
182
|
-
|
|
183
|
-
{#if isRunning}
|
|
184
|
-
<div class="mx-auto">
|
|
197
|
+
{#if render}
|
|
198
|
+
<div class="flex flex-row w-full items-center gap-x-2">
|
|
199
|
+
<div class="w-8">
|
|
185
200
|
<Button
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
try {
|
|
190
|
-
jobId &&
|
|
191
|
-
(await JobService.cancelQueuedJob({
|
|
192
|
-
workspace: $workspaceStore ?? '',
|
|
193
|
-
id: jobId,
|
|
194
|
-
requestBody: {}
|
|
195
|
-
}))
|
|
196
|
-
} catch {}
|
|
197
|
-
}}
|
|
201
|
+
on:click={() => dispatch('close')}
|
|
202
|
+
startIcon={{ icon: X }}
|
|
203
|
+
iconOnly
|
|
198
204
|
size="sm"
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
>
|
|
203
|
-
Cancel
|
|
204
|
-
</Button>
|
|
205
|
+
color="light"
|
|
206
|
+
btnClasses="hover:bg-surface-hover bg-surface-secondaryw-8 h-8 rounded-full p-0"
|
|
207
|
+
/>
|
|
205
208
|
</div>
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
209
|
+
|
|
210
|
+
{#if isRunning}
|
|
211
|
+
<div class="mx-auto">
|
|
212
|
+
<Button
|
|
213
|
+
color="red"
|
|
214
|
+
on:click={async () => {
|
|
215
|
+
cancelTest()
|
|
216
|
+
}}
|
|
217
|
+
size="sm"
|
|
218
|
+
btnClasses="w-full max-w-lg"
|
|
219
|
+
loading={true}
|
|
220
|
+
clickableWhileLoading
|
|
221
|
+
>
|
|
222
|
+
Cancel
|
|
223
|
+
</Button>
|
|
224
|
+
</div>
|
|
225
|
+
{:else}
|
|
226
|
+
<div class="grow justify-center flex flex-row gap-4">
|
|
227
|
+
{#if jobId !== undefined && selectedJobStep !== undefined && selectedJobStepIsTopLevel && aiChatManager.flowAiChatHelpers?.getModuleAction(selectedJobStep) !== 'removed'}
|
|
228
|
+
{#if selectedJobStepType == 'single'}
|
|
229
|
+
<Button
|
|
230
|
+
size="xs"
|
|
231
|
+
color="light"
|
|
232
|
+
variant="border"
|
|
233
|
+
title={`Re-start this flow from step ${selectedJobStep} (included).`}
|
|
234
|
+
on:click={() => {
|
|
235
|
+
runPreview(previewArgs.val, {
|
|
236
|
+
flow_job_id: jobId,
|
|
237
|
+
step_id: selectedJobStep,
|
|
238
|
+
branch_or_iteration_n: 0
|
|
239
|
+
})
|
|
240
|
+
}}
|
|
241
|
+
startIcon={{ icon: Play }}
|
|
242
|
+
>
|
|
243
|
+
Re-start from
|
|
244
|
+
<Badge baseClass="ml-1" color="indigo">
|
|
245
|
+
{selectedJobStep}
|
|
246
|
+
</Badge>
|
|
247
|
+
</Button>
|
|
248
|
+
{:else}
|
|
249
|
+
<Popover
|
|
250
|
+
floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}
|
|
251
|
+
contentClasses="p-4"
|
|
252
|
+
>
|
|
253
|
+
{#snippet button()}
|
|
254
|
+
<Button
|
|
255
|
+
title={`Re-start this flow from step ${selectedJobStep} (included).`}
|
|
256
|
+
variant="border"
|
|
257
|
+
color="blue"
|
|
258
|
+
startIcon={{ icon: RefreshCw }}
|
|
259
|
+
on:click={() => {
|
|
260
|
+
runPreview(previewArgs.val, {
|
|
261
|
+
flow_job_id: jobId,
|
|
262
|
+
step_id: selectedJobStep,
|
|
263
|
+
branch_or_iteration_n: 0
|
|
264
|
+
})
|
|
265
|
+
}}
|
|
266
|
+
nonCaptureEvent={true}
|
|
259
267
|
>
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
class="!w-32 grow"
|
|
273
|
-
on:click|stopPropagation={() => {}}
|
|
274
|
-
>
|
|
275
|
-
{#each restartBranchNames as [branchIdx, branchName]}
|
|
276
|
-
<option value={branchIdx}>{branchName}</option>
|
|
277
|
-
{/each}
|
|
278
|
-
</select>
|
|
279
|
-
{/if}
|
|
280
|
-
<Button
|
|
281
|
-
size="xs"
|
|
282
|
-
color="blue"
|
|
283
|
-
buttonType="button"
|
|
284
|
-
btnClasses="!p-1 !w-[34px] !ml-1"
|
|
285
|
-
aria-label="Restart flow"
|
|
286
|
-
on:click|once={() => {
|
|
287
|
-
runPreview(previewArgs.val, {
|
|
288
|
-
flow_job_id: jobId,
|
|
289
|
-
step_id: selectedJobStep,
|
|
290
|
-
branch_or_iteration_n: branchOrIterationN
|
|
291
|
-
})
|
|
292
|
-
}}
|
|
268
|
+
Re-start from
|
|
269
|
+
<Badge baseClass="ml-1" color="indigo">
|
|
270
|
+
{selectedJobStep}
|
|
271
|
+
</Badge>
|
|
272
|
+
</Button>
|
|
273
|
+
{/snippet}
|
|
274
|
+
{#snippet content()}
|
|
275
|
+
<label class="block text-primary p-4">
|
|
276
|
+
<div class="pb-1 text-sm text-secondary"
|
|
277
|
+
>{selectedJobStepType == 'forloop'
|
|
278
|
+
? 'From iteration #:'
|
|
279
|
+
: 'From branch:'}</div
|
|
293
280
|
>
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
281
|
+
<div class="flex w-full">
|
|
282
|
+
{#if selectedJobStepType === 'forloop'}
|
|
283
|
+
<input
|
|
284
|
+
type="number"
|
|
285
|
+
min="0"
|
|
286
|
+
bind:value={branchOrIterationN}
|
|
287
|
+
class="!w-32 grow"
|
|
288
|
+
onclick={stopPropagation(() => {})}
|
|
289
|
+
/>
|
|
290
|
+
{:else}
|
|
291
|
+
<select
|
|
292
|
+
bind:value={branchOrIterationN}
|
|
293
|
+
class="!w-32 grow"
|
|
294
|
+
onclick={stopPropagation(() => {})}
|
|
295
|
+
>
|
|
296
|
+
{#each restartBranchNames as [branchIdx, branchName]}
|
|
297
|
+
<option value={branchIdx}>{branchName}</option>
|
|
298
|
+
{/each}
|
|
299
|
+
</select>
|
|
300
|
+
{/if}
|
|
301
|
+
<Button
|
|
302
|
+
size="xs"
|
|
303
|
+
color="blue"
|
|
304
|
+
buttonType="button"
|
|
305
|
+
btnClasses="!p-1 !w-[34px] !ml-1"
|
|
306
|
+
aria-label="Restart flow"
|
|
307
|
+
on:click|once={() => {
|
|
308
|
+
runPreview(previewArgs.val, {
|
|
309
|
+
flow_job_id: jobId,
|
|
310
|
+
step_id: selectedJobStep,
|
|
311
|
+
branch_or_iteration_n: branchOrIterationN
|
|
312
|
+
})
|
|
313
|
+
}}
|
|
314
|
+
>
|
|
315
|
+
<ArrowRight size={18} />
|
|
316
|
+
</Button>
|
|
317
|
+
</div>
|
|
318
|
+
</label>
|
|
319
|
+
{/snippet}
|
|
320
|
+
</Popover>
|
|
321
|
+
{/if}
|
|
319
322
|
{/if}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
323
|
+
<Button
|
|
324
|
+
variant="contained"
|
|
325
|
+
startIcon={{ icon: isRunning ? RefreshCw : Play }}
|
|
326
|
+
color="dark"
|
|
327
|
+
size="sm"
|
|
328
|
+
btnClasses="w-full max-w-lg"
|
|
329
|
+
on:click={() => runPreview(previewArgs.val, undefined)}
|
|
330
|
+
id="flow-editor-test-flow-drawer"
|
|
331
|
+
shortCut={{ Icon: CornerDownLeft }}
|
|
332
|
+
>
|
|
333
|
+
{#if previewMode == 'upTo'}
|
|
334
|
+
Test up to
|
|
335
|
+
<Badge baseClass="ml-1" color="indigo">
|
|
336
|
+
{$selectedId}
|
|
337
|
+
</Badge>
|
|
338
|
+
{:else}
|
|
339
|
+
Test flow
|
|
340
|
+
{/if}
|
|
341
|
+
</Button>
|
|
332
342
|
</div>
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
<FlowProgressBar {job} bind:reset={jobProgressReset} />
|
|
336
|
-
</div>
|
|
343
|
+
{/if}
|
|
344
|
+
</div>
|
|
337
345
|
|
|
346
|
+
<div class="w-full flex flex-col gap-y-1">
|
|
347
|
+
{#if flowHasChanged()}
|
|
348
|
+
<div class="pt-1">
|
|
349
|
+
<div
|
|
350
|
+
class="bg-orange-200 text-orange-600 border border-orange-600 p-2 flex items-center gap-2 rounded"
|
|
351
|
+
>
|
|
352
|
+
<AlertTriangle size={14} /> Flow changed since last preview
|
|
353
|
+
<div class="flex"></div>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
{/if}
|
|
357
|
+
<FlowProgressBar {job} bind:this={flowProgressBar} />
|
|
358
|
+
</div>
|
|
359
|
+
{/if}
|
|
338
360
|
<div
|
|
339
361
|
bind:this={scrollableDiv}
|
|
340
362
|
class="overflow-y-auto grow flex flex-col pt-4"
|
|
341
|
-
|
|
363
|
+
onscroll={(e) => handleScroll()}
|
|
342
364
|
>
|
|
343
|
-
|
|
344
|
-
<
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
<
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
<div class="flex flex-row gap-2">
|
|
363
|
-
<Toggle
|
|
364
|
-
bind:checked={jsonView}
|
|
365
|
-
label="JSON View"
|
|
366
|
-
size="xs"
|
|
367
|
-
options={{
|
|
368
|
-
right: 'JSON',
|
|
369
|
-
rightTooltip: 'Fill args from JSON'
|
|
370
|
-
}}
|
|
371
|
-
lightMode
|
|
372
|
-
on:change={(e) => {
|
|
373
|
-
jsonEditor?.setCode(JSON.stringify(previewArgs.val ?? {}, null, '\t'))
|
|
374
|
-
refresh()
|
|
375
|
-
}}
|
|
376
|
-
/>
|
|
377
|
-
</div>
|
|
378
|
-
</div>
|
|
379
|
-
{#if jsonView}
|
|
380
|
-
<div class="py-2" style="height: {Math.max(schemaHeight, 100)}px" data-schema-picker>
|
|
381
|
-
<JsonInputs
|
|
382
|
-
bind:this={jsonEditor}
|
|
383
|
-
on:select={(e) => {
|
|
384
|
-
if (e.detail) {
|
|
385
|
-
previewArgs.val = e.detail
|
|
386
|
-
}
|
|
387
|
-
}}
|
|
388
|
-
updateOnBlur={false}
|
|
389
|
-
placeholder={`Write args as JSON.<br/><br/>Example:<br/><br/>{<br/> "foo": "12"<br/>}`}
|
|
365
|
+
{#if render}
|
|
366
|
+
<div class="border-b">
|
|
367
|
+
<SchemaFormWithArgPicker
|
|
368
|
+
bind:this={schemaFormWithArgPicker}
|
|
369
|
+
runnableId={$initialPathStore}
|
|
370
|
+
stablePathForCaptures={$initialPathStore || fakeInitialPath}
|
|
371
|
+
runnableType={'FlowPath'}
|
|
372
|
+
previewArgs={previewArgs.val}
|
|
373
|
+
on:openTriggers
|
|
374
|
+
on:select={(e) => {
|
|
375
|
+
selectInput(e.detail.payload, e.detail?.type)
|
|
376
|
+
}}
|
|
377
|
+
{isValid}
|
|
378
|
+
{jsonView}
|
|
379
|
+
>
|
|
380
|
+
<div class="w-full flex flex-row justify-between">
|
|
381
|
+
<InputSelectedBadge
|
|
382
|
+
onReject={() => schemaFormWithArgPicker?.resetSelected()}
|
|
383
|
+
{inputSelected}
|
|
390
384
|
/>
|
|
385
|
+
<div class="flex flex-row gap-2">
|
|
386
|
+
<Toggle
|
|
387
|
+
bind:checked={jsonView}
|
|
388
|
+
label="JSON View"
|
|
389
|
+
size="xs"
|
|
390
|
+
options={{
|
|
391
|
+
right: 'JSON',
|
|
392
|
+
rightTooltip: 'Fill args from JSON'
|
|
393
|
+
}}
|
|
394
|
+
lightMode
|
|
395
|
+
on:change={(e) => {
|
|
396
|
+
jsonEditor?.setCode(JSON.stringify(previewArgs.val ?? {}, null, '\t'))
|
|
397
|
+
refresh()
|
|
398
|
+
}}
|
|
399
|
+
/>
|
|
400
|
+
</div>
|
|
391
401
|
</div>
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
on:change={() => {
|
|
401
|
-
savedArgs = previewArgs.val
|
|
402
|
+
{#if jsonView}
|
|
403
|
+
<div class="py-2" style="height: {Math.max(schemaHeight, 100)}px" data-schema-picker>
|
|
404
|
+
<JsonInputs
|
|
405
|
+
bind:this={jsonEditor}
|
|
406
|
+
on:select={(e) => {
|
|
407
|
+
if (e.detail) {
|
|
408
|
+
previewArgs.val = e.detail
|
|
409
|
+
}
|
|
402
410
|
}}
|
|
403
|
-
|
|
411
|
+
updateOnBlur={false}
|
|
412
|
+
placeholder={`Write args as JSON.<br/><br/>Example:<br/><br/>{<br/> "foo": "12"<br/>}`}
|
|
404
413
|
/>
|
|
405
414
|
</div>
|
|
406
|
-
{
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
415
|
+
{:else}
|
|
416
|
+
{#key renderCount}
|
|
417
|
+
<div bind:clientHeight={schemaHeight} class="min-h-[40vh]">
|
|
418
|
+
<SchemaForm
|
|
419
|
+
noVariablePicker
|
|
420
|
+
compact
|
|
421
|
+
schema={flowStore.val.schema}
|
|
422
|
+
bind:args={previewArgs.val}
|
|
423
|
+
on:change={() => {
|
|
424
|
+
savedArgs = previewArgs.val
|
|
425
|
+
}}
|
|
426
|
+
bind:isValid
|
|
427
|
+
/>
|
|
428
|
+
</div>
|
|
429
|
+
{/key}
|
|
430
|
+
{/if}
|
|
431
|
+
</SchemaFormWithArgPicker>
|
|
432
|
+
</div>
|
|
433
|
+
{/if}
|
|
410
434
|
<div class="pt-4 flex flex-col grow relative">
|
|
411
435
|
<div
|
|
412
436
|
class="absolute top-[22px] right-2 border p-1.5 hover:bg-surface-hover rounded-md center-center"
|
|
413
437
|
>
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
currentJobId
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
438
|
+
{#if render}
|
|
439
|
+
<FlowHistoryJobPicker
|
|
440
|
+
selectInitial={jobId == undefined}
|
|
441
|
+
on:select={(e) => {
|
|
442
|
+
if (!currentJobId) {
|
|
443
|
+
currentJobId = jobId
|
|
444
|
+
}
|
|
445
|
+
const detail = e.detail
|
|
446
|
+
jobId = detail.jobId
|
|
447
|
+
if (detail.initial && stepHistoryLoader?.flowJobInitial === undefined) {
|
|
448
|
+
stepHistoryLoader?.setFlowJobInitial(detail.initial)
|
|
449
|
+
}
|
|
450
|
+
}}
|
|
451
|
+
on:unselect={() => {
|
|
452
|
+
jobId = currentJobId
|
|
453
|
+
currentJobId = undefined
|
|
454
|
+
}}
|
|
455
|
+
path={$initialPathStore == '' ? $pathStore : $initialPathStore}
|
|
456
|
+
/>
|
|
457
|
+
{/if}
|
|
432
458
|
</div>
|
|
459
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
433
460
|
{#if jobId}
|
|
434
461
|
{#if stepHistoryLoader?.flowJobInitial}
|
|
435
|
-
<!-- svelte-ignore
|
|
436
|
-
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
462
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
437
463
|
<div
|
|
438
|
-
|
|
464
|
+
onclick={() => {
|
|
439
465
|
stepHistoryLoader?.setFlowJobInitial(false)
|
|
440
466
|
}}
|
|
441
467
|
class="cursor-pointer h-full hover:bg-gray-500/20 dark:hover:bg-gray-500/20 dark:bg-gray-500/80 rounded bg-gray-500/40 absolute top-0 left-0 w-full z-50"
|
|
@@ -451,15 +477,20 @@ function onScrollableDivChange() {
|
|
|
451
477
|
bind:job
|
|
452
478
|
bind:localModuleStates
|
|
453
479
|
bind:localDurationStatuses
|
|
480
|
+
bind:suspendStatus
|
|
454
481
|
hideDownloadInGraph={customUi?.downloadLogs === false}
|
|
455
482
|
wideResults
|
|
456
483
|
{flowStateStore}
|
|
457
484
|
{jobId}
|
|
458
485
|
on:done={() => {
|
|
486
|
+
isRunning = false
|
|
459
487
|
$executionCount = $executionCount + 1
|
|
488
|
+
onJobDone?.()
|
|
460
489
|
}}
|
|
461
490
|
bind:selectedJobStep
|
|
462
491
|
bind:rightColumnSelect
|
|
492
|
+
bind:isOwner
|
|
493
|
+
{render}
|
|
463
494
|
/>
|
|
464
495
|
{:else}
|
|
465
496
|
<div class="italic text-tertiary h-full grow"> Flow status will be displayed here </div>
|