Portal Community

useNodeExecutionSync

// useNodeExecutionSync.ts
export function useNodeExecutionSync(executionId: string) {
  const { subscribeToNodeStream, subscribeToWorkflowStream } = useExecutionSignalR(executionId);
  const designerStore = useDesignerModeStore();
  const observerStore = useFlowObserverPanelStore();

  useEffect(() => {
    // Subscribe to node events
    const unsubNode = subscribeToWorkflowStream((event) => {
      switch (event.type) {
        case 'NodeExecutionStarted':
          designerStore.setNodeStatus(event.nodeId, {
            status: 'running',
            startedAt: event.startedAt
          });
          break;
        case 'NodeExecutionCompleted':
          designerStore.setNodeStatus(event.nodeId, {
            status: 'completed',
            durationMs: event.durationMs,
            output: event.output
          });
          observerStore.incrementCompletedCount();
          break;
        case 'NodeExecutionFailed':
          designerStore.setNodeStatus(event.nodeId, {
            status: 'failed',
            error: { message: event.errorMessage, type: event.errorType }
          });
          break;
        case 'WorkflowExecutionCompleted':
          designerStore.setExecutionComplete(event.status);
          break;
      }
    });
    return () => unsubNode();
  }, [executionId]);
}

executionStateMapper

The executionStateMapper.ts utility converts raw event data into the NodeExecutionState format consumed by node components. It also handles the colour mapping:

// executionStateMapper.ts
export function mapEventToNodeState(event): NodeExecutionState {
  return {
    status: mapStatus(event.type),
    borderColor: statusToColor(mapStatus(event.type)),
    iconClass: statusToIcon(mapStatus(event.type)),
    isAnimating: event.type === 'NodeExecutionStarted',
    durationMs: event.durationMs,
    errorSummary: event.errorMessage?.substring(0, 100)
  };
}

function statusToColor(status: string): string {
  const map = {
    pending: '#4a5568',
    running: '#60a5fa',
    completed: '#34d399',
    failed: '#f87171',
    skipped: '#4a5568',
    suspended: '#fbbf24'
  };
  return map[status] ?? '#4a5568';
}