fix: clean up runtime UI and harden session expiry handling
Remove redundant "X/X LIVE" badge from runtime page, breadcrumb trail and routes section from agent detail page (pills moved into Process Information card). Fix session expiry: guard against concurrent 401 refresh races and skip re-entrant triggers on auth endpoints. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -400,14 +400,6 @@ export default function AgentHealth() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Badge
|
||||
label={`${liveCount}/${totalInstances} live`}
|
||||
color={deadCount > 0 ? 'error' : staleCount > 0 ? 'warning' : 'success'}
|
||||
variant="filled"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Application config bar */}
|
||||
{appId && appConfig && (
|
||||
<div className={`${sectionStyles.section} ${styles.configBar}`}>
|
||||
|
||||
@@ -14,42 +14,20 @@
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* Scope trail — matches /agents */
|
||||
.scopeTrail {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.scopeLink {
|
||||
color: var(--amber);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.scopeLink:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.scopeSep {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.scopeCurrent {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
/* Process info card — card styling via sectionStyles.section */
|
||||
.processCard {
|
||||
padding: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.processBadges {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.processGrid {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto 1fr;
|
||||
@@ -70,14 +48,6 @@
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* Route badges */
|
||||
.routeBadges {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Charts 3x2 grid */
|
||||
.chartsGrid {
|
||||
display: grid;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useParams, Link } from 'react-router';
|
||||
import { RefreshCw, ChevronRight } from 'lucide-react';
|
||||
import { useParams } from 'react-router';
|
||||
import { RefreshCw } from 'lucide-react';
|
||||
import {
|
||||
StatCard, StatusDot, Badge, ThemedChart, Line, Area, ReferenceLine, CHART_COLORS,
|
||||
EventFeed, Spinner, EmptyState, SectionHeader, MonoText,
|
||||
@@ -213,36 +213,25 @@ export default function AgentInstance() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Scope trail + badges */}
|
||||
{agent && (
|
||||
<>
|
||||
<div className={styles.scopeTrail}>
|
||||
<Link to="/agents" className={styles.scopeLink}>
|
||||
All Agents
|
||||
</Link>
|
||||
<span className={styles.scopeSep}><ChevronRight size={12} /></span>
|
||||
<Link to={`/agents/${appId}`} className={styles.scopeLink}>
|
||||
{appId}
|
||||
</Link>
|
||||
<span className={styles.scopeSep}><ChevronRight size={12} /></span>
|
||||
<span className={styles.scopeCurrent}>{agent.displayName}</span>
|
||||
<StatusDot variant={statusVariant} />
|
||||
<Badge label={agent.status} color={statusColor} />
|
||||
{agent.containerStatus && agent.containerStatus !== 'UNKNOWN' && (
|
||||
<Badge label={`Container: ${agent.containerStatus}`} variant="outlined" color="auto" />
|
||||
)}
|
||||
{agent.version && <Badge label={agent.version} variant="outlined" color="auto" />}
|
||||
<Badge
|
||||
label={`${agent.activeRoutes ?? (agent.routeIds?.length ?? 0)}/${agent.totalRoutes ?? (agent.routeIds?.length ?? 0)} routes`}
|
||||
color={
|
||||
(agent.activeRoutes ?? 0) < (agent.totalRoutes ?? 0) ? 'warning' : 'success'
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Process info card */}
|
||||
<div className={`${sectionStyles.section} ${styles.processCard}`}>
|
||||
<SectionHeader>Process Information</SectionHeader>
|
||||
<div className={styles.processBadges}>
|
||||
<StatusDot variant={statusVariant} />
|
||||
<Badge label={agent.status} color={statusColor} />
|
||||
{agent.containerStatus && agent.containerStatus !== 'UNKNOWN' && (
|
||||
<Badge label={`Container: ${agent.containerStatus}`} variant="outlined" color="auto" />
|
||||
)}
|
||||
{agent.version && <Badge label={agent.version} variant="outlined" color="auto" />}
|
||||
<Badge
|
||||
label={`${agent.activeRoutes ?? (agent.routeIds?.length ?? 0)}/${agent.totalRoutes ?? (agent.routeIds?.length ?? 0)} routes`}
|
||||
color={
|
||||
(agent.activeRoutes ?? 0) < (agent.totalRoutes ?? 0) ? 'warning' : 'success'
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.processGrid}>
|
||||
{agent.capabilities?.jvmVersion && (
|
||||
<>
|
||||
@@ -281,17 +270,7 @@ export default function AgentInstance() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Routes */}
|
||||
{(agent.routeIds?.length ?? 0) > 0 && (
|
||||
<>
|
||||
<SectionHeader>Routes</SectionHeader>
|
||||
<div className={styles.routeBadges}>
|
||||
{(agent.routeIds || []).map((r: string) => (
|
||||
<Badge key={r} label={r} color="auto" />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user