fix: align AgentInstance page with mock design
All checks were successful
CI / build (push) Successful in 1m13s
CI / cleanup-branch (push) Has been skipped
CI / docker (push) Successful in 49s
CI / deploy (push) Successful in 40s
CI / deploy-feature (push) Has been skipped

- Chart headers: add current value meta text (CPU %, memory MB, TPS,
  error rate, thread count) matching mock layout
- Bottom section: 2-column grid with log placeholder (left) and
  timeline events (right) matching mock layout
- Timeline header: show "Timeline" + event count like mock
- Remove duplicate EmptyState placeholder

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-23 21:51:44 +01:00
parent a06808a2a2
commit 717367252c
2 changed files with 67 additions and 17 deletions

View File

@@ -145,3 +145,31 @@
color: var(--text-primary); color: var(--text-primary);
margin-bottom: 12px; margin-bottom: 12px;
} }
.chartMeta {
font-size: 11px;
font-weight: 500;
color: var(--text-muted);
font-family: var(--font-mono);
}
.bottomSection {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
margin-bottom: 20px;
}
.eventCount {
font-size: 11px;
font-weight: 500;
color: var(--text-muted);
font-family: var(--font-mono);
}
.emptyEvents {
padding: 20px;
text-align: center;
font-size: 12px;
color: var(--text-muted);
}

View File

@@ -200,54 +200,76 @@ export default function AgentInstance() {
</> </>
)} )}
<div className={styles.sectionTitle}>Performance</div>
<div className={styles.chartsGrid}> <div className={styles.chartsGrid}>
<div className={styles.chartCard}> <div className={styles.chartCard}>
<div className={styles.chartHeader}><div className={styles.chartTitle}>CPU Usage</div></div> <div className={styles.chartHeader}>
<div className={styles.chartTitle}>CPU Usage</div>
<div className={styles.chartMeta}>{cpuPct != null ? `${(cpuPct * 100).toFixed(0)}% current` : ''}</div>
</div>
{cpuSeries {cpuSeries
? <AreaChart series={cpuSeries} yLabel="%" height={200} /> ? <AreaChart series={cpuSeries} yLabel="%" height={200} />
: <EmptyState title="No data" description="No CPU metrics available" />} : <EmptyState title="No data" description="No CPU metrics available" />}
</div> </div>
<div className={styles.chartCard}> <div className={styles.chartCard}>
<div className={styles.chartHeader}><div className={styles.chartTitle}>Memory Heap</div></div> <div className={styles.chartHeader}>
<div className={styles.chartTitle}>Memory (Heap)</div>
<div className={styles.chartMeta}>{heapUsed != null && heapMax != null ? `${(heapUsed / (1024 * 1024)).toFixed(0)} MB / ${(heapMax / (1024 * 1024)).toFixed(0)} MB` : ''}</div>
</div>
{heapSeries {heapSeries
? <AreaChart series={heapSeries} yLabel="MB" height={200} /> ? <AreaChart series={heapSeries} yLabel="MB" height={200} />
: <EmptyState title="No data" description="No heap metrics available" />} : <EmptyState title="No data" description="No heap metrics available" />}
</div> </div>
<div className={styles.chartCard}> <div className={styles.chartCard}>
<div className={styles.chartHeader}><div className={styles.chartTitle}>Throughput</div></div> <div className={styles.chartHeader}>
<div className={styles.chartTitle}>Throughput</div>
<div className={styles.chartMeta}>{agent?.tps != null ? `${agent.tps.toFixed(1)} msg/s` : ''}</div>
</div>
{throughputSeries {throughputSeries
? <AreaChart series={throughputSeries} height={200} /> ? <AreaChart series={throughputSeries} yLabel="msg/s" height={200} />
: <EmptyState title="No data" description="No throughput data in range" />} : <EmptyState title="No data" description="No throughput data in range" />}
</div> </div>
<div className={styles.chartCard}> <div className={styles.chartCard}>
<div className={styles.chartHeader}><div className={styles.chartTitle}>Error Rate</div></div> <div className={styles.chartHeader}>
<div className={styles.chartTitle}>Error Rate</div>
<div className={styles.chartMeta}>{agent?.errorRate != null ? `${(agent.errorRate * 100).toFixed(1)}%` : ''}</div>
</div>
{errorSeries {errorSeries
? <LineChart series={errorSeries} height={200} /> ? <LineChart series={errorSeries} yLabel="%" height={200} />
: <EmptyState title="No data" description="No error data in range" />} : <EmptyState title="No data" description="No error data in range" />}
</div> </div>
<div className={styles.chartCard}> <div className={styles.chartCard}>
<div className={styles.chartHeader}><div className={styles.chartTitle}>Thread Count</div></div> <div className={styles.chartHeader}>
<div className={styles.chartTitle}>Thread Count</div>
{threadSeries && <div className={styles.chartMeta}>{threadSeries[0].data[threadSeries[0].data.length - 1]?.y.toFixed(0)} active</div>}
</div>
{threadSeries {threadSeries
? <LineChart series={threadSeries} height={200} /> ? <LineChart series={threadSeries} yLabel="threads" height={200} />
: <EmptyState title="No data" description="No thread metrics available" />} : <EmptyState title="No data" description="No thread metrics available" />}
</div> </div>
<div className={styles.chartCard}> <div className={styles.chartCard}>
<div className={styles.chartHeader}><div className={styles.chartTitle}>GC Pauses</div></div> <div className={styles.chartHeader}>
<div className={styles.chartTitle}>GC Pauses</div>
</div>
{gcSeries {gcSeries
? <BarChart series={gcSeries} yLabel="ms" height={200} /> ? <BarChart series={gcSeries} yLabel="ms" height={200} />
: <EmptyState title="No data" description="No GC metrics available" />} : <EmptyState title="No data" description="No GC metrics available" />}
</div> </div>
</div> </div>
{feedEvents.length > 0 && ( <div className={styles.bottomSection}>
<div className={styles.eventCard}> <EmptyState title="Application Log" description="Application log streaming is not yet available" />
<div className={styles.eventCardHeader}>Events</div>
<EventFeed events={feedEvents} maxItems={50} /> <div className={styles.eventCard}>
</div> <div className={styles.eventCardHeader}>
)} <span>Timeline</span>
<span className={styles.eventCount}>{feedEvents.length} events</span>
</div>
{feedEvents.length > 0
? <EventFeed events={feedEvents} maxItems={50} />
: <div className={styles.emptyEvents}>No events in the selected time range.</div>}
</div>
</div>
<EmptyState title="Application Logs" description="Application log streaming is not yet available" />
</div> </div>
); );
} }