feat: add execution overlay types and extend ProcessDiagram with diagramLayout prop

Define the execution overlay type system (NodeExecutionState, IterationInfo,
DetailTab) and extend ProcessDiagramProps with optional overlay props. Add
diagramLayout prop so ExecutionDiagram can pass a pre-fetched layout by content
hash, bypassing the internal route-based fetch in useDiagramData.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-27 18:40:57 +01:00
parent 3928743ea7
commit ff59dc5d57
4 changed files with 49 additions and 5 deletions

View File

@@ -0,0 +1,24 @@
import type { components } from '../../api/schema';
export type ExecutionDetail = components['schemas']['ExecutionDetail'];
export type ProcessorNode = components['schemas']['ProcessorNode'];
export interface NodeExecutionState {
status: 'COMPLETED' | 'FAILED';
durationMs: number;
/** True if this node's target sub-route failed (DIRECT/SEDA) */
subRouteFailed?: boolean;
/** True if trace data is available for this processor */
hasTraceData?: boolean;
}
export interface IterationInfo {
/** Current iteration index (0-based) */
current: number;
/** Total number of iterations */
total: number;
/** Type of iteration (determines label) */
type: 'loop' | 'split' | 'multicast';
}
export type DetailTab = 'info' | 'headers' | 'input' | 'output' | 'error' | 'config' | 'timeline';

View File

@@ -52,6 +52,7 @@ export function ProcessDiagram({
nodeConfigs,
knownRouteIds,
className,
diagramLayout,
}: ProcessDiagramProps) {
// Route stack for drill-down navigation
const [routeStack, setRouteStack] = useState<string[]>([routeId]);
@@ -64,7 +65,7 @@ export function ProcessDiagram({
const currentRouteId = routeStack[routeStack.length - 1];
const { sections, totalWidth, totalHeight, isLoading, error } = useDiagramData(
application, currentRouteId, direction,
application, currentRouteId, direction, diagramLayout,
);
const zoom = useZoomPan();

View File

@@ -1,4 +1,5 @@
import type { DiagramNode, DiagramEdge } from '../../api/queries/diagrams';
import type { DiagramNode, DiagramEdge, DiagramLayout } from '../../api/queries/diagrams';
import type { NodeExecutionState, IterationInfo } from '../ExecutionDiagram/types';
export type NodeAction = 'inspect' | 'toggle-trace' | 'configure-tap' | 'copy-id';
@@ -26,4 +27,12 @@ export interface ProcessDiagramProps {
/** Known route IDs for this application (enables drill-down resolution) */
knownRouteIds?: Set<string>;
className?: string;
/** Pre-fetched diagram layout (bypasses internal fetch by application/routeId) */
diagramLayout?: DiagramLayout;
/** Execution overlay: maps diagram node ID → execution state */
executionOverlay?: Map<string, NodeExecutionState>;
/** Per-compound iteration info: maps compound node ID → iteration info */
iterationState?: Map<string, IterationInfo>;
/** Called when user changes iteration on a compound stepper */
onIterationChange?: (compoundNodeId: string, iterationIndex: number) => void;
}

View File

@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useDiagramByRoute } from '../../api/queries/diagrams';
import type { DiagramNode, DiagramEdge } from '../../api/queries/diagrams';
import type { DiagramNode, DiagramEdge, DiagramLayout } from '../../api/queries/diagrams';
import type { DiagramSection } from './types';
import { isErrorCompoundType, isCompletionCompoundType } from './node-colors';
@@ -10,8 +10,14 @@ export function useDiagramData(
application: string,
routeId: string,
direction: 'LR' | 'TB' = 'LR',
preloadedLayout?: DiagramLayout,
) {
const { data: layout, isLoading, error } = useDiagramByRoute(application, routeId, direction);
// When a preloaded layout is provided, disable the internal fetch
const fetchApp = preloadedLayout ? undefined : application;
const fetchRoute = preloadedLayout ? undefined : routeId;
const { data: fetchedLayout, isLoading, error } = useDiagramByRoute(fetchApp, fetchRoute, direction);
const layout = preloadedLayout ?? fetchedLayout;
const result = useMemo(() => {
if (!layout?.nodes) {
@@ -106,7 +112,11 @@ export function useDiagramData(
return { sections, totalWidth, totalHeight };
}, [layout]);
return { ...result, isLoading, error };
return {
...result,
isLoading: preloadedLayout ? false : isLoading,
error: preloadedLayout ? null : error,
};
}
/** Shift all node coordinates by subtracting an offset, recursively. */