Portal Community

addNode

addNode: (node: WorkflowNode) => void

// Usage — called when dragging a node from the palette onto the canvas
const { addNode } = useWorkflowStore();

addNode({
    id      : crypto.randomUUID(),
    type    : 'ApprovalNode',
    position: { x: 400, y: 200 },
    data    : {
        label       : 'Manager Approval',
        config      : {},
        inputPorts  : [{ id: 'in', label: 'In' }],
        outputPorts : [
            { id: 'approved', label: 'Approved' },
            { id: 'rejected', label: 'Rejected' }
        ]
    }
});

updateNode

updateNode: (id: string, patch: Partial<WorkflowNode>) => void

// Usage — called by the config form when the user edits a node's settings
const { updateNode } = useWorkflowStore();

// Update just the config (deep merge on data)
updateNode('node-abc', {
    data: {
        ...existingData,
        config: {
            actorId        : '{{$context.managerId}}',
            timeoutDuration: 'P1D',
            timeoutBehavior: 'Escalate'
        }
    }
});

// Rename the node label
updateNode('node-abc', {
    data: { ...existingData, label: 'Department Head Approval' }
});

// Note: updateNode triggers a debounced auto-save via the persistence middleware

removeNode

removeNode: (id: string) => void

// Usage — called when the user presses Delete on a selected node
const { removeNode } = useWorkflowStore();

removeNode('node-abc');

// Note: removeNode automatically removes all edges connected to the deleted node
// The history middleware captures this as a single undoable operation

moveNode

moveNode: (id: string, position: XYPosition) => void

// Usage — called by React Flow's onNodeDragStop callback
const { moveNode } = useWorkflowStore();

// React Flow gives us the new position after the user finishes dragging
moveNode('node-abc', { x: 600, y: 350 });

// Note: moveNode is only pushed to history on drag END (onNodeDragStop)
// Intermediate drag positions are NOT tracked — dragging is smooth but produces one history entry

selectNode

selectNode: (id: string | null) => void

// Usage — called when the user clicks a node on the canvas
const { selectNode } = useWorkflowStore();

// Select a node — drives the right panel (config form) to show this node's form
selectNode('node-abc');

// Deselect all — pass null
selectNode(null);

// selectNode sets selectedNodes = [id] (single selection)
// Multi-selection is handled via Shift+Click — sets selectedNodes = [...existing, id]

Action Summary

ActionHistory Tracked?Auto-Save Triggered?
addNodeYesYes
updateNodeYesYes (debounced)
removeNodeYesYes
moveNodeYes (drag end only)Yes
selectNodeNoNo
Do not mutate node data directly: Never modify workflowStore.getState().nodes directly. Always go through the actions. Direct mutation bypasses history tracking, auto-save, and React Flow sync.