import React, { useState, useMemo } from 'react'; import { useParams, useNavigate } from 'react-router'; import { Badge, StatusDot, MonoText, CodeBlock, InfoCallout, ProcessorTimeline, Breadcrumb, Spinner, SegmentedTabs, RouteFlow, } from '@cameleer/design-system'; import { useExecutionDetail, useProcessorSnapshot } from '../../api/queries/executions'; import { useCorrelationChain } from '../../api/queries/correlation'; import { useDiagramByRoute } from '../../api/queries/diagrams'; import { mapDiagramToRouteNodes } from '../../utils/diagram-mapping'; import styles from './ExchangeDetail.module.css'; function countProcessors(nodes: any[]): number { return nodes.reduce((sum, n) => sum + 1 + countProcessors(n.children || []), 0); } export default function ExchangeDetail() { const { id } = useParams(); const navigate = useNavigate(); const { data: detail, isLoading } = useExecutionDetail(id ?? null); const [selectedProcessor, setSelectedProcessor] = useState(null); const [viewMode, setViewMode] = useState<'timeline' | 'flow'>('timeline'); const { data: snapshot } = useProcessorSnapshot(id ?? null, selectedProcessor); const { data: correlationData } = useCorrelationChain(detail?.correlationId ?? null); const { data: diagram } = useDiagramByRoute(detail?.groupName, detail?.routeId); const processors = useMemo(() => { if (!detail?.children) return []; const result: any[] = []; let offset = 0; function walk(node: any) { result.push({ name: node.processorId || node.processorType, type: node.processorType, durationMs: node.durationMs ?? 0, status: node.status === 'COMPLETED' ? 'ok' : node.status === 'FAILED' ? 'fail' : 'ok', startMs: offset, }); offset += node.durationMs ?? 0; if (node.children) node.children.forEach(walk); } detail.children.forEach(walk); return result; }, [detail]); if (isLoading) return
; if (!detail) return Exchange not found; return (
{id}
Duration
{detail.durationMs}ms
Agent
{detail.agentId}
Processors
{countProcessors(detail.processors || detail.children || [])}
Route
{detail.routeId}
Application
{detail.groupName || 'unknown'}
{correlationData?.data && correlationData.data.length > 1 && (
Correlation Chain
{correlationData.data.map((exec, i) => ( {i > 0 && } { e.preventDefault(); navigate(`/exchanges/${exec.executionId}`); }} > {exec.routeId} {exec.durationMs}ms ))} {correlationData.total > 20 && ( +{correlationData.total - 20} more )}
)} {detail.errorMessage && ( {detail.errorMessage} )}
Processors setViewMode(v as 'timeline' | 'flow')} />
{viewMode === 'timeline' ? ( processors.length > 0 ? ( setSelectedProcessor(i)} selectedIndex={selectedProcessor ?? undefined} /> ) : ( No processor data available ) ) : ( diagram ? ( setSelectedProcessor(i)} selectedIndex={selectedProcessor ?? undefined} /> ) : ( ) )}
{snapshot && ( <>
Exchange Snapshot
Input Body
Output Body
Input Headers
Output Headers
)}
); }