fix(metrics): guard toFixed() calls against undefined/null values
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
149939f5f0
commit
23daa8e122
|
|
@ -164,17 +164,18 @@ function EnvironmentBadge({ env }: { env: ServerMetric['environment'] }) {
|
||||||
// Percent bar
|
// Percent bar
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function PercentBar({ value, label }: { value: number; label?: string }) {
|
function PercentBar({ value, label }: { value: number | null | undefined; label?: string }) {
|
||||||
|
const v = value ?? 0;
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2 min-w-[120px]">
|
<div className="flex items-center gap-2 min-w-[120px]">
|
||||||
<div className="flex-1 h-2 bg-muted rounded-full overflow-hidden">
|
<div className="flex-1 h-2 bg-muted rounded-full overflow-hidden">
|
||||||
<div
|
<div
|
||||||
className={cn('h-full rounded-full transition-all', getPercentBarColor(value))}
|
className={cn('h-full rounded-full transition-all', getPercentBarColor(v))}
|
||||||
style={{ width: `${Math.min(value, 100)}%` }}
|
style={{ width: `${Math.min(v, 100)}%` }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className={cn('text-xs font-medium tabular-nums w-10 text-right', getPercentColor(value))}>
|
<span className={cn('text-xs font-medium tabular-nums w-10 text-right', getPercentColor(v))}>
|
||||||
{value.toFixed(1)}%
|
{v.toFixed(1)}%
|
||||||
</span>
|
</span>
|
||||||
{label && <span className="text-xs text-muted-foreground">{label}</span>}
|
{label && <span className="text-xs text-muted-foreground">{label}</span>}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -360,21 +361,21 @@ export default function MetricsPage() {
|
||||||
/>
|
/>
|
||||||
<OverviewCard
|
<OverviewCard
|
||||||
label={t('metrics.overview.online')}
|
label={t('metrics.overview.online')}
|
||||||
value={`${overview.onlinePercent.toFixed(1)}`}
|
value={`${(overview.onlinePercent ?? 0).toFixed(1)}`}
|
||||||
suffix="%"
|
suffix="%"
|
||||||
color={overview.onlinePercent >= 95 ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'}
|
color={(overview.onlinePercent ?? 0) >= 95 ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'}
|
||||||
/>
|
/>
|
||||||
<OverviewCard
|
<OverviewCard
|
||||||
label={t('metrics.overview.avgCpu')}
|
label={t('metrics.overview.avgCpu')}
|
||||||
value={`${overview.avgCpuPercent.toFixed(1)}`}
|
value={`${(overview.avgCpuPercent ?? 0).toFixed(1)}`}
|
||||||
suffix="%"
|
suffix="%"
|
||||||
color={getPercentColor(overview.avgCpuPercent)}
|
color={getPercentColor(overview.avgCpuPercent ?? 0)}
|
||||||
/>
|
/>
|
||||||
<OverviewCard
|
<OverviewCard
|
||||||
label={t('metrics.overview.avgMemory')}
|
label={t('metrics.overview.avgMemory')}
|
||||||
value={`${overview.avgMemoryPercent.toFixed(1)}`}
|
value={`${(overview.avgMemoryPercent ?? 0).toFixed(1)}`}
|
||||||
suffix="%"
|
suffix="%"
|
||||||
color={getPercentColor(overview.avgMemoryPercent)}
|
color={getPercentColor(overview.avgMemoryPercent ?? 0)}
|
||||||
/>
|
/>
|
||||||
<OverviewCard
|
<OverviewCard
|
||||||
label={t('metrics.overview.alertsToday')}
|
label={t('metrics.overview.alertsToday')}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue