// Admin: the assets volume, the virus scanner, the archive folder (phase 10) and the open alerts (phase 4). import { useState } from "react"; import { storageApi } from "../../api/storage"; import type { AlertRow } from "../../api/types"; import { errorText, fmtBytes, fmtTime } from "../../lib/format"; import { useLoad } from "../../lib/useLoad"; import { FileLocations } from "./FileLocations"; const whoName = (a: AlertRow["acknowledged_by"]) => (a && typeof a === "object" ? a.display_name : (a ?? "")); function alertText(a: AlertRow): string { if (a.kind === "assets_quota") { const pct = Number((a.detail as { pct?: unknown }).pct); return Number.isFinite(pct) ? `The assets volume is ${Math.round(pct)}% full.` : "The assets volume is nearly full."; } return a.subject ? `${a.kind.replace(/_/g, " ")}: ${a.subject}` : a.kind.replace(/_/g, " "); } export function StorageTab() { const [load, reload] = useLoad((s) => storageApi.storage(s)); const [alerts, reloadAlerts] = useLoad((s) => storageApi.alerts(s)); const [busy, setBusy] = useState(false); const [msg, setMsg] = useState<{ ok: boolean; text: string } | null>(null); const ack = async (id: number) => { setBusy(true); setMsg(null); try { await storageApi.ack(id); setMsg({ ok: true, text: "Alert acknowledged." }); reload(); reloadAlerts(); } catch (err) { setMsg({ ok: false, text: errorText(err) }); } finally { setBusy(false); } }; if (load.state === "loading") return
| Raised | Severity | What | Acknowledged | |
|---|---|---|---|---|
| {fmtTime(a.created_at)} | {a.severity} | {alertText(a)} | {a.acknowledged_at ? `${fmtTime(a.acknowledged_at)} ${whoName(a.acknowledged_by)}` : "-"} | {a.acknowledged_at ? null : ( )} |