feat(frontend): slice 3 — Backups cluster migration + nav/IA

Web UI rework.
- Migrate BackupAlertsTable, BackupJobsTable, BackupRunsTable,
  BackupsPage, BackupDashboardWidget off @mui (shadcn Table + Badge
  severity variants: success=chart-2, warning=chart-3, destructive)
- App.tsx IA: Backups now top-level nav (DatabaseBackup icon);
  Media surface primary at /media; /applications -> /media redirect
  in both route trees (mirrors /monitoring -> /observability)

Gate: build + lint + test green.
This commit is contained in:
Developer
2026-06-17 12:53:36 +00:00
parent 109e74db41
commit 77c6b62ee2
11 changed files with 720 additions and 323 deletions
@@ -0,0 +1,59 @@
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import BackupRunsTable from "../BackupRunsTable";
import type { BackupRun } from "../../types/backups";
function run(overrides: Partial<BackupRun> = {}): BackupRun {
return {
id: "r1",
job_id: "job-1",
started_at: 1_700_000_000,
ended_at: null,
status: "success",
bytes_transferred: 2048,
duration_ms: 1500,
error_message: null,
details_json: null,
created_at: 1_700_000_000,
...overrides,
};
}
describe("BackupRunsTable", () => {
it("maps run status onto Badge variants per design §2.3", () => {
render(
<BackupRunsTable
runs={[
run({ id: "a", status: "success" }),
run({ id: "b", status: "failure" }),
run({ id: "c", status: "in_progress" }),
]}
/>,
);
expect(screen.getByText("success").getAttribute("data-variant")).toBe(
"success",
);
expect(screen.getByText("failure").getAttribute("data-variant")).toBe(
"destructive",
);
expect(screen.getByText("in_progress").getAttribute("data-variant")).toBe(
"warning",
);
});
it("renders the formatted duration and transferred size", () => {
render(
<BackupRunsTable
runs={[
run({
id: "fmt",
duration_ms: 1500,
bytes_transferred: 2048,
}),
]}
/>,
);
expect(screen.getByText("1.5s")).toBeInTheDocument();
expect(screen.getByText("2.0 KB")).toBeInTheDocument();
});
});