@flowdrop/flowdrop 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -47
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/WorkflowAdapter.js +26 -26
- package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +2 -2
- package/dist/adapters/agentspec/AgentSpecAdapter.js +122 -133
- package/dist/adapters/agentspec/agentAdapter.d.ts +2 -2
- package/dist/adapters/agentspec/agentAdapter.js +10 -10
- package/dist/adapters/agentspec/autoLayout.d.ts +1 -1
- package/dist/adapters/agentspec/autoLayout.js +7 -9
- package/dist/adapters/agentspec/componentTypeDefaults.d.ts +1 -1
- package/dist/adapters/agentspec/componentTypeDefaults.js +120 -120
- package/dist/adapters/agentspec/defaultNodeTypes.d.ts +2 -2
- package/dist/adapters/agentspec/defaultNodeTypes.js +307 -307
- package/dist/adapters/agentspec/index.d.ts +10 -10
- package/dist/adapters/agentspec/index.js +6 -6
- package/dist/adapters/agentspec/validator.d.ts +2 -2
- package/dist/adapters/agentspec/validator.js +20 -22
- package/dist/api/enhanced-client.d.ts +3 -3
- package/dist/api/enhanced-client.js +72 -73
- package/dist/chat/commandClassifier.js +6 -6
- package/dist/chat/index.d.ts +5 -5
- package/dist/chat/index.js +4 -4
- package/dist/chat/responseParser.d.ts +6 -6
- package/dist/chat/responseParser.js +28 -24
- package/dist/commands/batch.d.ts +1 -1
- package/dist/commands/batch.js +5 -7
- package/dist/commands/executor.d.ts +2 -2
- package/dist/commands/executor.js +320 -231
- package/dist/commands/index.d.ts +6 -6
- package/dist/commands/index.js +5 -5
- package/dist/commands/parser.d.ts +1 -1
- package/dist/commands/parser.js +91 -74
- package/dist/commands/positioner.d.ts +2 -2
- package/dist/commands/positioner.js +1 -1
- package/dist/commands/storeIntegration.svelte.d.ts +2 -2
- package/dist/commands/storeIntegration.svelte.js +5 -5
- package/dist/commands/types.d.ts +42 -42
- package/dist/commands/types.js +2 -2
- package/dist/components/App.svelte +240 -294
- package/dist/components/App.svelte.d.ts +9 -9
- package/dist/components/CanvasBanner.stories.svelte +10 -16
- package/dist/components/CanvasBanner.stories.svelte.d.ts +1 -1
- package/dist/components/CanvasBanner.svelte +2 -2
- package/dist/components/CanvasBanner.svelte.d.ts +1 -1
- package/dist/components/CanvasController.svelte +3 -4
- package/dist/components/ConfigForm.svelte +118 -256
- package/dist/components/ConfigForm.svelte.d.ts +2 -2
- package/dist/components/ConfigMappingRow.svelte +7 -9
- package/dist/components/ConfigMappingRow.svelte.d.ts +1 -1
- package/dist/components/ConfigModal.svelte +3 -3
- package/dist/components/ConfigModal.svelte.d.ts +1 -1
- package/dist/components/ConfigPanel.stories.svelte +19 -19
- package/dist/components/ConfigPanel.stories.svelte.d.ts +1 -1
- package/dist/components/ConfigPanel.svelte +9 -20
- package/dist/components/ConfigPanel.svelte.d.ts +1 -1
- package/dist/components/ConnectionLine.svelte +4 -4
- package/dist/components/EdgeRefresher.svelte +1 -1
- package/dist/components/FlowDropEdge.stories.svelte +110 -110
- package/dist/components/FlowDropEdge.svelte +9 -9
- package/dist/components/FlowDropEdge.svelte.d.ts +1 -1
- package/dist/components/FlowDropZone.svelte +6 -9
- package/dist/components/FlowDropZone.svelte.d.ts +1 -1
- package/dist/components/LoadingSpinner.stories.svelte +13 -13
- package/dist/components/LoadingSpinner.stories.svelte.d.ts +1 -1
- package/dist/components/LoadingSpinner.svelte +3 -3
- package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
- package/dist/components/Logo.stories.svelte +4 -4
- package/dist/components/Logo.stories.svelte.d.ts +1 -1
- package/dist/components/Logo.svelte +3 -9
- package/dist/components/LogsSidebar.svelte +41 -48
- package/dist/components/LogsSidebar.svelte.d.ts +1 -1
- package/dist/components/MarkdownDisplay.stories.svelte +10 -14
- package/dist/components/MarkdownDisplay.stories.svelte.d.ts +1 -1
- package/dist/components/MarkdownDisplay.svelte +4 -6
- package/dist/components/Navbar.stories.svelte +19 -19
- package/dist/components/Navbar.stories.svelte.d.ts +1 -1
- package/dist/components/Navbar.svelte +28 -49
- package/dist/components/Navbar.svelte.d.ts +2 -2
- package/dist/components/NodeSidebar.svelte +42 -88
- package/dist/components/NodeSidebar.svelte.d.ts +1 -1
- package/dist/components/NodeStatusOverlay.stories.svelte +19 -31
- package/dist/components/NodeStatusOverlay.stories.svelte.d.ts +1 -1
- package/dist/components/NodeStatusOverlay.svelte +40 -55
- package/dist/components/NodeStatusOverlay.svelte.d.ts +3 -3
- package/dist/components/NodeSwapPicker.svelte +20 -64
- package/dist/components/NodeSwapPicker.svelte.d.ts +1 -1
- package/dist/components/PipelineStatus.svelte +63 -89
- package/dist/components/PipelineStatus.svelte.d.ts +4 -4
- package/dist/components/PortCoordinateTracker.svelte +5 -7
- package/dist/components/PortCoordinateTracker.svelte.d.ts +1 -1
- package/dist/components/PortMappingRow.svelte +20 -24
- package/dist/components/PortMappingRow.svelte.d.ts +2 -2
- package/dist/components/ReadOnlyDetails.svelte +1 -1
- package/dist/components/SchemaForm.stories.svelte +53 -53
- package/dist/components/SchemaForm.stories.svelte.d.ts +1 -1
- package/dist/components/SchemaForm.svelte +24 -51
- package/dist/components/SchemaForm.svelte.d.ts +2 -2
- package/dist/components/SettingsModal.svelte +6 -9
- package/dist/components/SettingsModal.svelte.d.ts +1 -1
- package/dist/components/SettingsPanel.svelte +138 -158
- package/dist/components/SettingsPanel.svelte.d.ts +1 -1
- package/dist/components/StatusIcon.stories.svelte +16 -29
- package/dist/components/StatusIcon.stories.svelte.d.ts +1 -1
- package/dist/components/StatusIcon.svelte +19 -19
- package/dist/components/StatusIcon.svelte.d.ts +2 -2
- package/dist/components/StatusLabel.stories.svelte +8 -8
- package/dist/components/StatusLabel.stories.svelte.d.ts +1 -1
- package/dist/components/SwapMappingEditor.svelte +35 -56
- package/dist/components/SwapMappingEditor.svelte.d.ts +2 -2
- package/dist/components/ThemeToggle.stories.svelte +10 -10
- package/dist/components/ThemeToggle.stories.svelte.d.ts +1 -1
- package/dist/components/ThemeToggle.svelte +22 -33
- package/dist/components/ThemeToggle.svelte.d.ts +1 -1
- package/dist/components/UniversalNode.svelte +29 -41
- package/dist/components/UniversalNode.svelte.d.ts +3 -3
- package/dist/components/WorkflowEditor.svelte +113 -168
- package/dist/components/WorkflowEditor.svelte.d.ts +4 -4
- package/dist/components/chat/AIChatPanel.svelte +272 -133
- package/dist/components/chat/AIChatPanel.svelte.d.ts +3 -3
- package/dist/components/chat/CommandPreview.svelte +74 -24
- package/dist/components/chat/CommandPreview.svelte.d.ts +1 -1
- package/dist/components/console/CommandConsole.stories.svelte +71 -53
- package/dist/components/console/CommandConsole.stories.svelte.d.ts +1 -1
- package/dist/components/console/CommandConsole.svelte +39 -35
- package/dist/components/console/CommandConsole.svelte.d.ts +2 -2
- package/dist/components/console/ConsoleAutocomplete.svelte +6 -3
- package/dist/components/console/ConsoleInput.svelte +148 -89
- package/dist/components/console/ConsoleInput.svelte.d.ts +1 -1
- package/dist/components/console/ConsoleOutput.svelte +5 -10
- package/dist/components/console/ConsoleOutput.svelte.d.ts +1 -1
- package/dist/components/console/formatters.d.ts +1 -1
- package/dist/components/console/formatters.js +27 -29
- package/dist/components/form/FormArray.svelte +75 -132
- package/dist/components/form/FormArray.svelte.d.ts +1 -1
- package/dist/components/form/FormAutocomplete.svelte +65 -108
- package/dist/components/form/FormAutocomplete.svelte.d.ts +1 -1
- package/dist/components/form/FormCheckboxGroup.stories.svelte +13 -16
- package/dist/components/form/FormCheckboxGroup.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormCheckboxGroup.svelte +2 -2
- package/dist/components/form/FormCodeEditor.svelte +42 -56
- package/dist/components/form/FormField.svelte +79 -90
- package/dist/components/form/FormField.svelte.d.ts +2 -2
- package/dist/components/form/FormFieldLight.svelte +72 -88
- package/dist/components/form/FormFieldLight.svelte.d.ts +1 -1
- package/dist/components/form/FormFieldWrapper.stories.svelte +14 -14
- package/dist/components/form/FormFieldWrapper.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormFieldWrapper.svelte +2 -9
- package/dist/components/form/FormFieldWrapper.svelte.d.ts +1 -1
- package/dist/components/form/FormFieldset.svelte +3 -3
- package/dist/components/form/FormFieldset.svelte.d.ts +2 -2
- package/dist/components/form/FormMarkdownEditor.svelte +123 -156
- package/dist/components/form/FormNumberField.stories.svelte +18 -18
- package/dist/components/form/FormNumberField.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormNumberField.svelte +6 -6
- package/dist/components/form/FormRangeField.stories.svelte +13 -13
- package/dist/components/form/FormRangeField.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormRangeField.svelte +4 -12
- package/dist/components/form/FormSelect.stories.svelte +21 -21
- package/dist/components/form/FormSelect.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormSelect.svelte +5 -5
- package/dist/components/form/FormSelect.svelte.d.ts +1 -1
- package/dist/components/form/FormTemplateEditor.svelte +126 -175
- package/dist/components/form/FormTemplateEditor.svelte.d.ts +1 -1
- package/dist/components/form/FormTextField.stories.svelte +17 -23
- package/dist/components/form/FormTextField.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormTextField.svelte +4 -4
- package/dist/components/form/FormTextarea.stories.svelte +18 -21
- package/dist/components/form/FormTextarea.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormTextarea.svelte +4 -4
- package/dist/components/form/FormToggle.stories.svelte +13 -16
- package/dist/components/form/FormToggle.stories.svelte.d.ts +1 -1
- package/dist/components/form/FormToggle.svelte +3 -3
- package/dist/components/form/FormUISchemaRenderer.svelte +12 -19
- package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +3 -3
- package/dist/components/form/index.d.ts +19 -19
- package/dist/components/form/index.js +18 -18
- package/dist/components/form/templateAutocomplete.d.ts +2 -2
- package/dist/components/form/templateAutocomplete.js +55 -64
- package/dist/components/form/types.d.ts +6 -6
- package/dist/components/form/types.js +4 -9
- package/dist/components/icons/AlertCircleIcon.svelte +1 -6
- package/dist/components/icons/CogIcon.svelte +1 -6
- package/dist/components/interrupt/ChoicePrompt.stories.svelte +27 -27
- package/dist/components/interrupt/ChoicePrompt.stories.svelte.d.ts +1 -1
- package/dist/components/interrupt/ChoicePrompt.svelte +17 -41
- package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +1 -1
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte +17 -17
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte.d.ts +1 -1
- package/dist/components/interrupt/ConfirmationPrompt.svelte +10 -16
- package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +1 -1
- package/dist/components/interrupt/FormPrompt.svelte +10 -15
- package/dist/components/interrupt/FormPrompt.svelte.d.ts +1 -1
- package/dist/components/interrupt/InterruptBubble.svelte +87 -121
- package/dist/components/interrupt/InterruptBubble.svelte.d.ts +2 -2
- package/dist/components/interrupt/ReviewPrompt.stories.svelte +37 -37
- package/dist/components/interrupt/ReviewPrompt.stories.svelte.d.ts +1 -1
- package/dist/components/interrupt/ReviewPrompt.svelte +55 -75
- package/dist/components/interrupt/ReviewPrompt.svelte.d.ts +1 -1
- package/dist/components/interrupt/TextInputPrompt.stories.svelte +16 -17
- package/dist/components/interrupt/TextInputPrompt.stories.svelte.d.ts +1 -1
- package/dist/components/interrupt/TextInputPrompt.svelte +13 -18
- package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +1 -1
- package/dist/components/interrupt/index.d.ts +6 -6
- package/dist/components/interrupt/index.js +6 -6
- package/dist/components/layouts/MainLayout.svelte +46 -84
- package/dist/components/layouts/MainLayout.svelte.d.ts +6 -6
- package/dist/components/nodes/GatewayNode.stories.svelte +64 -65
- package/dist/components/nodes/GatewayNode.svelte +37 -70
- package/dist/components/nodes/GatewayNode.svelte.d.ts +3 -3
- package/dist/components/nodes/IdeaNode.stories.svelte +25 -26
- package/dist/components/nodes/IdeaNode.svelte +22 -36
- package/dist/components/nodes/IdeaNode.svelte.d.ts +1 -1
- package/dist/components/nodes/NotesNode.stories.svelte +37 -38
- package/dist/components/nodes/NotesNode.svelte +28 -39
- package/dist/components/nodes/NotesNode.svelte.d.ts +1 -1
- package/dist/components/nodes/SimpleNode.stories.svelte +137 -138
- package/dist/components/nodes/SimpleNode.svelte +44 -74
- package/dist/components/nodes/SimpleNode.svelte.d.ts +1 -1
- package/dist/components/nodes/SquareNode.stories.svelte +75 -75
- package/dist/components/nodes/SquareNode.svelte +42 -68
- package/dist/components/nodes/SquareNode.svelte.d.ts +1 -1
- package/dist/components/nodes/TerminalNode.stories.svelte +10 -10
- package/dist/components/nodes/TerminalNode.svelte +74 -112
- package/dist/components/nodes/TerminalNode.svelte.d.ts +1 -1
- package/dist/components/nodes/ToolNode.stories.svelte +115 -116
- package/dist/components/nodes/ToolNode.svelte +31 -64
- package/dist/components/nodes/ToolNode.svelte.d.ts +1 -1
- package/dist/components/nodes/WorkflowNode.stories.svelte +84 -89
- package/dist/components/nodes/WorkflowNode.svelte +50 -103
- package/dist/components/nodes/WorkflowNode.svelte.d.ts +3 -3
- package/dist/components/playground/ChatPanel.svelte +47 -103
- package/dist/components/playground/ExecutionLogs.svelte +45 -68
- package/dist/components/playground/InputCollector.svelte +32 -51
- package/dist/components/playground/MessageBubble.stories.svelte +25 -25
- package/dist/components/playground/MessageBubble.stories.svelte.d.ts +1 -1
- package/dist/components/playground/MessageBubble.svelte +54 -70
- package/dist/components/playground/MessageBubble.svelte.d.ts +1 -1
- package/dist/components/playground/Playground.svelte +60 -91
- package/dist/components/playground/Playground.svelte.d.ts +3 -3
- package/dist/components/playground/PlaygroundModal.svelte +8 -12
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -3
- package/dist/components/playground/SessionManager.svelte +34 -40
- package/dist/components/playground/SessionManager.svelte.d.ts +1 -1
- package/dist/config/agentSpecEndpoints.d.ts +1 -1
- package/dist/config/agentSpecEndpoints.js +20 -20
- package/dist/config/constants.js +2 -2
- package/dist/config/defaultCategories.d.ts +1 -1
- package/dist/config/defaultCategories.js +86 -86
- package/dist/config/defaultPortConfig.d.ts +1 -1
- package/dist/config/defaultPortConfig.js +144 -144
- package/dist/config/endpoints.d.ts +4 -4
- package/dist/config/endpoints.js +68 -68
- package/dist/config/runtimeConfig.d.ts +2 -2
- package/dist/config/runtimeConfig.js +8 -8
- package/dist/core/index.d.ts +68 -68
- package/dist/core/index.js +38 -38
- package/dist/display/index.d.ts +2 -2
- package/dist/display/index.js +2 -2
- package/dist/editor/index.d.ts +64 -64
- package/dist/editor/index.js +54 -54
- package/dist/form/code.d.ts +5 -5
- package/dist/form/code.js +14 -14
- package/dist/form/fieldRegistry.d.ts +3 -3
- package/dist/form/fieldRegistry.js +9 -11
- package/dist/form/full.d.ts +8 -8
- package/dist/form/full.js +9 -9
- package/dist/form/index.d.ts +18 -18
- package/dist/form/index.js +16 -16
- package/dist/form/markdown.d.ts +4 -4
- package/dist/form/markdown.js +8 -8
- package/dist/helpers/proximityConnect.d.ts +3 -3
- package/dist/helpers/proximityConnect.js +32 -34
- package/dist/helpers/workflowEditorHelper.d.ts +6 -6
- package/dist/helpers/workflowEditorHelper.js +64 -68
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/mocks/app-environment.js +2 -2
- package/dist/mocks/app-forms.js +1 -1
- package/dist/mocks/app-navigation.js +2 -2
- package/dist/mocks/app-stores.js +3 -3
- package/dist/playground/index.d.ts +19 -19
- package/dist/playground/index.js +16 -16
- package/dist/playground/mount.d.ts +3 -3
- package/dist/playground/mount.js +24 -24
- package/dist/registry/builtinFormats.js +13 -13
- package/dist/registry/builtinNodes.d.ts +2 -2
- package/dist/registry/builtinNodes.js +77 -77
- package/dist/registry/index.d.ts +4 -4
- package/dist/registry/index.js +4 -4
- package/dist/registry/nodeComponentRegistry.d.ts +8 -8
- package/dist/registry/nodeComponentRegistry.js +9 -11
- package/dist/registry/plugin.d.ts +2 -2
- package/dist/registry/plugin.js +11 -11
- package/dist/registry/workflowFormatRegistry.d.ts +3 -3
- package/dist/registry/workflowFormatRegistry.js +2 -2
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.js +2 -2
- package/dist/services/agentSpecExecutionService.d.ts +3 -3
- package/dist/services/agentSpecExecutionService.js +55 -56
- package/dist/services/api.d.ts +2 -2
- package/dist/services/api.js +37 -37
- package/dist/services/apiVariableService.d.ts +1 -1
- package/dist/services/apiVariableService.js +34 -41
- package/dist/services/autoSaveService.js +8 -8
- package/dist/services/categoriesApi.d.ts +2 -2
- package/dist/services/categoriesApi.js +8 -8
- package/dist/services/chatService.d.ts +1 -1
- package/dist/services/chatService.js +18 -18
- package/dist/services/draftStorage.d.ts +1 -1
- package/dist/services/draftStorage.js +11 -11
- package/dist/services/dynamicSchemaService.d.ts +1 -1
- package/dist/services/dynamicSchemaService.js +39 -41
- package/dist/services/globalSave.d.ts +2 -2
- package/dist/services/globalSave.js +38 -41
- package/dist/services/historyService.d.ts +1 -1
- package/dist/services/historyService.js +10 -10
- package/dist/services/interruptService.d.ts +1 -1
- package/dist/services/interruptService.js +29 -35
- package/dist/services/nodeExecutionService.d.ts +1 -1
- package/dist/services/nodeExecutionService.js +44 -45
- package/dist/services/playgroundService.d.ts +1 -1
- package/dist/services/playgroundService.js +29 -29
- package/dist/services/portConfigApi.d.ts +2 -2
- package/dist/services/portConfigApi.js +8 -8
- package/dist/services/settingsService.d.ts +2 -2
- package/dist/services/settingsService.js +19 -25
- package/dist/services/toastService.d.ts +4 -4
- package/dist/services/toastService.js +33 -33
- package/dist/services/variableService.d.ts +1 -1
- package/dist/services/variableService.js +36 -36
- package/dist/services/workflowStorage.d.ts +2 -2
- package/dist/services/workflowStorage.js +13 -13
- package/dist/settings/index.d.ts +7 -7
- package/dist/settings/index.js +6 -6
- package/dist/skins/default.d.ts +1 -1
- package/dist/skins/default.js +1 -1
- package/dist/skins/index.d.ts +3 -3
- package/dist/skins/index.js +7 -7
- package/dist/skins/slate.d.ts +1 -1
- package/dist/skins/slate.js +69 -69
- package/dist/stores/categoriesStore.svelte.d.ts +1 -1
- package/dist/stores/categoriesStore.svelte.js +5 -5
- package/dist/stores/editorStateMachine.svelte.d.ts +2 -2
- package/dist/stores/editorStateMachine.svelte.js +34 -34
- package/dist/stores/historyStore.svelte.d.ts +4 -4
- package/dist/stores/historyStore.svelte.js +4 -4
- package/dist/stores/interruptStore.svelte.d.ts +3 -3
- package/dist/stores/interruptStore.svelte.js +21 -21
- package/dist/stores/playgroundStore.svelte.d.ts +2 -2
- package/dist/stores/playgroundStore.svelte.js +18 -21
- package/dist/stores/portCoordinateStore.svelte.d.ts +2 -2
- package/dist/stores/portCoordinateStore.svelte.js +10 -13
- package/dist/stores/settingsStore.svelte.d.ts +2 -2
- package/dist/stores/settingsStore.svelte.js +57 -62
- package/dist/stores/workflowStore.svelte.d.ts +3 -3
- package/dist/stores/workflowStore.svelte.js +46 -47
- package/dist/stories/CanvasDecorator.svelte +7 -10
- package/dist/stories/CanvasDecorator.svelte.d.ts +2 -2
- package/dist/stories/EdgeDecorator.svelte +28 -31
- package/dist/stories/EdgeDecorator.svelte.d.ts +1 -1
- package/dist/stories/NodeDecorator.svelte +14 -20
- package/dist/stories/NodeDecorator.svelte.d.ts +1 -1
- package/dist/stories/utils.d.ts +2 -2
- package/dist/stories/utils.js +89 -93
- package/dist/styles/base.css +16 -50
- package/dist/styles/tokens.css +10 -28
- package/dist/svelte-app.d.ts +10 -10
- package/dist/svelte-app.js +39 -39
- package/dist/themes/default.d.ts +1 -1
- package/dist/themes/default.js +4 -4
- package/dist/themes/index.d.ts +3 -3
- package/dist/themes/index.js +11 -11
- package/dist/themes/minimal.d.ts +1 -1
- package/dist/themes/minimal.js +5 -5
- package/dist/types/agentspec.d.ts +18 -18
- package/dist/types/agentspec.js +2 -2
- package/dist/types/auth.d.ts +1 -1
- package/dist/types/auth.js +6 -6
- package/dist/types/chat.d.ts +2 -2
- package/dist/types/config.d.ts +6 -6
- package/dist/types/events.d.ts +3 -3
- package/dist/types/events.js +2 -2
- package/dist/types/index.d.ts +32 -32
- package/dist/types/index.js +6 -6
- package/dist/types/interrupt.d.ts +6 -6
- package/dist/types/interrupt.js +21 -21
- package/dist/types/interruptState.d.ts +12 -12
- package/dist/types/interruptState.js +66 -66
- package/dist/types/playground.d.ts +7 -7
- package/dist/types/playground.js +14 -14
- package/dist/types/settings.d.ts +7 -5
- package/dist/types/settings.js +19 -24
- package/dist/types/skin.d.ts +1 -1
- package/dist/types/theme.d.ts +2 -2
- package/dist/types/uischema.d.ts +4 -4
- package/dist/types/uischema.js +3 -3
- package/dist/utils/colors.d.ts +1 -1
- package/dist/utils/colors.js +95 -97
- package/dist/utils/config.d.ts +2 -2
- package/dist/utils/config.js +48 -48
- package/dist/utils/connections.d.ts +2 -2
- package/dist/utils/connections.js +15 -15
- package/dist/utils/edgeStyling.d.ts +2 -2
- package/dist/utils/edgeStyling.js +36 -39
- package/dist/utils/errors.js +3 -3
- package/dist/utils/fetchWithAuth.d.ts +1 -1
- package/dist/utils/fetchWithAuth.js +2 -2
- package/dist/utils/handleIds.d.ts +2 -2
- package/dist/utils/handleIds.js +8 -8
- package/dist/utils/handlePositioning.d.ts +1 -1
- package/dist/utils/handlePositioning.js +2 -2
- package/dist/utils/icons.d.ts +1 -1
- package/dist/utils/icons.js +74 -74
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +7 -7
- package/dist/utils/nodeIds.d.ts +1 -1
- package/dist/utils/nodeIds.js +1 -1
- package/dist/utils/nodeStatus.d.ts +1 -1
- package/dist/utils/nodeStatus.js +48 -48
- package/dist/utils/nodeSwap.d.ts +9 -9
- package/dist/utils/nodeSwap.js +52 -58
- package/dist/utils/nodeTypes.d.ts +1 -1
- package/dist/utils/nodeTypes.js +20 -21
- package/dist/utils/nodeWrapper.d.ts +7 -7
- package/dist/utils/nodeWrapper.js +19 -21
- package/dist/utils/performanceUtils.d.ts +1 -1
- package/dist/utils/performanceUtils.js +1 -2
- package/dist/utils/portUtils.d.ts +2 -2
- package/dist/utils/portUtils.js +1 -1
- package/dist/utils/sanitize.js +1 -1
- package/dist/utils/uischema.d.ts +2 -2
- package/dist/utils/uischema.js +8 -8
- package/dist/utils/validation.js +8 -8
- package/package.json +7 -11
|
@@ -5,71 +5,65 @@
|
|
|
5
5
|
-->
|
|
6
6
|
|
|
7
7
|
<script lang="ts">
|
|
8
|
-
import { onMount, tick } from
|
|
9
|
-
import MainLayout from
|
|
10
|
-
import WorkflowEditor from
|
|
11
|
-
import NodeSidebar from
|
|
12
|
-
import Icon from
|
|
13
|
-
import ConfigForm from
|
|
14
|
-
import ConfigPanel from
|
|
15
|
-
import CommandConsole from
|
|
16
|
-
import AIChatPanel from
|
|
17
|
-
import type { UIAction } from
|
|
18
|
-
import NodeSwapPicker from
|
|
19
|
-
import SwapMappingEditor from
|
|
20
|
-
import Navbar from
|
|
21
|
-
import { api, setEndpointConfig } from
|
|
22
|
-
import { EnhancedFlowDropApiClient } from
|
|
8
|
+
import { onMount, tick } from 'svelte';
|
|
9
|
+
import MainLayout from './layouts/MainLayout.svelte';
|
|
10
|
+
import WorkflowEditor from './WorkflowEditor.svelte';
|
|
11
|
+
import NodeSidebar from './NodeSidebar.svelte';
|
|
12
|
+
import Icon from '@iconify/svelte';
|
|
13
|
+
import ConfigForm from './ConfigForm.svelte';
|
|
14
|
+
import ConfigPanel from './ConfigPanel.svelte';
|
|
15
|
+
import CommandConsole from './console/CommandConsole.svelte';
|
|
16
|
+
import AIChatPanel from './chat/AIChatPanel.svelte';
|
|
17
|
+
import type { UIAction } from '../commands/index.js';
|
|
18
|
+
import NodeSwapPicker from './NodeSwapPicker.svelte';
|
|
19
|
+
import SwapMappingEditor from './SwapMappingEditor.svelte';
|
|
20
|
+
import Navbar from './Navbar.svelte';
|
|
21
|
+
import { api, setEndpointConfig } from '../services/api.js';
|
|
22
|
+
import { EnhancedFlowDropApiClient } from '../api/enhanced-client.js';
|
|
23
23
|
import type {
|
|
24
24
|
NodeMetadata,
|
|
25
25
|
Workflow,
|
|
26
26
|
WorkflowNode,
|
|
27
27
|
ConfigSchema,
|
|
28
|
-
NodeUIExtensions
|
|
29
|
-
} from
|
|
30
|
-
import type { InteractiveSwapState, SwapEventContext } from
|
|
28
|
+
NodeUIExtensions
|
|
29
|
+
} from '../types/index.js';
|
|
30
|
+
import type { InteractiveSwapState, SwapEventContext } from '../utils/nodeSwap.js';
|
|
31
31
|
import {
|
|
32
32
|
computeInteractiveState,
|
|
33
33
|
buildSwapPreviewFromState,
|
|
34
34
|
executeSwap,
|
|
35
|
-
validateSwapResult
|
|
36
|
-
} from
|
|
37
|
-
import type { SwapStrategy } from
|
|
38
|
-
import { DEFAULT_WORKFLOW_FORMAT } from
|
|
39
|
-
import { createEndpointConfig } from
|
|
40
|
-
import type { EndpointConfig } from
|
|
41
|
-
import type { AuthProvider } from
|
|
42
|
-
import type {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
} from
|
|
46
|
-
import {
|
|
47
|
-
import type { FlowDropTheme, FlowDropThemeName } from "../types/theme.js";
|
|
48
|
-
import type { FlowDropSkinTokens } from "../types/skin.js";
|
|
49
|
-
import { resolveTheme } from "../themes/index.js";
|
|
35
|
+
validateSwapResult
|
|
36
|
+
} from '../utils/nodeSwap.js';
|
|
37
|
+
import type { SwapStrategy } from '../utils/nodeSwap.js';
|
|
38
|
+
import { DEFAULT_WORKFLOW_FORMAT } from '../types/index.js';
|
|
39
|
+
import { createEndpointConfig } from '../config/endpoints.js';
|
|
40
|
+
import type { EndpointConfig } from '../config/endpoints.js';
|
|
41
|
+
import type { AuthProvider } from '../types/auth.js';
|
|
42
|
+
import type { FlowDropEventHandlers, FlowDropFeatures } from '../types/events.js';
|
|
43
|
+
import { mergeFeatures } from '../types/events.js';
|
|
44
|
+
import type { FlowDropTheme, FlowDropThemeName } from '../types/theme.js';
|
|
45
|
+
import type { FlowDropSkinTokens } from '../types/skin.js';
|
|
46
|
+
import { resolveTheme } from '../themes/index.js';
|
|
50
47
|
import {
|
|
51
48
|
getWorkflowStore,
|
|
52
49
|
workflowActions,
|
|
53
50
|
getWorkflowName,
|
|
54
51
|
getWorkflowFormat,
|
|
55
|
-
markAsSaved
|
|
56
|
-
} from
|
|
57
|
-
import {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
} from
|
|
61
|
-
import { apiToasts, dismissToast } from "../services/toastService.js";
|
|
62
|
-
import { initAutoSave } from "../services/autoSaveService.js";
|
|
52
|
+
markAsSaved
|
|
53
|
+
} from '../stores/workflowStore.svelte.js';
|
|
54
|
+
import { globalSaveWorkflow, globalExportWorkflow } from '../services/globalSave.js';
|
|
55
|
+
import { apiToasts, dismissToast } from '../services/toastService.js';
|
|
56
|
+
import { initAutoSave } from '../services/autoSaveService.js';
|
|
57
|
+
import { getUiSettings, updateSettings } from '../stores/settingsStore.svelte.js';
|
|
63
58
|
import {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} from
|
|
67
|
-
import {
|
|
68
|
-
import {
|
|
69
|
-
import {
|
|
70
|
-
import {
|
|
71
|
-
import {
|
|
72
|
-
import type { SettingsCategory } from "../types/settings.js";
|
|
59
|
+
initializePortCompatibility,
|
|
60
|
+
getPortCompatibilityChecker
|
|
61
|
+
} from '../utils/connections.js';
|
|
62
|
+
import { DEFAULT_PORT_CONFIG } from '../config/defaultPortConfig.js';
|
|
63
|
+
import { workflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
|
|
64
|
+
import { logger } from '../utils/logger.js';
|
|
65
|
+
import { validateWorkflowData } from '../utils/validation.js';
|
|
66
|
+
import type { SettingsCategory } from '../types/settings.js';
|
|
73
67
|
|
|
74
68
|
/**
|
|
75
69
|
* Configuration props for runtime customization
|
|
@@ -92,10 +86,7 @@
|
|
|
92
86
|
/** Read-only mode */
|
|
93
87
|
readOnly?: boolean;
|
|
94
88
|
/** Node execution statuses */
|
|
95
|
-
nodeStatuses?: Record<
|
|
96
|
-
string,
|
|
97
|
-
"pending" | "running" | "completed" | "error"
|
|
98
|
-
>;
|
|
89
|
+
nodeStatuses?: Record<string, 'pending' | 'running' | 'completed' | 'error'>;
|
|
99
90
|
/** Pipeline ID for fetching node execution info */
|
|
100
91
|
pipelineId?: string;
|
|
101
92
|
/** Custom navbar title */
|
|
@@ -105,7 +96,7 @@
|
|
|
105
96
|
label: string;
|
|
106
97
|
href: string;
|
|
107
98
|
icon?: string;
|
|
108
|
-
variant?:
|
|
99
|
+
variant?: 'primary' | 'secondary' | 'outline';
|
|
109
100
|
onclick?: (event: Event) => void;
|
|
110
101
|
}>;
|
|
111
102
|
/** Show settings gear icon in navbar */
|
|
@@ -135,8 +126,8 @@
|
|
|
135
126
|
let {
|
|
136
127
|
workflow: initialWorkflow,
|
|
137
128
|
nodes: propNodes,
|
|
138
|
-
height =
|
|
139
|
-
width =
|
|
129
|
+
height = '100vh',
|
|
130
|
+
width = '100%',
|
|
140
131
|
showNavbar = false,
|
|
141
132
|
disableSidebar = false,
|
|
142
133
|
lockWorkflow = false,
|
|
@@ -155,7 +146,7 @@
|
|
|
155
146
|
settingsCategories,
|
|
156
147
|
showSettingsSyncButton,
|
|
157
148
|
showSettingsResetButton,
|
|
158
|
-
swapStrategies
|
|
149
|
+
swapStrategies
|
|
159
150
|
}: Props = $props();
|
|
160
151
|
|
|
161
152
|
// svelte-ignore state_referenced_locally — feature flags don't change at runtime
|
|
@@ -163,9 +154,7 @@
|
|
|
163
154
|
|
|
164
155
|
// Theme system — resolve named theme or custom object, inject CSS tokens from skin
|
|
165
156
|
// Explicit prop wins; falls back to user's persisted theme preference from settings
|
|
166
|
-
let resolvedTheme = $derived(
|
|
167
|
-
resolveTheme(themeProp ?? getUiSettings().theme),
|
|
168
|
-
);
|
|
157
|
+
let resolvedTheme = $derived(resolveTheme(themeProp ?? getUiSettings().theme));
|
|
169
158
|
let themeConfig = $derived(resolvedTheme.config);
|
|
170
159
|
|
|
171
160
|
// Inject skin tokens as a style tag so light/dark palettes can coexist.
|
|
@@ -176,19 +165,19 @@
|
|
|
176
165
|
const skin = resolvedTheme.skin;
|
|
177
166
|
const tokens = skin?.tokens;
|
|
178
167
|
const darkTokens = skin?.darkTokens;
|
|
179
|
-
if ((!tokens && !darkTokens) || typeof document ===
|
|
168
|
+
if ((!tokens && !darkTokens) || typeof document === 'undefined') return;
|
|
180
169
|
|
|
181
170
|
const toRules = (dict: FlowDropSkinTokens) =>
|
|
182
171
|
Object.entries(dict)
|
|
183
172
|
.map(([k, v]) => ` --fd-${k}: ${v};`)
|
|
184
|
-
.join(
|
|
173
|
+
.join('\n');
|
|
185
174
|
|
|
186
|
-
let css =
|
|
175
|
+
let css = '';
|
|
187
176
|
if (tokens) css += `:root {\n${toRules(tokens)}\n}\n`;
|
|
188
177
|
if (darkTokens) css += `[data-theme='dark'] {\n${toRules(darkTokens)}\n}\n`;
|
|
189
178
|
|
|
190
|
-
const style = document.createElement(
|
|
191
|
-
style.id =
|
|
179
|
+
const style = document.createElement('style');
|
|
180
|
+
style.id = 'fd-skin-tokens';
|
|
192
181
|
document.head.appendChild(style);
|
|
193
182
|
style.textContent = css;
|
|
194
183
|
|
|
@@ -203,8 +192,8 @@
|
|
|
203
192
|
}
|
|
204
193
|
// Default workflow title logic
|
|
205
194
|
const wfName = getWorkflowName();
|
|
206
|
-
if (!wfName || wfName ===
|
|
207
|
-
return
|
|
195
|
+
if (!wfName || wfName === 'Untitled Workflow') {
|
|
196
|
+
return 'Workflow / New Workflow';
|
|
208
197
|
}
|
|
209
198
|
return `Workflow / ${wfName}`;
|
|
210
199
|
});
|
|
@@ -230,43 +219,43 @@
|
|
|
230
219
|
let isWorkflowSettingsOpen = $state(false);
|
|
231
220
|
|
|
232
221
|
// Node swap state
|
|
233
|
-
let swapMode = $state<
|
|
222
|
+
let swapMode = $state<'idle' | 'picking' | 'mapping'>('idle');
|
|
234
223
|
let swapTargetMetadata = $state<NodeMetadata | null>(null);
|
|
235
224
|
let swapInteractiveState = $state<InteractiveSwapState | null>(null);
|
|
236
225
|
|
|
237
226
|
// Workflow configuration schema (derived to pick up dynamic format options)
|
|
238
227
|
let workflowConfigSchema: ConfigSchema = $derived({
|
|
239
|
-
type:
|
|
228
|
+
type: 'object' as const,
|
|
240
229
|
properties: {
|
|
241
230
|
name: {
|
|
242
|
-
type:
|
|
243
|
-
title:
|
|
244
|
-
description:
|
|
245
|
-
default:
|
|
231
|
+
type: 'string',
|
|
232
|
+
title: 'Workflow Name',
|
|
233
|
+
description: 'The name of the workflow',
|
|
234
|
+
default: ''
|
|
246
235
|
},
|
|
247
236
|
description: {
|
|
248
|
-
type:
|
|
249
|
-
title:
|
|
250
|
-
description:
|
|
251
|
-
format:
|
|
252
|
-
default:
|
|
237
|
+
type: 'string',
|
|
238
|
+
title: 'Description',
|
|
239
|
+
description: 'A description of the workflow',
|
|
240
|
+
format: 'multiline',
|
|
241
|
+
default: ''
|
|
253
242
|
},
|
|
254
243
|
format: {
|
|
255
|
-
type:
|
|
256
|
-
title:
|
|
257
|
-
description:
|
|
244
|
+
type: 'string',
|
|
245
|
+
title: 'Workflow Format',
|
|
246
|
+
description: 'The specification format for this workflow',
|
|
258
247
|
oneOf: workflowFormatRegistry.getOneOfOptions(),
|
|
259
|
-
default:
|
|
260
|
-
}
|
|
248
|
+
default: 'flowdrop'
|
|
249
|
+
}
|
|
261
250
|
},
|
|
262
|
-
required: [
|
|
251
|
+
required: ['name']
|
|
263
252
|
});
|
|
264
253
|
|
|
265
254
|
// Workflow configuration values
|
|
266
255
|
let workflowConfigValues = $derived({
|
|
267
|
-
name: getWorkflowName() ||
|
|
268
|
-
description: getWorkflowStore()?.description ||
|
|
269
|
-
format: getWorkflowStore()?.metadata?.format ||
|
|
256
|
+
name: getWorkflowName() || '',
|
|
257
|
+
description: getWorkflowStore()?.description || '',
|
|
258
|
+
format: getWorkflowStore()?.metadata?.format || 'flowdrop'
|
|
270
259
|
});
|
|
271
260
|
|
|
272
261
|
// Get the current node from the workflow store
|
|
@@ -291,18 +280,14 @@
|
|
|
291
280
|
// Merge format-provided nodes with prop nodes (deduplicate by ID, props take priority)
|
|
292
281
|
const formatNodes = workflowFormatRegistry.getAllFormatNodes();
|
|
293
282
|
const existingIds = new Set(propNodes.map((n) => n.id));
|
|
294
|
-
const uniqueFormatNodes = formatNodes.filter(
|
|
295
|
-
(n) => !existingIds.has(n.id),
|
|
296
|
-
);
|
|
283
|
+
const uniqueFormatNodes = formatNodes.filter((n) => !existingIds.has(n.id));
|
|
297
284
|
nodes = [...propNodes, ...uniqueFormatNodes];
|
|
298
285
|
nodeTypesLoading = false;
|
|
299
286
|
return;
|
|
300
287
|
}
|
|
301
288
|
|
|
302
289
|
// Show loading toast (if toasts are enabled)
|
|
303
|
-
const loadingToast = features.showToasts
|
|
304
|
-
? apiToasts.loading("Loading node types")
|
|
305
|
-
: null;
|
|
290
|
+
const loadingToast = features.showToasts ? apiToasts.loading('Loading node types') : null;
|
|
306
291
|
try {
|
|
307
292
|
error = null;
|
|
308
293
|
|
|
@@ -317,9 +302,7 @@
|
|
|
317
302
|
// Merge format-provided nodes with API nodes (deduplicate by ID, API takes priority)
|
|
318
303
|
const formatNodes = workflowFormatRegistry.getAllFormatNodes();
|
|
319
304
|
const existingIds = new Set(fetchedNodes.map((n) => n.id));
|
|
320
|
-
const uniqueFormatNodes = formatNodes.filter(
|
|
321
|
-
(n) => !existingIds.has(n.id),
|
|
322
|
-
);
|
|
305
|
+
const uniqueFormatNodes = formatNodes.filter((n) => !existingIds.has(n.id));
|
|
323
306
|
nodes = [...fetchedNodes, ...uniqueFormatNodes];
|
|
324
307
|
error = null;
|
|
325
308
|
nodeTypesLoading = false;
|
|
@@ -334,13 +317,13 @@
|
|
|
334
317
|
dismissToast(loadingToast);
|
|
335
318
|
}
|
|
336
319
|
|
|
337
|
-
const errorMessage = err instanceof Error ? err.message :
|
|
320
|
+
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
338
321
|
|
|
339
322
|
// Notify parent via event handler
|
|
340
323
|
if (eventHandlers?.onApiError) {
|
|
341
324
|
const suppressToast = eventHandlers.onApiError(
|
|
342
325
|
err instanceof Error ? err : new Error(errorMessage),
|
|
343
|
-
|
|
326
|
+
'fetchNodes'
|
|
344
327
|
);
|
|
345
328
|
if (suppressToast) {
|
|
346
329
|
// Parent handled the error, keep nodes empty
|
|
@@ -353,7 +336,7 @@
|
|
|
353
336
|
// Show error and set empty nodes array (no fallback to sample data)
|
|
354
337
|
error = `API Error: ${errorMessage}. No node types available.`;
|
|
355
338
|
if (features.showToasts) {
|
|
356
|
-
apiToasts.error(
|
|
339
|
+
apiToasts.error('Load node types', errorMessage);
|
|
357
340
|
}
|
|
358
341
|
|
|
359
342
|
// Set empty nodes array instead of fallback data
|
|
@@ -374,22 +357,19 @@
|
|
|
374
357
|
*/
|
|
375
358
|
async function testApiConnection(): Promise<void> {
|
|
376
359
|
try {
|
|
377
|
-
const baseUrl = endpointConfig?.baseUrl || apiBaseUrl ||
|
|
360
|
+
const baseUrl = endpointConfig?.baseUrl || apiBaseUrl || '/api/flowdrop';
|
|
378
361
|
const testUrl = `${baseUrl}/nodes`;
|
|
379
362
|
|
|
380
363
|
const response = await fetch(testUrl);
|
|
381
364
|
const data = await response.json();
|
|
382
365
|
|
|
383
366
|
if (response.ok && data.success) {
|
|
384
|
-
apiToasts.success(
|
|
367
|
+
apiToasts.success('API connection test', 'Connection successful');
|
|
385
368
|
} else {
|
|
386
|
-
apiToasts.error(
|
|
369
|
+
apiToasts.error('API connection test', 'Connection failed');
|
|
387
370
|
}
|
|
388
371
|
} catch (err) {
|
|
389
|
-
apiToasts.error(
|
|
390
|
-
"API connection test",
|
|
391
|
-
err instanceof Error ? err.message : "Unknown error",
|
|
392
|
-
);
|
|
372
|
+
apiToasts.error('API connection test', err instanceof Error ? err.message : 'Unknown error');
|
|
393
373
|
}
|
|
394
374
|
}
|
|
395
375
|
|
|
@@ -405,16 +385,13 @@
|
|
|
405
385
|
|
|
406
386
|
// Create enhanced API client with authProvider support if provided
|
|
407
387
|
if (authProvider) {
|
|
408
|
-
apiClient = new EnhancedFlowDropApiClient(
|
|
409
|
-
propEndpointConfig,
|
|
410
|
-
authProvider,
|
|
411
|
-
);
|
|
388
|
+
apiClient = new EnhancedFlowDropApiClient(propEndpointConfig, authProvider);
|
|
412
389
|
}
|
|
413
390
|
return;
|
|
414
391
|
}
|
|
415
392
|
|
|
416
393
|
// Second priority: Check if endpoint config is already set (e.g., by parent layout)
|
|
417
|
-
const { getEndpointConfig } = await import(
|
|
394
|
+
const { getEndpointConfig } = await import('../services/api.js');
|
|
418
395
|
const existingConfig = getEndpointConfig();
|
|
419
396
|
|
|
420
397
|
// If config already exists and no override provided, use existing
|
|
@@ -429,19 +406,19 @@
|
|
|
429
406
|
}
|
|
430
407
|
|
|
431
408
|
// Third priority: Use provided apiBaseUrl or default
|
|
432
|
-
const baseUrl = apiBaseUrl ||
|
|
409
|
+
const baseUrl = apiBaseUrl || '/api/flowdrop';
|
|
433
410
|
|
|
434
411
|
const config = createEndpointConfig(baseUrl, {
|
|
435
412
|
auth: {
|
|
436
|
-
type:
|
|
413
|
+
type: 'none' // No authentication for now
|
|
437
414
|
},
|
|
438
415
|
timeout: 10000, // 10 second timeout
|
|
439
416
|
retry: {
|
|
440
417
|
enabled: true,
|
|
441
418
|
maxAttempts: 2,
|
|
442
419
|
delay: 1000,
|
|
443
|
-
backoff:
|
|
444
|
-
}
|
|
420
|
+
backoff: 'exponential'
|
|
421
|
+
}
|
|
445
422
|
});
|
|
446
423
|
|
|
447
424
|
setEndpointConfig(config);
|
|
@@ -466,7 +443,7 @@
|
|
|
466
443
|
selectedNodeId = node.id;
|
|
467
444
|
isConfigSidebarOpen = true;
|
|
468
445
|
// Reset swap state when switching nodes
|
|
469
|
-
swapMode =
|
|
446
|
+
swapMode = 'idle';
|
|
470
447
|
swapTargetMetadata = null;
|
|
471
448
|
swapInteractiveState = null;
|
|
472
449
|
}
|
|
@@ -475,7 +452,7 @@
|
|
|
475
452
|
isConfigSidebarOpen = false;
|
|
476
453
|
selectedNodeId = null;
|
|
477
454
|
// Reset swap state when closing
|
|
478
|
-
swapMode =
|
|
455
|
+
swapMode = 'idle';
|
|
479
456
|
swapTargetMetadata = null;
|
|
480
457
|
swapInteractiveState = null;
|
|
481
458
|
}
|
|
@@ -495,7 +472,7 @@
|
|
|
495
472
|
* Start swap mode — transitions the right sidebar to the node picker
|
|
496
473
|
*/
|
|
497
474
|
function startSwap(): void {
|
|
498
|
-
swapMode =
|
|
475
|
+
swapMode = 'picking';
|
|
499
476
|
swapTargetMetadata = null;
|
|
500
477
|
swapInteractiveState = null;
|
|
501
478
|
}
|
|
@@ -517,24 +494,21 @@
|
|
|
517
494
|
}
|
|
518
495
|
|
|
519
496
|
// Get port compatibility checker (may be null if not initialized)
|
|
520
|
-
let checker: import(
|
|
497
|
+
let checker: import('../utils/connections.js').PortCompatibilityChecker | null = null;
|
|
521
498
|
try {
|
|
522
499
|
checker = getPortCompatibilityChecker();
|
|
523
500
|
} catch {
|
|
524
501
|
// Checker not initialized — computeSwapPreview will use exact dataType matching
|
|
525
502
|
}
|
|
526
503
|
|
|
527
|
-
const interactive = computeInteractiveState(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
wf.nodes,
|
|
532
|
-
{ checker, strategies: swapStrategies },
|
|
533
|
-
);
|
|
504
|
+
const interactive = computeInteractiveState(node, metadata, wf.edges, wf.nodes, {
|
|
505
|
+
checker,
|
|
506
|
+
strategies: swapStrategies
|
|
507
|
+
});
|
|
534
508
|
|
|
535
509
|
swapTargetMetadata = metadata;
|
|
536
510
|
swapInteractiveState = interactive;
|
|
537
|
-
swapMode =
|
|
511
|
+
swapMode = 'mapping';
|
|
538
512
|
}
|
|
539
513
|
|
|
540
514
|
/**
|
|
@@ -554,18 +528,12 @@
|
|
|
554
528
|
const preview = buildSwapPreviewFromState(state, wf.edges);
|
|
555
529
|
|
|
556
530
|
// Execute the swap
|
|
557
|
-
const result = executeSwap(
|
|
558
|
-
state.oldNode,
|
|
559
|
-
state.newMetadata,
|
|
560
|
-
preview,
|
|
561
|
-
wf.nodes,
|
|
562
|
-
wf.edges,
|
|
563
|
-
);
|
|
531
|
+
const result = executeSwap(state.oldNode, state.newMetadata, preview, wf.nodes, wf.edges);
|
|
564
532
|
|
|
565
533
|
// Post-swap validation
|
|
566
534
|
const validation = validateSwapResult(result);
|
|
567
535
|
if (!validation.valid) {
|
|
568
|
-
logger.error(
|
|
536
|
+
logger.error('Swap validation failed:', validation.error);
|
|
569
537
|
return;
|
|
570
538
|
}
|
|
571
539
|
|
|
@@ -576,7 +544,7 @@
|
|
|
576
544
|
newMetadata: state.newMetadata,
|
|
577
545
|
preview,
|
|
578
546
|
portOverrides: [],
|
|
579
|
-
configOverrides: []
|
|
547
|
+
configOverrides: []
|
|
580
548
|
};
|
|
581
549
|
const shouldProceed = await eventHandlers.onBeforeSwap(swapEventCtx);
|
|
582
550
|
if (shouldProceed === false) return;
|
|
@@ -586,7 +554,7 @@
|
|
|
586
554
|
workflowActions.swapNode({
|
|
587
555
|
nodes: result.updatedNodes,
|
|
588
556
|
edges: result.updatedEdges,
|
|
589
|
-
description: `Swap node: ${oldLabel} → ${newLabel}
|
|
557
|
+
description: `Swap node: ${oldLabel} → ${newLabel}`
|
|
590
558
|
});
|
|
591
559
|
|
|
592
560
|
// onAfterSwap hook (fire-and-forget — swap is already applied)
|
|
@@ -594,7 +562,7 @@
|
|
|
594
562
|
try {
|
|
595
563
|
eventHandlers.onAfterSwap(result, state.oldNode, state.newNodeId);
|
|
596
564
|
} catch (err) {
|
|
597
|
-
logger.error(
|
|
565
|
+
logger.error('onAfterSwap hook error:', err);
|
|
598
566
|
}
|
|
599
567
|
}
|
|
600
568
|
|
|
@@ -603,7 +571,7 @@
|
|
|
603
571
|
selectedNodeId = newNodeId;
|
|
604
572
|
|
|
605
573
|
// Reset swap state
|
|
606
|
-
swapMode =
|
|
574
|
+
swapMode = 'idle';
|
|
607
575
|
swapTargetMetadata = null;
|
|
608
576
|
swapInteractiveState = null;
|
|
609
577
|
|
|
@@ -624,7 +592,7 @@
|
|
|
624
592
|
* Cancel swap and return to normal config view
|
|
625
593
|
*/
|
|
626
594
|
function cancelSwap(): void {
|
|
627
|
-
swapMode =
|
|
595
|
+
swapMode = 'idle';
|
|
628
596
|
swapTargetMetadata = null;
|
|
629
597
|
swapInteractiveState = null;
|
|
630
598
|
}
|
|
@@ -632,14 +600,12 @@
|
|
|
632
600
|
/**
|
|
633
601
|
* Handle workflow configuration save
|
|
634
602
|
*/
|
|
635
|
-
async function handleWorkflowSave(
|
|
636
|
-
config: Record<string, unknown>,
|
|
637
|
-
): Promise<void> {
|
|
603
|
+
async function handleWorkflowSave(config: Record<string, unknown>): Promise<void> {
|
|
638
604
|
// Update the workflow store
|
|
639
605
|
if (getWorkflowStore()) {
|
|
640
606
|
workflowActions.batchUpdate({
|
|
641
607
|
name: config.name as string | undefined,
|
|
642
|
-
description: config.description as string | undefined
|
|
608
|
+
description: config.description as string | undefined
|
|
643
609
|
});
|
|
644
610
|
}
|
|
645
611
|
|
|
@@ -650,7 +616,7 @@
|
|
|
650
616
|
try {
|
|
651
617
|
await saveWorkflow();
|
|
652
618
|
} catch (error) {
|
|
653
|
-
logger.error(
|
|
619
|
+
logger.error('Failed to save workflow to backend:', error);
|
|
654
620
|
// Note: We don't throw the error here to avoid breaking the UI flow
|
|
655
621
|
// The user can still manually save via the main Save button if needed
|
|
656
622
|
}
|
|
@@ -667,7 +633,7 @@
|
|
|
667
633
|
apiClient: apiClient ?? undefined,
|
|
668
634
|
eventHandlers,
|
|
669
635
|
features,
|
|
670
|
-
onMarkAsSaved: markAsSaved
|
|
636
|
+
onMarkAsSaved: markAsSaved
|
|
671
637
|
});
|
|
672
638
|
}
|
|
673
639
|
|
|
@@ -691,45 +657,38 @@
|
|
|
691
657
|
reader.onload = (event) => {
|
|
692
658
|
try {
|
|
693
659
|
const text = event.target?.result;
|
|
694
|
-
if (typeof text !==
|
|
695
|
-
throw new Error(
|
|
660
|
+
if (typeof text !== 'string') {
|
|
661
|
+
throw new Error('Could not read file contents.');
|
|
696
662
|
}
|
|
697
663
|
const data = JSON.parse(text);
|
|
698
664
|
const validation = validateWorkflowData(data);
|
|
699
665
|
if (!validation.valid) {
|
|
700
666
|
if (features.showToasts) {
|
|
701
|
-
apiToasts.error(
|
|
702
|
-
"Import workflow",
|
|
703
|
-
validation.error ?? "Invalid workflow JSON",
|
|
704
|
-
);
|
|
667
|
+
apiToasts.error('Import workflow', validation.error ?? 'Invalid workflow JSON');
|
|
705
668
|
}
|
|
706
|
-
logger.warn(
|
|
669
|
+
logger.warn('Workflow import validation failed:', validation.error);
|
|
707
670
|
return;
|
|
708
671
|
}
|
|
709
672
|
workflowActions.initialize(data as Workflow);
|
|
710
673
|
if (features.showToasts) {
|
|
711
|
-
apiToasts.success(
|
|
712
|
-
"Import workflow",
|
|
713
|
-
"Workflow imported successfully",
|
|
714
|
-
);
|
|
674
|
+
apiToasts.success('Import workflow', 'Workflow imported successfully');
|
|
715
675
|
}
|
|
716
676
|
if (eventHandlers?.onWorkflowLoad) {
|
|
717
677
|
eventHandlers.onWorkflowLoad(data as Workflow);
|
|
718
678
|
}
|
|
719
679
|
} catch (error) {
|
|
720
|
-
const errorObj =
|
|
721
|
-
|
|
722
|
-
logger.error("Workflow import failed:", errorObj);
|
|
680
|
+
const errorObj = error instanceof Error ? error : new Error('Unknown error occurred');
|
|
681
|
+
logger.error('Workflow import failed:', errorObj);
|
|
723
682
|
if (features.showToasts) {
|
|
724
|
-
apiToasts.error(
|
|
683
|
+
apiToasts.error('Import workflow', errorObj.message);
|
|
725
684
|
}
|
|
726
685
|
}
|
|
727
686
|
};
|
|
728
687
|
reader.onerror = () => {
|
|
729
|
-
const message =
|
|
688
|
+
const message = 'Failed to read the selected file.';
|
|
730
689
|
logger.error(message);
|
|
731
690
|
if (features.showToasts) {
|
|
732
|
-
apiToasts.error(
|
|
691
|
+
apiToasts.error('Import workflow', message);
|
|
733
692
|
}
|
|
734
693
|
};
|
|
735
694
|
reader.readAsText(file);
|
|
@@ -745,15 +704,13 @@
|
|
|
745
704
|
importWorkflow(file);
|
|
746
705
|
}
|
|
747
706
|
// Reset input so same file can be re-imported
|
|
748
|
-
input.value =
|
|
707
|
+
input.value = '';
|
|
749
708
|
}
|
|
750
709
|
|
|
751
710
|
// Function to handle clicks outside the sidebar
|
|
752
711
|
function handleCanvasClick(event: MouseEvent): void {
|
|
753
712
|
// Check if the click is outside the right sidebar
|
|
754
|
-
const rightSidebar = document.querySelector(
|
|
755
|
-
".flowdrop-main-layout__sidebar--right",
|
|
756
|
-
);
|
|
713
|
+
const rightSidebar = document.querySelector('.flowdrop-main-layout__sidebar--right');
|
|
757
714
|
if (rightSidebar && !rightSidebar.contains(event.target as Node)) {
|
|
758
715
|
// Close sidebar when clicking outside of it
|
|
759
716
|
if (isConfigSidebarOpen) {
|
|
@@ -786,21 +743,21 @@
|
|
|
786
743
|
// Initialize with a default empty workflow so the editor is functional
|
|
787
744
|
// (e.g., drag-and-drop requires a non-null workflow in the store)
|
|
788
745
|
const defaultWorkflow: Workflow = {
|
|
789
|
-
id:
|
|
790
|
-
name:
|
|
746
|
+
id: '',
|
|
747
|
+
name: 'Untitled Workflow',
|
|
791
748
|
nodes: [],
|
|
792
749
|
edges: [],
|
|
793
750
|
metadata: {
|
|
794
|
-
version:
|
|
751
|
+
version: '1.0.0',
|
|
795
752
|
format: DEFAULT_WORKFLOW_FORMAT,
|
|
796
753
|
createdAt: new Date().toISOString(),
|
|
797
|
-
updatedAt: new Date().toISOString()
|
|
798
|
-
}
|
|
754
|
+
updatedAt: new Date().toISOString()
|
|
755
|
+
}
|
|
799
756
|
};
|
|
800
757
|
workflowActions.initialize(defaultWorkflow);
|
|
801
758
|
}
|
|
802
759
|
} catch (error) {
|
|
803
|
-
logger.error(
|
|
760
|
+
logger.error('Failed to initialize editor:', error);
|
|
804
761
|
}
|
|
805
762
|
})();
|
|
806
763
|
|
|
@@ -809,10 +766,7 @@
|
|
|
809
766
|
toggleWorkflowSettings();
|
|
810
767
|
};
|
|
811
768
|
|
|
812
|
-
window.addEventListener(
|
|
813
|
-
"workflow-settings-toggle",
|
|
814
|
-
handleWorkflowSettingsToggle,
|
|
815
|
-
);
|
|
769
|
+
window.addEventListener('workflow-settings-toggle', handleWorkflowSettingsToggle);
|
|
816
770
|
|
|
817
771
|
// Initialize auto-save based on user settings
|
|
818
772
|
const cleanupAutoSave = initAutoSave({
|
|
@@ -821,18 +775,15 @@
|
|
|
821
775
|
},
|
|
822
776
|
onError: (error) => {
|
|
823
777
|
// Don't show toast for auto-save errors to avoid noise
|
|
824
|
-
logger.warn(
|
|
778
|
+
logger.warn('Auto-save failed:', error);
|
|
825
779
|
},
|
|
826
780
|
onSuccess: () => {
|
|
827
|
-
logger.debug(
|
|
828
|
-
}
|
|
781
|
+
logger.debug('Auto-saved workflow');
|
|
782
|
+
}
|
|
829
783
|
});
|
|
830
784
|
|
|
831
785
|
return () => {
|
|
832
|
-
window.removeEventListener(
|
|
833
|
-
"workflow-settings-toggle",
|
|
834
|
-
handleWorkflowSettingsToggle,
|
|
835
|
-
);
|
|
786
|
+
window.removeEventListener('workflow-settings-toggle', handleWorkflowSettingsToggle);
|
|
836
787
|
cleanupAutoSave();
|
|
837
788
|
};
|
|
838
789
|
});
|
|
@@ -842,9 +793,7 @@
|
|
|
842
793
|
* Config panel always appears on the right side
|
|
843
794
|
*/
|
|
844
795
|
const hasConfigPanelOpen = $derived(
|
|
845
|
-
isWorkflowSettingsOpen ||
|
|
846
|
-
!!selectedNodeForConfig ||
|
|
847
|
-
swapMode !== "idle",
|
|
796
|
+
isWorkflowSettingsOpen || !!selectedNodeForConfig || swapMode !== 'idle'
|
|
848
797
|
);
|
|
849
798
|
const showRightPanel = $derived(!disableSidebar && hasConfigPanelOpen);
|
|
850
799
|
|
|
@@ -853,7 +802,7 @@
|
|
|
853
802
|
* When collapsed, use 0; otherwise use user-configured width
|
|
854
803
|
*/
|
|
855
804
|
const leftSidebarWidth = $derived(
|
|
856
|
-
getUiSettings().sidebarCollapsed ? 0 : getUiSettings().sidebarWidth
|
|
805
|
+
getUiSettings().sidebarCollapsed ? 0 : getUiSettings().sidebarWidth
|
|
857
806
|
);
|
|
858
807
|
|
|
859
808
|
/** Whether the sidebar is collapsed */
|
|
@@ -862,7 +811,7 @@
|
|
|
862
811
|
/** Toggle sidebar collapsed state */
|
|
863
812
|
function toggleSidebar(): void {
|
|
864
813
|
updateSettings({
|
|
865
|
-
ui: { sidebarCollapsed: !getUiSettings().sidebarCollapsed }
|
|
814
|
+
ui: { sidebarCollapsed: !getUiSettings().sidebarCollapsed }
|
|
866
815
|
});
|
|
867
816
|
}
|
|
868
817
|
|
|
@@ -875,16 +824,14 @@
|
|
|
875
824
|
*/
|
|
876
825
|
function handleGlobalKeydown(event: KeyboardEvent): void {
|
|
877
826
|
// Dead key on international keyboards — do not intercept
|
|
878
|
-
if (event.key ===
|
|
827
|
+
if (event.key === 'Dead') return;
|
|
879
828
|
|
|
880
|
-
if (event.key !==
|
|
829
|
+
if (event.key !== '`') return;
|
|
881
830
|
|
|
882
831
|
// Don't intercept when user is typing in an input, textarea, or contenteditable
|
|
883
832
|
const target = event.target as HTMLElement;
|
|
884
833
|
const isInputElement =
|
|
885
|
-
target.tagName ===
|
|
886
|
-
target.tagName === "TEXTAREA" ||
|
|
887
|
-
target.isContentEditable;
|
|
834
|
+
target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;
|
|
888
835
|
|
|
889
836
|
if (isInputElement) return;
|
|
890
837
|
|
|
@@ -893,24 +840,24 @@
|
|
|
893
840
|
}
|
|
894
841
|
|
|
895
842
|
function handleConsoleUIAction(action: UIAction): void {
|
|
896
|
-
if (action.type ===
|
|
843
|
+
if (action.type === 'open_config') {
|
|
897
844
|
const wf = getWorkflowStore();
|
|
898
845
|
if (!wf) return;
|
|
899
846
|
const node = wf.nodes.find((n) => n.id === action.nodeId);
|
|
900
847
|
if (node) openConfigSidebar(node);
|
|
901
|
-
} else if (action.type ===
|
|
848
|
+
} else if (action.type === 'select_node') {
|
|
902
849
|
selectedNodeId = action.nodeId;
|
|
903
|
-
} else if (action.type ===
|
|
850
|
+
} else if (action.type === 'canvas_fit_view') {
|
|
904
851
|
workflowEditorRef?.canvasFitView();
|
|
905
|
-
} else if (action.type ===
|
|
852
|
+
} else if (action.type === 'canvas_zoom_in') {
|
|
906
853
|
workflowEditorRef?.canvasZoomIn();
|
|
907
|
-
} else if (action.type ===
|
|
854
|
+
} else if (action.type === 'canvas_zoom_out') {
|
|
908
855
|
workflowEditorRef?.canvasZoomOut();
|
|
909
|
-
} else if (action.type ===
|
|
856
|
+
} else if (action.type === 'canvas_zoom_to') {
|
|
910
857
|
workflowEditorRef?.canvasZoomTo(action.level);
|
|
911
|
-
} else if (action.type ===
|
|
858
|
+
} else if (action.type === 'canvas_pan_to') {
|
|
912
859
|
workflowEditorRef?.canvasPanTo(action.position.x, action.position.y);
|
|
913
|
-
} else if (action.type ===
|
|
860
|
+
} else if (action.type === 'canvas_reset_view') {
|
|
914
861
|
workflowEditorRef?.canvasResetView();
|
|
915
862
|
}
|
|
916
863
|
}
|
|
@@ -923,13 +870,12 @@
|
|
|
923
870
|
tick().then(() => {
|
|
924
871
|
if (currentOpen) {
|
|
925
872
|
// Console was open, now closing — focus the canvas
|
|
926
|
-
const canvas = document.querySelector<HTMLElement>(
|
|
873
|
+
const canvas = document.querySelector<HTMLElement>('.flowdrop-editor-main');
|
|
927
874
|
canvas?.focus();
|
|
928
875
|
} else {
|
|
929
876
|
// Console was closed, now opening — focus first focusable element inside console
|
|
930
|
-
const consoleEl = document.querySelector<HTMLElement>(
|
|
931
|
-
const focusTarget =
|
|
932
|
-
consoleEl?.querySelector<HTMLElement>("input, button, [tabindex]");
|
|
877
|
+
const consoleEl = document.querySelector<HTMLElement>('.command-console');
|
|
878
|
+
const focusTarget = consoleEl?.querySelector<HTMLElement>('input, button, [tabindex]');
|
|
933
879
|
focusTarget?.focus();
|
|
934
880
|
}
|
|
935
881
|
});
|
|
@@ -940,10 +886,7 @@
|
|
|
940
886
|
|
|
941
887
|
<svelte:head>
|
|
942
888
|
<title>FlowDrop - Visual Workflow Manager</title>
|
|
943
|
-
<meta
|
|
944
|
-
name="description"
|
|
945
|
-
content="A modern drag-and-drop workflow editor for LLM applications"
|
|
946
|
-
/>
|
|
889
|
+
<meta name="description" content="A modern drag-and-drop workflow editor for LLM applications" />
|
|
947
890
|
</svelte:head>
|
|
948
891
|
|
|
949
892
|
<!-- Hidden file input for workflow JSON import -->
|
|
@@ -983,45 +926,45 @@
|
|
|
983
926
|
? navbarActions
|
|
984
927
|
: [
|
|
985
928
|
{
|
|
986
|
-
label:
|
|
987
|
-
href:
|
|
988
|
-
icon:
|
|
989
|
-
variant:
|
|
929
|
+
label: 'Save',
|
|
930
|
+
href: '#save',
|
|
931
|
+
icon: 'heroicons:document-arrow-down',
|
|
932
|
+
variant: 'primary',
|
|
990
933
|
onclick: (e) => {
|
|
991
934
|
e.preventDefault();
|
|
992
935
|
saveWorkflow();
|
|
993
|
-
}
|
|
936
|
+
}
|
|
994
937
|
},
|
|
995
938
|
{
|
|
996
|
-
label:
|
|
997
|
-
href:
|
|
998
|
-
icon:
|
|
999
|
-
variant:
|
|
939
|
+
label: 'Export',
|
|
940
|
+
href: '#export',
|
|
941
|
+
icon: 'heroicons:arrow-down-tray',
|
|
942
|
+
variant: 'outline',
|
|
1000
943
|
onclick: (e) => {
|
|
1001
944
|
e.preventDefault();
|
|
1002
945
|
exportWorkflow();
|
|
1003
|
-
}
|
|
946
|
+
}
|
|
1004
947
|
},
|
|
1005
948
|
{
|
|
1006
|
-
label:
|
|
1007
|
-
href:
|
|
1008
|
-
icon:
|
|
1009
|
-
variant:
|
|
949
|
+
label: 'Import',
|
|
950
|
+
href: '#import',
|
|
951
|
+
icon: 'heroicons:arrow-up-tray',
|
|
952
|
+
variant: 'outline',
|
|
1010
953
|
onclick: (e) => {
|
|
1011
954
|
e.preventDefault();
|
|
1012
955
|
fileInputRef?.click();
|
|
1013
|
-
}
|
|
956
|
+
}
|
|
1014
957
|
},
|
|
1015
958
|
{
|
|
1016
|
-
label:
|
|
1017
|
-
href:
|
|
1018
|
-
icon:
|
|
1019
|
-
variant:
|
|
959
|
+
label: 'Workflow Settings',
|
|
960
|
+
href: '#settings',
|
|
961
|
+
icon: 'heroicons:cog-6-tooth',
|
|
962
|
+
variant: 'outline',
|
|
1020
963
|
onclick: (e) => {
|
|
1021
964
|
e.preventDefault();
|
|
1022
965
|
toggleWorkflowSettings();
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
1025
968
|
]}
|
|
1026
969
|
showStatus={true}
|
|
1027
970
|
{showSettings}
|
|
@@ -1037,23 +980,31 @@
|
|
|
1037
980
|
{nodes}
|
|
1038
981
|
loading={nodeTypesLoading}
|
|
1039
982
|
activeFormat={getWorkflowFormat()}
|
|
1040
|
-
categoriesDefaultOpen={themeConfig?.sidebar?.categoriesDefaultOpen ??
|
|
1041
|
-
false}
|
|
983
|
+
categoriesDefaultOpen={themeConfig?.sidebar?.categoriesDefaultOpen ?? false}
|
|
1042
984
|
/>
|
|
1043
985
|
{/snippet}
|
|
1044
986
|
|
|
1045
987
|
<!-- Right Sidebar: Configuration, Swap, or Workflow Settings -->
|
|
1046
988
|
{#snippet rightSidebar()}
|
|
1047
|
-
{#if swapMode ===
|
|
1048
|
-
{@const swapChecker = (() => {
|
|
989
|
+
{#if swapMode === 'mapping' && swapInteractiveState && selectedNodeForConfig}
|
|
990
|
+
{@const swapChecker = (() => {
|
|
991
|
+
try {
|
|
992
|
+
return getPortCompatibilityChecker();
|
|
993
|
+
} catch {
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
996
|
+
})()}
|
|
1049
997
|
<SwapMappingEditor
|
|
1050
998
|
interactiveState={swapInteractiveState}
|
|
1051
999
|
checker={swapChecker}
|
|
1052
1000
|
onConfirm={executeNodeSwap}
|
|
1053
1001
|
onCancel={cancelSwap}
|
|
1054
|
-
onBack={() => {
|
|
1002
|
+
onBack={() => {
|
|
1003
|
+
swapMode = 'picking';
|
|
1004
|
+
swapInteractiveState = null;
|
|
1005
|
+
}}
|
|
1055
1006
|
/>
|
|
1056
|
-
{:else if swapMode ===
|
|
1007
|
+
{:else if swapMode === 'picking' && selectedNodeForConfig}
|
|
1057
1008
|
<NodeSwapPicker
|
|
1058
1009
|
currentNode={selectedNodeForConfig}
|
|
1059
1010
|
availableNodes={nodes}
|
|
@@ -1067,13 +1018,13 @@
|
|
|
1067
1018
|
id={getWorkflowStore()?.id}
|
|
1068
1019
|
details={[
|
|
1069
1020
|
{
|
|
1070
|
-
label:
|
|
1071
|
-
value: String(getWorkflowStore()?.nodes?.length ?? 0)
|
|
1021
|
+
label: 'Nodes',
|
|
1022
|
+
value: String(getWorkflowStore()?.nodes?.length ?? 0)
|
|
1072
1023
|
},
|
|
1073
1024
|
{
|
|
1074
|
-
label:
|
|
1075
|
-
value: String(getWorkflowStore()?.edges?.length ?? 0)
|
|
1076
|
-
}
|
|
1025
|
+
label: 'Connections',
|
|
1026
|
+
value: String(getWorkflowStore()?.edges?.length ?? 0)
|
|
1027
|
+
}
|
|
1077
1028
|
]}
|
|
1078
1029
|
configTitle="Settings"
|
|
1079
1030
|
onClose={() => (isWorkflowSettingsOpen = false)}
|
|
@@ -1087,25 +1038,19 @@
|
|
|
1087
1038
|
// Sync workflow settings changes immediately on field blur
|
|
1088
1039
|
const wf = getWorkflowStore();
|
|
1089
1040
|
if (wf) {
|
|
1090
|
-
const newFormat =
|
|
1091
|
-
|
|
1092
|
-
const currentFormat =
|
|
1093
|
-
wf.metadata?.format || DEFAULT_WORKFLOW_FORMAT;
|
|
1041
|
+
const newFormat = (config.format as string) || DEFAULT_WORKFLOW_FORMAT;
|
|
1042
|
+
const currentFormat = wf.metadata?.format || DEFAULT_WORKFLOW_FORMAT;
|
|
1094
1043
|
|
|
1095
1044
|
// Warn about incompatible nodes when format changes
|
|
1096
1045
|
if (newFormat !== currentFormat) {
|
|
1097
1046
|
const incompatibleNodes = wf.nodes?.filter((node) => {
|
|
1098
1047
|
const formats = node.data?.metadata?.formats;
|
|
1099
|
-
return (
|
|
1100
|
-
formats &&
|
|
1101
|
-
formats.length > 0 &&
|
|
1102
|
-
!formats.includes(newFormat)
|
|
1103
|
-
);
|
|
1048
|
+
return formats && formats.length > 0 && !formats.includes(newFormat);
|
|
1104
1049
|
});
|
|
1105
1050
|
if (incompatibleNodes && incompatibleNodes.length > 0) {
|
|
1106
1051
|
logger.warn(
|
|
1107
1052
|
`Format changed to '${newFormat}'. ${incompatibleNodes.length} node(s) are not compatible with this format and may not export correctly:`,
|
|
1108
|
-
incompatibleNodes.map((n) => n.data?.label || n.type)
|
|
1053
|
+
incompatibleNodes.map((n) => n.data?.label || n.type)
|
|
1109
1054
|
);
|
|
1110
1055
|
}
|
|
1111
1056
|
}
|
|
@@ -1115,8 +1060,8 @@
|
|
|
1115
1060
|
description: config.description as string | undefined,
|
|
1116
1061
|
metadata: {
|
|
1117
1062
|
...wf.metadata,
|
|
1118
|
-
format: newFormat
|
|
1119
|
-
}
|
|
1063
|
+
format: newFormat
|
|
1064
|
+
}
|
|
1120
1065
|
});
|
|
1121
1066
|
}
|
|
1122
1067
|
}}
|
|
@@ -1127,17 +1072,16 @@
|
|
|
1127
1072
|
<ConfigPanel
|
|
1128
1073
|
title={currentNode.data.label}
|
|
1129
1074
|
id={currentNode.id}
|
|
1130
|
-
description={currentNode.data.metadata?.description ||
|
|
1131
|
-
"Node configuration"}
|
|
1075
|
+
description={currentNode.data.metadata?.description || 'Node configuration'}
|
|
1132
1076
|
details={[
|
|
1133
1077
|
{
|
|
1134
|
-
label:
|
|
1135
|
-
value: currentNode.data.metadata?.type || currentNode.type
|
|
1078
|
+
label: 'Type',
|
|
1079
|
+
value: currentNode.data.metadata?.type || currentNode.type
|
|
1136
1080
|
},
|
|
1137
1081
|
{
|
|
1138
|
-
label:
|
|
1139
|
-
value: currentNode.data.metadata?.category ||
|
|
1140
|
-
}
|
|
1082
|
+
label: 'Category',
|
|
1083
|
+
value: currentNode.data.metadata?.category || 'general'
|
|
1084
|
+
}
|
|
1141
1085
|
]}
|
|
1142
1086
|
onClose={closeConfigSidebar}
|
|
1143
1087
|
onSwap={!readOnly && !lockWorkflow && features.enableNodeSwap ? startSwap : undefined}
|
|
@@ -1154,20 +1098,20 @@
|
|
|
1154
1098
|
// Build the updated node data
|
|
1155
1099
|
const updatedData = {
|
|
1156
1100
|
...currentNode.data,
|
|
1157
|
-
config: updatedConfig
|
|
1101
|
+
config: updatedConfig
|
|
1158
1102
|
};
|
|
1159
1103
|
|
|
1160
1104
|
// Include UI extensions if provided
|
|
1161
1105
|
if (uiExtensions) {
|
|
1162
1106
|
updatedData.extensions = {
|
|
1163
1107
|
...currentNode.data.extensions,
|
|
1164
|
-
ui: uiExtensions
|
|
1108
|
+
ui: uiExtensions
|
|
1165
1109
|
};
|
|
1166
1110
|
}
|
|
1167
1111
|
|
|
1168
1112
|
// Update the node in the workflow store
|
|
1169
1113
|
const nodeUpdates: Record<string, unknown> = {
|
|
1170
|
-
data: updatedData
|
|
1114
|
+
data: updatedData
|
|
1171
1115
|
};
|
|
1172
1116
|
|
|
1173
1117
|
workflowActions.updateNode(selectedNodeId, nodeUpdates);
|
|
@@ -1190,24 +1134,39 @@
|
|
|
1190
1134
|
<div class="bottom-panel-tabs">
|
|
1191
1135
|
<div class="bottom-panel-tabs__bar">
|
|
1192
1136
|
<button
|
|
1193
|
-
class="bottom-panel-tabs__tab {getUiSettings().bottomPanelTab === 'console'
|
|
1137
|
+
class="bottom-panel-tabs__tab {getUiSettings().bottomPanelTab === 'console'
|
|
1138
|
+
? 'bottom-panel-tabs__tab--active'
|
|
1139
|
+
: ''}"
|
|
1194
1140
|
onclick={() => updateSettings({ ui: { bottomPanelTab: 'console' } })}
|
|
1195
1141
|
>
|
|
1196
1142
|
Console
|
|
1197
1143
|
</button>
|
|
1198
1144
|
<button
|
|
1199
|
-
class="bottom-panel-tabs__tab {getUiSettings().bottomPanelTab === 'chat'
|
|
1145
|
+
class="bottom-panel-tabs__tab {getUiSettings().bottomPanelTab === 'chat'
|
|
1146
|
+
? 'bottom-panel-tabs__tab--active'
|
|
1147
|
+
: ''}"
|
|
1200
1148
|
onclick={() => updateSettings({ ui: { bottomPanelTab: 'chat' } })}
|
|
1201
1149
|
>
|
|
1202
1150
|
AI Chat
|
|
1203
1151
|
</button>
|
|
1204
1152
|
</div>
|
|
1205
1153
|
<div class="bottom-panel-tabs__content">
|
|
1206
|
-
<div
|
|
1154
|
+
<div
|
|
1155
|
+
class="bottom-panel-tabs__panel"
|
|
1156
|
+
style:display={getUiSettings().bottomPanelTab === 'console' ? 'contents' : 'none'}
|
|
1157
|
+
>
|
|
1207
1158
|
<CommandConsole nodeTypes={nodes} onUIAction={handleConsoleUIAction} />
|
|
1208
1159
|
</div>
|
|
1209
|
-
<div
|
|
1210
|
-
|
|
1160
|
+
<div
|
|
1161
|
+
class="bottom-panel-tabs__panel"
|
|
1162
|
+
style:display={getUiSettings().bottomPanelTab === 'chat' ? 'flex' : 'none'}
|
|
1163
|
+
>
|
|
1164
|
+
<AIChatPanel
|
|
1165
|
+
nodeTypes={nodes}
|
|
1166
|
+
workflowId={getWorkflowStore()?.id}
|
|
1167
|
+
onUIAction={handleConsoleUIAction}
|
|
1168
|
+
{endpointConfig}
|
|
1169
|
+
/>
|
|
1211
1170
|
</div>
|
|
1212
1171
|
</div>
|
|
1213
1172
|
</div>
|
|
@@ -1216,19 +1175,11 @@
|
|
|
1216
1175
|
<!-- Main Content: Workflow Editor with Error Status -->
|
|
1217
1176
|
<!-- Status Display: aria-live announces API errors dynamically without requiring focus -->
|
|
1218
1177
|
{#if error}
|
|
1219
|
-
<div
|
|
1220
|
-
class="flowdrop-status flowdrop-status--error"
|
|
1221
|
-
aria-live="polite"
|
|
1222
|
-
aria-atomic="true"
|
|
1223
|
-
>
|
|
1178
|
+
<div class="flowdrop-status flowdrop-status--error" aria-live="polite" aria-atomic="true">
|
|
1224
1179
|
<div class="flowdrop-status__content">
|
|
1225
1180
|
<div class="flowdrop-flex flowdrop-gap--3">
|
|
1226
|
-
<div
|
|
1227
|
-
|
|
1228
|
-
></div>
|
|
1229
|
-
<span class="flowdrop-text--sm flowdrop-font--medium"
|
|
1230
|
-
>Error: {error}</span
|
|
1231
|
-
>
|
|
1181
|
+
<div class="flowdrop-status__indicator flowdrop-status__indicator--error"></div>
|
|
1182
|
+
<span class="flowdrop-text--sm flowdrop-font--medium">Error: {error}</span>
|
|
1232
1183
|
</div>
|
|
1233
1184
|
<div class="flowdrop-flex flowdrop-gap--2">
|
|
1234
1185
|
<button
|
|
@@ -1241,8 +1192,8 @@
|
|
|
1241
1192
|
<button
|
|
1242
1193
|
class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--outline"
|
|
1243
1194
|
onclick={() => {
|
|
1244
|
-
const defaultUrl =
|
|
1245
|
-
const newUrl = prompt(
|
|
1195
|
+
const defaultUrl = '/api/flowdrop';
|
|
1196
|
+
const newUrl = prompt('Enter Backend API URL:', defaultUrl);
|
|
1246
1197
|
if (newUrl) {
|
|
1247
1198
|
const endpointConfig = createEndpointConfig(newUrl);
|
|
1248
1199
|
setEndpointConfig(endpointConfig);
|
|
@@ -1277,11 +1228,9 @@
|
|
|
1277
1228
|
<div
|
|
1278
1229
|
class="flowdrop-editor-main"
|
|
1279
1230
|
class:pipeline-view={!!pipelineId}
|
|
1280
|
-
style="--fd-canvas-left-offset: {!disableSidebar
|
|
1281
|
-
? leftSidebarWidth + 'px'
|
|
1282
|
-
: '0px'}"
|
|
1231
|
+
style="--fd-canvas-left-offset: {!disableSidebar ? leftSidebarWidth + 'px' : '0px'}"
|
|
1283
1232
|
onclick={handleCanvasClick}
|
|
1284
|
-
onkeydown={(e) => e.key ===
|
|
1233
|
+
onkeydown={(e) => e.key === 'Escape' && closeConfigSidebar()}
|
|
1285
1234
|
role="region"
|
|
1286
1235
|
aria-label="Workflow canvas"
|
|
1287
1236
|
>
|
|
@@ -1290,12 +1239,10 @@
|
|
|
1290
1239
|
<button
|
|
1291
1240
|
class="flowdrop-sidebar-fab"
|
|
1292
1241
|
onclick={toggleSidebar}
|
|
1293
|
-
aria-label={isSidebarCollapsed
|
|
1294
|
-
|
|
1295
|
-
: "Collapse sidebar"}
|
|
1296
|
-
title={isSidebarCollapsed ? "Expand sidebar" : "Collapse sidebar"}
|
|
1242
|
+
aria-label={isSidebarCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}
|
|
1243
|
+
title={isSidebarCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}
|
|
1297
1244
|
>
|
|
1298
|
-
<Icon icon={isSidebarCollapsed ?
|
|
1245
|
+
<Icon icon={isSidebarCollapsed ? 'mdi:menu' : 'mdi:menu-open'} />
|
|
1299
1246
|
</button>
|
|
1300
1247
|
{/if}
|
|
1301
1248
|
|
|
@@ -1306,7 +1253,7 @@
|
|
|
1306
1253
|
{width}
|
|
1307
1254
|
endpointConfig={endpointConfig ?? undefined}
|
|
1308
1255
|
{isConfigSidebarOpen}
|
|
1309
|
-
|
|
1256
|
+
{selectedNodeForConfig}
|
|
1310
1257
|
{openConfigSidebar}
|
|
1311
1258
|
{closeConfigSidebar}
|
|
1312
1259
|
{lockWorkflow}
|
|
@@ -1520,5 +1467,4 @@
|
|
|
1520
1467
|
overflow: hidden;
|
|
1521
1468
|
flex-direction: column;
|
|
1522
1469
|
}
|
|
1523
|
-
|
|
1524
1470
|
</style>
|