@particle-academy/fancy-flow 0.20.0 → 0.22.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/dist/{capabilities-DUhAc-EJ.d.ts → capabilities-85Mjn4uW.d.ts} +1 -1
- package/dist/{capabilities-ChE3Xi8R.d.cts → capabilities-exVeADXz.d.cts} +1 -1
- package/dist/{chunk-L4AX73Q6.js → chunk-KDHLKBL2.js} +11 -5
- package/dist/chunk-KDHLKBL2.js.map +1 -0
- package/dist/{chunk-KI4RI2N3.js → chunk-O7F6SGV4.js} +4 -4
- package/dist/{chunk-KI4RI2N3.js.map → chunk-O7F6SGV4.js.map} +1 -1
- package/dist/{chunk-D6W5FMCT.js → chunk-OHVSEHDC.js} +23 -5
- package/dist/chunk-OHVSEHDC.js.map +1 -0
- package/dist/{chunk-U5F22BHV.js → chunk-YXRLIV7A.js} +4 -2
- package/dist/chunk-YXRLIV7A.js.map +1 -0
- package/dist/{chunk-AW2QUEL2.js → chunk-YZTBRXBZ.js} +66 -8
- package/dist/chunk-YZTBRXBZ.js.map +1 -0
- package/dist/{chunk-XETAGLH6.js → chunk-ZB4HHQMR.js} +130 -32
- package/dist/chunk-ZB4HHQMR.js.map +1 -0
- package/dist/engine.cjs +8 -2
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.cts +3 -3
- package/dist/engine.d.ts +3 -3
- package/dist/engine.js +3 -3
- package/dist/index.cjs +3553 -3278
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -8
- package/dist/index.d.ts +25 -8
- package/dist/index.js +200 -107
- package/dist/index.js.map +1 -1
- package/dist/llm/vercel-ai.d.cts +2 -2
- package/dist/llm/vercel-ai.d.ts +2 -2
- package/dist/registry/index.d.cts +5 -5
- package/dist/registry/index.d.ts +5 -5
- package/dist/registry.cjs +197 -33
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +4 -4
- package/dist/{run-flow-ChBi6q-W.d.ts → run-flow-9U-gaYVF.d.ts} +1 -1
- package/dist/{run-flow-VKm57Hcj.d.cts → run-flow-AXzOR-Wq.d.cts} +1 -1
- package/dist/runtime/index.d.cts +3 -3
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime.cjs +8 -2
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +4 -4
- package/dist/schema/index.d.cts +21 -2
- package/dist/schema/index.d.ts +21 -2
- package/dist/schema.cjs +20 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +2 -2
- package/dist/styles.css +61 -0
- package/dist/styles.css.map +1 -1
- package/dist/{types-NerkPtHS.d.ts → types-CFEtuRWJ.d.ts} +33 -3
- package/dist/{types-sOmpCitB.d.cts → types-CMSrWVYM.d.cts} +1 -1
- package/dist/{types-sOmpCitB.d.ts → types-CMSrWVYM.d.ts} +1 -1
- package/dist/{types-D_jOR3Z2.d.cts → types-DneUoivl.d.cts} +33 -3
- package/dist/ux.cjs.map +1 -1
- package/dist/ux.d.cts +3 -3
- package/dist/ux.d.ts +3 -3
- package/dist/ux.js +1 -1
- package/package.json +23 -3
- package/dist/chunk-AW2QUEL2.js.map +0 -1
- package/dist/chunk-D6W5FMCT.js.map +0 -1
- package/dist/chunk-L4AX73Q6.js.map +0 -1
- package/dist/chunk-U5F22BHV.js.map +0 -1
- package/dist/chunk-XETAGLH6.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -3,17 +3,17 @@ import { ReactNode, CSSProperties, ComponentType } from 'react';
|
|
|
3
3
|
import { ReactFlowProps, Edge, BackgroundVariant, Connection, NodeProps, NodeTypes } from '@xyflow/react';
|
|
4
4
|
import { ConnectionValidatorOptions } from './registry/index.cjs';
|
|
5
5
|
export { ANY_PORT_TYPE, BUILTIN_KINDS, PortCompatibility, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, createConnectionValidator, defaultConfigFor, defaultPortCompatibility, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.cjs';
|
|
6
|
-
import {
|
|
7
|
-
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData,
|
|
6
|
+
import { a as FlowNode, F as FlowGraph, e as NodeRunStatus, E as ExecutorRegistry } from './types-CMSrWVYM.cjs';
|
|
7
|
+
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, b as FlowEdge, c as FlowNodeData, d as FlowNodeKind, N as NodeExecutor, f as NoteNodeData, O as OutputNodeData, P as PortDescriptor, R as RunEvent, S as SubgraphNodeData, T as TriggerNodeData } from './types-CMSrWVYM.cjs';
|
|
8
8
|
import { WorkflowSchema, WorkflowMetadata } from './schema/index.cjs';
|
|
9
|
-
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, workflowToBlob } from './schema/index.cjs';
|
|
10
|
-
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-
|
|
11
|
-
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-
|
|
9
|
+
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.cjs';
|
|
10
|
+
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-DneUoivl.cjs';
|
|
11
|
+
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-DneUoivl.cjs';
|
|
12
12
|
import { FlowRunFeedEntry } from './runtime/index.cjs';
|
|
13
13
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.cjs';
|
|
14
|
-
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-
|
|
14
|
+
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-AXzOR-Wq.cjs';
|
|
15
15
|
export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, P as PauseAwaiting, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.cjs';
|
|
16
|
-
import './capabilities-
|
|
16
|
+
import './capabilities-exVeADXz.cjs';
|
|
17
17
|
|
|
18
18
|
type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
|
|
19
19
|
nodes: FlowNode[];
|
|
@@ -136,6 +136,12 @@ type FlowEditorApi = {
|
|
|
136
136
|
alignSelected: (edge: AlignEdge) => void;
|
|
137
137
|
/** Evenly distribute the multi-selection's gaps along an axis (needs 3+). */
|
|
138
138
|
distributeSelected: (axis: "h" | "v") => void;
|
|
139
|
+
/** Add a swimlane, stacked with existing lanes. Returns the new lane id. */
|
|
140
|
+
addLane: (orientation?: "horizontal" | "vertical", title?: string) => string | null;
|
|
141
|
+
/** Put a node inside a lane (sets parentId + a lane-relative position). */
|
|
142
|
+
assignToLane: (nodeId: string, laneId: string) => void;
|
|
143
|
+
/** Remove a node from its lane (restores its absolute position). */
|
|
144
|
+
removeFromLane: (nodeId: string) => void;
|
|
139
145
|
/** Copy the current selection to the editor clipboard. */
|
|
140
146
|
copy: () => void;
|
|
141
147
|
/** Copy then delete the current selection. */
|
|
@@ -192,6 +198,8 @@ type FlowEditorBuiltins = {
|
|
|
192
198
|
delete?: boolean;
|
|
193
199
|
/** Undo/redo toolbar buttons. Default true. */
|
|
194
200
|
history?: boolean;
|
|
201
|
+
/** "Add lane" toolbar button. Default true. */
|
|
202
|
+
addLane?: boolean;
|
|
195
203
|
/** Right-click a node for Delete / Duplicate. Default true. */
|
|
196
204
|
contextMenu?: boolean;
|
|
197
205
|
/** Right-click a connection for Label / Delete. Default true. */
|
|
@@ -426,6 +434,15 @@ declare const NoteNode: react.MemoExoticComponent<typeof NoteNodeInner>;
|
|
|
426
434
|
declare function SubgraphNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
427
435
|
declare const SubgraphNode: react.MemoExoticComponent<typeof SubgraphNodeInner>;
|
|
428
436
|
|
|
437
|
+
/**
|
|
438
|
+
* LaneNode — a resizable swimlane band. A portless container: child nodes are
|
|
439
|
+
* parented into it (`parentId` + `extent:'parent'`) and render on top, so this
|
|
440
|
+
* node is just the titled background. Wired as the `@particle-academy/lane`
|
|
441
|
+
* kind's `component`, so `buildNodeTypes` uses it instead of the default card.
|
|
442
|
+
*/
|
|
443
|
+
declare function LaneNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
444
|
+
declare const LaneNode: react.MemoExoticComponent<typeof LaneNodeInner>;
|
|
445
|
+
|
|
429
446
|
type NodeShellProps = {
|
|
430
447
|
/** Required: the xyflow node this is rendering. */
|
|
431
448
|
node: NodeProps<FlowNode>;
|
|
@@ -522,4 +539,4 @@ type FlowRunFeedProps = {
|
|
|
522
539
|
/** FlowRunFeed — scrolling log panel. Auto-scrolls to bottom on new entries. */
|
|
523
540
|
declare function FlowRunFeed({ entries, className, style }: FlowRunFeedProps): react.JSX.Element;
|
|
524
541
|
|
|
525
|
-
export { ActionNode, type AlignEdge, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
|
542
|
+
export { ActionNode, type AlignEdge, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, LaneNode, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,17 +3,17 @@ import { ReactNode, CSSProperties, ComponentType } from 'react';
|
|
|
3
3
|
import { ReactFlowProps, Edge, BackgroundVariant, Connection, NodeProps, NodeTypes } from '@xyflow/react';
|
|
4
4
|
import { ConnectionValidatorOptions } from './registry/index.js';
|
|
5
5
|
export { ANY_PORT_TYPE, BUILTIN_KINDS, PortCompatibility, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, createConnectionValidator, defaultConfigFor, defaultPortCompatibility, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.js';
|
|
6
|
-
import {
|
|
7
|
-
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData,
|
|
6
|
+
import { a as FlowNode, F as FlowGraph, e as NodeRunStatus, E as ExecutorRegistry } from './types-CMSrWVYM.js';
|
|
7
|
+
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, b as FlowEdge, c as FlowNodeData, d as FlowNodeKind, N as NodeExecutor, f as NoteNodeData, O as OutputNodeData, P as PortDescriptor, R as RunEvent, S as SubgraphNodeData, T as TriggerNodeData } from './types-CMSrWVYM.js';
|
|
8
8
|
import { WorkflowSchema, WorkflowMetadata } from './schema/index.js';
|
|
9
|
-
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, workflowToBlob } from './schema/index.js';
|
|
10
|
-
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-
|
|
11
|
-
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-
|
|
9
|
+
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.js';
|
|
10
|
+
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-CFEtuRWJ.js';
|
|
11
|
+
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-CFEtuRWJ.js';
|
|
12
12
|
import { FlowRunFeedEntry } from './runtime/index.js';
|
|
13
13
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.js';
|
|
14
|
-
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-
|
|
14
|
+
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-9U-gaYVF.js';
|
|
15
15
|
export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, P as PauseAwaiting, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.js';
|
|
16
|
-
import './capabilities-
|
|
16
|
+
import './capabilities-85Mjn4uW.js';
|
|
17
17
|
|
|
18
18
|
type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
|
|
19
19
|
nodes: FlowNode[];
|
|
@@ -136,6 +136,12 @@ type FlowEditorApi = {
|
|
|
136
136
|
alignSelected: (edge: AlignEdge) => void;
|
|
137
137
|
/** Evenly distribute the multi-selection's gaps along an axis (needs 3+). */
|
|
138
138
|
distributeSelected: (axis: "h" | "v") => void;
|
|
139
|
+
/** Add a swimlane, stacked with existing lanes. Returns the new lane id. */
|
|
140
|
+
addLane: (orientation?: "horizontal" | "vertical", title?: string) => string | null;
|
|
141
|
+
/** Put a node inside a lane (sets parentId + a lane-relative position). */
|
|
142
|
+
assignToLane: (nodeId: string, laneId: string) => void;
|
|
143
|
+
/** Remove a node from its lane (restores its absolute position). */
|
|
144
|
+
removeFromLane: (nodeId: string) => void;
|
|
139
145
|
/** Copy the current selection to the editor clipboard. */
|
|
140
146
|
copy: () => void;
|
|
141
147
|
/** Copy then delete the current selection. */
|
|
@@ -192,6 +198,8 @@ type FlowEditorBuiltins = {
|
|
|
192
198
|
delete?: boolean;
|
|
193
199
|
/** Undo/redo toolbar buttons. Default true. */
|
|
194
200
|
history?: boolean;
|
|
201
|
+
/** "Add lane" toolbar button. Default true. */
|
|
202
|
+
addLane?: boolean;
|
|
195
203
|
/** Right-click a node for Delete / Duplicate. Default true. */
|
|
196
204
|
contextMenu?: boolean;
|
|
197
205
|
/** Right-click a connection for Label / Delete. Default true. */
|
|
@@ -426,6 +434,15 @@ declare const NoteNode: react.MemoExoticComponent<typeof NoteNodeInner>;
|
|
|
426
434
|
declare function SubgraphNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
427
435
|
declare const SubgraphNode: react.MemoExoticComponent<typeof SubgraphNodeInner>;
|
|
428
436
|
|
|
437
|
+
/**
|
|
438
|
+
* LaneNode — a resizable swimlane band. A portless container: child nodes are
|
|
439
|
+
* parented into it (`parentId` + `extent:'parent'`) and render on top, so this
|
|
440
|
+
* node is just the titled background. Wired as the `@particle-academy/lane`
|
|
441
|
+
* kind's `component`, so `buildNodeTypes` uses it instead of the default card.
|
|
442
|
+
*/
|
|
443
|
+
declare function LaneNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
444
|
+
declare const LaneNode: react.MemoExoticComponent<typeof LaneNodeInner>;
|
|
445
|
+
|
|
429
446
|
type NodeShellProps = {
|
|
430
447
|
/** Required: the xyflow node this is rendering. */
|
|
431
448
|
node: NodeProps<FlowNode>;
|
|
@@ -522,4 +539,4 @@ type FlowRunFeedProps = {
|
|
|
522
539
|
/** FlowRunFeed — scrolling log panel. Auto-scrolls to bottom on new entries. */
|
|
523
540
|
declare function FlowRunFeed({ entries, className, style }: FlowRunFeedProps): react.JSX.Element;
|
|
524
541
|
|
|
525
|
-
export { ActionNode, type AlignEdge, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
|
542
|
+
export { ActionNode, type AlignEdge, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, LaneNode, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { useFlowState, useFlowRun, useFlowHistory, applyStatusesToNodes } from './chunk-
|
|
2
|
-
export { applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-
|
|
3
|
-
import { buildNodeTypes, registerBuiltinKinds, createConnectionValidator } from './chunk-
|
|
4
|
-
export { ANY_PORT_TYPE, BUILTIN_KINDS, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds } from './chunk-
|
|
5
|
-
import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, reconnectEdge, index, BackgroundVariant, Background, Controls, MiniMap } from './chunk-
|
|
1
|
+
import { useFlowState, useFlowRun, useFlowHistory, applyStatusesToNodes } from './chunk-O7F6SGV4.js';
|
|
2
|
+
export { applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-O7F6SGV4.js';
|
|
3
|
+
import { buildNodeTypes, registerBuiltinKinds, createConnectionValidator } from './chunk-YZTBRXBZ.js';
|
|
4
|
+
export { ANY_PORT_TYPE, BUILTIN_KINDS, LaneNode, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds } from './chunk-YZTBRXBZ.js';
|
|
5
|
+
import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, reconnectEdge, index, BackgroundVariant, Background, Controls, MiniMap } from './chunk-ZB4HHQMR.js';
|
|
6
6
|
export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, decodePause, encodePause, isPause, pauseForHuman } from './chunk-UEOE6B52.js';
|
|
7
|
-
export { runFlow } from './chunk-
|
|
8
|
-
import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-
|
|
9
|
-
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, workflowToBlob } from './chunk-
|
|
7
|
+
export { runFlow } from './chunk-KDHLKBL2.js';
|
|
8
|
+
import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-OHVSEHDC.js';
|
|
9
|
+
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-OHVSEHDC.js';
|
|
10
10
|
export { resolveNodePorts, resolvePortSpec } from './chunk-TITD5W4Y.js';
|
|
11
|
-
import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-
|
|
12
|
-
export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-
|
|
11
|
+
import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-YXRLIV7A.js';
|
|
12
|
+
export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-YXRLIV7A.js';
|
|
13
13
|
import { getRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
14
14
|
export { RichInputPreview, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
15
15
|
import './chunk-USL4FMFU.js';
|
|
@@ -139,6 +139,140 @@ var defaultNodeTypes = {
|
|
|
139
139
|
note: NoteNode,
|
|
140
140
|
subgraph: SubgraphNode
|
|
141
141
|
};
|
|
142
|
+
|
|
143
|
+
// src/components/FlowEditor/graph-ops.ts
|
|
144
|
+
function removeNodes(graph, ids) {
|
|
145
|
+
if (ids.length === 0) return graph;
|
|
146
|
+
const doomed = new Set(ids);
|
|
147
|
+
return {
|
|
148
|
+
nodes: graph.nodes.filter((n) => !doomed.has(n.id)),
|
|
149
|
+
edges: graph.edges.filter((e) => !doomed.has(e.source) && !doomed.has(e.target))
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function removeEdges(edges, ids) {
|
|
153
|
+
if (ids.length === 0) return edges;
|
|
154
|
+
const doomed = new Set(ids);
|
|
155
|
+
return edges.filter((e) => !doomed.has(e.id));
|
|
156
|
+
}
|
|
157
|
+
function setEdgeLabel(edges, id, label) {
|
|
158
|
+
const next = label?.trim();
|
|
159
|
+
return edges.map((e) => {
|
|
160
|
+
if (e.id !== id) return e;
|
|
161
|
+
if (!next) {
|
|
162
|
+
const { label: _drop, ...rest } = e;
|
|
163
|
+
return rest;
|
|
164
|
+
}
|
|
165
|
+
return { ...e, label: next };
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function duplicateNode(node, id, offset = 40) {
|
|
169
|
+
return {
|
|
170
|
+
...node,
|
|
171
|
+
id,
|
|
172
|
+
position: { x: node.position.x + offset, y: node.position.y + offset },
|
|
173
|
+
// Deep copy so the clone's config edits don't mutate the original.
|
|
174
|
+
data: JSON.parse(JSON.stringify(node.data ?? {}))
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function cloneSubgraph(nodes, edges, opts) {
|
|
178
|
+
const offset = opts.offset ?? 40;
|
|
179
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
180
|
+
for (const n of nodes) idMap.set(n.id, opts.makeId());
|
|
181
|
+
const clonedNodes = nodes.map((n) => {
|
|
182
|
+
const cloned = duplicateNode(n, idMap.get(n.id), offset);
|
|
183
|
+
const parentId = n.parentId;
|
|
184
|
+
if (parentId && idMap.has(parentId)) cloned.parentId = idMap.get(parentId);
|
|
185
|
+
else if (parentId) delete cloned.parentId;
|
|
186
|
+
return cloned;
|
|
187
|
+
});
|
|
188
|
+
const clonedEdges = edges.filter((e) => idMap.has(e.source) && idMap.has(e.target)).map((e) => ({ ...e, id: opts.makeId(), source: idMap.get(e.source), target: idMap.get(e.target) }));
|
|
189
|
+
return { nodes: clonedNodes, edges: clonedEdges, idMap };
|
|
190
|
+
}
|
|
191
|
+
function reconnectEdge2(edges, oldEdge, newConnection) {
|
|
192
|
+
return reconnectEdge(oldEdge, newConnection, edges, { shouldReplaceId: false });
|
|
193
|
+
}
|
|
194
|
+
var nodeW = (n) => n.width ?? n.measured?.width ?? 0;
|
|
195
|
+
var nodeH = (n) => n.height ?? n.measured?.height ?? 0;
|
|
196
|
+
function alignNodes(nodes, edge) {
|
|
197
|
+
if (nodes.length < 2) return nodes;
|
|
198
|
+
const minL = Math.min(...nodes.map((n) => n.position.x));
|
|
199
|
+
const maxR = Math.max(...nodes.map((n) => n.position.x + nodeW(n)));
|
|
200
|
+
const minT = Math.min(...nodes.map((n) => n.position.y));
|
|
201
|
+
const maxB = Math.max(...nodes.map((n) => n.position.y + nodeH(n)));
|
|
202
|
+
const cx = (minL + maxR) / 2;
|
|
203
|
+
const cy = (minT + maxB) / 2;
|
|
204
|
+
return nodes.map((n) => {
|
|
205
|
+
let { x, y } = n.position;
|
|
206
|
+
if (edge === "left") x = minL;
|
|
207
|
+
else if (edge === "right") x = maxR - nodeW(n);
|
|
208
|
+
else if (edge === "hcenter") x = cx - nodeW(n) / 2;
|
|
209
|
+
else if (edge === "top") y = minT;
|
|
210
|
+
else if (edge === "bottom") y = maxB - nodeH(n);
|
|
211
|
+
else if (edge === "vcenter") y = cy - nodeH(n) / 2;
|
|
212
|
+
return { ...n, position: { x, y } };
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function sortNodesParentFirst(nodes) {
|
|
216
|
+
const byId = new Map(nodes.map((n) => [n.id, n]));
|
|
217
|
+
const seen = /* @__PURE__ */ new Set();
|
|
218
|
+
const out = [];
|
|
219
|
+
const visit = (n) => {
|
|
220
|
+
if (seen.has(n.id)) return;
|
|
221
|
+
const pid = n.parentId;
|
|
222
|
+
if (pid && byId.has(pid) && !seen.has(pid)) visit(byId.get(pid));
|
|
223
|
+
seen.add(n.id);
|
|
224
|
+
out.push(n);
|
|
225
|
+
};
|
|
226
|
+
for (const n of nodes) visit(n);
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
function absolutePosition(node, nodes) {
|
|
230
|
+
const pid = node.parentId;
|
|
231
|
+
if (!pid) return node.position;
|
|
232
|
+
const parent = nodes.find((n) => n.id === pid);
|
|
233
|
+
return parent ? { x: node.position.x + parent.position.x, y: node.position.y + parent.position.y } : node.position;
|
|
234
|
+
}
|
|
235
|
+
function assignToLane(nodes, nodeId, laneId) {
|
|
236
|
+
if (nodeId === laneId) return nodes;
|
|
237
|
+
const node = nodes.find((n) => n.id === nodeId);
|
|
238
|
+
const lane = nodes.find((n) => n.id === laneId);
|
|
239
|
+
if (!node || !lane) return nodes;
|
|
240
|
+
const abs = absolutePosition(node, nodes);
|
|
241
|
+
const laneAbs = absolutePosition(lane, nodes);
|
|
242
|
+
const rel = { x: abs.x - laneAbs.x, y: abs.y - laneAbs.y };
|
|
243
|
+
return nodes.map((n) => n.id === nodeId ? { ...n, parentId: laneId, extent: "parent", position: rel } : n);
|
|
244
|
+
}
|
|
245
|
+
function removeFromLane(nodes, nodeId) {
|
|
246
|
+
const node = nodes.find((n) => n.id === nodeId);
|
|
247
|
+
if (!node || !node.parentId) return nodes;
|
|
248
|
+
const abs = absolutePosition(node, nodes);
|
|
249
|
+
return nodes.map((n) => {
|
|
250
|
+
if (n.id !== nodeId) return n;
|
|
251
|
+
const { parentId: _p, extent: _e, ...rest } = n;
|
|
252
|
+
return { ...rest, position: abs };
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
function distributeNodes(nodes, axis) {
|
|
256
|
+
if (nodes.length < 3) return nodes;
|
|
257
|
+
const size = (n) => axis === "h" ? nodeW(n) : nodeH(n);
|
|
258
|
+
const coord = (n) => axis === "h" ? n.position.x : n.position.y;
|
|
259
|
+
const sorted = [...nodes].sort((a, b) => coord(a) - coord(b));
|
|
260
|
+
const start = coord(sorted[0]);
|
|
261
|
+
const last = sorted[sorted.length - 1];
|
|
262
|
+
const end = coord(last) + size(last);
|
|
263
|
+
const totalSize = sorted.reduce((s, n) => s + size(n), 0);
|
|
264
|
+
const gap = (end - start - totalSize) / (sorted.length - 1);
|
|
265
|
+
const posById = /* @__PURE__ */ new Map();
|
|
266
|
+
let cursor = start;
|
|
267
|
+
for (const n of sorted) {
|
|
268
|
+
posById.set(n.id, cursor);
|
|
269
|
+
cursor += size(n) + gap;
|
|
270
|
+
}
|
|
271
|
+
return nodes.map((n) => {
|
|
272
|
+
const p = posById.get(n.id);
|
|
273
|
+
return { ...n, position: axis === "h" ? { ...n.position, x: p } : { ...n.position, y: p } };
|
|
274
|
+
});
|
|
275
|
+
}
|
|
142
276
|
var DEFAULT_FIT_VIEW = { padding: 0.2 };
|
|
143
277
|
var DEFAULT_EDGE_OPTIONS = {
|
|
144
278
|
type: "smoothstep",
|
|
@@ -178,12 +312,13 @@ function FlowCanvas({
|
|
|
178
312
|
() => edgeTypes ? { ...edgeTypes } : void 0,
|
|
179
313
|
[edgeTypes]
|
|
180
314
|
);
|
|
315
|
+
const orderedNodes = useMemo(() => sortNodesParentFirst(nodes), [nodes]);
|
|
181
316
|
return /* @__PURE__ */ jsxs("div", { className: ["ff-canvas", className ?? ""].filter(Boolean).join(" "), style: { height, ...style }, children: [
|
|
182
317
|
toolbar && /* @__PURE__ */ jsx("div", { className: "ff-canvas__toolbar", children: toolbar }),
|
|
183
318
|
/* @__PURE__ */ jsx("div", { className: "ff-canvas__surface", children: /* @__PURE__ */ jsxs(
|
|
184
319
|
index,
|
|
185
320
|
{
|
|
186
|
-
nodes,
|
|
321
|
+
nodes: orderedNodes,
|
|
187
322
|
edges,
|
|
188
323
|
nodeTypes: mergedNodeTypes,
|
|
189
324
|
edgeTypes: mergedEdgeTypes,
|
|
@@ -204,7 +339,7 @@ function FlowCanvas({
|
|
|
204
339
|
) })
|
|
205
340
|
] });
|
|
206
341
|
}
|
|
207
|
-
var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "custom"];
|
|
342
|
+
var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "layout", "custom"];
|
|
208
343
|
var CATEGORY_LABELS = {
|
|
209
344
|
trigger: "Triggers",
|
|
210
345
|
logic: "Logic",
|
|
@@ -213,6 +348,7 @@ var CATEGORY_LABELS = {
|
|
|
213
348
|
io: "Connectors",
|
|
214
349
|
human: "Human",
|
|
215
350
|
output: "Output",
|
|
351
|
+
layout: "Layout",
|
|
216
352
|
custom: "Custom"
|
|
217
353
|
};
|
|
218
354
|
function NodePalette({ categories, onPick, className, style }) {
|
|
@@ -804,100 +940,6 @@ function formatTime(at) {
|
|
|
804
940
|
const d = new Date(at);
|
|
805
941
|
return `${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}.${Math.floor(d.getMilliseconds() / 100)}`;
|
|
806
942
|
}
|
|
807
|
-
|
|
808
|
-
// src/components/FlowEditor/graph-ops.ts
|
|
809
|
-
function removeNodes(graph, ids) {
|
|
810
|
-
if (ids.length === 0) return graph;
|
|
811
|
-
const doomed = new Set(ids);
|
|
812
|
-
return {
|
|
813
|
-
nodes: graph.nodes.filter((n) => !doomed.has(n.id)),
|
|
814
|
-
edges: graph.edges.filter((e) => !doomed.has(e.source) && !doomed.has(e.target))
|
|
815
|
-
};
|
|
816
|
-
}
|
|
817
|
-
function removeEdges(edges, ids) {
|
|
818
|
-
if (ids.length === 0) return edges;
|
|
819
|
-
const doomed = new Set(ids);
|
|
820
|
-
return edges.filter((e) => !doomed.has(e.id));
|
|
821
|
-
}
|
|
822
|
-
function setEdgeLabel(edges, id, label) {
|
|
823
|
-
const next = label?.trim();
|
|
824
|
-
return edges.map((e) => {
|
|
825
|
-
if (e.id !== id) return e;
|
|
826
|
-
if (!next) {
|
|
827
|
-
const { label: _drop, ...rest } = e;
|
|
828
|
-
return rest;
|
|
829
|
-
}
|
|
830
|
-
return { ...e, label: next };
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
function duplicateNode(node, id, offset = 40) {
|
|
834
|
-
return {
|
|
835
|
-
...node,
|
|
836
|
-
id,
|
|
837
|
-
position: { x: node.position.x + offset, y: node.position.y + offset },
|
|
838
|
-
// Deep copy so the clone's config edits don't mutate the original.
|
|
839
|
-
data: JSON.parse(JSON.stringify(node.data ?? {}))
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
function cloneSubgraph(nodes, edges, opts) {
|
|
843
|
-
const offset = opts.offset ?? 40;
|
|
844
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
845
|
-
for (const n of nodes) idMap.set(n.id, opts.makeId());
|
|
846
|
-
const clonedNodes = nodes.map((n) => {
|
|
847
|
-
const cloned = duplicateNode(n, idMap.get(n.id), offset);
|
|
848
|
-
const parentId = n.parentId;
|
|
849
|
-
if (parentId && idMap.has(parentId)) cloned.parentId = idMap.get(parentId);
|
|
850
|
-
else if (parentId) delete cloned.parentId;
|
|
851
|
-
return cloned;
|
|
852
|
-
});
|
|
853
|
-
const clonedEdges = edges.filter((e) => idMap.has(e.source) && idMap.has(e.target)).map((e) => ({ ...e, id: opts.makeId(), source: idMap.get(e.source), target: idMap.get(e.target) }));
|
|
854
|
-
return { nodes: clonedNodes, edges: clonedEdges, idMap };
|
|
855
|
-
}
|
|
856
|
-
function reconnectEdge2(edges, oldEdge, newConnection) {
|
|
857
|
-
return reconnectEdge(oldEdge, newConnection, edges, { shouldReplaceId: false });
|
|
858
|
-
}
|
|
859
|
-
var nodeW = (n) => n.width ?? n.measured?.width ?? 0;
|
|
860
|
-
var nodeH = (n) => n.height ?? n.measured?.height ?? 0;
|
|
861
|
-
function alignNodes(nodes, edge) {
|
|
862
|
-
if (nodes.length < 2) return nodes;
|
|
863
|
-
const minL = Math.min(...nodes.map((n) => n.position.x));
|
|
864
|
-
const maxR = Math.max(...nodes.map((n) => n.position.x + nodeW(n)));
|
|
865
|
-
const minT = Math.min(...nodes.map((n) => n.position.y));
|
|
866
|
-
const maxB = Math.max(...nodes.map((n) => n.position.y + nodeH(n)));
|
|
867
|
-
const cx = (minL + maxR) / 2;
|
|
868
|
-
const cy = (minT + maxB) / 2;
|
|
869
|
-
return nodes.map((n) => {
|
|
870
|
-
let { x, y } = n.position;
|
|
871
|
-
if (edge === "left") x = minL;
|
|
872
|
-
else if (edge === "right") x = maxR - nodeW(n);
|
|
873
|
-
else if (edge === "hcenter") x = cx - nodeW(n) / 2;
|
|
874
|
-
else if (edge === "top") y = minT;
|
|
875
|
-
else if (edge === "bottom") y = maxB - nodeH(n);
|
|
876
|
-
else if (edge === "vcenter") y = cy - nodeH(n) / 2;
|
|
877
|
-
return { ...n, position: { x, y } };
|
|
878
|
-
});
|
|
879
|
-
}
|
|
880
|
-
function distributeNodes(nodes, axis) {
|
|
881
|
-
if (nodes.length < 3) return nodes;
|
|
882
|
-
const size = (n) => axis === "h" ? nodeW(n) : nodeH(n);
|
|
883
|
-
const coord = (n) => axis === "h" ? n.position.x : n.position.y;
|
|
884
|
-
const sorted = [...nodes].sort((a, b) => coord(a) - coord(b));
|
|
885
|
-
const start = coord(sorted[0]);
|
|
886
|
-
const last = sorted[sorted.length - 1];
|
|
887
|
-
const end = coord(last) + size(last);
|
|
888
|
-
const totalSize = sorted.reduce((s, n) => s + size(n), 0);
|
|
889
|
-
const gap = (end - start - totalSize) / (sorted.length - 1);
|
|
890
|
-
const posById = /* @__PURE__ */ new Map();
|
|
891
|
-
let cursor = start;
|
|
892
|
-
for (const n of sorted) {
|
|
893
|
-
posById.set(n.id, cursor);
|
|
894
|
-
cursor += size(n) + gap;
|
|
895
|
-
}
|
|
896
|
-
return nodes.map((n) => {
|
|
897
|
-
const p = posById.get(n.id);
|
|
898
|
-
return { ...n, position: axis === "h" ? { ...n.position, x: p } : { ...n.position, y: p } };
|
|
899
|
-
});
|
|
900
|
-
}
|
|
901
943
|
var FlowEditorContext = createContext(null);
|
|
902
944
|
var FlowEditorProvider = FlowEditorContext.Provider;
|
|
903
945
|
function useFlowEditor() {
|
|
@@ -1128,6 +1170,49 @@ function FlowEditorInner({
|
|
|
1128
1170
|
(oldEdge, conn) => flow.setEdges((eds) => reconnectEdge2(eds, oldEdge, conn)),
|
|
1129
1171
|
[flow]
|
|
1130
1172
|
);
|
|
1173
|
+
const isLaneNode = useCallback(
|
|
1174
|
+
(n) => getNodeKind(n.data?.kind ?? n.type)?.category === "layout",
|
|
1175
|
+
[]
|
|
1176
|
+
);
|
|
1177
|
+
const addLane = useCallback(
|
|
1178
|
+
(orientation = "horizontal", title) => {
|
|
1179
|
+
const vertical = orientation === "vertical";
|
|
1180
|
+
const lanes = flow.nodes.filter(isLaneNode);
|
|
1181
|
+
const w = vertical ? 280 : 680;
|
|
1182
|
+
const h = vertical ? 480 : 168;
|
|
1183
|
+
const end = lanes.reduce(
|
|
1184
|
+
(m, l) => Math.max(m, vertical ? l.position.x + (l.width ?? w) : l.position.y + (l.height ?? h)),
|
|
1185
|
+
0
|
|
1186
|
+
);
|
|
1187
|
+
const id = newNodeId();
|
|
1188
|
+
const name = title ?? `Lane ${lanes.length + 1}`;
|
|
1189
|
+
const node = {
|
|
1190
|
+
id,
|
|
1191
|
+
type: "@particle-academy/lane",
|
|
1192
|
+
position: vertical ? { x: lanes.length ? end + 12 : 0, y: 0 } : { x: 0, y: lanes.length ? end + 12 : 0 },
|
|
1193
|
+
width: w,
|
|
1194
|
+
height: h,
|
|
1195
|
+
data: { kind: "@particle-academy/lane", label: name, config: { title: name, orientation } }
|
|
1196
|
+
};
|
|
1197
|
+
flow.setNodes((all) => [...all, node]);
|
|
1198
|
+
setSelectedId(id);
|
|
1199
|
+
return id;
|
|
1200
|
+
},
|
|
1201
|
+
[flow, isLaneNode]
|
|
1202
|
+
);
|
|
1203
|
+
const handleNodeDragStop = useCallback(
|
|
1204
|
+
(_e, node) => {
|
|
1205
|
+
if (isLaneNode(node)) return;
|
|
1206
|
+
const overLane = rf.getIntersectingNodes(node).find((n) => isLaneNode(n));
|
|
1207
|
+
const currentParent = node.parentId;
|
|
1208
|
+
if (overLane && overLane.id !== currentParent) {
|
|
1209
|
+
flow.setNodes((all) => assignToLane(all, node.id, overLane.id));
|
|
1210
|
+
} else if (!overLane && currentParent) {
|
|
1211
|
+
flow.setNodes((all) => removeFromLane(all, node.id));
|
|
1212
|
+
}
|
|
1213
|
+
},
|
|
1214
|
+
[rf, flow, isLaneNode]
|
|
1215
|
+
);
|
|
1131
1216
|
useEffect(() => {
|
|
1132
1217
|
const onKey = (e) => {
|
|
1133
1218
|
const t = e.target;
|
|
@@ -1191,6 +1276,9 @@ function FlowEditorInner({
|
|
|
1191
1276
|
deleteNodes(selectedIds);
|
|
1192
1277
|
},
|
|
1193
1278
|
paste: pasteClipboard,
|
|
1279
|
+
addLane,
|
|
1280
|
+
assignToLane: (nodeId, laneId) => flow.setNodes((all) => assignToLane(all, nodeId, laneId)),
|
|
1281
|
+
removeFromLane: (nodeId) => flow.setNodes((all) => removeFromLane(all, nodeId)),
|
|
1194
1282
|
run: () => runner.run({ nodes: flow.nodes, edges: flow.edges }, executors),
|
|
1195
1283
|
cancel: runner.cancel,
|
|
1196
1284
|
reset: runner.reset,
|
|
@@ -1203,7 +1291,7 @@ function FlowEditorInner({
|
|
|
1203
1291
|
canUndo: hist.canUndo,
|
|
1204
1292
|
canRedo: hist.canRedo
|
|
1205
1293
|
};
|
|
1206
|
-
}, [flow, selectedId, selected, selectedEdgeId, selectedEdge, selectedIds, selectedNodes, runner, executors, metadata, addNode, deleteNodes, deleteEdges, duplicateSelected, alignSelected, distributeSelected, copySelection, pasteClipboard, hist, rf]);
|
|
1294
|
+
}, [flow, selectedId, selected, selectedEdgeId, selectedEdge, selectedIds, selectedNodes, runner, executors, metadata, addNode, deleteNodes, deleteEdges, duplicateSelected, alignSelected, distributeSelected, copySelection, pasteClipboard, addLane, hist, rf]);
|
|
1207
1295
|
useImperativeHandle(apiRef, () => api, [api]);
|
|
1208
1296
|
const dropHandlers = paletteDropHandlers((kindName, evt) => {
|
|
1209
1297
|
const point = rf.screenToFlowPosition({ x: evt.clientX, y: evt.clientY });
|
|
@@ -1239,6 +1327,10 @@ function FlowEditorInner({
|
|
|
1239
1327
|
}
|
|
1240
1328
|
)
|
|
1241
1329
|
] }),
|
|
1330
|
+
builtins.addLane !== false && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1331
|
+
/* @__PURE__ */ jsx("span", { className: "ff-editor__sep" }),
|
|
1332
|
+
/* @__PURE__ */ jsx("button", { className: "ff-editor__btn", "data-action": "add-lane", title: "Add a swimlane", onClick: () => api.addLane(), children: "\u25A4 Lane" })
|
|
1333
|
+
] }),
|
|
1242
1334
|
(builtins.export !== false || builtins.import !== false) && /* @__PURE__ */ jsx("span", { className: "ff-editor__sep" }),
|
|
1243
1335
|
builtins.export !== false && /* @__PURE__ */ jsx("button", { className: "ff-editor__btn", "data-action": "export", onClick: api.exportWorkflow, children: "\u2193 Export" }),
|
|
1244
1336
|
builtins.import !== false && /* @__PURE__ */ jsx("button", { className: "ff-editor__btn", "data-action": "import", onClick: api.importWorkflow, children: "\u2191 Import" }),
|
|
@@ -1266,6 +1358,7 @@ function FlowEditorInner({
|
|
|
1266
1358
|
onReconnect,
|
|
1267
1359
|
edgesReconnectable: true,
|
|
1268
1360
|
onNodeDragStart: hist.onNodeDragStart,
|
|
1361
|
+
onNodeDragStop: handleNodeDragStop,
|
|
1269
1362
|
onNodeClick: handleNodeClick,
|
|
1270
1363
|
onNodeContextMenu: builtins.contextMenu === false ? void 0 : handleNodeContextMenu,
|
|
1271
1364
|
onEdgeClick: handleEdgeClick,
|