polish: rebrand to Fleet Ops, add trilingual i18n, adaptive demo guide, and UX overhaul
Rebrands the product from MobilityOps to Fleet Ops across the UI, backend defaults and knowledge base, and makes nl-BE/en-GB/fr-BE full first-class languages: i18next with eager-bundled per-namespace resources, a persisted accessible language switcher (topbar and mobile drawer), locale-aware date/number formatting, and a coverage test that fails the build on any missing or empty translation key. Backend dynamic content (demo scenarios, blocked-reason text, integration status) moves from fixed English/Dutch prose to stable message codes + params so the frontend can localize it; the demo knowledge base gains a fully translated NL/EN/FR procedure corpus (11 documents each) with per-language retrieval and localized evidence-state messages. The Demo Guide becomes breakpoint-adaptive: a docked rail on extra-wide desktop, a floating panel that auto-collapses to a persistent, closable progress chip on standard desktop/tablet, and a collapsed/half/full bottom sheet on mobile -- with scroll+focus+ highlight on "go to this step", Escape handling, and reduced-motion support. The Data Quality Workbench gets accessible choice-card decisions with a clear primary/ secondary/tertiary action hierarchy; the Automation ledger groups repeated successes and uses meaningful short refs; the Audit trail groups events by correlation id with human action labels and readable before/after diffs. Attention Queue, Today's movements, Vehicles, Bookings and Data Quality rows are fully clickable (stretched-link pattern) with independent secondary links, keyboard support and mobile touch targets. Fixes a topbar overflow on mobile caused by the new language switcher (moved into the mobile drawer at <=960px) and two dangling aria-labelledby references introduced this session. Updates all affected Playwright specs for the new nl-BE default and the new Audit/DemoGuide DOM structure, and adds new i18n-coverage, demo-guide-adaptive and clickable-rows specs. 131 backend tests, Ruff and mypy, and 71 Playwright tests pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
257a4cf6c0
commit
337f8716bb
@@ -17,17 +17,17 @@ test("return flow pre-fills the suspicious odometer reading and explains why", a
|
||||
await page.goto("/bookings/BK-DEMO-RETURN");
|
||||
|
||||
await expect(page.getByText("Demonstratiescenario: afwijkende kilometerstand")).toBeVisible();
|
||||
const odometerInput = page.getByLabel("End odometer (km)");
|
||||
const odometerInput = page.getByLabel("Eindkilometerstand (km)");
|
||||
await expect(odometerInput).not.toHaveValue("");
|
||||
const prefilled = Number(await odometerInput.inputValue());
|
||||
expect(prefilled).toBeGreaterThan(0);
|
||||
|
||||
await page.getByRole("button", { name: "Review return" }).click();
|
||||
await expect(page.getByText(/below.*canonical reading/)).toBeVisible();
|
||||
await page.getByRole("button", { name: "Confirm return" }).click();
|
||||
await expect(page.getByRole("heading", { name: "Return registered" })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "View automation status" })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "View audit trail" })).toBeVisible();
|
||||
await page.getByRole("button", { name: "Retour nakijken" }).click();
|
||||
await expect(page.getByText(/laatst bevestigde stand/)).toBeVisible();
|
||||
await page.getByRole("button", { name: "Retour bevestigen" }).click();
|
||||
await expect(page.getByRole("heading", { name: "Retour geregistreerd" })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "Automatiseringsstatus bekijken" })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "Audit trail bekijken" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("data quality issue detail explains what's wrong and why it matters", async ({ page }) => {
|
||||
@@ -36,9 +36,9 @@ test("data quality issue detail explains what's wrong and why it matters", async
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
await page.goto("/data-quality/DQ-DEMO-DUPLICATE");
|
||||
|
||||
await expect(page.getByText("What's wrong")).toBeVisible();
|
||||
await expect(page.getByText("Why it matters")).toBeVisible();
|
||||
await expect(page.getByText(/likely the same person/)).toBeVisible();
|
||||
await expect(page.getByText("Wat is er mis")).toBeVisible();
|
||||
await expect(page.getByText("Waarom dit belangrijk is")).toBeVisible();
|
||||
await expect(page.getByText(/waarschijnlijk dezelfde persoon/)).toBeVisible();
|
||||
});
|
||||
|
||||
test("data quality list can filter to demo scenarios only", async ({ page }) => {
|
||||
@@ -49,7 +49,7 @@ test("data quality list can filter to demo scenarios only", async ({ page }) =>
|
||||
|
||||
await expect(page.locator(".data-table tbody tr").first()).toBeVisible();
|
||||
const allRows = await page.locator(".data-table tbody tr").count();
|
||||
await page.getByRole("checkbox", { name: "Demo scenario's only" }).check();
|
||||
await page.getByRole("checkbox", { name: "Enkel demoscenario's" }).check();
|
||||
const filteredRows = await page.locator(".data-table tbody tr").count();
|
||||
expect(filteredRows).toBeGreaterThan(0);
|
||||
expect(filteredRows).toBeLessThanOrEqual(allRows);
|
||||
@@ -68,10 +68,10 @@ test("knowledge page suggested question returns a grounded, honestly-labelled an
|
||||
// The status badge and retrieval-flow diagram must name the actual active provider
|
||||
// honestly, not the not-yet-connected "RAGcore" -- the honest disclosure note below is
|
||||
// allowed to mention RAGcore by name when explaining it isn't live yet.
|
||||
await expect(page.locator(".knowledge-status strong")).toHaveText("Demo knowledge base");
|
||||
await expect(page.locator(".retrieval-flow")).toContainText("Demo knowledge base");
|
||||
await expect(page.locator(".knowledge-status strong")).toHaveText("de demokennisbank");
|
||||
await expect(page.locator(".retrieval-flow")).toContainText("de demokennisbank");
|
||||
await expect(page.locator(".knowledge-status")).not.toContainText("RAGcore");
|
||||
|
||||
await page.getByRole("button", { name: "Who reviews an unusual odometer reading?" }).click();
|
||||
await expect(page.getByText("Grounded in cited procedures")).toBeVisible();
|
||||
await page.getByRole("button", { name: "Wie beoordeelt een ongewone kilometerstand?" }).click();
|
||||
await expect(page.getByText("Onderbouwd met geciteerde procedures")).toBeVisible();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user