Fix route diagram open issues: bugs, visual polish, interactive features
Some checks failed
CI / build (push) Successful in 1m12s
CI / deploy (push) Has been cancelled
CI / docker (push) Has been cancelled

Batch 1 — Bug fixes:
- #51: Pass group+routeId to stats/timeseries API for route-scoped data
- #55: Propagate processor FAILED status to diagram error node highlighting

Batch 2 — Visual polish:
- #56: Brighter canvas background with amber/cyan radial gradients
- #57: Stronger glow filters (stdDeviation 3→6, opacity 0.4→0.6)
- #58: Uniform 200×40px leaf nodes with label truncation at 22 chars
- #59: Diagram legend (node types, edge types, overlay indicators)
- #64: SVG <title> tooltips on all nodes showing type, status, duration

Batch 3 — Interactive features:
- #60: Draggable minimap viewport (click-to-center, drag-to-pan)
- #62: CSS View Transitions slide animation, back arrow, Backspace key

Batch 4 — Advanced features:
- #50: Execution picker dropdown scoped to group+routeId
- #49: Iteration count badge (×N) on compound nodes
- #63: Route header stats (Executions Today, Success Rate, Avg, P99)

Closes #49 #50 #51 #55 #56 #57 #58 #59 #60 #62 #63 #64

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-14 22:14:23 +01:00
parent 7553139cf2
commit a108b57591
15 changed files with 643 additions and 58 deletions

View File

@@ -13,6 +13,7 @@ export interface OverlayState {
executedEdges: Set<string>;
durations: Map<string, number>;
sequences: Map<string, number>;
statuses: Map<string, string>;
iterationData: Map<string, IterationData>;
selectedNodeId: string | null;
selectNode: (nodeId: string | null) => void;
@@ -25,6 +26,7 @@ function collectProcessorData(
executedNodes: Set<string>,
durations: Map<string, number>,
sequences: Map<string, number>,
statuses: Map<string, string>,
counter: { seq: number },
) {
for (const proc of processors) {
@@ -33,9 +35,10 @@ function collectProcessorData(
executedNodes.add(nodeId);
durations.set(nodeId, proc.durationMs ?? 0);
sequences.set(nodeId, ++counter.seq);
if (proc.status) statuses.set(nodeId, proc.status);
}
if (proc.children && proc.children.length > 0) {
collectProcessorData(proc.children, executedNodes, durations, sequences, counter);
collectProcessorData(proc.children, executedNodes, durations, sequences, statuses, counter);
}
}
}
@@ -68,19 +71,20 @@ export function useExecutionOverlay(
if (execution) setIsActive(true);
}, [execution]);
const { executedNodes, durations, sequences, iterationData } = useMemo(() => {
const { executedNodes, durations, sequences, statuses, iterationData } = useMemo(() => {
const en = new Set<string>();
const dur = new Map<string, number>();
const seq = new Map<string, number>();
const st = new Map<string, string>();
const iter = new Map<string, IterationData>();
if (!execution?.processors) {
return { executedNodes: en, durations: dur, sequences: seq, iterationData: iter };
return { executedNodes: en, durations: dur, sequences: seq, statuses: st, iterationData: iter };
}
collectProcessorData(execution.processors, en, dur, seq, { seq: 0 });
collectProcessorData(execution.processors, en, dur, seq, st, { seq: 0 });
return { executedNodes: en, durations: dur, sequences: seq, iterationData: iter };
return { executedNodes: en, durations: dur, sequences: seq, statuses: st, iterationData: iter };
}, [execution]);
const executedEdges = useMemo(
@@ -119,6 +123,7 @@ export function useExecutionOverlay(
executedEdges,
durations,
sequences,
statuses,
iterationData: new Map([...iterationData].map(([k, v]) => {
const current = iterations.get(k) ?? v.current;
return [k, { ...v, current }];