import { Icon } from './Icon'; import { Tag } from './ui'; import type { Tone } from '../lib/format'; import type { RuntimeHealth, RuntimeLevel, RuntimeTrend } from '../api/types'; /* The two places the process figures are read — the overview's Process card and the Runtime page — say the same things about them, so the wording lives here rather than twice. None of it decides anything: the verdict, its sentences and the areas to investigate all arrive from the gateway, and this renders what it was handed. */ export const levelTone: Record = { ok: 'ok', watch: 'warn', bad: 'bad', }; const levelWord: Record = { ok: 'Healthy', watch: 'Worth watching', bad: 'Needs attention', }; /** RuntimeVerdict is the headline. It replaces a bare goroutine count with the answer that * count was standing in for, and when there is something to look at it names the area * rather than leaving an operator to work out which number matters. */ export function RuntimeVerdict({ health, compact, }: { health: RuntimeHealth; compact?: boolean; }) { const notes = health.notes ?? []; return (
{levelWord[health.level] ?? 'Unknown'} {health.summary}
{/* On the overview the summary is the whole of it — the card is a signpost, and the notes belong on the page it points at. */} {compact || notes.length === 0 ? null : (
    {notes.map((note, index) => (
  • {note.area} {note.message}
  • ))}
)}
); } /** trendWord turns a trend into the half-sentence that sits under a figure. "Steady" is * worth printing: it is the answer to the question the figure raises, and a tile that * says nothing when nothing is wrong makes the operator check anyway. */ export function trendWord(trend: RuntimeTrend, format: (value: number) => string): string { switch (trend.direction) { case 'rising': return `rising ${format(Math.abs(trend.perHour))} an hour`; case 'falling': return `falling ${format(Math.abs(trend.perHour))} an hour`; case 'steady': return 'steady'; default: return 'gathering history'; } } /** uptime words how long the process has been up. Days matter here and seconds do not: the * question this answers is "has it restarted", not "how long exactly". */ export function uptime(seconds: number): string { if (!seconds || seconds < 60) return `${Math.max(0, Math.round(seconds))}s`; const minutes = Math.floor(seconds / 60); if (minutes < 60) return `${minutes} min`; const hours = Math.floor(minutes / 60); if (hours < 48) return `${hours}h ${minutes % 60}m`; return `${Math.floor(hours / 24)} days`; }