mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
refactor(format): one byte formatter for every surface
The document vault and the admin area each carried a formatBytes; the same backup read 1.25 MB in one and 1.2 MB in the other, and only the vault knew gigabytes. The vault rule (one decimal below 100, up to GB, digits in the reader's locale) now lives in src/lib/format/bytes.ts and takes the locale, so the server-rendered share page uses it too. A test holds the definition to that one module.
This commit is contained in:
1 parent
67cc56f707
commit
56daa57350
12 files changed
+84
-70
No files matched your search
@@ -843,7 +843,7 @@ async function uploadOnce(file: File) {
|
||||
}
|
||||
|
||||
export function BackupsSection() {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -1327,7 +1327,7 @@ export function BackupsSection() {
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-right font-mono text-xs tabular-nums">
|
||||
{formatBytes(row.sizeBytes, fmt)}
|
||||
{formatBytes(row.sizeBytes, locale)}
|
||||
</td>
|
||||
<td className="text-muted-foreground px-3 py-2 text-right text-xs whitespace-nowrap">
|
||||
{fmt.dateTime(row.createdAt)}
|
||||
@@ -1394,7 +1394,7 @@ export function BackupsSection() {
|
||||
</div>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{t("admin.section.backups.colSize")}:{" "}
|
||||
{formatBytes(row.sizeBytes, fmt)} ·{" "}
|
||||
{formatBytes(row.sizeBytes, locale)} ·{" "}
|
||||
{fmt.dateTime(row.createdAt)}
|
||||
</p>
|
||||
<div className="mt-2 flex flex-wrap items-center gap-2">
|
||||
|
||||
@@ -45,20 +45,8 @@ const ENDPOINT = "/api/admin/maintenance/measurements";
|
||||
/** How often the card asks while a run is waiting or working. */
|
||||
const POLL_MS = 10_000;
|
||||
|
||||
const GIB = 1024 * 1024 * 1024;
|
||||
|
||||
function sizeLabel(
|
||||
bytes: number,
|
||||
fmt: ReturnType<typeof useFormatters>,
|
||||
): string {
|
||||
// The shared formatter stops at MB; this table is routinely gigabytes.
|
||||
return bytes >= GIB
|
||||
? `${fmt.number(bytes / GIB, 2)} GB`
|
||||
: formatBytes(bytes, fmt);
|
||||
}
|
||||
|
||||
export function MeasurementMaintenanceCard() {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -132,11 +120,11 @@ export function MeasurementMaintenanceCard() {
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
<StatTile
|
||||
label={t("admin.section.maintenance.tableSize")}
|
||||
value={sizeLabel(s.sizes.tableBytes, fmt)}
|
||||
value={formatBytes(s.sizes.tableBytes, locale)}
|
||||
/>
|
||||
<StatTile
|
||||
label={t("admin.section.maintenance.indexSize")}
|
||||
value={sizeLabel(s.sizes.indexBytes, fmt)}
|
||||
value={formatBytes(s.sizes.indexBytes, locale)}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -84,7 +84,7 @@ function freshnessLabel(
|
||||
}
|
||||
|
||||
function AccountRow({ row }: { row: OffhostAccountRow }) {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
|
||||
return (
|
||||
@@ -128,7 +128,7 @@ function AccountRow({ row }: { row: OffhostAccountRow }) {
|
||||
})
|
||||
: `${fmt.dateTime(row.lastSuccessAt)} · ${formatBytes(
|
||||
row.sizeBytes,
|
||||
fmt,
|
||||
locale,
|
||||
)} · ${t("admin.section.backups.offhost.age", {
|
||||
hours: row.ageHours ?? 0,
|
||||
})}`}
|
||||
|
||||
Reference in new issue
Block a user