diff --git a/ui/src/pages/AgentHealth/AgentHealth.module.css b/ui/src/pages/AgentHealth/AgentHealth.module.css index 5f0a9283..37efb44b 100644 --- a/ui/src/pages/AgentHealth/AgentHealth.module.css +++ b/ui/src/pages/AgentHealth/AgentHealth.module.css @@ -13,7 +13,7 @@ /* Stat strip */ .statStrip { display: grid; - grid-template-columns: repeat(5, 1fr) auto; + grid-template-columns: repeat(5, 1fr); gap: 10px; margin-bottom: 16px; } @@ -99,6 +99,7 @@ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; margin-bottom: 20px; + position: relative; } /* Group meta row */ @@ -317,25 +318,49 @@ color: var(--card-accent); } -/* Expanded card inside compact grid */ +/* Wrapper for each compact grid cell — anchor for overlay */ +.compactGridCell { + position: relative; +} + +/* Expanded card overlay — floats from the clicked card */ .compactGridExpanded { - grid-column: span 2; + position: absolute; + z-index: 10; + top: 0; + left: 0; + min-width: 500px; + background: var(--bg-body); + border-radius: var(--radius-md); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); + padding: 4px; } /* Expand/collapse animation wrapper */ .expandWrapper { overflow: hidden; - transition: max-height 200ms ease, opacity 150ms ease; + transition: opacity 200ms ease, transform 200ms ease; } .expandWrapperCollapsed { - max-height: 0; opacity: 0; + transform: scaleY(0.95); + transform-origin: top; } .expandWrapperExpanded { - max-height: 1000px; opacity: 1; + transform: scaleY(1); + transform-origin: top; +} + +/* View toolbar — between stat strip and cards grid */ +.viewToolbar { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; + margin-bottom: 12px; } /* View mode toggle */ diff --git a/ui/src/pages/AgentHealth/AgentHealth.tsx b/ui/src/pages/AgentHealth/AgentHealth.tsx index dcb6048a..bf0ea7af 100644 --- a/ui/src/pages/AgentHealth/AgentHealth.tsx +++ b/ui/src/pages/AgentHealth/AgentHealth.tsx @@ -289,7 +289,7 @@ export default function AgentHealth() { const agentList = agents ?? []; - const groups = useMemo(() => groupByApp(agentList), [agentList]); + const groups = useMemo(() => groupByApp(agentList).sort((a, b) => a.appId.localeCompare(b.appId)), [agentList]); // Aggregate stats const totalInstances = agentList.length; @@ -515,6 +515,10 @@ export default function AgentHealth() { accent={deadCount > 0 ? 'error' : 'success'} detail={deadCount > 0 ? 'requires attention' : 'all healthy'} /> + + + {/* View toolbar */} +