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:
24
ui/src/components/ExecutionDiagram/types.ts
Normal file
24
ui/src/components/ExecutionDiagram/types.ts
Normal 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';
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user