/** * dashboard-client/src/tabs/MaintenanceTab/DbStatsCard.tsx — DB Stats card. * * Extracted from MaintenanceTab.tsx (delegate-shell split). Renders file sizes * and table row counts from GET /api/maintenance. */ import type React from "react"; import type { DbStatsResponse } from "@contracts"; import { Card, CardHeader, CardTitle, CardContent, } from "../../components/ui/card"; // --------------------------------------------------------------------------- // Format helpers (local — matches html.ts fmtBytes) // --------------------------------------------------------------------------- export function fmtBytes(b: number): string { if (b < 1024) return `${b} B`; if (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`; return `${(b / (1024 * 1024)).toFixed(1)} MB`; } // --------------------------------------------------------------------------- // DB Stats card // --------------------------------------------------------------------------- function FileSizesCard({ files, pageSize, pageCount, freelistPages, }: { files: DbStatsResponse["storage"]["files"]; pageSize: number; pageCount: number; freelistPages: number; }): React.ReactElement { const total = files.dbBytes + files.walBytes + files.shmBytes; return (
File Sizes
{files.walBytes > 0 && ( )} {files.shmBytes > 0 && ( )}
sqlite.db {fmtBytes(files.dbBytes)}
.wal {fmtBytes(files.walBytes)}
.shm {fmtBytes(files.shmBytes)}
Total {fmtBytes(total)}
Page size {fmtBytes(pageSize)}
Pages {pageCount.toLocaleString()} ({freelistPages.toLocaleString()}{" "} free)
); } function TableRowCountsCard({ tables, }: { tables: DbStatsResponse["tables"]; }): React.ReactElement { const totalRows = tables.reduce((s, t) => s + Math.max(0, t.rowCount), 0); return (
Table Row Counts ({totalRows.toLocaleString()} total)
{tables.map((t) => ( ))}
Table Rows
{t.table} {t.rowCount >= 0 ? t.rowCount.toLocaleString() : "—"}
); } export function DbStatsCard({ data, loading, error, }: { data: DbStatsResponse | null; loading: boolean; error: Error | null; }): React.ReactElement { return ( DB Stats {loading && !data && ( Loading… )} {error && !data && ( {error.message} )} {data && ( <> )} ); }