feat: add app name filter to runtime toolbar
Some checks failed
CI / cleanup-branch (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m9s
CI / cleanup-branch (push) Has been skipped
CI / docker (pull_request) Has been skipped
CI / build (push) Successful in 2m10s
CI / deploy (pull_request) Has been skipped
CI / deploy-feature (pull_request) Has been skipped
CI / deploy (push) Has been cancelled
CI / deploy-feature (push) Has been cancelled
CI / docker (push) Has been cancelled
Some checks failed
CI / cleanup-branch (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m9s
CI / cleanup-branch (push) Has been skipped
CI / docker (pull_request) Has been skipped
CI / build (push) Successful in 2m10s
CI / deploy (pull_request) Has been skipped
CI / deploy-feature (pull_request) Has been skipped
CI / deploy (push) Has been cancelled
CI / deploy-feature (push) Has been cancelled
CI / docker (push) Has been cancelled
Text input next to view toggle filters apps by name (case-insensitive substring match). KPI stat strip uses unfiltered counts so totals stay accurate. Clear button on non-empty input. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -284,6 +284,7 @@ export default function AgentHealth() {
|
||||
const [eventRefreshTo, setEventRefreshTo] = useState<string | undefined>();
|
||||
const { data: events } = useAgentEvents(appId, undefined, 50, eventRefreshTo, selectedEnv);
|
||||
|
||||
const [appFilter, setAppFilter] = useState('');
|
||||
const [logSearch, setLogSearch] = useState('');
|
||||
const [logLevels, setLogLevels] = useState<Set<string>>(new Set());
|
||||
const [logSource, setLogSource] = useState<string>(''); // '' = all, 'app', 'agent'
|
||||
@@ -305,7 +306,9 @@ export default function AgentHealth() {
|
||||
|
||||
const agentList = agents ?? [];
|
||||
|
||||
const groups = useMemo(() => groupByApp(agentList).sort((a, b) => a.appId.localeCompare(b.appId)), [agentList]);
|
||||
const allGroups = useMemo(() => groupByApp(agentList).sort((a, b) => a.appId.localeCompare(b.appId)), [agentList]);
|
||||
const appFilterLower = appFilter.toLowerCase();
|
||||
const groups = appFilterLower ? allGroups.filter((g) => g.appId.toLowerCase().includes(appFilterLower)) : allGroups;
|
||||
|
||||
// Aggregate stats
|
||||
const totalInstances = agentList.length;
|
||||
@@ -486,18 +489,18 @@ export default function AgentHealth() {
|
||||
/>
|
||||
<StatCard
|
||||
label="Applications"
|
||||
value={String(groups.length)}
|
||||
value={String(allGroups.length)}
|
||||
accent="running"
|
||||
detail={
|
||||
<span className={styles.breakdown}>
|
||||
<span className={styles.bpLive}>
|
||||
<StatusDot variant="live" /> {groups.filter((g) => g.deadCount === 0 && g.staleCount === 0).length} healthy
|
||||
<StatusDot variant="live" /> {allGroups.filter((g) => g.deadCount === 0 && g.staleCount === 0).length} healthy
|
||||
</span>
|
||||
<span className={styles.bpStale}>
|
||||
<StatusDot variant="stale" /> {groups.filter((g) => g.staleCount > 0 && g.deadCount === 0).length} degraded
|
||||
<StatusDot variant="stale" /> {allGroups.filter((g) => g.staleCount > 0 && g.deadCount === 0).length} degraded
|
||||
</span>
|
||||
<span className={styles.bpDead}>
|
||||
<StatusDot variant="dead" /> {groups.filter((g) => g.deadCount > 0).length} critical
|
||||
<StatusDot variant="dead" /> {allGroups.filter((g) => g.deadCount > 0).length} critical
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
@@ -666,6 +669,26 @@ export default function AgentHealth() {
|
||||
<List size={14} />
|
||||
</button>
|
||||
</div>
|
||||
<div className={styles.appFilterWrap}>
|
||||
<input
|
||||
type="text"
|
||||
className={styles.appFilterInput}
|
||||
placeholder="Filter apps\u2026"
|
||||
value={appFilter}
|
||||
onChange={(e) => setAppFilter(e.target.value)}
|
||||
aria-label="Filter applications"
|
||||
/>
|
||||
{appFilter && (
|
||||
<button
|
||||
type="button"
|
||||
className={styles.appFilterClear}
|
||||
onClick={() => setAppFilter('')}
|
||||
aria-label="Clear filter"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user