feat: show tracing badges on processor nodes
Update design system to 0.1.8 and pass NodeBadge[] to both ProcessorTimeline and RouteFlow. Traced processors display a blue "TRACED" badge that updates reactively via Zustand store. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import {
|
||||
Badge, StatusDot, MonoText, CodeBlock, InfoCallout,
|
||||
ProcessorTimeline, Breadcrumb, Spinner, RouteFlow, useToast,
|
||||
} from '@cameleer/design-system'
|
||||
import type { ProcessorStep, RouteNode } from '@cameleer/design-system'
|
||||
import type { ProcessorStep, RouteNode, NodeBadge } from '@cameleer/design-system'
|
||||
import { useExecutionDetail, useProcessorSnapshot } from '../../api/queries/executions'
|
||||
import { useCorrelationChain } from '../../api/queries/correlation'
|
||||
import { useDiagramLayout } from '../../api/queries/diagrams'
|
||||
@@ -74,25 +74,35 @@ export default function ExchangeDetail() {
|
||||
? (detail.processors?.length ? detail.processors : (detail.children ?? []))
|
||||
: []
|
||||
|
||||
// Subscribe to tracing state for badge rendering
|
||||
const tracedMap = useTracingStore((s) => s.tracedProcessors[detail?.applicationName ?? ''])
|
||||
|
||||
function badgesFor(processorId: string): NodeBadge[] | undefined {
|
||||
if (!tracedMap || !(processorId in tracedMap)) return undefined
|
||||
return [{ label: 'Traced', variant: 'info' }]
|
||||
}
|
||||
|
||||
// Flatten processor tree into ProcessorStep[]
|
||||
const processors: ProcessorStep[] = useMemo(() => {
|
||||
if (!procList.length) return []
|
||||
const result: ProcessorStep[] = []
|
||||
let offset = 0
|
||||
function walk(node: any) {
|
||||
const pid = node.processorId || node.processorType
|
||||
result.push({
|
||||
name: node.processorId || node.processorType,
|
||||
name: pid,
|
||||
type: node.processorType,
|
||||
durationMs: node.durationMs ?? 0,
|
||||
status: procStatusToStep(node.status ?? ''),
|
||||
startMs: offset,
|
||||
badges: badgesFor(node.processorId || ''),
|
||||
})
|
||||
offset += node.durationMs ?? 0
|
||||
if (node.children) node.children.forEach(walk)
|
||||
}
|
||||
procList.forEach(walk)
|
||||
return result
|
||||
}, [procList])
|
||||
}, [procList, tracedMap])
|
||||
|
||||
// Default selected processor: first failed, or 0
|
||||
const defaultIndex = useMemo(() => {
|
||||
@@ -121,7 +131,20 @@ export default function ExchangeDetail() {
|
||||
// Build RouteFlow nodes from diagram + execution data
|
||||
const routeNodes: RouteNode[] = useMemo(() => {
|
||||
if (diagram?.nodes) {
|
||||
return mapDiagramToRouteNodes(diagram.nodes, procList)
|
||||
// Flatten processors to build diagramNodeId → processorId lookup
|
||||
const flatProcs: Array<{ diagramNodeId?: string; processorId?: string }> = []
|
||||
function flattenProcs(nodes: any[]) {
|
||||
for (const n of nodes) { flatProcs.push(n); if (n.children) flattenProcs(n.children) }
|
||||
}
|
||||
flattenProcs(procList)
|
||||
const pidLookup = new Map(flatProcs
|
||||
.filter(p => p.diagramNodeId && p.processorId)
|
||||
.map(p => [p.diagramNodeId!, p.processorId!]))
|
||||
|
||||
return mapDiagramToRouteNodes(diagram.nodes, procList).map((node, i) => ({
|
||||
...node,
|
||||
badges: badgesFor(pidLookup.get(diagram.nodes[i]?.id ?? '') ?? diagram.nodes[i]?.id ?? ''),
|
||||
}))
|
||||
}
|
||||
// Fallback: build from processor list
|
||||
return processors.map((p) => ({
|
||||
@@ -129,8 +152,9 @@ export default function ExchangeDetail() {
|
||||
type: 'process' as RouteNode['type'],
|
||||
durationMs: p.durationMs,
|
||||
status: p.status,
|
||||
badges: badgesFor(p.name),
|
||||
}))
|
||||
}, [diagram, processors, procList])
|
||||
}, [diagram, processors, procList, tracedMap])
|
||||
|
||||
// ProcessorId lookup: timeline index → processorId
|
||||
const processorIds: string[] = useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user