From bfd76261ef3ffe4da0b33da28afdcc8f898da19a Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Fri, 27 Mar 2026 19:43:51 +0100 Subject: [PATCH] fix: disable execution overlay when drilled into sub-route The execution overlay data maps to the root route's processor IDs. When drilled into a sub-route, those IDs don't match, causing all nodes to appear dimmed. Now clears the overlay and shows pure topology when viewing a sub-route via drill-down. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../ProcessDiagram/ProcessDiagram.tsx | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ui/src/components/ProcessDiagram/ProcessDiagram.tsx b/ui/src/components/ProcessDiagram/ProcessDiagram.tsx index 05b47e94..d1b33c00 100644 --- a/ui/src/components/ProcessDiagram/ProcessDiagram.tsx +++ b/ui/src/components/ProcessDiagram/ProcessDiagram.tsx @@ -57,8 +57,6 @@ export function ProcessDiagram({ iterationState, onIterationChange, }: ProcessDiagramProps) { - const overlayActive = !!executionOverlay; - // Route stack for drill-down navigation const [routeStack, setRouteStack] = useState([routeId]); @@ -68,10 +66,15 @@ export function ProcessDiagram({ }, [routeId]); const currentRouteId = routeStack[routeStack.length - 1]; + const isDrilledDown = currentRouteId !== routeId; + + // Disable overlay when drilled down — the execution data is for the root route + // and doesn't map to sub-route node IDs. Sub-route shows topology only. + const overlayActive = !!executionOverlay && !isDrilledDown; + const effectiveOverlay = isDrilledDown ? undefined : executionOverlay; // Only use the pre-fetched diagramLayout for the root route. - // When drilled down into a sub-route, fetch the sub-route's diagram by route ID. - const effectiveLayout = currentRouteId === routeId ? diagramLayout : undefined; + const effectiveLayout = isDrilledDown ? undefined : diagramLayout; const { sections, totalWidth, totalHeight, isLoading, error } = useDiagramData( application, currentRouteId, direction, effectiveLayout, @@ -108,16 +111,16 @@ export function ProcessDiagram({ // COMPLETED when the route executed (i.e., overlay has any entries). const getNodeExecutionState = useCallback( (nodeId: string | undefined, nodeType: string | undefined) => { - if (!nodeId || !executionOverlay) return undefined; - const state = executionOverlay.get(nodeId); + if (!nodeId || !effectiveOverlay) return undefined; + const state = effectiveOverlay.get(nodeId); if (state) return state; // Synthesize COMPLETED for ENDPOINT nodes when overlay is active - if (nodeType === 'ENDPOINT' && executionOverlay.size > 0) { + if (nodeType === 'ENDPOINT' && effectiveOverlay.size > 0) { return { status: 'COMPLETED' as const, durationMs: 0, hasTraceData: false }; } return undefined; }, - [executionOverlay], + [effectiveOverlay], ); const handleNodeClick = useCallback( @@ -264,9 +267,9 @@ export function ProcessDiagram({ {/* Main section top-level edges (not inside compounds) */} {mainSection.edges.filter(e => topLevelEdge(e, mainSection.nodes)).map((edge, i) => { - const sourceHasState = executionOverlay?.has(edge.sourceId) || endpointNodeIds.has(edge.sourceId); - const targetHasState = executionOverlay?.has(edge.targetId) || endpointNodeIds.has(edge.targetId); - const isTraversed = executionOverlay + const sourceHasState = effectiveOverlay?.has(edge.sourceId) || endpointNodeIds.has(edge.sourceId); + const targetHasState = effectiveOverlay?.has(edge.targetId) || endpointNodeIds.has(edge.targetId); + const isTraversed = effectiveOverlay ? (!!sourceHasState && !!targetHasState) : undefined; return ( @@ -287,7 +290,7 @@ export function ProcessDiagram({ selectedNodeId={selectedNodeId} hoveredNodeId={toolbar.hoveredNodeId} nodeConfigs={nodeConfigs} - executionOverlay={executionOverlay} + executionOverlay={effectiveOverlay} overlayActive={overlayActive} iterationState={iterationState} onIterationChange={onIterationChange}