69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
import * as stylex from "@stylexjs/stylex";
|
|
import { formatBytes } from "@/lib/format";
|
|
import type { Health } from "@/lib/types";
|
|
import { colors } from "@/ui/tokens.stylex";
|
|
|
|
const styles = stylex.create({
|
|
stack: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
gap: "0.5rem",
|
|
},
|
|
banner: {
|
|
borderRadius: "0.25rem",
|
|
borderWidth: 1,
|
|
borderStyle: "solid",
|
|
paddingInline: "1rem",
|
|
paddingBlock: "0.5rem",
|
|
fontSize: "0.875rem",
|
|
lineHeight: "1.25rem",
|
|
},
|
|
warn: {
|
|
borderColor: colors.warnBorder,
|
|
backgroundColor: colors.warnSurface,
|
|
color: colors.warnText,
|
|
},
|
|
critical: {
|
|
borderColor: colors.dangerBorder,
|
|
backgroundColor: colors.dangerSurface,
|
|
color: colors.dangerText,
|
|
},
|
|
});
|
|
|
|
function Banner({ tone, children }: { tone: "warn" | "critical"; children: React.ReactNode }) {
|
|
return (
|
|
<p role="alert" {...stylex.props(styles.banner, tone === "critical" ? styles.critical : styles.warn)}>
|
|
{children}
|
|
</p>
|
|
);
|
|
}
|
|
|
|
export default function HealthBanners({ health }: { health: Health }) {
|
|
const banners: React.ReactNode[] = [];
|
|
if (health.disk.state !== "ok") {
|
|
banners.push(
|
|
<Banner key="disk" tone={health.disk.state === "critical" ? "critical" : "warn"}>
|
|
{health.disk.state === "critical"
|
|
? `Disk critically low: ${formatBytes(health.disk.free_bytes)} free. Blocklist updates and log flushes are stopped.`
|
|
: `Disk space low: ${formatBytes(health.disk.free_bytes)} free.`}
|
|
</Banner>,
|
|
);
|
|
}
|
|
if (health.writer_failed) {
|
|
banners.push(
|
|
<Banner key="writer" tone="critical">
|
|
Query log writer failed; new queries are not being persisted.
|
|
</Banner>,
|
|
);
|
|
}
|
|
if (health.queries_dropped > 0) {
|
|
banners.push(
|
|
<Banner key="dropped" tone="warn">
|
|
{health.queries_dropped.toLocaleString()} queries dropped from the log buffer.
|
|
</Banner>,
|
|
);
|
|
}
|
|
if (banners.length === 0) return null;
|
|
return <div {...stylex.props(styles.stack)}>{banners}</div>;
|
|
}
|