fix(plan): readable audit descriptions, project labels, dashboard invalidation, view-only & sticky-column UI

Work-plan fixes from this session:
- Czech audit descriptions for plan entries/overrides (was empty '-')
- server-embedded project label on grid cells (was '-' past the 100-project cap)
- dashboard activity + audit-log cache invalidation on plan mutations
- read-only cells: no '+' on empty, keep hover on cells with a record
- view modal: Czech category + formatted dates
- sticky date column made opaque (no bleed-through on horizontal scroll)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-06 00:24:33 +02:00
parent 2f76fe0bc1
commit 4a9c283789
13 changed files with 2240 additions and 261 deletions

View File

@@ -0,0 +1,95 @@
import { describe, it, expect } from "vitest";
import {
planCategoryLabel,
buildPlanAuditDescription,
} from "../utils/planAuditDescription";
describe("planCategoryLabel", () => {
it("maps known plan categories to Czech labels", () => {
expect(planCategoryLabel("work")).toBe("Práce");
expect(planCategoryLabel("preparation")).toBe("Příprava");
expect(planCategoryLabel("travel")).toBe("Cesta / Montáž");
expect(planCategoryLabel("leave")).toBe("Dovolená");
expect(planCategoryLabel("sick")).toBe("Nemoc");
expect(planCategoryLabel("training")).toBe("Školení");
expect(planCategoryLabel("other")).toBe("Jiné");
});
it("falls back to the raw value for an unknown category", () => {
expect(planCategoryLabel("unknown_xyz")).toBe("unknown_xyz");
});
});
describe("buildPlanAuditDescription", () => {
it("describes a multi-day entry with project", () => {
const desc = buildPlanAuditDescription({
userName: "Jan Novák",
category: "work",
projectName: "Rekonstrukce haly",
dateFrom: "2026-06-08",
dateTo: "2026-06-12",
});
expect(desc).toBe(
"Jan Novák · 08.06.2026 12.06.2026 · Práce · Rekonstrukce haly",
);
});
it("collapses a single-day range to one date", () => {
const desc = buildPlanAuditDescription({
userName: "Jan Novák",
category: "work",
projectName: "Rekonstrukce haly",
dateFrom: "2026-06-08",
dateTo: "2026-06-08",
});
expect(desc).toBe("Jan Novák · 08.06.2026 · Práce · Rekonstrukce haly");
});
it("omits the project segment when there is no project", () => {
const desc = buildPlanAuditDescription({
userName: "Petr Svoboda",
category: "leave",
projectName: null,
dateFrom: "2026-06-10",
dateTo: "2026-06-10",
});
expect(desc).toBe("Petr Svoboda · 10.06.2026 · Dovolená");
});
it("appends the emergency-edit note when force is set", () => {
const desc = buildPlanAuditDescription({
userName: "Jan Novák",
category: "work",
projectName: null,
dateFrom: "2026-01-02",
dateTo: "2026-01-02",
force: true,
});
expect(desc).toBe("Jan Novák · 02.01.2026 · Práce · nouzová úprava");
});
it("appends a custom suffix (e.g. replaced override)", () => {
const desc = buildPlanAuditDescription({
userName: "Jan Novák",
category: "sick",
projectName: null,
dateFrom: "2026-06-10",
dateTo: "2026-06-10",
suffix: "nahrazeno novým záznamem",
});
expect(desc).toBe(
"Jan Novák · 10.06.2026 · Nemoc · nahrazeno novým záznamem",
);
});
it("treats a whitespace-only project name as no project", () => {
const desc = buildPlanAuditDescription({
userName: "Jan Novák",
category: "work",
projectName: " ",
dateFrom: "2026-06-08",
dateTo: "2026-06-08",
});
expect(desc).toBe("Jan Novák · 08.06.2026 · Práce");
});
});