diff --git a/ui/src/pages/Exchanges/ExchangeHeader.module.css b/ui/src/pages/Exchanges/ExchangeHeader.module.css index a178c68d..c686646e 100644 --- a/ui/src/pages/Exchanges/ExchangeHeader.module.css +++ b/ui/src/pages/Exchanges/ExchangeHeader.module.css @@ -185,6 +185,11 @@ font-weight: 500; } +.replayIcon { + color: var(--amber); + flex-shrink: 0; +} + .chainDuration { color: var(--text-muted); font-size: 9px; diff --git a/ui/src/pages/Exchanges/ExchangeHeader.tsx b/ui/src/pages/Exchanges/ExchangeHeader.tsx index 9d13fda9..2ef8d2d2 100644 --- a/ui/src/pages/Exchanges/ExchangeHeader.tsx +++ b/ui/src/pages/Exchanges/ExchangeHeader.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react'; import { useNavigate } from 'react-router'; -import { GitBranch, Server } from 'lucide-react'; +import { GitBranch, Server, RotateCcw } from 'lucide-react'; import { StatusDot, MonoText, Badge } from '@cameleer/design-system'; import { useCorrelationChain } from '../../api/queries/correlation'; import { useAgents } from '../../api/queries/agents'; @@ -122,6 +122,7 @@ export function ExchangeHeader({ detail, onCorrelatedSelect, onClearSelection }: {showChain ? chain.map((ce: any, i: number) => { const isCurrent = ce.executionId === detail.executionId; const variant = statusVariant(ce.status); + const isReplay = ce.attributes?._replay != null; const statusCls = variant === 'success' ? styles.chainNodeSuccess : variant === 'error' ? styles.chainNodeError @@ -137,9 +138,10 @@ export function ExchangeHeader({ detail, onCorrelatedSelect, onClearSelection }: onCorrelatedSelect(ce.executionId, ce.applicationName ?? detail.applicationName, ce.routeId); } }} - title={`${ce.executionId}\n${ce.routeId} \u2014 ${formatDuration(ce.durationMs)}`} + title={`${ce.executionId}\n${ce.routeId} \u2014 ${formatDuration(ce.durationMs)}${isReplay ? '\n(replay)' : ''}`} > + {isReplay && } {ce.routeId} {formatDuration(ce.durationMs)}