fix: infer compound node color from descendants when no own overlay state
Path containers (EIP_WHEN, EIP_OTHERWISE, etc.) don't have their own processor records, so they never get an overlay entry. Now inferred from descendants: green if any descendant executed, red if any failed. Gated (amber) only when no descendants executed at all. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -68,18 +68,19 @@ export function CompoundNode({
|
|||||||
|
|
||||||
// Execution overlay state for this compound
|
// Execution overlay state for this compound
|
||||||
const ownState = node.id ? executionOverlay?.get(node.id) : undefined;
|
const ownState = node.id ? executionOverlay?.get(node.id) : undefined;
|
||||||
const hasExecutedChild = ownState && hasExecutedDescendant(node, executionOverlay);
|
const executedDescendant = hasExecutedDescendant(node, executionOverlay);
|
||||||
const isCompleted = ownState?.status === 'COMPLETED';
|
const isCompleted = ownState?.status === 'COMPLETED';
|
||||||
const isFailed = ownState?.status === 'FAILED';
|
const isFailed = ownState?.status === 'FAILED';
|
||||||
|
const descendantFailed = executedDescendant && hasFailedDescendant(node, executionOverlay);
|
||||||
|
|
||||||
// Gated = gate processor (filter/idempotent) blocked all children from executing
|
// Gated = gate processor blocked all children from executing
|
||||||
const isGated = ownState && !hasExecutedChild
|
const isGated = ownState && !executedDescendant
|
||||||
&& (ownState.filterMatched === false || ownState.duplicateMessage === true);
|
&& (ownState.filterMatched === false || ownState.duplicateMessage === true);
|
||||||
|
|
||||||
// Color priority: gated (amber) > failed (red) > completed (green) > default
|
// Color: own status first, then infer from descendants (for path containers like when/otherwise)
|
||||||
const effectiveColor = isGated ? 'var(--amber)'
|
const effectiveColor = isGated ? 'var(--amber)'
|
||||||
: isFailed ? '#C0392B'
|
: isFailed || descendantFailed ? '#C0392B'
|
||||||
: isCompleted ? '#3D7C47'
|
: isCompleted || executedDescendant ? '#3D7C47'
|
||||||
: color;
|
: color;
|
||||||
|
|
||||||
// Dim compound when overlay is active but neither the compound nor any
|
// Dim compound when overlay is active but neither the compound nor any
|
||||||
@@ -295,3 +296,18 @@ function hasExecutedDescendant(
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasFailedDescendant(
|
||||||
|
node: DiagramNodeType,
|
||||||
|
overlay?: Map<string, NodeExecutionState>,
|
||||||
|
): boolean {
|
||||||
|
if (!overlay || !node.children) return false;
|
||||||
|
for (const child of node.children) {
|
||||||
|
if (child.id) {
|
||||||
|
const state = overlay.get(child.id);
|
||||||
|
if (state?.status === 'FAILED') return true;
|
||||||
|
}
|
||||||
|
if (child.children && hasFailedDescendant(child, overlay)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user