From cf3cec016430eac893dd60f62f7b280aa33c45a6 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Mon, 30 Mar 2026 23:26:55 +0200 Subject: [PATCH] feat: show replay marker on correlated chain entries Exchanges with a _replay attribute now display a small amber RotateCcw icon between the status dot and route name in the correlation chain. Tooltip also indicates (replay). Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/src/pages/Exchanges/ExchangeHeader.module.css | 5 +++++ ui/src/pages/Exchanges/ExchangeHeader.tsx | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) 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)}