({
className,
nodes,
edges,
setNodes,
setEdges,
onNodesChange,
onEdgesChange,
workflowId,
workflowSchedules,
schedulesLoading,
scheduleError,
onScheduleCreate,
onScheduleEdit,
onScheduleAction,
onScheduleDelete,
onViewSchedules,
onOpenScheduleSidebar,
onCloseScheduleSidebar,
onCloseWebhooksSidebar,
onClearNodeSelection,
onNodeSelectionChange,
onSnapshot,
schedulePanelExpanded,
webhooksPanelExpanded,
}: CanvasProps)
| 106 | } |
| 107 | |
| 108 | export function Canvas({ |
| 109 | className, |
| 110 | nodes, |
| 111 | edges, |
| 112 | setNodes, |
| 113 | setEdges, |
| 114 | onNodesChange, |
| 115 | onEdgesChange, |
| 116 | workflowId, |
| 117 | workflowSchedules, |
| 118 | schedulesLoading, |
| 119 | scheduleError, |
| 120 | onScheduleCreate, |
| 121 | onScheduleEdit, |
| 122 | onScheduleAction, |
| 123 | onScheduleDelete, |
| 124 | onViewSchedules, |
| 125 | onOpenScheduleSidebar, |
| 126 | onCloseScheduleSidebar, |
| 127 | onCloseWebhooksSidebar, |
| 128 | onClearNodeSelection, |
| 129 | onNodeSelectionChange, |
| 130 | onSnapshot, |
| 131 | schedulePanelExpanded, |
| 132 | webhooksPanelExpanded, |
| 133 | }: CanvasProps) { |
| 134 | const [reactFlowInstance, setReactFlowInstance] = useState<any>(null); |
| 135 | const [selectedNode, setSelectedNode] = useState<Node<NodeData> | null>(null); |
| 136 | const canvasContainerRef = useRef<HTMLDivElement>(null); |
| 137 | const { getComponent } = useComponentStore(); |
| 138 | const { nodeStates } = useExecutionStore(); |
| 139 | const { markDirty } = useWorkflowStore(); |
| 140 | const { dataFlows, selectedNodeId, selectNode, selectEvent } = useExecutionTimelineStore(); |
| 141 | const mode = useWorkflowUiStore((state) => state.mode); |
| 142 | const { toast } = useToast(); |
| 143 | const { setConfigPanelOpen } = useWorkflowUiStore(); |
| 144 | const isMobile = useIsMobile(); |
| 145 | |
| 146 | // Component placement state (for spotlight/sidebar component placement) |
| 147 | const placementState = usePlacementStore(); |
| 148 | const isPlacementActive = placementState.isPlacementActiveForWorkflow(workflowId ?? null); |
| 149 | |
| 150 | // Sync selection state with UI store for mobile bottom sheet visibility |
| 151 | useEffect(() => { |
| 152 | setConfigPanelOpen(Boolean(selectedNode)); |
| 153 | }, [selectedNode, setConfigPanelOpen]); |
| 154 | |
| 155 | const scheduleContext = useOptionalWorkflowSchedulesContext(); |
| 156 | const resolvedWorkflowSchedules = workflowSchedules ?? scheduleContext?.schedules ?? []; |
| 157 | const resolvedSchedulesLoading = schedulesLoading ?? scheduleContext?.isLoading ?? false; |
| 158 | const resolvedScheduleError = scheduleError ?? scheduleContext?.error ?? null; |
| 159 | const resolvedOnScheduleCreate = onScheduleCreate ?? scheduleContext?.onScheduleCreate; |
| 160 | const resolvedOnScheduleEdit = onScheduleEdit ?? scheduleContext?.onScheduleEdit; |
| 161 | const resolvedOnScheduleAction = onScheduleAction ?? scheduleContext?.onScheduleAction; |
| 162 | const resolvedOnScheduleDelete = onScheduleDelete ?? scheduleContext?.onScheduleDelete; |
| 163 | const resolvedOnViewSchedules = onViewSchedules ?? scheduleContext?.onViewSchedules; |
| 164 | const resolvedOnOpenScheduleSidebar = |
| 165 | onOpenScheduleSidebar ?? scheduleContext?.onOpenScheduleSidebar; |
nothing calls this directly
no test coverage detected