fix: color edges into compound nodes green when descendants were executed
Edges into/out of compound nodes (DO_TRY, EIP_CHOICE, etc.) now show as traversed (green) when any descendant node was executed, instead of grey. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,18 +81,44 @@ export function ProcessDiagram({
|
|||||||
application, currentRouteId, direction, effectiveLayout,
|
application, currentRouteId, direction, effectiveLayout,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Collect ENDPOINT node IDs — these are always "traversed" when overlay is active
|
// Build a set of node IDs that should count as "traversed" for edge coloring.
|
||||||
// because the endpoint is the route entry point (not in the processor execution tree).
|
// This includes ENDPOINT nodes (always traversed) and compound nodes where
|
||||||
const endpointNodeIds = useMemo(() => {
|
// any descendant was executed (so edges into/out of DO_TRY etc. are green).
|
||||||
|
const traversedNodeIds = useMemo(() => {
|
||||||
const ids = new Set<string>();
|
const ids = new Set<string>();
|
||||||
if (!overlayActive || !sections.length) return ids;
|
if (!overlayActive || !effectiveOverlay || !sections.length) return ids;
|
||||||
|
|
||||||
|
// ENDPOINTs are always traversed
|
||||||
for (const section of sections) {
|
for (const section of sections) {
|
||||||
for (const node of section.nodes) {
|
for (const node of section.nodes) {
|
||||||
if (node.type === 'ENDPOINT' && node.id) ids.add(node.id);
|
if (node.type === 'ENDPOINT' && node.id) ids.add(node.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark compound nodes as traversed if any descendant was executed
|
||||||
|
function hasExecutedDescendant(node: DiagramNodeType): boolean {
|
||||||
|
if (effectiveOverlay!.has(node.id)) return true;
|
||||||
|
if (node.children) {
|
||||||
|
for (const child of node.children) {
|
||||||
|
if (hasExecutedDescendant(child)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function markCompounds(nodes: DiagramNodeType[]) {
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (isCompoundType(node.type) && node.children?.length && hasExecutedDescendant(node)) {
|
||||||
|
ids.add(node.id);
|
||||||
|
}
|
||||||
|
if (node.children) markCompounds(node.children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const section of sections) {
|
||||||
|
markCompounds(section.nodes);
|
||||||
|
}
|
||||||
|
|
||||||
return ids;
|
return ids;
|
||||||
}, [overlayActive, sections]);
|
}, [overlayActive, effectiveOverlay, sections]);
|
||||||
|
|
||||||
const zoom = useZoomPan();
|
const zoom = useZoomPan();
|
||||||
const toolbar = useToolbarHover();
|
const toolbar = useToolbarHover();
|
||||||
@@ -299,8 +325,8 @@ export function ProcessDiagram({
|
|||||||
{/* Main section top-level edges (not inside compounds) */}
|
{/* Main section top-level edges (not inside compounds) */}
|
||||||
<g className="edges">
|
<g className="edges">
|
||||||
{mainSection.edges.filter(e => topLevelEdge(e, mainSection.nodes)).map((edge, i) => {
|
{mainSection.edges.filter(e => topLevelEdge(e, mainSection.nodes)).map((edge, i) => {
|
||||||
const sourceHasState = effectiveOverlay?.has(edge.sourceId) || endpointNodeIds.has(edge.sourceId);
|
const sourceHasState = effectiveOverlay?.has(edge.sourceId) || traversedNodeIds.has(edge.sourceId);
|
||||||
const targetHasState = effectiveOverlay?.has(edge.targetId) || endpointNodeIds.has(edge.targetId);
|
const targetHasState = effectiveOverlay?.has(edge.targetId) || traversedNodeIds.has(edge.targetId);
|
||||||
const isTraversed = effectiveOverlay
|
const isTraversed = effectiveOverlay
|
||||||
? (!!sourceHasState && !!targetHasState)
|
? (!!sourceHasState && !!targetHasState)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user