feat(ui): split agent links (app→overview, id→detail), color server icon by state
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m2s
CI / docker (push) Successful in 52s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 36s

This commit is contained in:
hsiegeln
2026-03-28 15:16:54 +01:00
parent 7ee57ca975
commit 2f2e503447
2 changed files with 29 additions and 2 deletions

View File

@@ -41,6 +41,21 @@
flex-shrink: 0;
}
.iconLive {
color: var(--success);
flex-shrink: 0;
}
.iconStale {
color: var(--warning);
flex-shrink: 0;
}
.iconDead {
color: var(--error);
flex-shrink: 0;
}
.linkBtn {
display: inline-flex;
align-items: center;

View File

@@ -1,7 +1,9 @@
import { useMemo } from 'react';
import { useNavigate } from 'react-router';
import { GitBranch, Server } from 'lucide-react';
import { StatusDot, MonoText, Badge } from '@cameleer/design-system';
import { useCorrelationChain } from '../../api/queries/correlation';
import { useAgents } from '../../api/queries/agents';
import type { ExecutionDetail } from '../../components/ExecutionDiagram/types';
import styles from './ExchangeHeader.module.css';
@@ -42,6 +44,14 @@ export function ExchangeHeader({ detail }: ExchangeHeaderProps) {
const showChain = chain && chain.length > 1;
const attrs = Object.entries(detail.attributes ?? {});
// Look up agent state for icon coloring
const { data: agents } = useAgents(undefined, detail.applicationName);
const agentState = useMemo(() => {
if (!agents || !detail.agentId) return undefined;
const agent = (agents as any[]).find((a: any) => a.id === detail.agentId);
return agent?.state?.toLowerCase() as 'live' | 'stale' | 'dead' | undefined;
}, [agents, detail.agentId]);
return (
<div className={styles.header}>
{/* Exchange info — always shown */}
@@ -67,10 +77,12 @@ export function ExchangeHeader({ detail }: ExchangeHeaderProps) {
{detail.agentId && (
<>
<span className={styles.separator} />
<button className={styles.linkBtn} onClick={() => navigate(`/runtime/${detail.applicationName}/${detail.agentId}`)} title="Go to agent details">
<button className={styles.linkBtn} onClick={() => navigate(`/runtime/${detail.applicationName}`)} title="All agents for this application">
<span className={styles.app}>{detail.applicationName}</span>
</button>
<button className={styles.linkBtn} onClick={() => navigate(`/runtime/${detail.applicationName}/${detail.agentId}`)} title="Agent details">
<MonoText size="xs">{detail.agentId}</MonoText>
<Server size={12} className={styles.icon} />
<Server size={12} className={agentState === 'live' ? styles.iconLive : agentState === 'stale' ? styles.iconStale : agentState === 'dead' ? styles.iconDead : styles.icon} />
</button>
</>
)}