windmill-components 1.687.0 → 1.695.1
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/ArgInput.svelte +2 -0
- package/package/components/AutoscalingConfigEditor.svelte +18 -4
- package/package/components/CompareWorkspaces.svelte +206 -157
- package/package/components/DatatableSchemaDiff.svelte +2 -2
- package/package/components/Dev.svelte +401 -85
- package/package/components/EditableSchemaForm.svelte +4 -0
- package/package/components/ErrorOrRecoveryHandler.svelte +2 -2
- package/package/components/FlowPreviewContent.svelte +32 -30
- package/package/components/FlowRestartButton.svelte +143 -61
- package/package/components/FlowRestartButton.svelte.d.ts +37 -0
- package/package/components/FlowStatusViewer.svelte +15 -1
- package/package/components/FlowStatusViewer.svelte.d.ts +10 -2
- package/package/components/FlowStatusViewerInner.svelte +1 -2
- package/package/components/FlowStatusViewerInner.svelte.d.ts +6 -2
- package/package/components/ForkConflictModal.svelte +57 -0
- package/package/components/ForkConflictModal.svelte.d.ts +3 -0
- package/package/components/GitRepoViewer.svelte +251 -97
- package/package/components/InputTransformSchemaForm.svelte +1 -1
- package/package/components/InstanceSettings.svelte +36 -16
- package/package/components/Login.svelte +113 -28
- package/package/components/Login.svelte.d.ts +1 -0
- package/package/components/Path.svelte +7 -1
- package/package/components/Path.svelte.d.ts +1 -1
- package/package/components/RunsPage.svelte +2 -1
- package/package/components/S3FilePickerInner.svelte +89 -89
- package/package/components/ScriptEditor.svelte +18 -5
- package/package/components/ShareModal.svelte.d.ts +1 -1
- package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +3 -0
- package/package/components/apps/components/helpers/executeRunnable.js +2 -1
- package/package/components/apps/editor/AppReportsDrawerInner.svelte +1 -1
- package/package/components/apps/editor/appPolicy.js +2 -1
- package/package/components/apps/editor/commonAppUtils.d.ts +3 -0
- package/package/components/apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte +1 -1
- package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +7 -0
- package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte +49 -0
- package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte.d.ts +9 -0
- package/package/components/apps/inputType.d.ts +1 -0
- package/package/components/apps/sharedTypes.d.ts +1 -0
- package/package/components/auditLogs/AuditLogsFilters.svelte +8 -3
- package/package/components/common/fileUpload/S3ArgInput.svelte +12 -10
- package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +2 -0
- package/package/components/copilot/chat/AIChatDisplay.svelte +5 -36
- package/package/components/copilot/chat/AIChatInput.svelte +56 -47
- package/package/components/copilot/chat/AIChatManager.svelte.js +48 -46
- package/package/components/copilot/chat/ContextElementBadge.svelte +6 -4
- package/package/components/copilot/chat/app/core.d.ts +12 -20
- package/package/components/copilot/chat/app/core.js +103 -160
- package/package/components/copilot/chat/app/core.test.js +234 -9
- package/package/components/copilot/chat/context.js +44 -0
- package/package/components/copilot/chat/flow/FlowAIChat.svelte +5 -3
- package/package/components/copilot/chat/flow/core.d.ts +2 -1
- package/package/components/copilot/chat/flow/core.js +48 -21
- package/package/components/copilot/chat/flow/helperUtils.d.ts +5 -2
- package/package/components/copilot/chat/flow/helperUtils.js +33 -1
- package/package/components/copilot/chat/flow/helperUtils.test.js +116 -1
- package/package/components/copilot/chat/flow/openFlow.json +1 -1
- package/package/components/copilot/chat/flow/openFlowZod.gen.js +24 -0
- package/package/components/copilot/chat/script/core.js +3 -0
- package/package/components/copilot/chat/shared.d.ts +6 -0
- package/package/components/copilot/chat/shared.js +22 -1
- package/package/components/copilot/chat/shared.test.d.ts +1 -0
- package/package/components/copilot/chat/shared.test.js +412 -0
- package/package/components/copilot/chat/workspaceTools.d.ts +7 -0
- package/package/components/copilot/chat/workspaceTools.js +239 -0
- package/package/components/copilot/chat/workspaceToolsZod.gen.d.ts +1295 -0
- package/package/components/copilot/chat/workspaceToolsZod.gen.js +424 -0
- package/package/components/copilot/lib.js +3 -1
- package/package/components/copilot/lib.test.d.ts +1 -0
- package/package/components/copilot/lib.test.js +19 -0
- package/package/components/copilot/modelConfig.d.ts +3 -0
- package/package/components/copilot/modelConfig.js +10 -0
- package/package/components/flows/FlowProgressBar.svelte +5 -2
- package/package/components/flows/content/FlowModuleComponent.svelte +636 -599
- package/package/components/flows/conversations/FlowChatManager.svelte.js +21 -10
- package/package/components/flows/flowStateUtils.svelte.js +5 -1
- package/package/components/flows/map/FlowModuleSchemaMap.svelte +3 -2
- package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +1 -0
- package/package/components/git_sync/GitSyncContext.svelte.js +0 -2
- package/package/components/graph/FlowGraphV2.svelte +7 -3
- package/package/components/graph/FlowGraphV2.svelte.d.ts +1 -0
- package/package/components/graph/renderers/triggers/TriggersBadge.svelte +3 -0
- package/package/components/home/deploy_ui.js +1 -1
- package/package/components/icons/AzureIcon.svelte +12 -25
- package/package/components/icons/AzureIcon.svelte.d.ts +3 -2
- package/package/components/instanceSettings.js +24 -0
- package/package/components/mcp/McpScopeSelector.svelte +119 -9
- package/package/components/mcp/McpScopeSelector.svelte.d.ts +1 -0
- package/package/components/offboarding-utils.js +2 -0
- package/package/components/progressBar/ProgressBar.svelte +9 -5
- package/package/components/progressBar/ProgressBar.svelte.d.ts +1 -0
- package/package/components/raw_apps/DeleteAfterUsePopup.svelte +52 -0
- package/package/components/raw_apps/DeleteAfterUsePopup.svelte.d.ts +9 -0
- package/package/components/raw_apps/RawAppBackgroundRunner.svelte +5 -1
- package/package/components/raw_apps/RawAppEditor.svelte +159 -102
- package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +9 -3
- package/package/components/raw_apps/RawAppInlineScriptEditor.svelte.d.ts +2 -1
- package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +1 -0
- package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte.d.ts +1 -0
- package/package/components/raw_apps/RawAppInputsSpecEditor.svelte +48 -5
- package/package/components/raw_apps/RawAppSharedUiDrawer.svelte +129 -0
- package/package/components/raw_apps/RawAppSharedUiDrawer.svelte.d.ts +5 -0
- package/package/components/raw_apps/RawAppSidebar.svelte +12 -0
- package/package/components/raw_apps/dataTableRefUtils.d.ts +7 -0
- package/package/components/raw_apps/dataTableRefUtils.js +34 -0
- package/package/components/raw_apps/dataTableRefUtils.test.d.ts +1 -0
- package/package/components/raw_apps/dataTableRefUtils.test.js +29 -0
- package/package/components/raw_apps/rawAppPolicy.d.ts +1 -0
- package/package/components/raw_apps/rawAppPolicy.js +17 -2
- package/package/components/resources/resourceTypesFilter.d.ts +19 -0
- package/package/components/resources/resourceTypesFilter.js +21 -0
- package/package/components/restartFromStepPath.d.ts +39 -0
- package/package/components/restartFromStepPath.js +89 -0
- package/package/components/runs/JobDetailFieldConfig.d.ts +1 -0
- package/package/components/runs/JobDetailFieldConfig.js +57 -10
- package/package/components/runs/JobDetailHeader.svelte +24 -3
- package/package/components/runs/runsFilter.d.ts +1 -1
- package/package/components/schema/FlowPropertyEditor.svelte +30 -1
- package/package/components/schema/FlowPropertyEditor.svelte.d.ts +5 -2
- package/package/components/search/GlobalSearchModal.svelte +8 -1
- package/package/components/select/Select.svelte +1 -1
- package/package/components/settings/CreateToken.svelte +48 -77
- package/package/components/settings/EditTokenScopesModal.svelte +57 -0
- package/package/components/settings/EditTokenScopesModal.svelte.d.ts +10 -0
- package/package/components/settings/ScopesPicker.svelte +43 -0
- package/package/components/settings/ScopesPicker.svelte.d.ts +11 -0
- package/package/components/settings/TokensTable.svelte +51 -15
- package/package/components/sidebar/OperatorMenu.svelte +6 -0
- package/package/components/sidebar/SidebarContent.svelte +11 -1
- package/package/components/triggers/AddTriggersButton.svelte +6 -0
- package/package/components/triggers/CaptureWrapper.svelte +19 -1
- package/package/components/triggers/TriggerEditorToolbar.svelte.d.ts +1 -1
- package/package/components/triggers/TriggerModeToggle.svelte +36 -7
- package/package/components/triggers/TriggerModeToggle.svelte.d.ts +1 -1
- package/package/components/triggers/TriggerSuspendedJobsModal.svelte.d.ts +1 -1
- package/package/components/triggers/TriggersEditor.svelte +5 -1
- package/package/components/triggers/TriggersWrapper.svelte +10 -0
- package/package/components/triggers/azure/AzureCapture.svelte +41 -0
- package/package/components/triggers/azure/AzureCapture.svelte.d.ts +44 -0
- package/package/components/triggers/azure/AzureTriggerEditor.svelte +20 -0
- package/package/components/triggers/azure/AzureTriggerEditor.svelte.d.ts +9 -0
- package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte +301 -0
- package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte.d.ts +16 -0
- package/package/components/triggers/azure/AzureTriggerEditorInner.svelte +422 -0
- package/package/components/triggers/azure/AzureTriggerEditorInner.svelte.d.ts +25 -0
- package/package/components/triggers/azure/AzureTriggerPanel.svelte +55 -0
- package/package/components/triggers/azure/AzureTriggerPanel.svelte.d.ts +10 -0
- package/{dist/sharedUtils/components/triggers/kafka → package/components/triggers/azure}/utils.d.ts +1 -1
- package/package/components/triggers/azure/utils.js +56 -0
- package/package/components/triggers/email/EmailTriggerEditorInner.svelte +2 -0
- package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +9 -3
- package/package/components/triggers/http/RouteEditorInner.svelte +2 -0
- package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +9 -3
- package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +9 -3
- package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +9 -3
- package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +9 -3
- package/package/components/triggers/schedules/ScheduleEditorInner.svelte +9 -3
- package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +9 -3
- package/package/components/triggers/triggers.svelte.d.ts +1 -0
- package/package/components/triggers/triggers.svelte.js +23 -1
- package/package/components/triggers/utils.js +20 -0
- package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +9 -3
- package/package/components/triggers.d.ts +1 -1
- package/package/components/useNestedRestartState.svelte.d.ts +56 -0
- package/package/components/useNestedRestartState.svelte.js +320 -0
- package/package/components/workspaceSettings/SharedUiSettings.svelte +175 -0
- package/package/components/workspaceSettings/SharedUiSettings.svelte.d.ts +3 -0
- package/package/gen/core/OpenAPI.js +1 -1
- package/package/gen/schemas.gen.d.ts +294 -24
- package/package/gen/schemas.gen.js +297 -25
- package/package/gen/services.gen.d.ts +247 -4
- package/package/gen/services.gen.js +498 -7
- package/package/gen/types.gen.d.ts +990 -37
- package/package/hubPaths.json +2 -5
- package/package/infer.d.ts +1 -1
- package/package/infer.js +37 -51
- package/package/mcpEndpointTools.js +60 -4
- package/package/script_helpers.js +17 -0
- package/package/stores.d.ts +7 -0
- package/package/stores.js +6 -1
- package/package/system_prompts/index.d.ts +1 -0
- package/package/system_prompts/index.js +8 -0
- package/package/system_prompts/prompts.d.ts +16 -13
- package/package/system_prompts/prompts.js +653 -43
- package/package/templates/ci_test_bun.ts.template +8 -0
- package/package/templates/ci_test_python.py.template +8 -0
- package/package/utils/forkConflict.d.ts +26 -0
- package/package/utils/forkConflict.js +56 -0
- package/package/utils_deployable.d.ts +164 -121
- package/package/utils_deployable.js +61 -11
- package/package/utils_workspace_deploy.js +3 -1
- package/package.json +29 -5
- package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +0 -2
- package/dist/sharedUtils/base.d.ts +0 -1
- package/dist/sharedUtils/cloud.d.ts +0 -1
- package/dist/sharedUtils/common.d.ts +0 -111
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +0 -5
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +0 -5
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +0 -5
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +0 -13
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +0 -11
- package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +0 -95
- package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +0 -6
- package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +0 -7
- package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +0 -33
- package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +0 -10
- package/dist/sharedUtils/components/apps/editor/component/components.d.ts +0 -5371
- package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +0 -3
- package/dist/sharedUtils/components/apps/editor/component/index.d.ts +0 -3
- package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +0 -7
- package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +0 -3
- package/dist/sharedUtils/components/apps/gridUtils.d.ts +0 -14
- package/dist/sharedUtils/components/apps/inputType.d.ts +0 -178
- package/dist/sharedUtils/components/apps/rx.d.ts +0 -29
- package/dist/sharedUtils/components/apps/sharedTypes.d.ts +0 -21
- package/dist/sharedUtils/components/apps/types.d.ts +0 -274
- package/dist/sharedUtils/components/assets/lib.d.ts +0 -25
- package/dist/sharedUtils/components/common/alert/model.d.ts +0 -2
- package/dist/sharedUtils/components/common/badge/model.d.ts +0 -8
- package/dist/sharedUtils/components/common/button/model.d.ts +0 -45
- package/dist/sharedUtils/components/common/fileInput/model.d.ts +0 -1
- package/dist/sharedUtils/components/common/index.d.ts +0 -24
- package/dist/sharedUtils/components/common/skeleton/model.d.ts +0 -21
- package/dist/sharedUtils/components/dbTypes.d.ts +0 -14
- package/dist/sharedUtils/components/diff_drawer.d.ts +0 -26
- package/dist/sharedUtils/components/ducklake.d.ts +0 -1
- package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +0 -7
- package/dist/sharedUtils/components/icons/index.d.ts +0 -101
- package/dist/sharedUtils/components/random_positive_adjetive.d.ts +0 -1
- package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +0 -10
- package/dist/sharedUtils/components/raw_apps/utils.d.ts +0 -15
- package/dist/sharedUtils/components/triggers/email/utils.d.ts +0 -4
- package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +0 -2
- package/dist/sharedUtils/components/triggers/http/utils.d.ts +0 -11
- package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +0 -2
- package/dist/sharedUtils/components/triggers/nats/utils.d.ts +0 -2
- package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +0 -8
- package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +0 -2
- package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +0 -32
- package/dist/sharedUtils/components/triggers/utils.d.ts +0 -80
- package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +0 -2
- package/dist/sharedUtils/components/triggers.d.ts +0 -20
- package/dist/sharedUtils/gen/core/ApiError.d.ts +0 -10
- package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +0 -13
- package/dist/sharedUtils/gen/core/ApiResult.d.ts +0 -7
- package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +0 -26
- package/dist/sharedUtils/gen/core/OpenAPI.d.ts +0 -27
- package/dist/sharedUtils/gen/core/request.d.ts +0 -29
- package/dist/sharedUtils/gen/index.d.ts +0 -6
- package/dist/sharedUtils/gen/schemas.gen.d.ts +0 -7036
- package/dist/sharedUtils/gen/services.gen.d.ts +0 -6047
- package/dist/sharedUtils/gen/types.gen.d.ts +0 -21881
- package/dist/sharedUtils/history.svelte.d.ts +0 -9
- package/dist/sharedUtils/hub.d.ts +0 -49
- package/dist/sharedUtils/jsr.json +0 -6
- package/dist/sharedUtils/lib.d.ts +0 -5
- package/dist/sharedUtils/lib.es.js +0 -1588
- package/dist/sharedUtils/package.json +0 -12
- package/dist/sharedUtils/schema.d.ts +0 -3
- package/dist/sharedUtils/stores.d.ts +0 -97
- package/dist/sharedUtils/svelte5Utils.svelte.d.ts +0 -80
- package/dist/sharedUtils/toast.d.ts +0 -8
- package/dist/sharedUtils/utils.d.ts +0 -265
- package/package/components/copilot/chat/flow/openFlowZod.js +0 -24
- /package/package/components/copilot/chat/flow/{openFlowZod.d.ts → openFlowZod.gen.d.ts} +0 -0
|
@@ -11,7 +11,7 @@ import FlowProgressBar from './flows/FlowProgressBar.svelte';
|
|
|
11
11
|
import FlowExecutionStatus from './runs/FlowExecutionStatus.svelte';
|
|
12
12
|
import JobDetailHeader from './runs/JobDetailHeader.svelte';
|
|
13
13
|
import { AlertTriangle, Circle, CornerDownLeft, Download, Loader2, Play, RefreshCw, X } from 'lucide-svelte';
|
|
14
|
-
import {
|
|
14
|
+
import { sendUserToast } from '../utils';
|
|
15
15
|
import { dfs } from './flows/dfs';
|
|
16
16
|
import { sliceModules } from './flows/flowStateUtils.svelte';
|
|
17
17
|
import InputSelectedBadge from './schema/InputSelectedBadge.svelte';
|
|
@@ -22,9 +22,26 @@ import { getStepHistoryLoaderContext } from './stepHistoryLoader.svelte';
|
|
|
22
22
|
import FlowChat from './flows/conversations/FlowChat.svelte';
|
|
23
23
|
import { stateSnapshot } from '../svelte5Utils.svelte';
|
|
24
24
|
import FlowRestartButton from './FlowRestartButton.svelte';
|
|
25
|
+
import { useNestedRestartState } from './useNestedRestartState.svelte';
|
|
25
26
|
import { createFlowRecording, setActiveRecording } from './recording/flowRecording.svelte';
|
|
26
27
|
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({}), localDurationStatuses = $bindable({}), onRunPreview, render = false, onJobDone, upToId = undefined, suspendStatus } = $props();
|
|
27
|
-
let
|
|
28
|
+
let previewExpandedSubflows = $state({});
|
|
29
|
+
const restart = useNestedRestartState({
|
|
30
|
+
selectedJobStep: () => selectedJobStep,
|
|
31
|
+
job: () => job,
|
|
32
|
+
graphModuleStates: () => localModuleStates,
|
|
33
|
+
expandedSubflows: () => previewExpandedSubflows
|
|
34
|
+
});
|
|
35
|
+
// `selectedJobStepType` and `selectedJobStepIsTopLevel` are still exposed as
|
|
36
|
+
// `$bindable` props to legacy parents (FlowPreviewButtons binds them but
|
|
37
|
+
// doesn't read them). Sync them out of the composable here so the prop
|
|
38
|
+
// surface stays unchanged.
|
|
39
|
+
$effect(() => {
|
|
40
|
+
selectedJobStepIsTopLevel = restart.selectedJobStepIsTopLevel;
|
|
41
|
+
});
|
|
42
|
+
$effect(() => {
|
|
43
|
+
selectedJobStepType = restart.selectedJobStepType;
|
|
44
|
+
});
|
|
28
45
|
let isRunning = $state(false);
|
|
29
46
|
let jsonView = $state(false);
|
|
30
47
|
let jsonEditor = $state(undefined);
|
|
@@ -118,28 +135,6 @@ function onKeyDown(event) {
|
|
|
118
135
|
}
|
|
119
136
|
}
|
|
120
137
|
}
|
|
121
|
-
function onSelectedJobStepChange() {
|
|
122
|
-
if (selectedJobStep !== undefined && job?.flow_status?.modules !== undefined) {
|
|
123
|
-
selectedJobStepIsTopLevel =
|
|
124
|
-
job?.flow_status?.modules.map((m) => m.id).indexOf(selectedJobStep) >= 0;
|
|
125
|
-
let moduleDefinition = job?.raw_flow?.modules.find((m) => m.id == selectedJobStep);
|
|
126
|
-
if (moduleDefinition?.value.type == 'forloopflow') {
|
|
127
|
-
selectedJobStepType = 'forloop';
|
|
128
|
-
}
|
|
129
|
-
else if (moduleDefinition?.value.type == 'branchall') {
|
|
130
|
-
selectedJobStepType = 'branchall';
|
|
131
|
-
moduleDefinition?.value.branches.forEach((branch, idx) => {
|
|
132
|
-
restartBranchNames.push([
|
|
133
|
-
idx,
|
|
134
|
-
emptyString(branch.summary) ? `Branch #${idx}` : branch.summary
|
|
135
|
-
]);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
selectedJobStepType = 'single';
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
138
|
let savedArgs = $state(previewArgs.val);
|
|
144
139
|
let inputSelected = $state(undefined);
|
|
145
140
|
async function selectInput(input, type) {
|
|
@@ -219,9 +214,6 @@ function onScrollableDivChange() {
|
|
|
219
214
|
scrollableDiv.scrollTop = scrollTop;
|
|
220
215
|
}
|
|
221
216
|
}
|
|
222
|
-
$effect.pre(() => {
|
|
223
|
-
selectedJobStep !== undefined && untrack(() => onSelectedJobStepChange());
|
|
224
|
-
});
|
|
225
217
|
$effect(() => {
|
|
226
218
|
scrollableDiv && render && untrack(() => onScrollableDivChange());
|
|
227
219
|
});
|
|
@@ -316,12 +308,21 @@ export function flowHasChanged() {
|
|
|
316
308
|
</div>
|
|
317
309
|
{:else}
|
|
318
310
|
<div class="grow justify-center flex flex-row gap-2 items-center">
|
|
319
|
-
{#if jobId !== undefined && selectedJobStep !== undefined &&
|
|
311
|
+
{#if jobId !== undefined && selectedJobStep !== undefined && restart.topLevelRestartable}
|
|
312
|
+
<!--
|
|
313
|
+
Nested-step restart is intentionally not surfaced from the editor
|
|
314
|
+
preview: the chain needs `flow_job_id` resolved at every level,
|
|
315
|
+
which only the backend can do (by walking the original
|
|
316
|
+
execution). Users who want nested restart should use the run
|
|
317
|
+
page, which goes through the dedicated restart API.
|
|
318
|
+
-->
|
|
320
319
|
<FlowRestartButton
|
|
321
320
|
{jobId}
|
|
322
321
|
{selectedJobStep}
|
|
323
|
-
{selectedJobStepType}
|
|
324
|
-
{restartBranchNames}
|
|
322
|
+
selectedJobStepType={restart.selectedJobStepType}
|
|
323
|
+
restartBranchNames={restart.restartBranchNames}
|
|
324
|
+
presetIterationN={restart.topLevelLoopIteration}
|
|
325
|
+
iterationCounts={restart.iterationCounts}
|
|
325
326
|
onRestart={(stepId, branchOrIterationN) => {
|
|
326
327
|
runPreview(previewArgs.val, {
|
|
327
328
|
flow_job_id: jobId,
|
|
@@ -544,6 +545,7 @@ export function flowHasChanged() {
|
|
|
544
545
|
<FlowStatusViewer
|
|
545
546
|
bind:job
|
|
546
547
|
bind:localModuleStates
|
|
548
|
+
bind:expandedSubflows={previewExpandedSubflows}
|
|
547
549
|
bind:localDurationStatuses
|
|
548
550
|
{suspendStatus}
|
|
549
551
|
hideDownloadInGraph={customUi?.downloadLogs === false}
|
|
@@ -4,24 +4,82 @@ import { Play, RefreshCw } from 'lucide-svelte';
|
|
|
4
4
|
import { FlowService, JobService } from '../gen';
|
|
5
5
|
import { workspaceStore } from '../stores';
|
|
6
6
|
import { emptyString, sendUserToast } from '../utils';
|
|
7
|
-
let { jobId, selectedJobStep, selectedJobStepType, restartBranchNames = [], flowPath = undefined, flowVersionId = undefined, disabled = false, enterpriseOnly = false, variant = 'default', unifiedSize = 'md', onRestart, onRestartComplete } = $props();
|
|
7
|
+
let { jobId, selectedJobStep, selectedJobStepType, restartBranchNames = [], flowPath = undefined, flowVersionId = undefined, disabled = false, enterpriseOnly = false, variant = 'default', unifiedSize = 'md', nestedPath = undefined, nestedTopStepId = undefined, nestedTopBranchOrIterationN = undefined, presetIterationN = undefined, iterationCounts = undefined, nestedPathIterationCounts = undefined, onRestart, onRestartComplete } = $props();
|
|
8
|
+
const isNested = $derived((nestedPath?.length ?? 0) > 0);
|
|
9
|
+
// Inline-expanded subflow steps come in as `subflow:A:B:leaf` — show only `leaf`.
|
|
10
|
+
const displayStepId = $derived(isNested && nestedPath && nestedPath.length > 0
|
|
11
|
+
? nestedPath[nestedPath.length - 1].step_id
|
|
12
|
+
: selectedJobStep);
|
|
8
13
|
// Sentinel value meaning "use the same version as the original run" (backend receives undefined)
|
|
9
14
|
const RUN_VERSION_SENTINEL = -1;
|
|
10
15
|
let branchOrIterationN = $state(0);
|
|
16
|
+
let iterationEdits = $state({});
|
|
17
|
+
function resetEditsFromProps() {
|
|
18
|
+
const next = {};
|
|
19
|
+
if (isNested && nestedTopBranchOrIterationN !== undefined) {
|
|
20
|
+
next['top'] = nestedTopBranchOrIterationN;
|
|
21
|
+
}
|
|
22
|
+
if (isNested) {
|
|
23
|
+
nestedPath?.forEach((entry, i) => {
|
|
24
|
+
if (entry.branch_or_iteration_n !== undefined) {
|
|
25
|
+
next[`inner-${i}`] = entry.branch_or_iteration_n;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
iterationEdits = next;
|
|
30
|
+
if (selectedJobStepType === 'forloop' && presetIterationN !== undefined) {
|
|
31
|
+
branchOrIterationN = presetIterationN;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const iterationFields = $derived.by(() => {
|
|
35
|
+
if (!isNested)
|
|
36
|
+
return [];
|
|
37
|
+
const out = [];
|
|
38
|
+
if (nestedTopBranchOrIterationN !== undefined && nestedTopStepId) {
|
|
39
|
+
out.push({
|
|
40
|
+
key: 'top',
|
|
41
|
+
label: nestedTopStepId,
|
|
42
|
+
value: iterationEdits['top'] ?? nestedTopBranchOrIterationN
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
nestedPath?.forEach((entry, i) => {
|
|
46
|
+
if (entry.branch_or_iteration_n !== undefined) {
|
|
47
|
+
const k = `inner-${i}`;
|
|
48
|
+
out.push({
|
|
49
|
+
key: k,
|
|
50
|
+
label: entry.step_id,
|
|
51
|
+
value: iterationEdits[k] ?? entry.branch_or_iteration_n
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return out;
|
|
56
|
+
});
|
|
57
|
+
const needsPopup = $derived(!!flowPath || iterationFields.length > 0 || selectedJobStepType !== 'single');
|
|
11
58
|
let selectedFlowVersion = $state(RUN_VERSION_SENTINEL);
|
|
12
59
|
let flowVersions = $state([]);
|
|
13
60
|
let loadingVersions = $state(false);
|
|
14
61
|
let versionsLoaded = $state(false);
|
|
15
62
|
let runVersionInList = $state(false);
|
|
16
63
|
async function restartFlow(stepId, branchOrIterationN, flowVersion) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
64
|
+
const requestBody = isNested
|
|
65
|
+
? {
|
|
66
|
+
step_id: nestedTopStepId,
|
|
67
|
+
branch_or_iteration_n: iterationEdits['top'] ?? nestedTopBranchOrIterationN,
|
|
68
|
+
flow_version: flowVersion,
|
|
69
|
+
nested_path: nestedPath?.map((entry, i) => ({
|
|
70
|
+
step_id: entry.step_id,
|
|
71
|
+
branch_or_iteration_n: iterationEdits[`inner-${i}`] ?? entry.branch_or_iteration_n
|
|
72
|
+
}))
|
|
73
|
+
}
|
|
74
|
+
: {
|
|
21
75
|
step_id: stepId,
|
|
22
76
|
branch_or_iteration_n: branchOrIterationN,
|
|
23
77
|
flow_version: flowVersion
|
|
24
|
-
}
|
|
78
|
+
};
|
|
79
|
+
let run = await JobService.restartFlowAtStep({
|
|
80
|
+
workspace: $workspaceStore,
|
|
81
|
+
id: jobId,
|
|
82
|
+
requestBody
|
|
25
83
|
});
|
|
26
84
|
onRestartComplete?.(run);
|
|
27
85
|
}
|
|
@@ -94,23 +152,23 @@ function handleRestart() {
|
|
|
94
152
|
{/if}
|
|
95
153
|
</label>
|
|
96
154
|
{/snippet}
|
|
97
|
-
{#snippet
|
|
155
|
+
{#snippet restartTriggerButton(usePlayIcon: boolean)}
|
|
98
156
|
<Button
|
|
99
|
-
title={`Re-start this flow from step ${
|
|
157
|
+
title={`Re-start this flow from step ${displayStepId} (included).${enterpriseOnly ? ' This is a feature only available in enterprise edition.' : ''}`}
|
|
100
158
|
{variant}
|
|
101
159
|
{unifiedSize}
|
|
102
160
|
{disabled}
|
|
103
|
-
startIcon={{ icon: Play }}
|
|
104
|
-
nonCaptureEvent={!!flowPath}
|
|
161
|
+
startIcon={{ icon: usePlayIcon ? Play : RefreshCw }}
|
|
162
|
+
nonCaptureEvent={!usePlayIcon || !!flowPath}
|
|
105
163
|
onClick={() => {
|
|
106
|
-
if (!flowPath) {
|
|
164
|
+
if (usePlayIcon && !flowPath) {
|
|
107
165
|
handleRestart()
|
|
108
166
|
}
|
|
109
167
|
}}
|
|
110
168
|
>
|
|
111
169
|
Re-start from
|
|
112
170
|
<Badge baseClass="ml-1" color="indigo">
|
|
113
|
-
{
|
|
171
|
+
{displayStepId}
|
|
114
172
|
</Badge>
|
|
115
173
|
{#if enterpriseOnly && disabled}
|
|
116
174
|
(EE)
|
|
@@ -118,68 +176,92 @@ function handleRestart() {
|
|
|
118
176
|
</Button>
|
|
119
177
|
{/snippet}
|
|
120
178
|
|
|
121
|
-
{#if
|
|
122
|
-
{
|
|
123
|
-
{@render singleRestartButton()}
|
|
124
|
-
{:else}
|
|
125
|
-
<Popover
|
|
126
|
-
floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}
|
|
127
|
-
disablePopup={!flowPath}
|
|
128
|
-
on:openChange={(e) => { if (e.detail) loadFlowVersions() }}
|
|
129
|
-
>
|
|
130
|
-
{#snippet trigger()}
|
|
131
|
-
{@render singleRestartButton()}
|
|
132
|
-
{/snippet}
|
|
133
|
-
{#snippet content()}
|
|
134
|
-
<div class="flex flex-col gap-4 text-primary p-4 w-80">
|
|
135
|
-
{@render flowVersionSelector()}
|
|
136
|
-
|
|
137
|
-
<Button variant="accent" onClick={handleRestart}>Restart</Button>
|
|
138
|
-
</div>
|
|
139
|
-
{/snippet}
|
|
140
|
-
</Popover>
|
|
141
|
-
{/if}
|
|
179
|
+
{#if !needsPopup}
|
|
180
|
+
{@render restartTriggerButton(true)}
|
|
142
181
|
{:else}
|
|
143
182
|
<Popover
|
|
144
183
|
floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}
|
|
145
|
-
|
|
184
|
+
disablePopup={!needsPopup}
|
|
185
|
+
on:openChange={(e) => {
|
|
186
|
+
if (e.detail) {
|
|
187
|
+
loadFlowVersions()
|
|
188
|
+
resetEditsFromProps()
|
|
189
|
+
}
|
|
190
|
+
}}
|
|
146
191
|
>
|
|
147
192
|
{#snippet trigger()}
|
|
148
|
-
|
|
149
|
-
title={`Re-start this flow from step ${selectedJobStep} (included).${enterpriseOnly ? ' This is a feature only available in enterprise edition.' : ''}`}
|
|
150
|
-
{variant}
|
|
151
|
-
{unifiedSize}
|
|
152
|
-
{disabled}
|
|
153
|
-
startIcon={{ icon: RefreshCw }}
|
|
154
|
-
nonCaptureEvent={true}
|
|
155
|
-
>
|
|
156
|
-
Re-start from
|
|
157
|
-
<Badge baseClass="ml-1" color="indigo">
|
|
158
|
-
{selectedJobStep}
|
|
159
|
-
</Badge>
|
|
160
|
-
{#if enterpriseOnly && disabled}
|
|
161
|
-
(EE)
|
|
162
|
-
{/if}
|
|
163
|
-
</Button>
|
|
193
|
+
{@render restartTriggerButton(selectedJobStepType === 'single')}
|
|
164
194
|
{/snippet}
|
|
165
195
|
{#snippet content()}
|
|
166
196
|
<div class="flex flex-col gap-4 text-primary p-4 w-80">
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
197
|
+
{#if selectedJobStepType === 'forloop'}
|
|
198
|
+
{@const topCount = iterationCounts?.[selectedJobStep] ?? 0}
|
|
199
|
+
<label>
|
|
200
|
+
<div class="pb-1 text-xs font-semibold text-emphasis">From iteration #</div>
|
|
201
|
+
<div class="flex w-full gap-2">
|
|
202
|
+
{#if topCount > 0}
|
|
203
|
+
<select bind:value={branchOrIterationN} class="!w-32 grow">
|
|
204
|
+
{#each Array.from({ length: topCount }, (_, i) => i) as i (i)}
|
|
205
|
+
<option value={i}>{i + 1}</option>
|
|
206
|
+
{/each}
|
|
207
|
+
</select>
|
|
208
|
+
{:else}
|
|
209
|
+
<input type="number" min="0" bind:value={branchOrIterationN} class="!w-32 grow" />
|
|
210
|
+
{/if}
|
|
211
|
+
</div>
|
|
212
|
+
</label>
|
|
213
|
+
{:else if selectedJobStepType === 'branchall'}
|
|
214
|
+
<label>
|
|
215
|
+
<div class="pb-1 text-xs font-semibold text-emphasis">From branch</div>
|
|
216
|
+
<div class="flex w-full gap-2">
|
|
175
217
|
<select bind:value={branchOrIterationN} class="!w-32 grow">
|
|
176
218
|
{#each restartBranchNames as [branchIdx, branchName] (branchIdx)}
|
|
177
219
|
<option value={branchIdx}>{branchName}</option>
|
|
178
220
|
{/each}
|
|
179
221
|
</select>
|
|
180
|
-
|
|
181
|
-
</
|
|
182
|
-
|
|
222
|
+
</div>
|
|
223
|
+
</label>
|
|
224
|
+
{/if}
|
|
225
|
+
|
|
226
|
+
{#each iterationFields as field (field.key)}
|
|
227
|
+
{@const count = nestedPathIterationCounts?.[field.key] ?? 0}
|
|
228
|
+
<label>
|
|
229
|
+
<div class="pb-1 text-xs font-semibold text-emphasis">
|
|
230
|
+
From iteration # of <code class="text-xs">{field.label}</code>
|
|
231
|
+
</div>
|
|
232
|
+
<div class="flex w-full gap-2">
|
|
233
|
+
{#if count > 0}
|
|
234
|
+
<select
|
|
235
|
+
value={field.value}
|
|
236
|
+
onchange={(e) => {
|
|
237
|
+
const v = parseInt((e.target as HTMLSelectElement).value, 10)
|
|
238
|
+
if (!Number.isNaN(v)) {
|
|
239
|
+
iterationEdits = { ...iterationEdits, [field.key]: v }
|
|
240
|
+
}
|
|
241
|
+
}}
|
|
242
|
+
class="!w-32 grow"
|
|
243
|
+
>
|
|
244
|
+
{#each Array.from({ length: count }, (_, i) => i) as i (i)}
|
|
245
|
+
<option value={i}>{i + 1}</option>
|
|
246
|
+
{/each}
|
|
247
|
+
</select>
|
|
248
|
+
{:else}
|
|
249
|
+
<input
|
|
250
|
+
type="number"
|
|
251
|
+
min="0"
|
|
252
|
+
value={field.value}
|
|
253
|
+
oninput={(e) => {
|
|
254
|
+
const v = parseInt((e.target as HTMLInputElement).value, 10)
|
|
255
|
+
if (!Number.isNaN(v)) {
|
|
256
|
+
iterationEdits = { ...iterationEdits, [field.key]: v }
|
|
257
|
+
}
|
|
258
|
+
}}
|
|
259
|
+
class="!w-32 grow"
|
|
260
|
+
/>
|
|
261
|
+
{/if}
|
|
262
|
+
</div>
|
|
263
|
+
</label>
|
|
264
|
+
{/each}
|
|
183
265
|
|
|
184
266
|
{#if flowPath}
|
|
185
267
|
{@render flowVersionSelector()}
|
|
@@ -10,6 +10,43 @@ interface Props {
|
|
|
10
10
|
enterpriseOnly?: boolean;
|
|
11
11
|
variant?: 'default' | 'accent';
|
|
12
12
|
unifiedSize?: 'xs' | 'sm' | 'md' | 'lg';
|
|
13
|
+
/**
|
|
14
|
+
* For nested-step restarts: path of ancestor containers from the top-level
|
|
15
|
+
* step down to the leaf. When provided, the LAST entry's step_id is the
|
|
16
|
+
* actual restart point and `selectedJobStep` (the leaf shown in the UI) is
|
|
17
|
+
* informational only — the request is built from `nestedTopStepId`,
|
|
18
|
+
* `nestedTopBranchOrIterationN` and `nestedPath`.
|
|
19
|
+
*/
|
|
20
|
+
nestedPath?: Array<{
|
|
21
|
+
step_id: string;
|
|
22
|
+
branch_or_iteration_n?: number;
|
|
23
|
+
}>;
|
|
24
|
+
/** Top-level container step id (only used when nestedPath is set) */
|
|
25
|
+
nestedTopStepId?: string;
|
|
26
|
+
/** Top-level container branch_or_iteration_n (only used when nestedPath is set) */
|
|
27
|
+
nestedTopBranchOrIterationN?: number;
|
|
28
|
+
/**
|
|
29
|
+
* For top-level ForLoop restart: iteration index the user is currently
|
|
30
|
+
* viewing in the graph (read from `selectedForloopIndex` upstream). When
|
|
31
|
+
* provided, the popup pre-fills the iteration selector with this value.
|
|
32
|
+
*/
|
|
33
|
+
presetIterationN?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Map from ForLoop step id to the number of iterations that ran in the
|
|
36
|
+
* original execution (i.e. `flow_jobs.length`). When provided for a step,
|
|
37
|
+
* the popup renders a `<select>` of `0..count-1` instead of a free-form
|
|
38
|
+
* number input — same surface as the graph's iteration tabs. Used for the
|
|
39
|
+
* SELECTED step's iteration picker when it is itself a top-level ForLoop.
|
|
40
|
+
*/
|
|
41
|
+
iterationCounts?: Record<string, number>;
|
|
42
|
+
/**
|
|
43
|
+
* Iteration counts for nested-path entries, keyed by the popup's field-key
|
|
44
|
+
* (`'top'` for the outer container, `'inner-N'` for nested ancestors).
|
|
45
|
+
* Populated by the composable so each entry uses the *correct* graph-state
|
|
46
|
+
* key (prefixed for in-subflow ancestors), avoiding collisions when the
|
|
47
|
+
* same step id appears at multiple nesting levels.
|
|
48
|
+
*/
|
|
49
|
+
nestedPathIterationCounts?: Record<string, number>;
|
|
13
50
|
/** Called when flow is restarted. If not provided, will navigate to the new run using goto (requires SvelteKit) */
|
|
14
51
|
onRestart?: (stepId: string, branchOrIterationN: number, flowVersion?: number) => void;
|
|
15
52
|
/** Called when flow restart completes with the new job ID. Used for navigation in non-SvelteKit contexts */
|
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
import { setContext, untrack } from 'svelte';
|
|
3
3
|
import { isOwner as loadIsOwner } from '../utils';
|
|
4
4
|
import { userStore, workspaceStore } from '../stores';
|
|
5
|
-
let { jobId, initialJob = undefined, workspaceId = undefined, flowState = $bindable({}), selectedJobStep = $bindable(undefined), hideFlowResult = false, hideTimeline = false, hideDownloadInGraph = false, hideNodeDefinition = false, hideJobId = false, hideDownloadLogs = false, rightColumnSelect = $bindable('timeline'), isOwner = $bindable(false), wideResults = false, localModuleStates = $bindable({}),
|
|
5
|
+
let { jobId, initialJob = undefined, workspaceId = undefined, flowState = $bindable({}), selectedJobStep = $bindable(undefined), hideFlowResult = false, hideTimeline = false, hideDownloadInGraph = false, hideNodeDefinition = false, hideJobId = false, hideDownloadLogs = false, rightColumnSelect = $bindable('timeline'), isOwner = $bindable(false), wideResults = false, localModuleStates = $bindable({}),
|
|
6
|
+
// `$bindable({})` is the right shape for this prop despite CLAUDE.md's
|
|
7
|
+
// general guidance against `$bindable(default_value)`: that rule targets
|
|
8
|
+
// props where `undefined` has distinct semantics from "empty default".
|
|
9
|
+
// For a Map-typed cache populated by the inner component, callers that
|
|
10
|
+
// don't bind it should still see a usable empty map (the inner writes to
|
|
11
|
+
// it when the user expands a subflow). Without the `{}` default, those
|
|
12
|
+
// callers would crash at write time. Same reasoning applies to the
|
|
13
|
+
// pre-existing `localModuleStates`/`localDurationStatuses` bindables.
|
|
14
|
+
expandedSubflows = $bindable({}), localDurationStatuses = $bindable({}), job = $bindable(undefined), render = true, suspendStatus = $bindable({ val: {} }), customUi, onStart, onJobsLoaded, onDone, showLogsWithResult = false, notes: notesProp = undefined, groups: groupsProp = undefined } = $props();
|
|
6
15
|
let lastJobId = untrack(() => jobId);
|
|
7
16
|
let retryStatus = $state({ val: {} });
|
|
8
17
|
let globalRefreshes = $state({});
|
|
@@ -30,6 +39,10 @@ async function updateJobId() {
|
|
|
30
39
|
delete flowState[key];
|
|
31
40
|
localDurationStatuses = {};
|
|
32
41
|
localModuleStates = {};
|
|
42
|
+
// Reset the subflow definition cache too — a new run can reference
|
|
43
|
+
// different subflow versions; stale entries would confuse nested
|
|
44
|
+
// restart path-finding.
|
|
45
|
+
expandedSubflows = {};
|
|
33
46
|
}
|
|
34
47
|
}
|
|
35
48
|
let lastScriptPath = $state(undefined);
|
|
@@ -61,6 +74,7 @@ let toolCallIndicesToLoad = $state([]);
|
|
|
61
74
|
}}
|
|
62
75
|
globalModuleStates={[]}
|
|
63
76
|
bind:localModuleStates
|
|
77
|
+
bind:expandedSubflows
|
|
64
78
|
bind:selectedNode={selectedJobStep}
|
|
65
79
|
bind:localDurationStatuses
|
|
66
80
|
{onStart}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FlowState } from './flows/flowState';
|
|
2
2
|
import type { DurationStatus, GraphModuleState } from './graph';
|
|
3
3
|
import { type StateStore } from '../utils';
|
|
4
|
-
import type { CompletedJob, FlowNote, FlowValue, Job } from '../gen';
|
|
4
|
+
import type { CompletedJob, FlowModule, FlowNote, FlowValue, Job } from '../gen';
|
|
5
5
|
interface Props {
|
|
6
6
|
jobId: string;
|
|
7
7
|
initialJob?: Job | undefined;
|
|
@@ -18,6 +18,14 @@ interface Props {
|
|
|
18
18
|
isOwner?: boolean;
|
|
19
19
|
wideResults?: boolean;
|
|
20
20
|
localModuleStates?: Record<string, GraphModuleState>;
|
|
21
|
+
/** Cached subflow definitions, keyed by graph node id (subflow step id, with
|
|
22
|
+
* `subflow:` prefix for nested subflows). Populated as the user expands a
|
|
23
|
+
* subflow in the graph. Bindable so callers can use it to walk inside
|
|
24
|
+
* subflows (e.g. for nested-restart path-finding). */
|
|
25
|
+
expandedSubflows?: Record<string, {
|
|
26
|
+
modules: FlowModule[];
|
|
27
|
+
groups?: any[];
|
|
28
|
+
}>;
|
|
21
29
|
localDurationStatuses?: Record<string, DurationStatus>;
|
|
22
30
|
job?: Job | undefined;
|
|
23
31
|
render?: boolean;
|
|
@@ -40,6 +48,6 @@ interface Props {
|
|
|
40
48
|
notes?: FlowNote[];
|
|
41
49
|
groups?: FlowValue['groups'];
|
|
42
50
|
}
|
|
43
|
-
declare const FlowStatusViewer: import("svelte").Component<Props, {}, "job" | "isOwner" | "suspendStatus" | "localModuleStates" | "localDurationStatuses" | "flowState" | "rightColumnSelect" | "selectedJobStep">;
|
|
51
|
+
declare const FlowStatusViewer: import("svelte").Component<Props, {}, "job" | "isOwner" | "suspendStatus" | "expandedSubflows" | "localModuleStates" | "localDurationStatuses" | "flowState" | "rightColumnSelect" | "selectedJobStep">;
|
|
44
52
|
type FlowStatusViewer = ReturnType<typeof FlowStatusViewer>;
|
|
45
53
|
export default FlowStatusViewer;
|
|
@@ -38,7 +38,7 @@ import { useThrottle } from 'runed';
|
|
|
38
38
|
import { Splitpanes, Pane } from 'svelte-splitpanes';
|
|
39
39
|
import { getActiveReplay } from './recording/flowRecording.svelte';
|
|
40
40
|
let { flowState: flowStateStore, retryStatus, suspendStatus, hideDownloadInGraph, hideTimeline, hideNodeDefinition, hideDownloadLogs } = getContext('FlowStatusViewer');
|
|
41
|
-
let { jobId, initialJob = undefined, workspaceId = undefined, flowJobIds = undefined, innerModule = undefined, render = true, selectedNode = $bindable(undefined), globalModuleStates, globalDurationStatuses = [], updateRecursiveRefreshFn = undefined, isSelectedBranch = true, isSubflow = false, reducedPolling = false, wideResults = false, workspace = $workspaceStore, prefix = undefined, topModuleStates = undefined, refreshGlobal, updateGlobalRefresh, subflowParentsGlobalModuleStates = [], subflowParentsDurationStatuses = [], isForloopSelected = false, job = $bindable(undefined), rightColumnSelect = $bindable('timeline'), localModuleStates = $bindable({}), localDurationStatuses = $bindable({}), customUi, onResultStreamUpdate = undefined, graphTabOpen, isNodeSelected, loadExtraLogs = undefined, onStart = undefined, onJobsLoaded = undefined, onDone = undefined, toolCallStore, showLogsWithResult = false, showJobDetailHeader = false, hideFlowResult = false, notes: notesProp = undefined, groups: groupsProp = undefined } = $props();
|
|
41
|
+
let { jobId, initialJob = undefined, workspaceId = undefined, flowJobIds = undefined, innerModule = undefined, render = true, selectedNode = $bindable(undefined), globalModuleStates, globalDurationStatuses = [], updateRecursiveRefreshFn = undefined, isSelectedBranch = true, isSubflow = false, reducedPolling = false, wideResults = false, workspace = $workspaceStore, prefix = undefined, topModuleStates = undefined, refreshGlobal, updateGlobalRefresh, subflowParentsGlobalModuleStates = [], subflowParentsDurationStatuses = [], isForloopSelected = false, job = $bindable(undefined), rightColumnSelect = $bindable('timeline'), localModuleStates = $bindable({}), expandedSubflows = $bindable({}), localDurationStatuses = $bindable({}), customUi, onResultStreamUpdate = undefined, graphTabOpen, isNodeSelected, loadExtraLogs = undefined, onStart = undefined, onJobsLoaded = undefined, onDone = undefined, toolCallStore, showLogsWithResult = false, showJobDetailHeader = false, hideFlowResult = false, notes: notesProp = undefined, groups: groupsProp = undefined } = $props();
|
|
42
42
|
let getTopModuleStates = $derived(topModuleStates ?? localModuleStates);
|
|
43
43
|
// Cache replay check to avoid repeated function calls in the template
|
|
44
44
|
let isReplay = $derived(!!getActiveReplay());
|
|
@@ -99,7 +99,6 @@ function getStepResults(x) {
|
|
|
99
99
|
}
|
|
100
100
|
let retry_selected = $state('');
|
|
101
101
|
let timeout = undefined;
|
|
102
|
-
let expandedSubflows = $state({});
|
|
103
102
|
let selectionManager = new SelectionManager();
|
|
104
103
|
function onFlowModuleId() {
|
|
105
104
|
let modId = flowJobIds?.moduleId;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import FlowStatusViewerInner from './FlowStatusViewerInner.svelte';
|
|
2
|
-
import { type Job, type FlowModuleValue, type CompletedJob, type FlowNote, type FlowValue } from '../gen';
|
|
2
|
+
import { type Job, type FlowModuleValue, type FlowModule, type CompletedJob, type FlowNote, type FlowValue } from '../gen';
|
|
3
3
|
import { type DurationStatus, type GraphModuleState } from './graph';
|
|
4
4
|
interface Props {
|
|
5
5
|
jobId: string;
|
|
@@ -39,6 +39,10 @@ interface Props {
|
|
|
39
39
|
}) | undefined;
|
|
40
40
|
rightColumnSelect?: 'timeline' | 'node_status' | 'node_definition' | 'user_states' | 'tracing';
|
|
41
41
|
localModuleStates?: Record<string, GraphModuleState>;
|
|
42
|
+
expandedSubflows?: Record<string, {
|
|
43
|
+
modules: FlowModule[];
|
|
44
|
+
groups?: any[];
|
|
45
|
+
}>;
|
|
42
46
|
localDurationStatuses?: Record<string, DurationStatus>;
|
|
43
47
|
onResultStreamUpdate?: ({ jobId, result_stream }: {
|
|
44
48
|
jobId: string;
|
|
@@ -75,6 +79,6 @@ export type FlowModuleForTimeline = {
|
|
|
75
79
|
id: string;
|
|
76
80
|
type: FlowModuleValue['type'];
|
|
77
81
|
};
|
|
78
|
-
declare const FlowStatusViewerInner: import("svelte").Component<Props, {}, "job" | "localModuleStates" | "localDurationStatuses" | "selectedNode" | "rightColumnSelect">;
|
|
82
|
+
declare const FlowStatusViewerInner: import("svelte").Component<Props, {}, "job" | "expandedSubflows" | "localModuleStates" | "localDurationStatuses" | "selectedNode" | "rightColumnSelect">;
|
|
79
83
|
type FlowStatusViewerInner = ReturnType<typeof FlowStatusViewerInner>;
|
|
80
84
|
export default FlowStatusViewerInner;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script lang="ts">import ConfirmationModal from './common/confirmationModal/ConfirmationModal.svelte';
|
|
2
|
+
import { forkConflictModal } from '../stores';
|
|
3
|
+
const state = $derived(forkConflictModal.val);
|
|
4
|
+
// Three failure shapes we want to describe accurately:
|
|
5
|
+
// - split-events: shared upstream subscription/queue, two listeners halve each other's traffic
|
|
6
|
+
// - duplicate-firing: independent triggers on shared input, every event fires twice
|
|
7
|
+
// - slot-takeover: PG replication slot is exclusive AND its position is destructively shared
|
|
8
|
+
const SPLIT_KINDS = new Set(['kafka', 'nats', 'mqtt', 'sqs', 'gcp', 'azure']);
|
|
9
|
+
const DUPLICATE_KINDS = new Set(['websocket', 'schedule']);
|
|
10
|
+
const family = $derived(!state
|
|
11
|
+
? 'unknown'
|
|
12
|
+
: state.kind === 'postgres'
|
|
13
|
+
? 'slot'
|
|
14
|
+
: SPLIT_KINDS.has(state.kind)
|
|
15
|
+
? 'split'
|
|
16
|
+
: DUPLICATE_KINDS.has(state.kind)
|
|
17
|
+
? 'duplicate'
|
|
18
|
+
: 'unknown');
|
|
19
|
+
function close(confirmed) {
|
|
20
|
+
const resolve = state?.resolve;
|
|
21
|
+
forkConflictModal.val = undefined;
|
|
22
|
+
resolve?.(confirmed);
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<ConfirmationModal
|
|
27
|
+
open={!!state}
|
|
28
|
+
title="Enable in fork conflicts with parent"
|
|
29
|
+
confirmationText="Enable anyway"
|
|
30
|
+
onConfirmed={() => close(true)}
|
|
31
|
+
onCanceled={() => close(false)}
|
|
32
|
+
>
|
|
33
|
+
{#if state}
|
|
34
|
+
<p>
|
|
35
|
+
The parent workspace (<span class="font-mono">{state.parentWorkspaceId}</span>) has the same
|
|
36
|
+
{state.kindLabel} configured at this path. Because this fork's row was cloned from it, the upstream
|
|
37
|
+
identifier is shared.
|
|
38
|
+
</p>
|
|
39
|
+
<p class="mt-2">
|
|
40
|
+
{#if family === 'split'}
|
|
41
|
+
If both are enabled, the two listeners will compete on the same upstream and each side will
|
|
42
|
+
receive only a fraction of its events.
|
|
43
|
+
{:else if family === 'duplicate'}
|
|
44
|
+
If both are enabled, every event will fire the script twice — once in the fork and once in
|
|
45
|
+
the parent.
|
|
46
|
+
{:else if family === 'slot'}
|
|
47
|
+
The cloned <span class="font-mono">replication_slot_name</span> points at the same Postgres slot,
|
|
48
|
+
which only allows one consumer at a time. Enabling here will either fail with "slot already active"
|
|
49
|
+
if the parent is enabled, or hijack the slot's WAL position if it isn't — causing the parent
|
|
50
|
+
to lose events when re-enabled.
|
|
51
|
+
{:else}
|
|
52
|
+
Enabling it here may compete for the same upstream events or duplicate side effects.
|
|
53
|
+
{/if}
|
|
54
|
+
</p>
|
|
55
|
+
<p class="mt-2">Enable in this fork anyway?</p>
|
|
56
|
+
{/if}
|
|
57
|
+
</ConfirmationModal>
|