fix: detail panel respects iteration filtering
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m35s
CI / docker (push) Successful in 1m12s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 48s

- findProcessorInTree now skips non-selected iteration wrappers so
  the returned ProcessorNode has data from the correct iteration
- Gate selectedProcessor on overlay presence so processors not
  executed in the current iteration don't show in the detail panel
- Header shows "Exchange Details" or "Processor Details" contextually

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-30 20:25:28 +02:00
parent 3091754b0f
commit 30e9b55379
2 changed files with 38 additions and 3 deletions

View File

@@ -90,7 +90,7 @@ export function DetailPanel({
<div className={styles.detailPanel}>
{/* Header bar */}
<div className={styles.processorHeader}>
<span className={styles.processorName}>Details</span>
<span className={styles.processorName}>{selectedProcessor ? 'Processor Details' : 'Exchange Details'}</span>
</div>
{/* Tab bar */}

View File

@@ -20,15 +20,46 @@ interface ExecutionDiagramProps {
className?: string;
}
const ITERATION_WRAPPER_TYPES = new Set([
'loopIteration', 'splitIteration', 'multicastBranch',
]);
function wrapperIndex(proc: ProcessorNode): number | undefined {
return proc.loopIndex ?? proc.splitIndex ?? proc.multicastIndex ?? undefined;
}
/**
* Find a processor in the tree, respecting iteration filtering.
* Only recurses into the selected iteration wrapper so the returned
* ProcessorNode has data from the correct iteration.
*/
function findProcessorInTree(
nodes: ProcessorNode[] | undefined,
processorId: string | null,
iterationState?: Map<string, import('./types').IterationInfo>,
parentId?: string,
): ProcessorNode | null {
if (!nodes || !processorId) return null;
for (const n of nodes) {
if (!n.processorId) continue;
// Iteration wrapper: only recurse into the selected iteration
if (ITERATION_WRAPPER_TYPES.has(n.processorType)) {
if (parentId && iterationState?.has(parentId)) {
const info = iterationState.get(parentId)!;
const idx = wrapperIndex(n);
if (idx != null && idx !== info.current) continue;
}
if (n.children) {
const found = findProcessorInTree(n.children, processorId, iterationState, n.processorId);
if (found) return found;
}
continue;
}
if (n.processorId === processorId) return n;
if (n.children) {
const found = findProcessorInTree(n.children, processorId);
const found = findProcessorInTree(n.children, processorId, iterationState, n.processorId);
if (found) return found;
}
}
@@ -204,7 +235,11 @@ export function ExecutionDiagram({
{/* Detail panel */}
<div className={styles.detailArea} style={{ height: `${100 - splitPercent}%` }}>
<DetailPanel
selectedProcessor={findProcessorInTree(detail.processors, selectedProcessorId || null)}
selectedProcessor={
selectedProcessorId && overlay.has(selectedProcessorId)
? findProcessorInTree(detail.processors, selectedProcessorId, iterationState)
: null
}
executionDetail={detail}
executionId={executionId}
onSelectProcessor={setSelectedProcessorId}