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
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"badge": {
|
||||
"trigger": "Synthetic demo",
|
||||
"dialogLabel": "About this demo environment",
|
||||
"close": "Close",
|
||||
"orgIntro": "<strong>{{orgName}}</strong> is a fictional organisation. All names, vehicles and bookings are synthetic.",
|
||||
"orgIntroFallback": "All names, vehicles and bookings in this environment are synthetic.",
|
||||
"realWorkflows": "The workflows, controls and automation are really implemented — only the data is invented.",
|
||||
"lastReset": "Last reset: <strong>{{when}}</strong> · this environment is resettable at any time.",
|
||||
"aboutLink": "About this demo",
|
||||
"unknown": "unknown"
|
||||
},
|
||||
"guide": {
|
||||
"dialogLabel": "Guided demo",
|
||||
"trigger": "Demo guide",
|
||||
"kicker": "Guided demo · step {{current}} of {{total}}",
|
||||
"whatYouWillSee": "What you'll see",
|
||||
"whyItMatters": "Why it matters",
|
||||
"startAction": "Get started",
|
||||
"expectedOutcome": "Expected outcome",
|
||||
"goToStep": "Go to this step",
|
||||
"next": "Next",
|
||||
"close": "Close",
|
||||
"restart": "Prepare demo again",
|
||||
"restarting": "Restarting…",
|
||||
"restartFailed": "Could not restart the demo.",
|
||||
"allStepsLabel": "All steps",
|
||||
"progressChip": "Demo guide · step {{current}} of {{total}}",
|
||||
"expand": "Expand demo guide",
|
||||
"collapse": "Collapse demo guide",
|
||||
"steps": {
|
||||
"understand-state": {
|
||||
"title": "1. Understand the operational state",
|
||||
"whatYouWillSee": "The dashboard shows fleet readiness, open attention points and today's movements.",
|
||||
"whyItMatters": "An Operations Manager starts every day with this overview to decide where to step in.",
|
||||
"startAction": "Open the dashboard and review the attention queue and today's timeline.",
|
||||
"expectedOutcome": "You see which bookings, vehicles or data-quality issues need attention."
|
||||
},
|
||||
"open-booking": {
|
||||
"title": "2. Open the booking needing attention",
|
||||
"whatYouWillSee": "Booking BK-DEMO-RETURN, active and due for return today.",
|
||||
"whyItMatters": "Returns are the moment incorrect odometer readings or damage first become visible.",
|
||||
"startAction": "Open the booking from the dashboard or the booking list.",
|
||||
"expectedOutcome": "You see the booking details and the button to process the return."
|
||||
},
|
||||
"process-return": {
|
||||
"title": "3. Process a return with an odometer anomaly",
|
||||
"whatYouWillSee": "A return form pre-filled with a suspicious odometer reading below the last known reading.",
|
||||
"whyItMatters": "A falling odometer signals a data-entry mistake or a mixed-up vehicle — this must be caught before release.",
|
||||
"startAction": "Submit the return with the suggested value and review the server preview before confirming.",
|
||||
"expectedOutcome": "The return is processed, the vehicle gets an appropriate status, and a data-quality issue is created automatically."
|
||||
},
|
||||
"handle-quality-issue": {
|
||||
"title": "4. Handle the created data-quality issue",
|
||||
"whatYouWillSee": "A new 'odometer regression' issue at the top of the work queue.",
|
||||
"whyItMatters": "Every detected issue has one bounded resolution step — nothing is silently auto-corrected.",
|
||||
"startAction": "Open the data-quality overview and choose the newest issue.",
|
||||
"expectedOutcome": "You see the recommended action, choose a resolution, and the issue resolves with an audit trail."
|
||||
},
|
||||
"merge-duplicate": {
|
||||
"title": "5. Review and handle a possible duplicate customer",
|
||||
"whatYouWillSee": "Two customer profiles with the same email and phone number, compared side by side.",
|
||||
"whyItMatters": "Duplicate customers split booking history and confuse communication.",
|
||||
"startAction": "Compare both profiles and choose which one survives.",
|
||||
"expectedOutcome": "The profiles are merged, bookings are rewired, and the losing profile becomes a tombstone."
|
||||
},
|
||||
"ask-knowledge": {
|
||||
"title": "6. Ask the procedure assistant a question",
|
||||
"whatYouWillSee": "An answer with citation from the scoped demo knowledge base.",
|
||||
"whyItMatters": "Staff need a quick, grounded answer about procedures, without guessing.",
|
||||
"startAction": "Click one of the suggested questions, in the current interface language.",
|
||||
"expectedOutcome": "You see the answer, the procedure used, and the source text — or an honest 'insufficient information' if none exists."
|
||||
},
|
||||
"check-automation-audit": {
|
||||
"title": "7. Check automation and the audit trail",
|
||||
"whatYouWillSee": "The delivery status of your return's automation job, and its related audit events.",
|
||||
"whyItMatters": "Every important action must be traceable: who did what, when, and what followed.",
|
||||
"startAction": "Open Integrations to see delivery status, and Audit trail for the full record.",
|
||||
"expectedOutcome": "You see a successful (or recoverable) delivery and a readable audit trail of your actions."
|
||||
},
|
||||
"review-real-vs-simulated": {
|
||||
"title": "8. Review what's real, simulated, or not yet connected",
|
||||
"whatYouWillSee": "An overview of what's functionally implemented in this demo, what's synthetic, and which integrations aren't live yet.",
|
||||
"whyItMatters": "A demo is only convincing if visitors can verify for themselves what really works and what's still ahead.",
|
||||
"startAction": "Read the 'About this demo' page.",
|
||||
"expectedOutcome": "You can explain yourself what Fleet Ops is and isn't, with no verbal explanation needed."
|
||||
}
|
||||
}
|
||||
},
|
||||
"scenarios": {
|
||||
"eyebrow": "Demonstration scenarios",
|
||||
"title": "Try a demonstration scenario",
|
||||
"description": "Five focused scenarios that always use the same fixed bookings, customers and vehicles — always re-findable after a reset.",
|
||||
"loading": "Loading scenarios…",
|
||||
"ready": "Ready for demo",
|
||||
"notReady": "Not available",
|
||||
"duration": "Duration",
|
||||
"durationValue": "± {{minutes}} min",
|
||||
"role": "Role",
|
||||
"demonstrates": "Demonstrates:",
|
||||
"requiresRole": "Requires role: {{roles}}.",
|
||||
"startScenario": "Start scenario",
|
||||
"roleOr": "{{a}} or {{b}}",
|
||||
"roles": {
|
||||
"operations_manager": "Operations Manager",
|
||||
"rental_employee": "Rental Employee"
|
||||
},
|
||||
"items": {
|
||||
"return-anomaly": {
|
||||
"title": "Return with an odometer anomaly",
|
||||
"problem": "A vehicle comes back with an odometer reading lower than the last recorded reading — a sign of a data-entry mistake or a mixed-up vehicle.",
|
||||
"demonstrates": "Return processing, automatic data-quality detection, and the audit trail it produces."
|
||||
},
|
||||
"duplicate-customer": {
|
||||
"title": "Merge a possible duplicate customer",
|
||||
"problem": "Two customer profiles share the same email address and phone number — likely the same person, registered twice.",
|
||||
"demonstrates": "Merging customers while preserving booking history and the audit trail."
|
||||
},
|
||||
"booking-overlap": {
|
||||
"title": "Resolve overlapping bookings",
|
||||
"problem": "One vehicle is double-booked for overlapping periods — a scheduling error that must be resolved before departure.",
|
||||
"demonstrates": "Detection and controlled resolution of scheduling conflicts."
|
||||
},
|
||||
"automation-retry": {
|
||||
"title": "Retry a failed automation job",
|
||||
"problem": "One earlier event could not be delivered to the automation job due to a simulated connection error.",
|
||||
"demonstrates": "Reliable delivery with bounded retries and visible failure status."
|
||||
},
|
||||
"knowledge-question": {
|
||||
"title": "Ask a procedure question",
|
||||
"problem": "An employee isn't sure which procedure applies to a specific operational situation.",
|
||||
"demonstrates": "Source-grounded answers from a scoped demo knowledge base."
|
||||
}
|
||||
},
|
||||
"blockedReasons": {
|
||||
"bookingNotFound": "Demo booking BK-DEMO-RETURN not found. {{resetHint}}",
|
||||
"bookingAlreadyProcessed": "This booking has already been processed since the last reset. {{resetHint}}",
|
||||
"duplicateIssueNotFound": "Demo issue DQ-DEMO-DUPLICATE not found. {{resetHint}}",
|
||||
"issueAlreadyResolved": "This issue has already been resolved since the last reset. {{resetHint}}",
|
||||
"overlapIssueNotFound": "Demo issue DQ-DEMO-OVERLAP not found. {{resetHint}}",
|
||||
"failedEventNotFound": "The simulated failed event was not found. {{resetHint}}",
|
||||
"eventAlreadyRecovered": "This event has already been recovered since the last reset. {{resetHint}}",
|
||||
"knowledgeUnavailable": "The demo knowledge base is currently unavailable.",
|
||||
"resetHint": "Reset the demo data to make this scenario available again."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"eyebrow": "About this demo",
|
||||
"title": "What Fleet Ops is and isn't",
|
||||
"description": "{{orgName}} is a fictional rental organisation that makes this demo tangible — not a real company.",
|
||||
"loading": "Loading demo information…",
|
||||
"ctaTitle": "Prefer to jump right in?",
|
||||
"ctaBody": "The guided demo walks through all eight steps above in practice.",
|
||||
"ctaButton": "Start guided demo",
|
||||
"problemTitle": "The fictional problem",
|
||||
"problemBody": "{{orgName}} rents around 50 campers and vans from one main location. Bookings, returns, customer records and maintenance used to live in separate spreadsheets and verbal hand-offs, so problems (duplicate customers, incorrect odometer readings, double-booked vehicles) only surfaced late. Fleet Ops shows how one connected system flags these problems early and lets them be resolved under control.",
|
||||
"scopeTitle": "Who it's for and its scope",
|
||||
"scopeBody": "This demo is for anyone who wants to see how Fleet Ops tackles operational problems at a small rental company: Operations Managers and Rental Employees, and anyone evaluating the approach. The scope is deliberately focused on one connected proof of concept — no accounting, no payments, no public reservations, no full CRM or ERP.",
|
||||
"realTitle": "What really works",
|
||||
"realBody": "Everything below is functional code, not just a mockup: role-based access and sessions, vehicle and booking management, return processing with server-side validation, five data-quality rules each with its own resolution step, a full audit trail, automated delivery to n8n with bounded retries, Docker-based deployment, and an automated test suite (backend and Playwright end-to-end).",
|
||||
"syntheticTitle": "What's synthetic",
|
||||
"syntheticBody": "The organisation, all customers, vehicles, bookings, maintenance history, procedures in the knowledge base, and the pre-set-up scenarios are entirely invented. No data refers to a real person, vehicle or company; email addresses only use the {{testDomain}} test domain.",
|
||||
"architectureTitle": "Architecture in brief",
|
||||
"architectureBody": "A React/TypeScript frontend talks to a FastAPI backend (PostgreSQL via SQLAlchemy/Alembic migrations); important business rules live in the backend, not in n8n or in prompts. Returns and other events are committed locally first and only then delivered asynchronously to n8n through an automation job, so a temporary automation outage never blocks an operational action.",
|
||||
"securityTitle": "Security and access",
|
||||
"securityBody": "Access runs through signed, HTTP-only session cookies per role; each role is bound to a set of allowed routes, both enforced server-side and reflected in navigation. Important state changes are always checked and logged — never silently auto-corrected.",
|
||||
"testingTitle": "How this is tested",
|
||||
"testingBody": "An automated backend test suite covers business rules and API contracts; a full Playwright end-to-end suite covers the user flows, including this demo experience itself in three languages. Every change is also validated against a clean checkout (empty database, rebuilt from seed data) before deployment.",
|
||||
"integrationsTitle": "Integrations — honestly labelled",
|
||||
"integrationsDescription": "What's operational, what's demo mode, and what's not yet connected.",
|
||||
"resetTitle": "Restoring the demo environment",
|
||||
"resetBodyManager": "The environment can be reset to its starting state at any time. Last reset: <strong>{{when}}</strong>. Use <strong>Reset demo data</strong> in the sidebar to start over.",
|
||||
"resetBodyEmployee": "The environment can be reset to its starting state at any time. Last reset: <strong>{{when}}</strong>. An Operations Manager can reset the demo environment via the sidebar.",
|
||||
"limitationsTitle": "Limitations",
|
||||
"limitationsBody": "This is a focused proof of concept, not a full ERP. RAGcore and the ITWorx MCP Hub are not yet live-connected; the knowledge assistant uses a local, scoped demo knowledge base instead of a live RAGcore environment.",
|
||||
"unknown": "unknown"
|
||||
},
|
||||
"integrationSummary": {
|
||||
"titles": {
|
||||
"n8n": "Automation (n8n)",
|
||||
"ragcore": "Knowledge assistant (RAGcore)",
|
||||
"mcp_hub": "ITWorx MCP Hub"
|
||||
},
|
||||
"n8nDetail": "{{succeeded}} succeeded · {{failed}} failed · {{pending}} pending.",
|
||||
"ragcoreDetail": "{{count}} procedures indexed in {{collection}}.",
|
||||
"mcpDetailEnabled": "Prepared for future, controlled tool calls from the Hub.",
|
||||
"mcpDetailNotConnected": "Not yet connected — prepared for future controlled tool calls from the Hub."
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user