feat(ui): E31 S4a — rail rows are links, the channel page opens on unwatched, users and audit tidied
- Nav rail page rows are real links (/?page=<id>): a middle-click or Ctrl-click opens the page in a new tab; a plain click stays in-app. - A fresh channel page shows the unwatched videos; a picked watch state is a remembered preference (channelShow). - Users: the role, suspend and delete move into the row's one menu (the "…", right-click, Shift+F10); locked ones keep their reason. - Audit log: back-to-back successful runs of one job fold into one row that opens to the earlier ones; a failed run reads in the danger colour. - DESIGN.md decision log: the E31 picks.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
// "log_level = DEBUG", "Background sync paused") reads in the reader's language, rebuilt from the row's
|
||||
// data through the REAL catalog. A row whose summary is data (an e-mail, a URL) keeps it.
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { render } from "@testing-library/react";
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
import i18n, { setLanguage } from "../i18n";
|
||||
import type { AuditRow } from "../lib/api";
|
||||
import { auditColumns } from "./auditColumns";
|
||||
@@ -152,3 +152,49 @@ describe("an audit row's details", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// E31: a folded run (lib/auditGroups) shows its newest run and opens to the earlier ones; a failed run
|
||||
// is the line to see in a page of routine ones.
|
||||
describe("a folded run of one job", () => {
|
||||
const ok = (id: number, enriched: number) =>
|
||||
row({
|
||||
id,
|
||||
target_type: "job",
|
||||
target_id: "enrich",
|
||||
after: { status: "ok", result: { enriched } },
|
||||
});
|
||||
|
||||
it("names how many earlier runs it holds, and opens to each", () => {
|
||||
setLanguage("hu");
|
||||
const t = i18n.getFixedT("hu");
|
||||
const col = auditColumns(t, "hu", []).find((c) => c.key === "details")!;
|
||||
const runs = [ok(3, 50), ok(2, 40), ok(1, 30)];
|
||||
const { getByRole, container } = render(<>{col.render!({ ...runs[0]!, runs })}</>);
|
||||
const toggle = getByRole("button", { name: "2 korábbi futás" });
|
||||
expect(toggle.getAttribute("aria-expanded")).toBe("false");
|
||||
expect(container.querySelector("li")).toBeNull();
|
||||
fireEvent.click(toggle);
|
||||
expect(toggle.getAttribute("aria-expanded")).toBe("true");
|
||||
expect([...container.querySelectorAll("li")].map((li) => li.textContent)).toEqual([
|
||||
"—dúsítva: 40",
|
||||
"—dúsítva: 30",
|
||||
]);
|
||||
});
|
||||
|
||||
it("has no toggle for a lone run", () => {
|
||||
const t = i18n.getFixedT("hu");
|
||||
const col = auditColumns(t, "hu", []).find((c) => c.key === "details")!;
|
||||
const { container } = render(<>{col.render!(ok(1, 5))}</>);
|
||||
expect(container.querySelector("button")).toBeNull();
|
||||
});
|
||||
|
||||
it("paints a failed run's line in the danger colour", () => {
|
||||
const t = i18n.getFixedT("hu");
|
||||
const col = auditColumns(t, "hu", []).find((c) => c.key === "details")!;
|
||||
const failed = row({ target_type: "job", target_id: "enrich", after: { status: "error" } });
|
||||
const { container } = render(<>{col.render!(failed)}</>);
|
||||
expect(container.querySelector(".wrap-break-word")!.className).toContain("text-danger");
|
||||
const { container: fine } = render(<>{col.render!(ok(2, 5))}</>);
|
||||
expect(fine.querySelector(".wrap-break-word")!.className).not.toContain("text-danger");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user