Demo

Workflow nodes

Build React Flow workflow nodes with createDefaultWorkflowNodeComponent or WorkflowNode from @quan-erp/base-frontend, then register them so they match backend workflow node definitions.

Overview

Frontend workflow nodes are React Flow nodes. Prefer the shared WorkflowNode wrapper from @quan-erp/base-frontend — do not import relative copies from base source. Pair with Backend → @Workflow.

  • Props from React Flow: { id, data, selected?}
  • Simple nodes — createDefaultWorkflowNodeComponent
  • Custom handles / styling — WorkflowNode + @xyflow/react Handle
  • Register the node component for the workflow designer to discover

1. Default node

TSXdefault
1import { AlarmClock } from "@icon-park/react"; 2import { createDefaultWorkflowNodeComponent } from "@quan-erp/base-frontend"; 3import metadata from "../../module.metadata.json" with { type: "json" }; 4 5export const OnBookingWorkflowNode = createDefaultWorkflowNodeComponent({ 6 defaultIcon: <AlarmClock size={20} />, 7 defaultLabel: "On Hotel booking", 8 pluginName: metadata.name, 9 defaultIconBg: 10 "bg-pink-50 dark:bg-pink-950/40 text-pink-600 dark:text-pink-400", 11 hasOutput: true, 12 hasInput: false, 13});

2. Custom WorkflowNode

  • WorkflowNode supplies card chrome, play, and delete controls
  • Pass Handle children for custom ports
  • Use ! important classes when overriding defaults
TSXcustom
1import { Handle, Position } from "@xyflow/react"; 2import { Tool } from "@icon-park/react"; 3import { WorkflowNode } from "@quan-erp/base-frontend"; 4import metadata from "../../module.metadata.json" with { type: "json" }; 5 6export function CustomNode({ 7 id, 8 data, 9 selected, 10}: { 11 id: string; 12 data: { label?: string }; 13 selected?: boolean; 14}) { 15 return ( 16 <WorkflowNode 17 pluginName={metadata.name} 18 id={id} 19 data={data} 20 selected={selected} 21 defaultIcon={<Tool size={18} theme="outline" />} 22 defaultLabel="Custom Tool" 23 defaultIconBg="bg-yellow-50 text-yellow-600" 24 > 25 <Handle type="source" id="output" position={Position.Top} /> 26 </WorkflowNode> 27 ); 28}