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,7 @@
|
||||
{
|
||||
"openRow": "Open: {{label}}",
|
||||
"reducedMotion": "Reduced motion active",
|
||||
"closeDialog": "Close dialog",
|
||||
"expandSection": "Expand section",
|
||||
"collapseSection": "Collapse section"
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"eyebrow": "Assure / Immutable history",
|
||||
"title": "Audit trail",
|
||||
"description": "Trace important state changes, actors and correlation references.",
|
||||
"actionFilterLabel": "Action",
|
||||
"actionFilterPlaceholder": "e.g. demo_login",
|
||||
"managerOnly": "The audit trail is visible to Operations Managers only.",
|
||||
"managerOnlyDetail": "Audit history is visible to Operations Managers only.",
|
||||
"loading": "Loading audit trail…",
|
||||
"unavailable": "Audit trail is unavailable right now.",
|
||||
"empty": "No audit events found",
|
||||
"emptyDetail": "Adjust the action filter.",
|
||||
"relatedFilterActive": "Showing only events linked to this action ({{count}} related events).",
|
||||
"clearFilter": "Clear this filter",
|
||||
"count": "{{count}} events",
|
||||
"storedRendered": "UTC stored · Brussels rendered",
|
||||
"columns": {
|
||||
"when": "When",
|
||||
"actor": "Actor",
|
||||
"action": "Action",
|
||||
"entity": "Entity",
|
||||
"change": "Change",
|
||||
"followUp": "Follow-up",
|
||||
"details": "Details"
|
||||
},
|
||||
"viewRelatedEvents": "View related events",
|
||||
"noChangeDetail": "No recorded change detail.",
|
||||
"noFieldChange": "No field-level change detected.",
|
||||
"reference": "Reference",
|
||||
"relatedEventsCount": "{{count}} linked event",
|
||||
"relatedEventsCount_other": "{{count}} linked events",
|
||||
"showTechnicalEvents": "Show {{count}} technical event",
|
||||
"showTechnicalEvents_other": "Show {{count}} technical events",
|
||||
"hideTechnicalEvents": "Hide technical events",
|
||||
"technicalDetails": "Technical details",
|
||||
"fullReference": "Full reference",
|
||||
"correlationId": "Correlation ID",
|
||||
"diff": {
|
||||
"setTo": "{{field}}: set to {{value}}",
|
||||
"was": "{{field}}: was {{value}}",
|
||||
"changed": "{{field}}: {{before}} → {{after}}"
|
||||
},
|
||||
"actions": {
|
||||
"demo_login": "Logged in",
|
||||
"demo_logout": "Logged out",
|
||||
"demo_reset": "Demo data reset",
|
||||
"demo_data_seeded": "Demo data seeded",
|
||||
"return_registered": "Vehicle return registered",
|
||||
"vehicle_status_changed": "Vehicle status changed",
|
||||
"data_quality_issue_resolved": "Data-quality issue resolved",
|
||||
"data_quality_issue_deferred": "Data-quality issue deferred",
|
||||
"data_quality_issue_rejected": "Data-quality issue rejected",
|
||||
"data_quality_fields_provided": "Missing fields provided",
|
||||
"data_quality_odometer_corrected": "Odometer corrected",
|
||||
"data_quality_odometer_retained": "Canonical odometer retained",
|
||||
"data_quality_status_applied": "Recommended status applied",
|
||||
"data_quality_booking_blocked": "Booking blocked",
|
||||
"data_quality_scan_run": "Quality scan run",
|
||||
"customer_merged": "Customers merged",
|
||||
"workflow_retry": "Automation retried",
|
||||
"knowledge_question_asked": "Knowledge question asked",
|
||||
"mcp_tool_request": "MCP tool called"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"brandTagline": "Control Centre",
|
||||
"orgLine": "Demo organisation: {{orgName}} (fictional)",
|
||||
"headline1": "Every hand-off.",
|
||||
"headline2": "One clear view.",
|
||||
"defaultDescription": "Fleet Ops brings vehicle, booking and operational data together, supports rental processes, detects data-quality problems and automates controlled follow-up steps.",
|
||||
"footnote": "Synthetic demo · no real customer or vehicle data · resettable at any time",
|
||||
"accessEyebrow": "Demo access",
|
||||
"accessHeading": "Choose how to start",
|
||||
"accessIntro": "No password needed. Each role opens a scoped synthetic environment — all workflows and controls are really implemented.",
|
||||
"startGuidedDemo": "Start guided demo",
|
||||
"exploreAsOperationsManager": "Explore as Operations Manager",
|
||||
"exploreAsOperationsManagerDetail": "Full overview, quality resolution and retries",
|
||||
"exploreAsRentalEmployee": "Explore as Rental Employee",
|
||||
"exploreAsRentalEmployeeDetail": "Bookings, returns, fleet and procedures",
|
||||
"safeByDesignTitle": "Safe by design",
|
||||
"safeByDesignDetail": "Every action is logged and is resettable in this demo.",
|
||||
"loginFailed": "The demo session could not be started. The API may be unreachable.",
|
||||
"roleOperationsManager": "Operations manager",
|
||||
"roleRentalEmployee": "Rental employee",
|
||||
"switchRole": "Switch role",
|
||||
"logout": "Log out"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Operations / Schedule",
|
||||
"title": "Bookings",
|
||||
"description": "Review active rental windows and upcoming vehicle commitments.",
|
||||
"searchLabel": "Search",
|
||||
"searchPlaceholder": "Booking, customer or vehicle",
|
||||
"statusLabel": "Status",
|
||||
"statusAll": "All statuses",
|
||||
"loading": "Loading booking ledger…",
|
||||
"empty": "No bookings found",
|
||||
"emptyDetail": "Adjust the booking status filter.",
|
||||
"noMatch": "No matching bookings",
|
||||
"noMatchDetail": "Try a broader search term.",
|
||||
"unavailable": "Booking list is unavailable right now.",
|
||||
"count": "{{count}} bookings",
|
||||
"pageOf": "Page {{page}} of {{total}}",
|
||||
"columns": {
|
||||
"reference": "Reference",
|
||||
"customer": "Customer",
|
||||
"vehicle": "Vehicle",
|
||||
"window": "Window",
|
||||
"status": "Status"
|
||||
},
|
||||
"paginationLabel": "Booking pages",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"rangeOf": "{{from}}–{{to}} of {{total}}"
|
||||
},
|
||||
"statuses": {
|
||||
"reserved": "reserved",
|
||||
"active": "active",
|
||||
"returned": "returned",
|
||||
"cancelled": "cancelled",
|
||||
"blocked": "blocked"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Booking ledger",
|
||||
"eyebrow": "Bookings / Rental record",
|
||||
"notFound": "This booking could not be found.",
|
||||
"loading": "Loading booking record…",
|
||||
"customer": "Customer",
|
||||
"vehicle": "Vehicle",
|
||||
"starts": "Starts",
|
||||
"ends": "Ends",
|
||||
"startOdometer": "Start odometer",
|
||||
"endOdometer": "End odometer",
|
||||
"requirementsComplete": "Requirements complete",
|
||||
"yes": "Yes",
|
||||
"no": "No"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"appName": "Fleet Ops",
|
||||
"orgName": "Northstar Mobility",
|
||||
"brandTagline": "Control Centre",
|
||||
"actions": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm",
|
||||
"close": "Close",
|
||||
"back": "Back",
|
||||
"next": "Next",
|
||||
"retry": "Retry",
|
||||
"reset": "Reset",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"viewDetails": "View details",
|
||||
"technicalDetails": "Technical details"
|
||||
},
|
||||
"status": {
|
||||
"loading": "Loading…",
|
||||
"saving": "Saving…",
|
||||
"error": "Something went wrong",
|
||||
"success": "Success",
|
||||
"noResults": "No results"
|
||||
},
|
||||
"states": {
|
||||
"loadingDefault": "Loading workspace…",
|
||||
"errorTitle": "We couldn't load this workspace."
|
||||
},
|
||||
"timezone": "Europe/Brussels",
|
||||
"language": {
|
||||
"label": "Language",
|
||||
"nl-BE": "Nederlands",
|
||||
"en-GB": "English",
|
||||
"fr-BE": "Français"
|
||||
},
|
||||
"footer": {
|
||||
"productLine": "Fleet Ops Demo",
|
||||
"locale": "Europe/Brussels · Synthetic demo data"
|
||||
},
|
||||
"demo": {
|
||||
"syntheticBadge": "Synthetic demo"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"eyebrow": "Operations / Live overview",
|
||||
"title": "Good morning. Here's the fleet.",
|
||||
"description": "Readiness, exceptions and hand-offs across today's operation.",
|
||||
"viewFleet": "View fleet",
|
||||
"demoStart": {
|
||||
"title": "Try a demonstration scenario",
|
||||
"readyCount": "{{ready}} of {{total}} scenarios ready for demo.",
|
||||
"readyCountFallback": "Five focused scenarios.",
|
||||
"startGuide": "Start demo guide",
|
||||
"resumeGuide": "Continue demo guide ({{current}}/{{total}})",
|
||||
"viewScenarios": "View scenarios"
|
||||
},
|
||||
"readiness": {
|
||||
"title": "Fleet readiness",
|
||||
"description": "Live from persisted vehicle state",
|
||||
"openFleet": "Open fleet",
|
||||
"available": "Available",
|
||||
"rented": "Rented",
|
||||
"cleaning": "Cleaning",
|
||||
"maintenance": "Maintenance",
|
||||
"blocked": "Blocked"
|
||||
},
|
||||
"attention": {
|
||||
"title": "Attention queue",
|
||||
"description": "{{openIssues}} open quality issues · {{workflowExceptions}} workflow exceptions",
|
||||
"reviewQueue": "Review queue",
|
||||
"filterPlaceholder": "Filter issues…",
|
||||
"filterAriaLabel": "Search attention queue",
|
||||
"severityAll": "All severity",
|
||||
"severityHigh": "Critical",
|
||||
"severityMedium": "Warning",
|
||||
"severityLow": "Info",
|
||||
"severityAriaLabel": "Severity",
|
||||
"empty": "No issues match this filter.",
|
||||
"openRecord": "Open {{title}}"
|
||||
},
|
||||
"movements": {
|
||||
"title": "Today's movements",
|
||||
"description": "Departures and returns in Europe/Brussels",
|
||||
"allBookings": "All bookings",
|
||||
"empty": "No movements scheduled today.",
|
||||
"departure": "departure",
|
||||
"return": "return",
|
||||
"openBooking": "Open booking {{ref}}"
|
||||
},
|
||||
"integrationPulse": {
|
||||
"title": "Integration pulse",
|
||||
"description": "Current evidence from connected services",
|
||||
"systemDetail": "System detail",
|
||||
"n8nTitle": "n8n delivery",
|
||||
"n8nSummary": "{{succeeded}} succeeded · {{failed}} failed",
|
||||
"n8nLatest": "Latest event {{ref}}",
|
||||
"n8nNoEvidence": "No workflow evidence recorded",
|
||||
"knowledgeTitle": "Knowledge assistant",
|
||||
"knowledgeSummary": "{{count}} procedures indexed",
|
||||
"knowledgeUnavailable": "Health check unavailable",
|
||||
"mcpTitle": "MCP Hub",
|
||||
"mcpEnabled": "Registration enabled",
|
||||
"mcpNotConnected": "Not yet connected"
|
||||
},
|
||||
"recent": {
|
||||
"title": "Recent activity",
|
||||
"description": "Latest audited workflow changes",
|
||||
"empty": "No automation activity recorded."
|
||||
}
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"generic": "Something went wrong. Please try again.",
|
||||
"workspaceLoadFailed": "We couldn't load this workspace.",
|
||||
"unauthorized": "Your session has expired. Please log in again.",
|
||||
"forbidden": "You don't have access to this section.",
|
||||
"notFound": "This record could not be found.",
|
||||
"networkUnavailable": "The connection to the server is currently unavailable."
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Fleet / Registry",
|
||||
"title": "Vehicle fleet",
|
||||
"description": "Live operational state, location and service readiness.",
|
||||
"searchLabel": "Search",
|
||||
"searchPlaceholder": "Reference, make or location",
|
||||
"statusLabel": "Status",
|
||||
"statusAll": "All statuses",
|
||||
"attentionOnly": "Attention only",
|
||||
"loading": "Loading fleet registry…",
|
||||
"empty": "No vehicles found",
|
||||
"emptyDetail": "Adjust the current fleet filters.",
|
||||
"noMatch": "No matching vehicles",
|
||||
"noMatchDetail": "Try a broader search term.",
|
||||
"unavailable": "Vehicle list is unavailable right now.",
|
||||
"count": "{{count}} vehicles",
|
||||
"persisted": "Persisted fleet data",
|
||||
"columns": {
|
||||
"reference": "Reference",
|
||||
"makeModel": "Make / model",
|
||||
"location": "Location",
|
||||
"status": "Status",
|
||||
"odometer": "Odometer (km)",
|
||||
"attention": "Attention"
|
||||
},
|
||||
"needsAttention": "Needs attention"
|
||||
},
|
||||
"statuses": {
|
||||
"available": "available",
|
||||
"rented": "rented",
|
||||
"cleaning": "cleaning",
|
||||
"maintenance": "maintenance",
|
||||
"blocked": "blocked"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Fleet registry",
|
||||
"eyebrow": "Fleet / Vehicle record",
|
||||
"notFound": "This vehicle could not be found.",
|
||||
"loading": "Loading vehicle record…",
|
||||
"needsAttention": "Needs attention",
|
||||
"tabs": {
|
||||
"overview": "Overview",
|
||||
"bookings": "Bookings",
|
||||
"inspections": "Inspections",
|
||||
"maintenance": "Maintenance",
|
||||
"quality": "Quality"
|
||||
},
|
||||
"tabsAriaLabel": "Vehicle sections",
|
||||
"overview": {
|
||||
"registration": "Registration",
|
||||
"modelYear": "Model year",
|
||||
"location": "Location",
|
||||
"odometer": "Odometer",
|
||||
"nextService": "Next service",
|
||||
"active": "Active"
|
||||
},
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"noBookings": "No bookings recorded.",
|
||||
"noInspections": "No inspections recorded.",
|
||||
"noMaintenance": "No maintenance records.",
|
||||
"noQualityIssues": "No quality issues recorded.",
|
||||
"fuel": "Fuel {{percent}}%",
|
||||
"damage": "Damage",
|
||||
"technicalWarning": "Technical warning"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"eyebrow": "Assure / Integrations",
|
||||
"title": "Integration control",
|
||||
"description": "Monitor delivery health, graceful degradation and retryable workflow events.",
|
||||
"cards": {
|
||||
"orchestrationKicker": "Orchestration",
|
||||
"n8nTitle": "n8n delivery",
|
||||
"n8nSummary": "{{succeeded}} succeeded · {{failed}} failed · {{pending}} pending · {{delivering}} delivering",
|
||||
"n8nFallback": "Return events are committed locally first and then delivered through the automation job.",
|
||||
"knowledgeKicker": "Knowledge",
|
||||
"knowledgeTitle": "Knowledge assistant",
|
||||
"knowledgeSummaryDemo": "Demo knowledge base · {{count}} procedures indexed in {{collection}}.",
|
||||
"knowledgeSummaryRagcore": "RAGcore · {{count}} procedures indexed in {{collection}}.",
|
||||
"knowledgeUnavailable": "Health evidence is currently unavailable.",
|
||||
"gatewayKicker": "Tool gateway",
|
||||
"mcpTitle": "MCP Hub",
|
||||
"mcpEnabled": "Registration is enabled for this deployment.",
|
||||
"mcpNotConnected": "Not yet connected — prepared for future controlled tool calls from the Hub."
|
||||
},
|
||||
"statusLabels": {
|
||||
"notConnected": "Not connected",
|
||||
"deliveryFailed": "Delivery failed",
|
||||
"retryAvailable": "Retry available",
|
||||
"operational": "Operational",
|
||||
"prepared": "Prepared",
|
||||
"demoMode": "Demo mode",
|
||||
"unavailable": "Unavailable"
|
||||
},
|
||||
"ledger": {
|
||||
"title": "Automation jobs",
|
||||
"description": "Persisted automation attempts with the latest failure evidence.",
|
||||
"filterLabel": "View",
|
||||
"filterNeedsAttention": "Needs attention",
|
||||
"filterRecent": "Recent",
|
||||
"filterSucceeded": "Succeeded",
|
||||
"filterAll": "All",
|
||||
"statusFilterLabel": "Status",
|
||||
"statusAll": "All statuses",
|
||||
"statusPending": "Pending",
|
||||
"statusDelivering": "Delivering",
|
||||
"statusSucceeded": "Succeeded",
|
||||
"statusFailed": "Failed",
|
||||
"unavailable": "Automation jobs are unavailable right now.",
|
||||
"managerOnly": "Automation is visible to Operations Managers only.",
|
||||
"loading": "Loading automation jobs…",
|
||||
"empty": "No automation jobs match this filter.",
|
||||
"count": "{{count}} workflow events",
|
||||
"boundedRetries": "Bounded retries",
|
||||
"groupedSucceeded": "{{count}} succeeded vehicle-return jobs",
|
||||
"showIndividually": "Show individual jobs",
|
||||
"hideIndividually": "Hide individual jobs",
|
||||
"columns": {
|
||||
"event": "Job",
|
||||
"type": "Type",
|
||||
"booking": "Booking",
|
||||
"status": "Status",
|
||||
"attempts": "Attempts",
|
||||
"lastError": "Last error",
|
||||
"when": "When",
|
||||
"action": "Action"
|
||||
},
|
||||
"retry": "Retry",
|
||||
"retrying": "Retrying…",
|
||||
"retryFailed": "Could not retry this delivery.",
|
||||
"noAction": "—",
|
||||
"eventTypes": {
|
||||
"vehicle.returned.v1": "Vehicle return processed"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"eyebrow": "Assure / Grounded knowledge",
|
||||
"title": "Procedure knowledge",
|
||||
"description": "Ask operational questions. Answers are shown only when {{provider}} returns sufficient cited evidence.",
|
||||
"providerDemo": "the demo knowledge base",
|
||||
"providerRagcore": "RAGcore",
|
||||
"statusAvailable": "Available",
|
||||
"statusUnavailable": "Unavailable",
|
||||
"proceduresIndexed": "{{count}} procedures indexed",
|
||||
"providerNote": "This demo answers from a small, fixed set of indexed procedures — not a live RAGcore connection. A live RAGcore backend will later take over the same interface without changing how this page works.",
|
||||
"askHeading": "Ask a procedure question",
|
||||
"askSubheading": "Retrieval → evidence check → grounded answer",
|
||||
"questionLabel": "Question",
|
||||
"questionPlaceholder": "e.g. What must I do when a vehicle returns with damage?",
|
||||
"ask": "Ask",
|
||||
"asking": "Asking…",
|
||||
"askFailed": "Could not reach the knowledge service.",
|
||||
"suggestedLabel": "Try one:",
|
||||
"suggestedQuestions": [
|
||||
"What must I do when a vehicle returns with damage?",
|
||||
"How do I register a vehicle return?",
|
||||
"When may a vehicle be made available again?",
|
||||
"Who reviews an unusual odometer reading?",
|
||||
"Which checks are required before checkout?"
|
||||
],
|
||||
"emptyTitle": "Evidence before answers",
|
||||
"emptyDescription": "Ask about returns, damage, inspections or another indexed procedure. Fleet Ops will not invent an answer when evidence is missing.",
|
||||
"retrievalFlow": {
|
||||
"question": "Question",
|
||||
"sources": "Sources",
|
||||
"answer": "Answer"
|
||||
},
|
||||
"questionLabelExchange": "Question",
|
||||
"evidenceStates": {
|
||||
"grounded": "Grounded in cited procedures",
|
||||
"insufficient": "Insufficient evidence",
|
||||
"unavailable": "Knowledge service unavailable"
|
||||
},
|
||||
"unavailableBody": "The knowledge service is currently unreachable. Operational features are unaffected — try again later.",
|
||||
"sourceVersion": "v{{version}}"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"skipToContent": "Skip to main content",
|
||||
"groups": {
|
||||
"operate": "Operate",
|
||||
"assure": "Assure"
|
||||
},
|
||||
"items": {
|
||||
"overview": "Overview",
|
||||
"fleet": "Fleet",
|
||||
"bookings": "Bookings",
|
||||
"quality": "Data quality",
|
||||
"knowledge": "Knowledge",
|
||||
"integrations": "Integrations",
|
||||
"audit": "Audit trail"
|
||||
},
|
||||
"primaryNavLabel": "Primary navigation",
|
||||
"mobileNavLabel": "Mobile navigation",
|
||||
"more": "More",
|
||||
"openNavigation": "Open navigation",
|
||||
"closeNavigation": "Close navigation",
|
||||
"sidebarEnvironment": "Demo environment",
|
||||
"sidebarEnvironmentDetail": "Synthetic data only",
|
||||
"resetDemoData": "Reset demo data",
|
||||
"resetConfirmTitle": "Confirm demo reset",
|
||||
"resetConfirmBody": "All synthetic changes will be discarded and deterministic demo data restored. You will be signed out.",
|
||||
"resetting": "Resetting…",
|
||||
"resetConfirmYes": "Yes, reset",
|
||||
"resetCancel": "Cancel",
|
||||
"resetFailed": "Could not reset demo data.",
|
||||
"searchLabel": "Search Fleet Ops",
|
||||
"searchPlaceholder": "Search fleet, booking or section…",
|
||||
"searchShortcutHint": "Ctrl K",
|
||||
"searchSearching": "Searching…",
|
||||
"searchUnavailable": "Search is unavailable right now.",
|
||||
"searchNoResults": "No matches for \"{{query}}\".",
|
||||
"switchRole": "Switch role",
|
||||
"switchRoleTitle": "Switch demo role",
|
||||
"languageSwitcherLabel": "Change language"
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Assure / Workbench",
|
||||
"title": "Data quality",
|
||||
"description": "Resolve evidence-backed exceptions before they disrupt operations.",
|
||||
"runScan": "Run quality scan",
|
||||
"confirmScanTitle": "Confirm quality scan",
|
||||
"confirmScanBody": "Run the deterministic scan across all five rule types now?",
|
||||
"scanning": "Scanning…",
|
||||
"confirmScanYes": "Yes, run scan",
|
||||
"cancel": "Cancel",
|
||||
"scanComplete": "Scan complete: {{summary}}",
|
||||
"scanNoNew": "no new issues found (existing open issues are not recreated).",
|
||||
"scanFailed": "Could not run the quality scan.",
|
||||
"statusLabel": "Status",
|
||||
"statusAll": "All statuses",
|
||||
"statusOpen": "Open",
|
||||
"statusDeferred": "Deferred",
|
||||
"statusResolved": "Resolved",
|
||||
"statusRejected": "Rejected",
|
||||
"ruleTypeLabel": "Rule type",
|
||||
"ruleTypeAll": "All rule types",
|
||||
"demoScenariosOnly": "Demo scenarios only",
|
||||
"loading": "Loading quality workbench…",
|
||||
"queueClear": "Queue is clear",
|
||||
"noIssuesMatch": "No issues match the current filters.",
|
||||
"noDemoIssuesMatch": "No demo-scenario issues match",
|
||||
"noDemoIssuesMatchDetail": "Uncheck 'Demo scenarios only' to see the full queue.",
|
||||
"unavailable": "Data-quality issues are unavailable right now.",
|
||||
"count": "{{count}} issues",
|
||||
"evidenceBacked": "Evidence-backed detection",
|
||||
"columns": {
|
||||
"reference": "Reference",
|
||||
"rule": "Rule",
|
||||
"entity": "Entity",
|
||||
"severity": "Severity",
|
||||
"status": "Status"
|
||||
}
|
||||
},
|
||||
"ruleTypes": {
|
||||
"possible_duplicate_customer": "Possible duplicate customer",
|
||||
"missing_required_field": "Missing required field",
|
||||
"odometer_regression": "Odometer regression",
|
||||
"booking_overlap": "Booking overlap",
|
||||
"vehicle_status_conflict": "Vehicle status conflict"
|
||||
},
|
||||
"severities": {
|
||||
"high": "Critical",
|
||||
"medium": "Warning",
|
||||
"low": "Info"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Quality workbench",
|
||||
"eyebrow": "Quality / {{rule}}",
|
||||
"title": "Review persisted evidence and record an audited resolution.",
|
||||
"notFound": "This issue could not be found.",
|
||||
"loading": "Loading issue evidence…",
|
||||
"managerOnly": "The quality workbench is visible to Operations Managers only.",
|
||||
"managerOnlyDetail": "Data-quality evidence and resolutions are visible to Operations Managers only.",
|
||||
"summary": {
|
||||
"rule": "Rule",
|
||||
"entity": "Entity",
|
||||
"evidenceSummary": "Evidence summary"
|
||||
},
|
||||
"resolved": {
|
||||
"title": "Issue {{ref}} resolved",
|
||||
"body": "The change has been applied and is recorded in the audit trail.",
|
||||
"viewAudit": "View audit trail",
|
||||
"viewVehicle": "View vehicle",
|
||||
"continueDemo": "Continue the demo"
|
||||
},
|
||||
"deferOrReject": {
|
||||
"heading": "Defer or reject",
|
||||
"description": "Defer to review later, or reject if this is not a real issue.",
|
||||
"defer": "Defer",
|
||||
"reject": "Reject",
|
||||
"deferFailed": "Could not defer this issue.",
|
||||
"rejectFailed": "Could not reject this issue."
|
||||
},
|
||||
"explainer": {
|
||||
"whatIsWrong": "What's wrong",
|
||||
"whyItMatters": "Why it matters",
|
||||
"possible_duplicate_customer": {
|
||||
"whatIsWrong": "Two customer profiles share identifying details (email, phone or a very similar name) strongly enough that they are likely the same person, registered twice.",
|
||||
"whyItMatters": "Duplicate customers split booking history across two records, risk duplicate billing, and confuse support conversations."
|
||||
},
|
||||
"missing_required_field": {
|
||||
"whatIsWrong": "This record is missing information that's required for normal operation (for example, a customer with neither an email nor a phone number on file).",
|
||||
"whyItMatters": "Without this data, the business can't reach the customer, or can't reliably identify the vehicle for compliance and hand-off checks."
|
||||
},
|
||||
"odometer_regression": {
|
||||
"whatIsWrong": "A submitted odometer reading is lower than the vehicle's last known (canonical) reading.",
|
||||
"whyItMatters": "A falling odometer usually means a data-entry mistake or that readings were recorded against the wrong vehicle. Letting it through silently would corrupt maintenance scheduling and resale mileage history."
|
||||
},
|
||||
"booking_overlap": {
|
||||
"whatIsWrong": "The same vehicle is committed to two bookings whose date ranges overlap.",
|
||||
"whyItMatters": "Only one of these bookings can actually be honoured. Left unresolved, a customer would arrive to find their vehicle already out with someone else."
|
||||
},
|
||||
"vehicle_status_conflict": {
|
||||
"whatIsWrong": "This vehicle's stored operational status doesn't match what its own booking and inspection history implies it should be.",
|
||||
"whyItMatters": "An incorrect status can make an unavailable vehicle appear bookable, or keep an available vehicle hidden from the fleet."
|
||||
}
|
||||
},
|
||||
"duplicateCustomer": {
|
||||
"heading": "Compare and merge",
|
||||
"description": "Choose the canonical customer and review each conflicting field.",
|
||||
"keepAsSurvivor": "Keep as survivor",
|
||||
"differs": "Differs",
|
||||
"match": "Match",
|
||||
"mergePreview": "{{loser}} will become a tombstone linked to {{survivor}}; its bookings will be rewired.",
|
||||
"mergeInto": "Merge into {{ref}}",
|
||||
"confirmMergeTitle": "Confirm merge",
|
||||
"confirmMergeBody": "Merge {{loser}} into {{survivor}}? This cannot be undone.",
|
||||
"merging": "Merging…",
|
||||
"confirmMergeYes": "Yes, merge",
|
||||
"mergeFailed": "Could not merge these customers.",
|
||||
"bothMissing": "Both customers in this comparison could not be loaded.",
|
||||
"fieldColumn": "Field",
|
||||
"fields": {
|
||||
"first_name": "First name",
|
||||
"last_name": "Last name",
|
||||
"email": "Email",
|
||||
"phone": "Phone",
|
||||
"postal_code": "Postal code",
|
||||
"city": "City"
|
||||
}
|
||||
},
|
||||
"missingField": {
|
||||
"heading": "Provide the missing fields",
|
||||
"description": "Complete the record for {{ref}}. The issue resolves automatically once nothing required is missing.",
|
||||
"atLeastOne": "At least one of email or phone is required.",
|
||||
"saveAndRecheck": "Save and re-check",
|
||||
"saving": "Saving…",
|
||||
"saveFailed": "Could not save these fields.",
|
||||
"fields": {
|
||||
"first_name": "First name",
|
||||
"last_name": "Last name",
|
||||
"email": "Email",
|
||||
"phone": "Phone",
|
||||
"registration_number": "Registration number",
|
||||
"make": "Make",
|
||||
"model": "Model",
|
||||
"location": "Location"
|
||||
}
|
||||
},
|
||||
"odometerRegression": {
|
||||
"heading": "Resolve the odometer regression",
|
||||
"description": "The canonical odometer is never lowered automatically -- choose how to reconcile it.",
|
||||
"canonicalOdometer": "Canonical odometer",
|
||||
"decisionLegend": "Decision",
|
||||
"retainCanonical": "Retain canonical reading",
|
||||
"retainCanonicalDetail": "Treat the submitted reading as erroneous; nothing changes on the vehicle record.",
|
||||
"correctReading": "Correct the reading",
|
||||
"correctReadingDetail": "Update both the booking and the canonical odometer with the correct value.",
|
||||
"noBookingAttached": "No related booking is attached to this issue, so only 'retain canonical' is available.",
|
||||
"booking": "Booking",
|
||||
"correctedOdometer": "Corrected odometer (km)",
|
||||
"note": "Note",
|
||||
"resolving": "Resolving…",
|
||||
"resolveIssue": "Resolve issue",
|
||||
"resolveFailed": "Could not resolve this issue."
|
||||
},
|
||||
"bookingOverlap": {
|
||||
"heading": "Resolve the booking overlap",
|
||||
"description": "Block one of the two overlapping commitments. The other keeps its current status.",
|
||||
"columns": {
|
||||
"booking": "Booking",
|
||||
"window": "Window",
|
||||
"status": "Status",
|
||||
"blockThis": "Block this one"
|
||||
},
|
||||
"blockLabel": "Block {{ref}}",
|
||||
"note": "Note",
|
||||
"resolving": "Resolving…",
|
||||
"blockButton": "Block {{ref}}",
|
||||
"blockButtonFallback": "Block booking",
|
||||
"resolveFailed": "Could not resolve this overlap."
|
||||
},
|
||||
"vehicleStatusConflict": {
|
||||
"heading": "Resolve the status conflict",
|
||||
"description": "One authoritative rule recommends a corrected operational status for this vehicle.",
|
||||
"currentStatus": "Current status",
|
||||
"calculateAndApply": "Calculate and apply recommended status",
|
||||
"confirmTitle": "Confirm status change",
|
||||
"confirmBody": "Apply the authoritative recommended status for this vehicle?",
|
||||
"applying": "Applying…",
|
||||
"confirmYes": "Yes, apply",
|
||||
"applied": "Applied {{status}} — {{reason}}",
|
||||
"applyFailed": "Could not apply a recommended status."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"progress": {
|
||||
"capture": "Capture",
|
||||
"review": "Review",
|
||||
"result": "Result",
|
||||
"ariaLabel": "Return registration progress"
|
||||
},
|
||||
"capture": {
|
||||
"heading": "Register vehicle return",
|
||||
"description": "Record the hand-back condition. The next step evaluates the exact operational consequences before anything is committed.",
|
||||
"endOdometer": "End odometer (km)",
|
||||
"fuelLevel": "Fuel level (%)",
|
||||
"conditionLegend": "Vehicle condition",
|
||||
"cleanlinessOk": "Cleanliness acceptable",
|
||||
"damageReported": "Damage reported",
|
||||
"technicalWarning": "Technical warning",
|
||||
"notes": "Notes",
|
||||
"evaluating": "Evaluating…",
|
||||
"reviewReturn": "Review return"
|
||||
},
|
||||
"review": {
|
||||
"heading": "Review return impact",
|
||||
"description": "This is the server's authoritative evaluation of what committing will do — confirm before it updates fleet state and queues automation.",
|
||||
"odometer": "Odometer",
|
||||
"fuel": "Fuel",
|
||||
"cleanliness": "Cleanliness",
|
||||
"cleanlinessAccepted": "Accepted",
|
||||
"cleanlinessFollowUp": "Follow-up needed",
|
||||
"damage": "Damage",
|
||||
"damageReported": "Reported",
|
||||
"damageNone": "None reported",
|
||||
"technicalWarning": "Technical warning",
|
||||
"technicalWarningReported": "Reported",
|
||||
"technicalWarningNone": "None reported",
|
||||
"expectedState": "Expected fleet state:",
|
||||
"odometerRegressionWarning": "Submitted odometer ({{submitted}} km) is below the canonical reading ({{canonical}} km). The canonical odometer will not change, and a data-quality issue will be opened.",
|
||||
"nextBookingRisk": "Next booking {{ref}} starts {{when}} — may be affected by this return.",
|
||||
"nextBookingLowRisk": "Next booking {{ref}} starts {{when}} — low risk.",
|
||||
"commitList": {
|
||||
"inspection": "Create a return inspection",
|
||||
"updateAtomic": "Update the booking and vehicle atomically",
|
||||
"queueAutomation": "Queue automation after the local commit"
|
||||
},
|
||||
"editDetails": "Edit details",
|
||||
"registering": "Registering…",
|
||||
"confirmReturn": "Confirm return"
|
||||
},
|
||||
"result": {
|
||||
"committedLocally": "Committed locally",
|
||||
"heading": "Return registered",
|
||||
"inspection": "Inspection",
|
||||
"resultingStatus": "Resulting vehicle status",
|
||||
"qualityIssue": "Quality issue",
|
||||
"noneCreated": "None created",
|
||||
"automationEvent": "Automation job",
|
||||
"queuedForDelivery": "Queued for delivery ({{ref}}) — local commit succeeded; automation delivery is asynchronous and not yet confirmed.",
|
||||
"nextBookingRisk": "Next booking risk",
|
||||
"nextBookingRiskValue": "{{ref}} {{status}}",
|
||||
"atRisk": "— may be affected",
|
||||
"lowRisk": "— low risk",
|
||||
"noUpcomingBooking": "No upcoming booking for this vehicle",
|
||||
"odometerRegressionNotice": "The submitted odometer reading was below the vehicle's canonical odometer. It was recorded as-is; the canonical odometer was not changed, and a data-quality issue was opened for review.",
|
||||
"viewVehicle": "View vehicle {{ref}}",
|
||||
"viewAutomation": "View automation status",
|
||||
"viewAudit": "View audit trail",
|
||||
"continueDemo": "Continue the demo"
|
||||
},
|
||||
"scenario": {
|
||||
"title": "Demo scenario: odometer anomaly",
|
||||
"body": "This vehicle currently reads {{odometer}} km. The form below is pre-filled with a return reading below that — a sign of a data-entry mistake or a mixed-up vehicle. Confirm the return to see how Fleet Ops detects and handles this.",
|
||||
"preparing": "Preparing scenario…"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"openRow": "Ouvrir : {{label}}",
|
||||
"reducedMotion": "Mouvement réduit actif",
|
||||
"closeDialog": "Fermer la boîte de dialogue",
|
||||
"expandSection": "Déplier la section",
|
||||
"collapseSection": "Replier la section"
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"eyebrow": "Assurance / Historique immuable",
|
||||
"title": "Piste d'audit",
|
||||
"description": "Suivez les changements d'état importants, les acteurs et les références corrélées.",
|
||||
"actionFilterLabel": "Action",
|
||||
"actionFilterPlaceholder": "p. ex. demo_login",
|
||||
"managerOnly": "La piste d'audit est visible uniquement pour les Operations Managers.",
|
||||
"managerOnlyDetail": "L'historique d'audit est visible uniquement pour les Operations Managers.",
|
||||
"loading": "Chargement de la piste d'audit…",
|
||||
"unavailable": "La piste d'audit est actuellement indisponible.",
|
||||
"empty": "Aucun événement d'audit trouvé",
|
||||
"emptyDetail": "Ajustez le filtre d'action.",
|
||||
"relatedFilterActive": "Affichage uniquement des événements liés à cette action ({{count}} événements liés).",
|
||||
"clearFilter": "Effacer ce filtre",
|
||||
"count": "{{count}} événements",
|
||||
"storedRendered": "Stocké en UTC · Affiché en heure de Bruxelles",
|
||||
"columns": {
|
||||
"when": "Quand",
|
||||
"actor": "Acteur",
|
||||
"action": "Action",
|
||||
"entity": "Entité",
|
||||
"change": "Changement",
|
||||
"followUp": "Suite",
|
||||
"details": "Détails"
|
||||
},
|
||||
"viewRelatedEvents": "Voir les événements liés",
|
||||
"noChangeDetail": "Aucun détail de changement enregistré.",
|
||||
"noFieldChange": "Aucun changement au niveau des champs détecté.",
|
||||
"reference": "Référence",
|
||||
"relatedEventsCount": "{{count}} événement lié",
|
||||
"relatedEventsCount_other": "{{count}} événements liés",
|
||||
"showTechnicalEvents": "Afficher {{count}} événement technique",
|
||||
"showTechnicalEvents_other": "Afficher {{count}} événements techniques",
|
||||
"hideTechnicalEvents": "Masquer les événements techniques",
|
||||
"technicalDetails": "Détails techniques",
|
||||
"fullReference": "Référence complète",
|
||||
"correlationId": "ID de corrélation",
|
||||
"diff": {
|
||||
"setTo": "{{field}} : défini à {{value}}",
|
||||
"was": "{{field}} : était {{value}}",
|
||||
"changed": "{{field}} : {{before}} → {{after}}"
|
||||
},
|
||||
"actions": {
|
||||
"demo_login": "Connecté",
|
||||
"demo_logout": "Déconnecté",
|
||||
"demo_reset": "Données de démo réinitialisées",
|
||||
"demo_data_seeded": "Données de démo chargées",
|
||||
"return_registered": "Retour de véhicule enregistré",
|
||||
"vehicle_status_changed": "Statut du véhicule modifié",
|
||||
"data_quality_issue_resolved": "Problème de qualité résolu",
|
||||
"data_quality_issue_deferred": "Problème de qualité reporté",
|
||||
"data_quality_issue_rejected": "Problème de qualité rejeté",
|
||||
"data_quality_fields_provided": "Champs manquants complétés",
|
||||
"data_quality_odometer_corrected": "Kilométrage corrigé",
|
||||
"data_quality_odometer_retained": "Kilométrage de référence conservé",
|
||||
"data_quality_status_applied": "Statut recommandé appliqué",
|
||||
"data_quality_booking_blocked": "Réservation bloquée",
|
||||
"data_quality_scan_run": "Contrôle qualité exécuté",
|
||||
"customer_merged": "Clients fusionnés",
|
||||
"workflow_retry": "Automatisation retentée",
|
||||
"knowledge_question_asked": "Question de connaissance posée",
|
||||
"mcp_tool_request": "Outil MCP appelé"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"brandTagline": "Centre de contrôle",
|
||||
"orgLine": "Organisation de démo : {{orgName}} (fictive)",
|
||||
"headline1": "Chaque transfert.",
|
||||
"headline2": "Une vue claire.",
|
||||
"defaultDescription": "Fleet Ops rassemble les données de véhicules, de réservations et d'exploitation, soutient les processus de location, détecte les problèmes de qualité des données et automatise les suites contrôlées.",
|
||||
"footnote": "Démo synthétique · aucune donnée client ou véhicule réelle · réinitialisable à tout moment",
|
||||
"accessEyebrow": "Accès démo",
|
||||
"accessHeading": "Choisissez comment démarrer",
|
||||
"accessIntro": "Aucun mot de passe requis. Chaque rôle ouvre un environnement synthétique délimité — tous les workflows et contrôles sont réellement implémentés.",
|
||||
"startGuidedDemo": "Démarrer la démo guidée",
|
||||
"exploreAsOperationsManager": "Explorer en tant qu'Operations Manager",
|
||||
"exploreAsOperationsManagerDetail": "Vue d'ensemble complète, résolution qualité et nouvelles tentatives",
|
||||
"exploreAsRentalEmployee": "Explorer en tant que Rental Employee",
|
||||
"exploreAsRentalEmployeeDetail": "Réservations, retours, flotte et procédures",
|
||||
"safeByDesignTitle": "Conçu pour la sécurité",
|
||||
"safeByDesignDetail": "Chaque action est enregistrée et peut être réinitialisée dans cette démo.",
|
||||
"loginFailed": "La session de démo n'a pas pu démarrer. L'API est peut-être inaccessible.",
|
||||
"roleOperationsManager": "Operations manager",
|
||||
"roleRentalEmployee": "Rental employee",
|
||||
"switchRole": "Changer de rôle",
|
||||
"logout": "Déconnexion"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Exploitation / Planning",
|
||||
"title": "Réservations",
|
||||
"description": "Consultez les périodes de location actives et les engagements de véhicules à venir.",
|
||||
"searchLabel": "Rechercher",
|
||||
"searchPlaceholder": "Réservation, client ou véhicule",
|
||||
"statusLabel": "Statut",
|
||||
"statusAll": "Tous les statuts",
|
||||
"loading": "Chargement du registre des réservations…",
|
||||
"empty": "Aucune réservation trouvée",
|
||||
"emptyDetail": "Ajustez le filtre de statut des réservations.",
|
||||
"noMatch": "Aucune réservation correspondante",
|
||||
"noMatchDetail": "Essayez un terme de recherche plus large.",
|
||||
"unavailable": "La liste des réservations est actuellement indisponible.",
|
||||
"count": "{{count}} réservations",
|
||||
"pageOf": "Page {{page}} sur {{total}}",
|
||||
"columns": {
|
||||
"reference": "Référence",
|
||||
"customer": "Client",
|
||||
"vehicle": "Véhicule",
|
||||
"window": "Période",
|
||||
"status": "Statut"
|
||||
},
|
||||
"paginationLabel": "Pages de réservations",
|
||||
"previous": "Précédent",
|
||||
"next": "Suivant",
|
||||
"rangeOf": "{{from}}–{{to}} sur {{total}}"
|
||||
},
|
||||
"statuses": {
|
||||
"reserved": "réservé",
|
||||
"active": "actif",
|
||||
"returned": "retourné",
|
||||
"cancelled": "annulé",
|
||||
"blocked": "bloqué"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Registre des réservations",
|
||||
"eyebrow": "Réservations / Fiche de location",
|
||||
"notFound": "Cette réservation est introuvable.",
|
||||
"loading": "Chargement de la fiche de réservation…",
|
||||
"customer": "Client",
|
||||
"vehicle": "Véhicule",
|
||||
"starts": "Début",
|
||||
"ends": "Fin",
|
||||
"startOdometer": "Kilométrage de départ",
|
||||
"endOdometer": "Kilométrage de retour",
|
||||
"requirementsComplete": "Exigences complètes",
|
||||
"yes": "Oui",
|
||||
"no": "Non"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"appName": "Fleet Ops",
|
||||
"orgName": "Northstar Mobility",
|
||||
"brandTagline": "Centre de contrôle",
|
||||
"actions": {
|
||||
"save": "Enregistrer",
|
||||
"cancel": "Annuler",
|
||||
"confirm": "Confirmer",
|
||||
"close": "Fermer",
|
||||
"back": "Retour",
|
||||
"next": "Suivant",
|
||||
"retry": "Réessayer",
|
||||
"reset": "Réinitialiser",
|
||||
"yes": "Oui",
|
||||
"no": "Non",
|
||||
"viewDetails": "Voir les détails",
|
||||
"technicalDetails": "Détails techniques"
|
||||
},
|
||||
"status": {
|
||||
"loading": "Chargement…",
|
||||
"saving": "Enregistrement…",
|
||||
"error": "Une erreur est survenue",
|
||||
"success": "Réussi",
|
||||
"noResults": "Aucun résultat"
|
||||
},
|
||||
"states": {
|
||||
"loadingDefault": "Chargement de l'espace de travail…",
|
||||
"errorTitle": "Impossible de charger cet espace de travail."
|
||||
},
|
||||
"timezone": "Europe/Bruxelles",
|
||||
"language": {
|
||||
"label": "Langue",
|
||||
"nl-BE": "Nederlands",
|
||||
"en-GB": "English",
|
||||
"fr-BE": "Français"
|
||||
},
|
||||
"footer": {
|
||||
"productLine": "Fleet Ops Demo",
|
||||
"locale": "Europe/Bruxelles · Données de démonstration synthétiques"
|
||||
},
|
||||
"demo": {
|
||||
"syntheticBadge": "Démo synthétique"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"eyebrow": "Exploitation / Aperçu en direct",
|
||||
"title": "Bonjour. Voici votre flotte.",
|
||||
"description": "Disponibilité, exceptions et transferts de l'activité en cours.",
|
||||
"viewFleet": "Voir la flotte",
|
||||
"demoStart": {
|
||||
"title": "Essayer un scénario de démonstration",
|
||||
"readyCount": "{{ready}} scénarios sur {{total}} prêts pour la démo.",
|
||||
"readyCountFallback": "Cinq scénarios ciblés.",
|
||||
"startGuide": "Démarrer le guide de démo",
|
||||
"resumeGuide": "Poursuivre le guide de démo ({{current}}/{{total}})",
|
||||
"viewScenarios": "Voir les scénarios"
|
||||
},
|
||||
"readiness": {
|
||||
"title": "Disponibilité de la flotte",
|
||||
"description": "En direct depuis l'état persistant des véhicules",
|
||||
"openFleet": "Ouvrir la flotte",
|
||||
"available": "Disponible",
|
||||
"rented": "Loué",
|
||||
"cleaning": "Nettoyage",
|
||||
"maintenance": "Entretien",
|
||||
"blocked": "Bloqué"
|
||||
},
|
||||
"attention": {
|
||||
"title": "File d'attention",
|
||||
"description": "{{openIssues}} problèmes de qualité ouverts · {{workflowExceptions}} exceptions de workflow",
|
||||
"reviewQueue": "Examiner la file",
|
||||
"filterPlaceholder": "Filtrer les problèmes…",
|
||||
"filterAriaLabel": "Rechercher dans la file d'attention",
|
||||
"severityAll": "Toute gravité",
|
||||
"severityHigh": "Critique",
|
||||
"severityMedium": "Avertissement",
|
||||
"severityLow": "Info",
|
||||
"severityAriaLabel": "Gravité",
|
||||
"empty": "Aucun problème ne correspond à ce filtre.",
|
||||
"openRecord": "Ouvrir {{title}}"
|
||||
},
|
||||
"movements": {
|
||||
"title": "Mouvements du jour",
|
||||
"description": "Départs et retours en Europe/Bruxelles",
|
||||
"allBookings": "Toutes les réservations",
|
||||
"empty": "Aucun mouvement prévu aujourd'hui.",
|
||||
"departure": "départ",
|
||||
"return": "retour",
|
||||
"openBooking": "Ouvrir la réservation {{ref}}"
|
||||
},
|
||||
"integrationPulse": {
|
||||
"title": "État des intégrations",
|
||||
"description": "Preuves actuelles des services connectés",
|
||||
"systemDetail": "Détail du système",
|
||||
"n8nTitle": "Livraison n8n",
|
||||
"n8nSummary": "{{succeeded}} réussies · {{failed}} échouées",
|
||||
"n8nLatest": "Dernier événement {{ref}}",
|
||||
"n8nNoEvidence": "Aucune preuve d'automatisation enregistrée",
|
||||
"knowledgeTitle": "Assistant de connaissances",
|
||||
"knowledgeSummary": "{{count}} procédures indexées",
|
||||
"knowledgeUnavailable": "Vérification de santé indisponible",
|
||||
"mcpTitle": "MCP Hub",
|
||||
"mcpEnabled": "Enregistrement activé",
|
||||
"mcpNotConnected": "Pas encore connecté"
|
||||
},
|
||||
"recent": {
|
||||
"title": "Activité récente",
|
||||
"description": "Derniers changements de workflow audités",
|
||||
"empty": "Aucune activité d'automatisation enregistrée."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"badge": {
|
||||
"trigger": "Démo synthétique",
|
||||
"dialogLabel": "À propos de cet environnement de démo",
|
||||
"close": "Fermer",
|
||||
"orgIntro": "<strong>{{orgName}}</strong> est une organisation fictive. Tous les noms, véhicules et réservations sont synthétiques.",
|
||||
"orgIntroFallback": "Tous les noms, véhicules et réservations de cet environnement sont synthétiques.",
|
||||
"realWorkflows": "Les workflows, contrôles et l'automatisation sont réellement implémentés — seules les données sont inventées.",
|
||||
"lastReset": "Dernière réinitialisation : <strong>{{when}}</strong> · cet environnement peut être réinitialisé à tout moment.",
|
||||
"aboutLink": "À propos de cette démo",
|
||||
"unknown": "inconnu"
|
||||
},
|
||||
"guide": {
|
||||
"dialogLabel": "Démo guidée",
|
||||
"trigger": "Guide de démo",
|
||||
"kicker": "Démo guidée · étape {{current}} sur {{total}}",
|
||||
"whatYouWillSee": "Ce que vous allez voir",
|
||||
"whyItMatters": "Pourquoi c'est important",
|
||||
"startAction": "Pour commencer",
|
||||
"expectedOutcome": "Résultat attendu",
|
||||
"goToStep": "Aller à cette étape",
|
||||
"next": "Suivant",
|
||||
"close": "Fermer",
|
||||
"restart": "Préparer à nouveau la démo",
|
||||
"restarting": "Réinitialisation…",
|
||||
"restartFailed": "Impossible de réinitialiser la démo.",
|
||||
"allStepsLabel": "Toutes les étapes",
|
||||
"progressChip": "Guide de démo · étape {{current}} sur {{total}}",
|
||||
"expand": "Déplier le guide de démo",
|
||||
"collapse": "Replier le guide de démo",
|
||||
"steps": {
|
||||
"understand-state": {
|
||||
"title": "1. Comprendre l'état opérationnel",
|
||||
"whatYouWillSee": "Le tableau de bord affiche la disponibilité de la flotte, les points d'attention ouverts et les mouvements du jour.",
|
||||
"whyItMatters": "Un Operations Manager commence chaque journée par cet aperçu pour décider où intervenir.",
|
||||
"startAction": "Ouvrez le tableau de bord et consultez la file d'attention et la chronologie du jour.",
|
||||
"expectedOutcome": "Vous voyez quelles réservations, véhicules ou problèmes de qualité nécessitent de l'attention."
|
||||
},
|
||||
"open-booking": {
|
||||
"title": "2. Ouvrir la réservation nécessitant de l'attention",
|
||||
"whatYouWillSee": "La réservation BK-DEMO-RETURN, active et à retourner aujourd'hui.",
|
||||
"whyItMatters": "Les retours sont le moment où les kilométrages incorrects ou les dommages deviennent visibles pour la première fois.",
|
||||
"startAction": "Ouvrez la réservation depuis le tableau de bord ou la liste des réservations.",
|
||||
"expectedOutcome": "Vous voyez les détails de la réservation et le bouton pour traiter le retour."
|
||||
},
|
||||
"process-return": {
|
||||
"title": "3. Traiter un retour avec une anomalie de kilométrage",
|
||||
"whatYouWillSee": "Un formulaire de retour pré-rempli avec un relevé de kilométrage suspect, inférieur au dernier relevé connu.",
|
||||
"whyItMatters": "Un kilométrage en baisse signale une erreur de saisie ou un véhicule confondu — cela doit être détecté avant la libération.",
|
||||
"startAction": "Soumettez le retour avec la valeur suggérée et examinez l'aperçu du serveur avant de confirmer.",
|
||||
"expectedOutcome": "Le retour est traité, le véhicule reçoit un statut approprié, et un problème de qualité des données est créé automatiquement."
|
||||
},
|
||||
"handle-quality-issue": {
|
||||
"title": "4. Traiter le problème de qualité créé",
|
||||
"whatYouWillSee": "Un nouveau problème « anomalie de kilométrage » en haut de la file de travail.",
|
||||
"whyItMatters": "Chaque problème détecté a une étape de résolution unique et délimitée — rien n'est corrigé automatiquement en silence.",
|
||||
"startAction": "Ouvrez l'aperçu qualité des données et choisissez le problème le plus récent.",
|
||||
"expectedOutcome": "Vous voyez l'action recommandée, choisissez une résolution, et le problème se résout avec une piste d'audit."
|
||||
},
|
||||
"merge-duplicate": {
|
||||
"title": "5. Examiner et traiter un client potentiellement en double",
|
||||
"whatYouWillSee": "Deux profils clients avec le même e-mail et numéro de téléphone, comparés côte à côte.",
|
||||
"whyItMatters": "Les clients en double divisent l'historique de réservation et compliquent la communication.",
|
||||
"startAction": "Comparez les deux profils et choisissez celui qui doit survivre.",
|
||||
"expectedOutcome": "Les profils sont fusionnés, les réservations sont transférées, et le profil perdant devient une fiche archivée."
|
||||
},
|
||||
"ask-knowledge": {
|
||||
"title": "6. Poser une question à l'assistant de procédures",
|
||||
"whatYouWillSee": "Une réponse avec citation issue de la base de connaissances de démo délimitée.",
|
||||
"whyItMatters": "Le personnel a besoin d'une réponse rapide et étayée sur les procédures, sans deviner.",
|
||||
"startAction": "Cliquez sur l'une des questions suggérées, dans la langue actuelle de l'interface.",
|
||||
"expectedOutcome": "Vous voyez la réponse, la procédure utilisée et le texte source — ou un honnête « informations insuffisantes » si aucune n'existe."
|
||||
},
|
||||
"check-automation-audit": {
|
||||
"title": "7. Vérifier l'automatisation et la piste d'audit",
|
||||
"whatYouWillSee": "Le statut de livraison de la tâche d'automatisation de votre retour, et ses événements d'audit liés.",
|
||||
"whyItMatters": "Chaque action importante doit être traçable : qui a fait quoi, quand, et ce qui a suivi.",
|
||||
"startAction": "Ouvrez Intégrations pour voir le statut de livraison, et Piste d'audit pour l'historique complet.",
|
||||
"expectedOutcome": "Vous voyez une livraison réussie (ou récupérable) et une piste d'audit lisible de vos actions."
|
||||
},
|
||||
"review-real-vs-simulated": {
|
||||
"title": "8. Passer en revue ce qui est réel, simulé ou pas encore connecté",
|
||||
"whatYouWillSee": "Un aperçu de ce qui est fonctionnellement implémenté dans cette démo, ce qui est synthétique, et quelles intégrations ne sont pas encore en direct.",
|
||||
"whyItMatters": "Une démo n'est convaincante que si les visiteurs peuvent vérifier eux-mêmes ce qui fonctionne réellement et ce qui reste à venir.",
|
||||
"startAction": "Lisez la page « À propos de cette démo ».",
|
||||
"expectedOutcome": "Vous pouvez expliquer vous-même ce que Fleet Ops est et n'est pas, sans explication verbale nécessaire."
|
||||
}
|
||||
}
|
||||
},
|
||||
"scenarios": {
|
||||
"eyebrow": "Scénarios de démonstration",
|
||||
"title": "Essayer un scénario de démonstration",
|
||||
"description": "Cinq scénarios ciblés qui utilisent toujours les mêmes réservations, clients et véhicules fixes — toujours retrouvables après une réinitialisation.",
|
||||
"loading": "Chargement des scénarios…",
|
||||
"ready": "Prêt pour la démo",
|
||||
"notReady": "Non disponible",
|
||||
"duration": "Durée",
|
||||
"durationValue": "± {{minutes}} min",
|
||||
"role": "Rôle",
|
||||
"demonstrates": "Démontre :",
|
||||
"requiresRole": "Nécessite le rôle : {{roles}}.",
|
||||
"startScenario": "Démarrer le scénario",
|
||||
"roleOr": "{{a}} ou {{b}}",
|
||||
"roles": {
|
||||
"operations_manager": "Operations Manager",
|
||||
"rental_employee": "Rental Employee"
|
||||
},
|
||||
"items": {
|
||||
"return-anomaly": {
|
||||
"title": "Retour avec anomalie de kilométrage",
|
||||
"problem": "Un véhicule revient avec un relevé de kilométrage inférieur au dernier relevé enregistré — un signe d'erreur de saisie ou de véhicule confondu.",
|
||||
"demonstrates": "Le traitement du retour, la détection automatique de problèmes de qualité des données et la piste d'audit qui en résulte."
|
||||
},
|
||||
"duplicate-customer": {
|
||||
"title": "Fusionner un possible client en double",
|
||||
"problem": "Deux fiches client partagent la même adresse e-mail et le même numéro de téléphone — probablement la même personne, enregistrée deux fois.",
|
||||
"demonstrates": "La fusion de clients avec conservation de l'historique des réservations et de la piste d'audit."
|
||||
},
|
||||
"booking-overlap": {
|
||||
"title": "Résoudre des réservations qui se chevauchent",
|
||||
"problem": "Un véhicule est réservé en double pour des périodes qui se chevauchent — une erreur de planification à résoudre avant le départ.",
|
||||
"demonstrates": "La détection et la résolution contrôlée des conflits de planification."
|
||||
},
|
||||
"automation-retry": {
|
||||
"title": "Relancer une tâche d'automatisation échouée",
|
||||
"problem": "Un événement précédent n'a pas pu être livré à l'automatisation en raison d'une erreur de connexion simulée.",
|
||||
"demonstrates": "Une livraison fiable avec des nouvelles tentatives limitées et un statut d'échec visible."
|
||||
},
|
||||
"knowledge-question": {
|
||||
"title": "Poser une question de procédure",
|
||||
"problem": "Un employé n'est pas sûr de la procédure applicable à une situation opérationnelle précise.",
|
||||
"demonstrates": "Des réponses étayées par les sources, issues d'une base de connaissances de démo délimitée."
|
||||
}
|
||||
},
|
||||
"blockedReasons": {
|
||||
"bookingNotFound": "Réservation de démo BK-DEMO-RETURN introuvable. {{resetHint}}",
|
||||
"bookingAlreadyProcessed": "Cette réservation a déjà été traitée depuis la dernière réinitialisation. {{resetHint}}",
|
||||
"duplicateIssueNotFound": "Problème de démo DQ-DEMO-DUPLICATE introuvable. {{resetHint}}",
|
||||
"issueAlreadyResolved": "Ce problème a déjà été résolu depuis la dernière réinitialisation. {{resetHint}}",
|
||||
"overlapIssueNotFound": "Problème de démo DQ-DEMO-OVERLAP introuvable. {{resetHint}}",
|
||||
"failedEventNotFound": "L'événement simulé en échec est introuvable. {{resetHint}}",
|
||||
"eventAlreadyRecovered": "Cet événement a déjà été rétabli depuis la dernière réinitialisation. {{resetHint}}",
|
||||
"knowledgeUnavailable": "La base de connaissances de démo est actuellement indisponible.",
|
||||
"resetHint": "Réinitialisez les données de démo pour rendre ce scénario à nouveau disponible."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"eyebrow": "À propos de cette démo",
|
||||
"title": "Ce que Fleet Ops est et n'est pas",
|
||||
"description": "{{orgName}} est une organisation de location fictive qui rend cette démo concrète — pas une véritable entreprise.",
|
||||
"loading": "Chargement des informations de démo…",
|
||||
"ctaTitle": "Vous préférez vous lancer directement ?",
|
||||
"ctaBody": "La démo guidée parcourt les huit étapes ci-dessus en pratique.",
|
||||
"ctaButton": "Démarrer la démo guidée",
|
||||
"problemTitle": "Le problème fictif",
|
||||
"problemBody": "{{orgName}} loue environ 50 campings-cars et fourgonnettes depuis un site principal. Les réservations, retours, fiches clients et l'entretien vivaient jusqu'ici dans des feuilles de calcul séparées et des échanges verbaux, si bien que les problèmes (clients en double, kilométrages incorrects, véhicules réservés en double) n'apparaissaient que tardivement. Fleet Ops montre comment un système unique et connecté signale ces problèmes tôt et permet de les résoudre de façon contrôlée.",
|
||||
"scopeTitle": "Pour qui et avec quelle portée",
|
||||
"scopeBody": "Cette démo s'adresse à quiconque veut voir comment Fleet Ops traite les problèmes opérationnels d'un petit loueur : Operations Managers et Rental Employees, et toute personne évaluant l'approche. La portée est délibérément limitée à une preuve de concept unique et cohérente — pas de comptabilité, pas de paiements, pas de réservations publiques, pas de CRM ou ERP complet.",
|
||||
"realTitle": "Ce qui fonctionne réellement",
|
||||
"realBody": "Tout ce qui suit est du code fonctionnel, pas seulement une maquette : accès et sessions basés sur les rôles, gestion des véhicules et réservations, traitement des retours avec validation côté serveur, cinq règles de qualité des données avec chacune sa propre étape de résolution, une piste d'audit complète, une livraison automatisée vers n8n avec nouvelles tentatives limitées, un déploiement basé sur Docker, et une suite de tests automatisés (backend et Playwright de bout en bout).",
|
||||
"syntheticTitle": "Ce qui est synthétique",
|
||||
"syntheticBody": "L'organisation, tous les clients, véhicules, réservations, historiques d'entretien, procédures de la base de connaissances et les scénarios préconfigurés sont entièrement inventés. Aucune donnée ne fait référence à une personne, un véhicule ou une entreprise réels ; les adresses e-mail utilisent uniquement le domaine de test {{testDomain}}.",
|
||||
"architectureTitle": "Architecture en bref",
|
||||
"architectureBody": "Un frontend React/TypeScript communique avec un backend FastAPI (PostgreSQL via des migrations SQLAlchemy/Alembic) ; les règles métier importantes vivent dans le backend, pas dans n8n ni dans des prompts. Les retours et autres événements sont d'abord validés localement, puis livrés de façon asynchrone à n8n via une tâche d'automatisation, de sorte qu'une panne temporaire de l'automatisation ne bloque jamais une action opérationnelle.",
|
||||
"securityTitle": "Sécurité et accès",
|
||||
"securityBody": "L'accès passe par des cookies de session signés, HTTP-only, par rôle ; chaque rôle est lié à un ensemble de routes autorisées, appliqué côté serveur et reflété dans la navigation. Les changements d'état importants sont toujours vérifiés et enregistrés — jamais corrigés automatiquement en silence.",
|
||||
"testingTitle": "Comment cela est testé",
|
||||
"testingBody": "Une suite de tests backend automatisée couvre les règles métier et les contrats d'API ; une suite Playwright de bout en bout complète couvre les parcours utilisateurs, y compris cette expérience de démo elle-même en trois langues. Chaque modification est également validée sur une installation propre (base de données vide, reconstruite à partir des données initiales) avant le déploiement.",
|
||||
"integrationsTitle": "Intégrations — étiquetées honnêtement",
|
||||
"integrationsDescription": "Ce qui est opérationnel, ce qui est en mode démo, et ce qui n'est pas encore connecté.",
|
||||
"resetTitle": "Restaurer l'environnement de démo",
|
||||
"resetBodyManager": "L'environnement peut être réinitialisé à son état de départ à tout moment. Dernière réinitialisation : <strong>{{when}}</strong>. Utilisez <strong>Réinitialiser les données de démo</strong> dans la barre latérale pour recommencer.",
|
||||
"resetBodyEmployee": "L'environnement peut être réinitialisé à son état de départ à tout moment. Dernière réinitialisation : <strong>{{when}}</strong>. Un Operations Manager peut réinitialiser l'environnement de démo via la barre latérale.",
|
||||
"limitationsTitle": "Limitations",
|
||||
"limitationsBody": "Ceci est une preuve de concept ciblée, pas un ERP complet. RAGcore et l'ITWorx MCP Hub ne sont pas encore connectés en direct ; l'assistant de connaissances utilise une base de connaissances de démo locale et délimitée au lieu d'un environnement RAGcore en direct.",
|
||||
"unknown": "inconnu"
|
||||
},
|
||||
"integrationSummary": {
|
||||
"titles": {
|
||||
"n8n": "Automatisation (n8n)",
|
||||
"ragcore": "Assistant de connaissances (RAGcore)",
|
||||
"mcp_hub": "ITWorx MCP Hub"
|
||||
},
|
||||
"n8nDetail": "{{succeeded}} réussi(s) · {{failed}} échoué(s) · {{pending}} en attente.",
|
||||
"ragcoreDetail": "{{count}} procédures indexées dans {{collection}}.",
|
||||
"mcpDetailEnabled": "Préparé pour de futurs appels d'outils contrôlés depuis le Hub.",
|
||||
"mcpDetailNotConnected": "Pas encore connecté — préparé pour de futurs appels d'outils contrôlés depuis le Hub."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"generic": "Une erreur est survenue. Veuillez réessayer.",
|
||||
"workspaceLoadFailed": "Nous n'avons pas pu charger cet espace de travail.",
|
||||
"unauthorized": "Votre session a expiré. Veuillez vous reconnecter.",
|
||||
"forbidden": "Vous n'avez pas accès à cette section.",
|
||||
"notFound": "Cette fiche est introuvable.",
|
||||
"networkUnavailable": "La connexion au serveur est actuellement indisponible."
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Flotte / Registre",
|
||||
"title": "Flotte de véhicules",
|
||||
"description": "État opérationnel en direct, localisation et disponibilité pour l'entretien.",
|
||||
"searchLabel": "Rechercher",
|
||||
"searchPlaceholder": "Référence, marque ou localisation",
|
||||
"statusLabel": "Statut",
|
||||
"statusAll": "Tous les statuts",
|
||||
"attentionOnly": "Attention uniquement",
|
||||
"loading": "Chargement du registre de la flotte…",
|
||||
"empty": "Aucun véhicule trouvé",
|
||||
"emptyDetail": "Ajustez les filtres de flotte actuels.",
|
||||
"noMatch": "Aucun véhicule correspondant",
|
||||
"noMatchDetail": "Essayez un terme de recherche plus large.",
|
||||
"unavailable": "La liste des véhicules est actuellement indisponible.",
|
||||
"count": "{{count}} véhicules",
|
||||
"persisted": "Données de flotte persistantes",
|
||||
"columns": {
|
||||
"reference": "Référence",
|
||||
"makeModel": "Marque / modèle",
|
||||
"location": "Localisation",
|
||||
"status": "Statut",
|
||||
"odometer": "Kilométrage (km)",
|
||||
"attention": "Attention"
|
||||
},
|
||||
"needsAttention": "Nécessite de l'attention"
|
||||
},
|
||||
"statuses": {
|
||||
"available": "disponible",
|
||||
"rented": "loué",
|
||||
"cleaning": "nettoyage",
|
||||
"maintenance": "entretien",
|
||||
"blocked": "bloqué"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Registre de la flotte",
|
||||
"eyebrow": "Flotte / Fiche véhicule",
|
||||
"notFound": "Ce véhicule est introuvable.",
|
||||
"loading": "Chargement de la fiche véhicule…",
|
||||
"needsAttention": "Nécessite de l'attention",
|
||||
"tabs": {
|
||||
"overview": "Aperçu",
|
||||
"bookings": "Réservations",
|
||||
"inspections": "Inspections",
|
||||
"maintenance": "Entretien",
|
||||
"quality": "Qualité"
|
||||
},
|
||||
"tabsAriaLabel": "Sections du véhicule",
|
||||
"overview": {
|
||||
"registration": "Immatriculation",
|
||||
"modelYear": "Année du modèle",
|
||||
"location": "Localisation",
|
||||
"odometer": "Kilométrage",
|
||||
"nextService": "Prochain entretien",
|
||||
"active": "Actif"
|
||||
},
|
||||
"yes": "Oui",
|
||||
"no": "Non",
|
||||
"noBookings": "Aucune réservation enregistrée.",
|
||||
"noInspections": "Aucune inspection enregistrée.",
|
||||
"noMaintenance": "Aucun historique d'entretien.",
|
||||
"noQualityIssues": "Aucun problème de qualité enregistré.",
|
||||
"fuel": "Carburant {{percent}}%",
|
||||
"damage": "Dommage",
|
||||
"technicalWarning": "Avertissement technique"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"eyebrow": "Assurance / Intégrations",
|
||||
"title": "Contrôle des intégrations",
|
||||
"description": "Surveillez la santé des livraisons, la dégradation contrôlée et les événements de workflow réessayables.",
|
||||
"cards": {
|
||||
"orchestrationKicker": "Orchestration",
|
||||
"n8nTitle": "Livraison n8n",
|
||||
"n8nSummary": "{{succeeded}} réussies · {{failed}} échouées · {{pending}} en attente · {{delivering}} en cours",
|
||||
"n8nFallback": "Les événements de retour sont d'abord validés localement, puis livrés via la tâche d'automatisation.",
|
||||
"knowledgeKicker": "Connaissances",
|
||||
"knowledgeTitle": "Assistant de connaissances",
|
||||
"knowledgeSummaryDemo": "Base de connaissances de démo · {{count}} procédures indexées dans {{collection}}.",
|
||||
"knowledgeSummaryRagcore": "RAGcore · {{count}} procédures indexées dans {{collection}}.",
|
||||
"knowledgeUnavailable": "Preuves de santé actuellement indisponibles.",
|
||||
"gatewayKicker": "Passerelle d'outils",
|
||||
"mcpTitle": "MCP Hub",
|
||||
"mcpEnabled": "L'enregistrement est activé pour ce déploiement.",
|
||||
"mcpNotConnected": "Pas encore connecté — préparé pour de futurs appels d'outils contrôlés depuis le Hub."
|
||||
},
|
||||
"statusLabels": {
|
||||
"notConnected": "Non connecté",
|
||||
"deliveryFailed": "Livraison échouée",
|
||||
"retryAvailable": "Nouvelle tentative possible",
|
||||
"operational": "Opérationnel",
|
||||
"prepared": "Préparé",
|
||||
"demoMode": "Mode démo",
|
||||
"unavailable": "Indisponible"
|
||||
},
|
||||
"ledger": {
|
||||
"title": "Tâches d'automatisation",
|
||||
"description": "Tentatives d'automatisation enregistrées avec les dernières preuves d'échec.",
|
||||
"filterLabel": "Vue",
|
||||
"filterNeedsAttention": "Nécessite de l'attention",
|
||||
"filterRecent": "Récent",
|
||||
"filterSucceeded": "Réussi",
|
||||
"filterAll": "Tout",
|
||||
"statusFilterLabel": "Statut",
|
||||
"statusAll": "Tous les statuts",
|
||||
"statusPending": "En attente",
|
||||
"statusDelivering": "En cours",
|
||||
"statusSucceeded": "Réussi",
|
||||
"statusFailed": "Échoué",
|
||||
"unavailable": "Les tâches d'automatisation sont actuellement indisponibles.",
|
||||
"managerOnly": "L'automatisation est visible uniquement pour les Operations Managers.",
|
||||
"loading": "Chargement des tâches d'automatisation…",
|
||||
"empty": "Aucune tâche d'automatisation ne correspond à ce filtre.",
|
||||
"count": "{{count}} événements de workflow",
|
||||
"boundedRetries": "Nouvelles tentatives limitées",
|
||||
"groupedSucceeded": "{{count}} retours de véhicules traités avec succès",
|
||||
"showIndividually": "Afficher les tâches individuelles",
|
||||
"hideIndividually": "Masquer les tâches individuelles",
|
||||
"columns": {
|
||||
"event": "Tâche",
|
||||
"type": "Type",
|
||||
"booking": "Réservation",
|
||||
"status": "Statut",
|
||||
"attempts": "Tentatives",
|
||||
"lastError": "Dernière erreur",
|
||||
"when": "Quand",
|
||||
"action": "Action"
|
||||
},
|
||||
"retry": "Réessayer",
|
||||
"retrying": "Nouvelle tentative…",
|
||||
"retryFailed": "Impossible de réessayer cette livraison.",
|
||||
"noAction": "—",
|
||||
"eventTypes": {
|
||||
"vehicle.returned.v1": "Retour de véhicule traité"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"eyebrow": "Assurance / Connaissances étayées",
|
||||
"title": "Connaissance des procédures",
|
||||
"description": "Posez des questions opérationnelles. Les réponses ne s'affichent que lorsque {{provider}} renvoie suffisamment de preuves citées.",
|
||||
"providerDemo": "la base de connaissances de démo",
|
||||
"providerRagcore": "RAGcore",
|
||||
"statusAvailable": "Disponible",
|
||||
"statusUnavailable": "Indisponible",
|
||||
"proceduresIndexed": "{{count}} procédures indexées",
|
||||
"providerNote": "Cette démo répond à partir d'un petit ensemble fixe de procédures indexées — pas d'une connexion RAGcore en direct. Un backend RAGcore en direct reprendra plus tard la même interface sans changer le fonctionnement de cette page.",
|
||||
"askHeading": "Poser une question de procédure",
|
||||
"askSubheading": "Recherche → vérification des preuves → réponse étayée",
|
||||
"questionLabel": "Question",
|
||||
"questionPlaceholder": "p. ex. Que dois-je faire quand un véhicule revient endommagé ?",
|
||||
"ask": "Demander",
|
||||
"asking": "Question en cours…",
|
||||
"askFailed": "Impossible de joindre le service de connaissances.",
|
||||
"suggestedLabel": "Essayez :",
|
||||
"suggestedQuestions": [
|
||||
"Que dois-je faire quand un véhicule revient avec des dommages ?",
|
||||
"Comment enregistrer le retour d'un véhicule ?",
|
||||
"Quand un véhicule peut-il redevenir disponible ?",
|
||||
"Qui examine un relevé de kilométrage inhabituel ?",
|
||||
"Quels contrôles sont requis avant le départ ?"
|
||||
],
|
||||
"emptyTitle": "Des preuves avant les réponses",
|
||||
"emptyDescription": "Posez des questions sur les retours, les dommages, les inspections ou une autre procédure indexée. Fleet Ops n'invente jamais de réponse en l'absence de preuves.",
|
||||
"retrievalFlow": {
|
||||
"question": "Question",
|
||||
"sources": "Sources",
|
||||
"answer": "Réponse"
|
||||
},
|
||||
"questionLabelExchange": "Question",
|
||||
"evidenceStates": {
|
||||
"grounded": "Étayé par des procédures citées",
|
||||
"insufficient": "Preuves insuffisantes",
|
||||
"unavailable": "Service de connaissances indisponible"
|
||||
},
|
||||
"unavailableBody": "Le service de connaissances est actuellement inaccessible. Les fonctions opérationnelles ne sont pas affectées — réessayez plus tard.",
|
||||
"sourceVersion": "v{{version}}"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"skipToContent": "Aller au contenu principal",
|
||||
"groups": {
|
||||
"operate": "Exploiter",
|
||||
"assure": "Assurer"
|
||||
},
|
||||
"items": {
|
||||
"overview": "Aperçu",
|
||||
"fleet": "Flotte",
|
||||
"bookings": "Réservations",
|
||||
"quality": "Qualité des données",
|
||||
"knowledge": "Connaissances",
|
||||
"integrations": "Intégrations",
|
||||
"audit": "Piste d'audit"
|
||||
},
|
||||
"primaryNavLabel": "Navigation principale",
|
||||
"mobileNavLabel": "Navigation mobile",
|
||||
"more": "Plus",
|
||||
"openNavigation": "Ouvrir la navigation",
|
||||
"closeNavigation": "Fermer la navigation",
|
||||
"sidebarEnvironment": "Environnement de démo",
|
||||
"sidebarEnvironmentDetail": "Données synthétiques uniquement",
|
||||
"resetDemoData": "Réinitialiser les données de démo",
|
||||
"resetConfirmTitle": "Confirmer la réinitialisation",
|
||||
"resetConfirmBody": "Toutes les modifications synthétiques seront annulées et les données de démo déterministes restaurées. Vous serez déconnecté.",
|
||||
"resetting": "Réinitialisation…",
|
||||
"resetConfirmYes": "Oui, réinitialiser",
|
||||
"resetCancel": "Annuler",
|
||||
"resetFailed": "Impossible de réinitialiser les données de démo.",
|
||||
"searchLabel": "Rechercher dans Fleet Ops",
|
||||
"searchPlaceholder": "Rechercher flotte, réservation ou section…",
|
||||
"searchShortcutHint": "Ctrl K",
|
||||
"searchSearching": "Recherche…",
|
||||
"searchUnavailable": "La recherche est momentanément indisponible.",
|
||||
"searchNoResults": "Aucun résultat pour « {{query}} ».",
|
||||
"switchRole": "Changer de rôle",
|
||||
"switchRoleTitle": "Changer de rôle de démo",
|
||||
"languageSwitcherLabel": "Changer de langue"
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Assurance / Atelier",
|
||||
"title": "Qualité des données",
|
||||
"description": "Résolvez les exceptions étayées par des preuves avant qu'elles ne perturbent l'exploitation.",
|
||||
"runScan": "Lancer le contrôle qualité",
|
||||
"confirmScanTitle": "Confirmer le contrôle qualité",
|
||||
"confirmScanBody": "Lancer maintenant le contrôle déterministe sur les cinq types de règles ?",
|
||||
"scanning": "Analyse en cours…",
|
||||
"confirmScanYes": "Oui, lancer",
|
||||
"cancel": "Annuler",
|
||||
"scanComplete": "Contrôle terminé : {{summary}}",
|
||||
"scanNoNew": "aucun nouveau problème trouvé (les problèmes ouverts existants ne sont pas recréés).",
|
||||
"scanFailed": "Impossible d'exécuter le contrôle qualité.",
|
||||
"statusLabel": "Statut",
|
||||
"statusAll": "Tous les statuts",
|
||||
"statusOpen": "Ouvert",
|
||||
"statusDeferred": "Reporté",
|
||||
"statusResolved": "Résolu",
|
||||
"statusRejected": "Rejeté",
|
||||
"ruleTypeLabel": "Type de règle",
|
||||
"ruleTypeAll": "Tous les types de règles",
|
||||
"demoScenariosOnly": "Scénarios de démo uniquement",
|
||||
"loading": "Chargement de l'atelier qualité…",
|
||||
"queueClear": "La file est vide",
|
||||
"noIssuesMatch": "Aucun problème ne correspond aux filtres actuels.",
|
||||
"noDemoIssuesMatch": "Aucun problème de scénario de démo ne correspond",
|
||||
"noDemoIssuesMatchDetail": "Décochez « Scénarios de démo uniquement » pour voir la file complète.",
|
||||
"unavailable": "Les problèmes de qualité des données sont actuellement indisponibles.",
|
||||
"count": "{{count}} problèmes",
|
||||
"evidenceBacked": "Détection étayée par des preuves",
|
||||
"columns": {
|
||||
"reference": "Référence",
|
||||
"rule": "Règle",
|
||||
"entity": "Entité",
|
||||
"severity": "Gravité",
|
||||
"status": "Statut"
|
||||
}
|
||||
},
|
||||
"ruleTypes": {
|
||||
"possible_duplicate_customer": "Client peut-être en double",
|
||||
"missing_required_field": "Champ obligatoire manquant",
|
||||
"odometer_regression": "Anomalie de kilométrage",
|
||||
"booking_overlap": "Chevauchement de réservations",
|
||||
"vehicle_status_conflict": "Conflit de statut du véhicule"
|
||||
},
|
||||
"severities": {
|
||||
"high": "Critique",
|
||||
"medium": "Avertissement",
|
||||
"low": "Info"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Atelier qualité",
|
||||
"eyebrow": "Qualité / {{rule}}",
|
||||
"title": "Examinez les preuves enregistrées et consignez une résolution auditée.",
|
||||
"notFound": "Ce problème est introuvable.",
|
||||
"loading": "Chargement des preuves du problème…",
|
||||
"managerOnly": "L'atelier qualité est visible uniquement pour les Operations Managers.",
|
||||
"managerOnlyDetail": "Les preuves et résolutions de qualité des données sont visibles uniquement pour les Operations Managers.",
|
||||
"summary": {
|
||||
"rule": "Règle",
|
||||
"entity": "Entité",
|
||||
"evidenceSummary": "Résumé des preuves"
|
||||
},
|
||||
"resolved": {
|
||||
"title": "Problème {{ref}} résolu",
|
||||
"body": "La modification a été appliquée et enregistrée dans la piste d'audit.",
|
||||
"viewAudit": "Voir la piste d'audit",
|
||||
"viewVehicle": "Voir le véhicule",
|
||||
"continueDemo": "Poursuivre la démo"
|
||||
},
|
||||
"deferOrReject": {
|
||||
"heading": "Reporter ou rejeter",
|
||||
"description": "Reportez pour un examen ultérieur, ou rejetez si ce n'est pas un véritable problème.",
|
||||
"defer": "Reporter",
|
||||
"reject": "Rejeter",
|
||||
"deferFailed": "Impossible de reporter ce problème.",
|
||||
"rejectFailed": "Impossible de rejeter ce problème."
|
||||
},
|
||||
"explainer": {
|
||||
"whatIsWrong": "Ce qui ne va pas",
|
||||
"whyItMatters": "Pourquoi c'est important",
|
||||
"possible_duplicate_customer": {
|
||||
"whatIsWrong": "Deux profils clients partagent des données d'identification (e-mail, téléphone ou un nom très similaire) suffisamment fortement pour qu'il s'agisse probablement de la même personne, enregistrée deux fois.",
|
||||
"whyItMatters": "Les clients en double répartissent l'historique de réservation entre deux fiches, risquent une double facturation et compliquent les échanges avec le support."
|
||||
},
|
||||
"missing_required_field": {
|
||||
"whatIsWrong": "Cette fiche manque d'informations requises pour un fonctionnement normal (par exemple, un client sans e-mail ni numéro de téléphone enregistré).",
|
||||
"whyItMatters": "Sans ces données, l'entreprise ne peut pas contacter le client, ni identifier de façon fiable le véhicule pour les contrôles de conformité et de remise."
|
||||
},
|
||||
"odometer_regression": {
|
||||
"whatIsWrong": "Un relevé de kilométrage soumis est inférieur au dernier relevé connu (de référence) du véhicule.",
|
||||
"whyItMatters": "Un kilométrage en baisse signifie généralement une erreur de saisie ou que les relevés ont été enregistrés pour le mauvais véhicule. Laisser passer cela silencieusement corromprait la planification de l'entretien et l'historique kilométrique à la revente."
|
||||
},
|
||||
"booking_overlap": {
|
||||
"whatIsWrong": "Le même véhicule est engagé sur deux réservations dont les périodes se chevauchent.",
|
||||
"whyItMatters": "Une seule de ces réservations peut réellement être honorée. Non résolu, un client arriverait pour constater que son véhicule est déjà chez quelqu'un d'autre."
|
||||
},
|
||||
"vehicle_status_conflict": {
|
||||
"whatIsWrong": "Le statut opérationnel enregistré de ce véhicule ne correspond pas à ce que son propre historique de réservations et d'inspections implique.",
|
||||
"whyItMatters": "Un statut incorrect peut faire apparaître un véhicule indisponible comme réservable, ou masquer un véhicule disponible de la flotte."
|
||||
}
|
||||
},
|
||||
"duplicateCustomer": {
|
||||
"heading": "Comparer et fusionner",
|
||||
"description": "Choisissez le client de référence et examinez chaque champ divergent.",
|
||||
"keepAsSurvivor": "Conserver comme fiche principale",
|
||||
"differs": "Diffère",
|
||||
"match": "Identique",
|
||||
"mergePreview": "{{loser}} deviendra une fiche archivée liée à {{survivor}} ; ses réservations seront transférées.",
|
||||
"mergeInto": "Fusionner avec {{ref}}",
|
||||
"confirmMergeTitle": "Confirmer la fusion",
|
||||
"confirmMergeBody": "Fusionner {{loser}} avec {{survivor}} ? Cette action est irréversible.",
|
||||
"merging": "Fusion en cours…",
|
||||
"confirmMergeYes": "Oui, fusionner",
|
||||
"mergeFailed": "Impossible de fusionner ces clients.",
|
||||
"bothMissing": "Les deux clients de cette comparaison n'ont pas pu être chargés.",
|
||||
"fieldColumn": "Champ",
|
||||
"fields": {
|
||||
"first_name": "Prénom",
|
||||
"last_name": "Nom",
|
||||
"email": "E-mail",
|
||||
"phone": "Téléphone",
|
||||
"postal_code": "Code postal",
|
||||
"city": "Ville"
|
||||
}
|
||||
},
|
||||
"missingField": {
|
||||
"heading": "Compléter les champs manquants",
|
||||
"description": "Complétez la fiche pour {{ref}}. Le problème se résout automatiquement dès qu'aucune donnée requise ne manque.",
|
||||
"atLeastOne": "Au moins un e-mail ou un numéro de téléphone est requis.",
|
||||
"saveAndRecheck": "Enregistrer et revérifier",
|
||||
"saving": "Enregistrement…",
|
||||
"saveFailed": "Impossible d'enregistrer ces champs.",
|
||||
"fields": {
|
||||
"first_name": "Prénom",
|
||||
"last_name": "Nom",
|
||||
"email": "E-mail",
|
||||
"phone": "Téléphone",
|
||||
"registration_number": "Numéro d'immatriculation",
|
||||
"make": "Marque",
|
||||
"model": "Modèle",
|
||||
"location": "Localisation"
|
||||
}
|
||||
},
|
||||
"odometerRegression": {
|
||||
"heading": "Résoudre l'anomalie de kilométrage",
|
||||
"description": "Le kilométrage de référence n'est jamais abaissé automatiquement — choisissez comment le régulariser.",
|
||||
"canonicalOdometer": "Kilométrage de référence",
|
||||
"decisionLegend": "Décision",
|
||||
"retainCanonical": "Conserver le relevé de référence",
|
||||
"retainCanonicalDetail": "Considérer le relevé soumis comme erroné ; rien ne change sur la fiche du véhicule.",
|
||||
"correctReading": "Corriger le relevé",
|
||||
"correctReadingDetail": "Mettre à jour à la fois la réservation et le kilométrage de référence avec la valeur correcte.",
|
||||
"noBookingAttached": "Aucune réservation liée à ce problème, seule l'option « conserver la référence » est donc disponible.",
|
||||
"booking": "Réservation",
|
||||
"correctedOdometer": "Kilométrage corrigé (km)",
|
||||
"note": "Note",
|
||||
"resolving": "Résolution en cours…",
|
||||
"resolveIssue": "Résoudre le problème",
|
||||
"resolveFailed": "Impossible de résoudre ce problème."
|
||||
},
|
||||
"bookingOverlap": {
|
||||
"heading": "Résoudre le chevauchement de réservations",
|
||||
"description": "Bloquez l'un des deux engagements qui se chevauchent. L'autre conserve son statut actuel.",
|
||||
"columns": {
|
||||
"booking": "Réservation",
|
||||
"window": "Période",
|
||||
"status": "Statut",
|
||||
"blockThis": "Bloquer celle-ci"
|
||||
},
|
||||
"blockLabel": "Bloquer {{ref}}",
|
||||
"note": "Note",
|
||||
"resolving": "Résolution en cours…",
|
||||
"blockButton": "Bloquer {{ref}}",
|
||||
"blockButtonFallback": "Bloquer la réservation",
|
||||
"resolveFailed": "Impossible de résoudre ce chevauchement."
|
||||
},
|
||||
"vehicleStatusConflict": {
|
||||
"heading": "Résoudre le conflit de statut",
|
||||
"description": "Une règle faisant autorité recommande un statut opérationnel corrigé pour ce véhicule.",
|
||||
"currentStatus": "Statut actuel",
|
||||
"calculateAndApply": "Calculer et appliquer le statut recommandé",
|
||||
"confirmTitle": "Confirmer le changement de statut",
|
||||
"confirmBody": "Appliquer le statut recommandé faisant autorité pour ce véhicule ?",
|
||||
"applying": "Application en cours…",
|
||||
"confirmYes": "Oui, appliquer",
|
||||
"applied": "Appliqué {{status}} — {{reason}}",
|
||||
"applyFailed": "Impossible d'appliquer un statut recommandé."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"progress": {
|
||||
"capture": "Saisie",
|
||||
"review": "Vérification",
|
||||
"result": "Résultat",
|
||||
"ariaLabel": "Progression de l'enregistrement du retour"
|
||||
},
|
||||
"capture": {
|
||||
"heading": "Enregistrer le retour du véhicule",
|
||||
"description": "Enregistrez l'état à la restitution. L'étape suivante évalue les conséquences opérationnelles exactes avant toute validation.",
|
||||
"endOdometer": "Kilométrage de retour (km)",
|
||||
"fuelLevel": "Niveau de carburant (%)",
|
||||
"conditionLegend": "État du véhicule",
|
||||
"cleanlinessOk": "Propreté acceptable",
|
||||
"damageReported": "Dommage signalé",
|
||||
"technicalWarning": "Avertissement technique",
|
||||
"notes": "Notes",
|
||||
"evaluating": "Évaluation…",
|
||||
"reviewReturn": "Vérifier le retour"
|
||||
},
|
||||
"review": {
|
||||
"heading": "Vérifier l'impact du retour",
|
||||
"description": "Ceci est l'évaluation faisant autorité du serveur sur ce que la validation entraînera — confirmez avant la mise à jour de l'état de la flotte et le déclenchement de l'automatisation.",
|
||||
"odometer": "Kilométrage",
|
||||
"fuel": "Carburant",
|
||||
"cleanliness": "Propreté",
|
||||
"cleanlinessAccepted": "Acceptée",
|
||||
"cleanlinessFollowUp": "Suivi nécessaire",
|
||||
"damage": "Dommage",
|
||||
"damageReported": "Signalé",
|
||||
"damageNone": "Aucun signalé",
|
||||
"technicalWarning": "Avertissement technique",
|
||||
"technicalWarningReported": "Signalé",
|
||||
"technicalWarningNone": "Aucun signalé",
|
||||
"expectedState": "État de flotte attendu :",
|
||||
"odometerRegressionWarning": "Le kilométrage saisi ({{submitted}} km) est inférieur au relevé de référence ({{canonical}} km). Le kilométrage de référence ne changera pas et un problème de qualité des données sera ouvert.",
|
||||
"nextBookingRisk": "La prochaine réservation {{ref}} débute {{when}} — peut être affectée par ce retour.",
|
||||
"nextBookingLowRisk": "La prochaine réservation {{ref}} débute {{when}} — risque faible.",
|
||||
"commitList": {
|
||||
"inspection": "Créer une inspection de retour",
|
||||
"updateAtomic": "Mettre à jour la réservation et le véhicule de façon atomique",
|
||||
"queueAutomation": "Planifier l'automatisation après la validation locale"
|
||||
},
|
||||
"editDetails": "Modifier les détails",
|
||||
"registering": "Enregistrement…",
|
||||
"confirmReturn": "Confirmer le retour"
|
||||
},
|
||||
"result": {
|
||||
"committedLocally": "Validé localement",
|
||||
"heading": "Retour enregistré",
|
||||
"inspection": "Inspection",
|
||||
"resultingStatus": "Statut de véhicule résultant",
|
||||
"qualityIssue": "Problème de qualité",
|
||||
"noneCreated": "Aucun créé",
|
||||
"automationEvent": "Tâche d'automatisation",
|
||||
"queuedForDelivery": "En attente de traitement ({{ref}}) — validation locale réussie ; la livraison par automatisation est asynchrone et pas encore confirmée.",
|
||||
"nextBookingRisk": "Risque prochaine réservation",
|
||||
"nextBookingRiskValue": "{{ref}} {{status}}",
|
||||
"atRisk": "— peut être affectée",
|
||||
"lowRisk": "— risque faible",
|
||||
"noUpcomingBooking": "Aucune réservation à venir pour ce véhicule",
|
||||
"odometerRegressionNotice": "Le kilométrage saisi était inférieur au kilométrage de référence du véhicule. Il a été enregistré tel quel ; le kilométrage de référence n'a pas changé et un problème de qualité des données a été ouvert pour examen.",
|
||||
"viewVehicle": "Voir le véhicule {{ref}}",
|
||||
"viewAutomation": "Voir le statut d'automatisation",
|
||||
"viewAudit": "Voir la piste d'audit",
|
||||
"continueDemo": "Poursuivre la démo"
|
||||
},
|
||||
"scenario": {
|
||||
"title": "Scénario de démo : anomalie de kilométrage",
|
||||
"body": "Ce véhicule affiche actuellement {{odometer}} km. Le formulaire ci-dessous est pré-rempli avec un relevé de retour inférieur — signe d'une erreur de saisie ou d'un véhicule confondu. Confirmez le retour pour voir comment Fleet Ops détecte et traite cela.",
|
||||
"preparing": "Préparation du scénario…"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"openRow": "Openen: {{label}}",
|
||||
"reducedMotion": "Beperkte beweging actief",
|
||||
"closeDialog": "Dialoogvenster sluiten",
|
||||
"expandSection": "Sectie uitklappen",
|
||||
"collapseSection": "Sectie inklappen"
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"eyebrow": "Bewaken / Onveranderlijke geschiedenis",
|
||||
"title": "Audit trail",
|
||||
"description": "Volg belangrijke statuswijzigingen, actoren en gekoppelde gebeurtenissen op.",
|
||||
"actionFilterLabel": "Actie",
|
||||
"actionFilterPlaceholder": "bv. demo-login",
|
||||
"managerOnly": "De audit trail is enkel zichtbaar voor Operations Managers.",
|
||||
"managerOnlyDetail": "Auditgeschiedenis is enkel zichtbaar voor Operations Managers.",
|
||||
"loading": "Audit trail laden…",
|
||||
"unavailable": "Audit trail is momenteel niet beschikbaar.",
|
||||
"empty": "Geen auditgebeurtenissen gevonden",
|
||||
"emptyDetail": "Pas het actiefilter aan.",
|
||||
"relatedFilterActive": "Enkel gebeurtenissen gekoppeld aan deze actie ({{count}} gerelateerde gebeurtenissen).",
|
||||
"clearFilter": "Filter wissen",
|
||||
"count": "{{count}} gebeurtenissen",
|
||||
"storedRendered": "UTC opgeslagen · Brussel weergegeven",
|
||||
"columns": {
|
||||
"when": "Wanneer",
|
||||
"actor": "Actor",
|
||||
"action": "Actie",
|
||||
"entity": "Entiteit",
|
||||
"change": "Wijziging",
|
||||
"followUp": "Vervolg",
|
||||
"details": "Details"
|
||||
},
|
||||
"viewRelatedEvents": "Gerelateerde gebeurtenissen bekijken",
|
||||
"noChangeDetail": "Geen wijzigingsdetail geregistreerd.",
|
||||
"noFieldChange": "Geen wijziging op veldniveau gedetecteerd.",
|
||||
"reference": "Referentie",
|
||||
"relatedEventsCount": "{{count}} gekoppelde gebeurtenis",
|
||||
"relatedEventsCount_other": "{{count}} gekoppelde gebeurtenissen",
|
||||
"showTechnicalEvents": "{{count}} technische gebeurtenis tonen",
|
||||
"showTechnicalEvents_other": "{{count}} technische gebeurtenissen tonen",
|
||||
"hideTechnicalEvents": "Technische gebeurtenissen verbergen",
|
||||
"technicalDetails": "Technische details",
|
||||
"fullReference": "Volledige referentie",
|
||||
"correlationId": "Gekoppelde gebeurtenis-ID",
|
||||
"diff": {
|
||||
"setTo": "{{field}}: ingesteld op {{value}}",
|
||||
"was": "{{field}}: was {{value}}",
|
||||
"changed": "{{field}}: {{before}} → {{after}}"
|
||||
},
|
||||
"actions": {
|
||||
"demo_login": "Ingelogd",
|
||||
"demo_logout": "Uitgelogd",
|
||||
"demo_reset": "Demogegevens hersteld",
|
||||
"demo_data_seeded": "Demogegevens ingeladen",
|
||||
"return_registered": "Voertuigretour geregistreerd",
|
||||
"vehicle_status_changed": "Voertuigstatus gewijzigd",
|
||||
"data_quality_issue_resolved": "Datakwaliteitsprobleem opgelost",
|
||||
"data_quality_issue_deferred": "Datakwaliteitsprobleem uitgesteld",
|
||||
"data_quality_issue_rejected": "Datakwaliteitsprobleem verworpen",
|
||||
"data_quality_fields_provided": "Ontbrekende velden aangevuld",
|
||||
"data_quality_odometer_corrected": "Kilometerstand gecorrigeerd",
|
||||
"data_quality_odometer_retained": "Laatst bevestigde kilometerstand behouden",
|
||||
"data_quality_status_applied": "Aanbevolen status toegepast",
|
||||
"data_quality_booking_blocked": "Boeking geblokkeerd",
|
||||
"data_quality_scan_run": "Kwaliteitscontrole uitgevoerd",
|
||||
"customer_merged": "Klanten samengevoegd",
|
||||
"workflow_retry": "Automatisering opnieuw geprobeerd",
|
||||
"knowledge_question_asked": "Kennisvraag gesteld",
|
||||
"mcp_tool_request": "MCP-tool aangeroepen"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"brandTagline": "Bedieningscentrum",
|
||||
"orgLine": "Demo-organisatie: {{orgName}} (fictief)",
|
||||
"headline1": "Elke overdracht.",
|
||||
"headline2": "Eén helder overzicht.",
|
||||
"defaultDescription": "Fleet Ops brengt voertuig-, boekings- en operationele gegevens samen, ondersteunt verhuurprocessen, detecteert datakwaliteitsproblemen en automatiseert gecontroleerde vervolgstappen.",
|
||||
"footnote": "Synthetische demo · geen echte klant- of voertuiggegevens · op elk moment herstelbaar",
|
||||
"accessEyebrow": "Demo-toegang",
|
||||
"accessHeading": "Kies hoe je wil starten",
|
||||
"accessIntro": "Geen wachtwoord nodig. Elke rol opent een afgebakende, synthetische omgeving — alle workflows en controles zijn echt geïmplementeerd.",
|
||||
"startGuidedDemo": "Start begeleide demo",
|
||||
"exploreAsOperationsManager": "Verken als Operations Manager",
|
||||
"exploreAsOperationsManagerDetail": "Volledig overzicht, kwaliteitsoplossing en herpogingen",
|
||||
"exploreAsRentalEmployee": "Verken als Rental Employee",
|
||||
"exploreAsRentalEmployeeDetail": "Boekingen, retours, wagenpark en procedures",
|
||||
"safeByDesignTitle": "Veilig ontworpen",
|
||||
"safeByDesignDetail": "Elke actie wordt gelogd en is in deze demo herstelbaar.",
|
||||
"loginFailed": "De demo-sessie kon niet gestart worden. De API is mogelijk niet bereikbaar.",
|
||||
"roleOperationsManager": "Operations manager",
|
||||
"roleRentalEmployee": "Rental employee",
|
||||
"switchRole": "Wissel van rol",
|
||||
"logout": "Uitloggen"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Uitvoeren / Planning",
|
||||
"title": "Boekingen",
|
||||
"description": "Bekijk actieve verhuurperiodes en aankomende voertuigverbintenissen.",
|
||||
"searchLabel": "Zoeken",
|
||||
"searchPlaceholder": "Boeking, klant of voertuig",
|
||||
"statusLabel": "Status",
|
||||
"statusAll": "Alle statussen",
|
||||
"loading": "Boekingsoverzicht laden…",
|
||||
"empty": "Geen boekingen gevonden",
|
||||
"emptyDetail": "Pas het statusfilter voor boekingen aan.",
|
||||
"noMatch": "Geen overeenkomende boekingen",
|
||||
"noMatchDetail": "Probeer een bredere zoekterm.",
|
||||
"unavailable": "Boekingsoverzicht is momenteel niet beschikbaar.",
|
||||
"count": "{{count}} boekingen",
|
||||
"pageOf": "Pagina {{page}} van {{total}}",
|
||||
"columns": {
|
||||
"reference": "Referentie",
|
||||
"customer": "Klant",
|
||||
"vehicle": "Voertuig",
|
||||
"window": "Periode",
|
||||
"status": "Status"
|
||||
},
|
||||
"paginationLabel": "Boekingspagina's",
|
||||
"previous": "Vorige",
|
||||
"next": "Volgende",
|
||||
"rangeOf": "{{from}}–{{to}} van {{total}}"
|
||||
},
|
||||
"statuses": {
|
||||
"reserved": "gereserveerd",
|
||||
"active": "actief",
|
||||
"returned": "geretourneerd",
|
||||
"cancelled": "geannuleerd",
|
||||
"blocked": "geblokkeerd"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Boekingsoverzicht",
|
||||
"eyebrow": "Boekingen / Huurrecord",
|
||||
"notFound": "Deze boeking kon niet gevonden worden.",
|
||||
"loading": "Boekingsrecord laden…",
|
||||
"customer": "Klant",
|
||||
"vehicle": "Voertuig",
|
||||
"starts": "Start",
|
||||
"ends": "Einde",
|
||||
"startOdometer": "Startkilometerstand",
|
||||
"endOdometer": "Eindkilometerstand",
|
||||
"requirementsComplete": "Vereisten volledig",
|
||||
"yes": "Ja",
|
||||
"no": "Nee"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"appName": "Fleet Ops",
|
||||
"orgName": "Northstar Mobility",
|
||||
"brandTagline": "Bedieningscentrum",
|
||||
"actions": {
|
||||
"save": "Opslaan",
|
||||
"cancel": "Annuleren",
|
||||
"confirm": "Bevestigen",
|
||||
"close": "Sluiten",
|
||||
"back": "Terug",
|
||||
"next": "Volgende",
|
||||
"retry": "Opnieuw proberen",
|
||||
"reset": "Herstellen",
|
||||
"yes": "Ja",
|
||||
"no": "Nee",
|
||||
"viewDetails": "Details bekijken",
|
||||
"technicalDetails": "Technische details"
|
||||
},
|
||||
"status": {
|
||||
"loading": "Laden…",
|
||||
"saving": "Opslaan…",
|
||||
"error": "Er ging iets mis",
|
||||
"success": "Gelukt",
|
||||
"noResults": "Geen resultaten"
|
||||
},
|
||||
"states": {
|
||||
"loadingDefault": "Werkruimte wordt geladen…",
|
||||
"errorTitle": "We konden deze werkruimte niet laden."
|
||||
},
|
||||
"timezone": "Europa/Brussel",
|
||||
"language": {
|
||||
"label": "Taal",
|
||||
"nl-BE": "Nederlands",
|
||||
"en-GB": "English",
|
||||
"fr-BE": "Français"
|
||||
},
|
||||
"footer": {
|
||||
"productLine": "Fleet Ops Demo",
|
||||
"locale": "Europa/Brussel · Synthetische demogegevens"
|
||||
},
|
||||
"demo": {
|
||||
"syntheticBadge": "Synthetische demo"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"eyebrow": "Uitvoeren / Live overzicht",
|
||||
"title": "Goedemorgen. Hier is je wagenpark.",
|
||||
"description": "Beschikbaarheid, uitzonderingen en overdrachten doorheen de huidige werking.",
|
||||
"viewFleet": "Wagenpark bekijken",
|
||||
"demoStart": {
|
||||
"title": "Probeer een demonstratiescenario",
|
||||
"readyCount": "{{ready}} van {{total}} scenario's klaar voor demo.",
|
||||
"readyCountFallback": "Vijf afgebakende scenario's.",
|
||||
"startGuide": "Start demo-gids",
|
||||
"resumeGuide": "Verder met demo-gids ({{current}}/{{total}})",
|
||||
"viewScenarios": "Bekijk scenario's"
|
||||
},
|
||||
"readiness": {
|
||||
"title": "Wagenparkstatus",
|
||||
"description": "Live vanuit persistente voertuigstatus",
|
||||
"openFleet": "Wagenpark openen",
|
||||
"available": "Beschikbaar",
|
||||
"rented": "Verhuurd",
|
||||
"cleaning": "Reiniging",
|
||||
"maintenance": "Onderhoud",
|
||||
"blocked": "Geblokkeerd"
|
||||
},
|
||||
"attention": {
|
||||
"title": "Aandachtspunten",
|
||||
"description": "{{openIssues}} open datakwaliteitsproblemen · {{workflowExceptions}} automatiseringsuitzonderingen",
|
||||
"reviewQueue": "Wachtrij bekijken",
|
||||
"filterPlaceholder": "Filter aandachtspunten…",
|
||||
"filterAriaLabel": "Zoek in aandachtspunten",
|
||||
"severityAll": "Alle ernst",
|
||||
"severityHigh": "Kritiek",
|
||||
"severityMedium": "Waarschuwing",
|
||||
"severityLow": "Info",
|
||||
"severityAriaLabel": "Ernst",
|
||||
"empty": "Geen aandachtspunten voor dit filter.",
|
||||
"openRecord": "Open {{title}}"
|
||||
},
|
||||
"movements": {
|
||||
"title": "Bewegingen vandaag",
|
||||
"description": "Vertrekken en retours in Europa/Brussel",
|
||||
"allBookings": "Alle boekingen",
|
||||
"empty": "Geen bewegingen gepland vandaag.",
|
||||
"departure": "vertrek",
|
||||
"return": "retour",
|
||||
"openBooking": "Open boeking {{ref}}"
|
||||
},
|
||||
"integrationPulse": {
|
||||
"title": "Integratiestatus",
|
||||
"description": "Actuele evidentie van gekoppelde diensten",
|
||||
"systemDetail": "Systeemdetail",
|
||||
"n8nTitle": "n8n-aflevering",
|
||||
"n8nSummary": "{{succeeded}} geslaagd · {{failed}} mislukt",
|
||||
"n8nLatest": "Meest recente gebeurtenis {{ref}}",
|
||||
"n8nNoEvidence": "Geen automatiseringsevidentie geregistreerd",
|
||||
"knowledgeTitle": "Kennisassistent",
|
||||
"knowledgeSummary": "{{count}} procedures geïndexeerd",
|
||||
"knowledgeUnavailable": "Statuscontrole niet beschikbaar",
|
||||
"mcpTitle": "MCP Hub",
|
||||
"mcpEnabled": "Registratie ingeschakeld",
|
||||
"mcpNotConnected": "Nog niet gekoppeld"
|
||||
},
|
||||
"recent": {
|
||||
"title": "Recente activiteit",
|
||||
"description": "Laatst geauditeerde workflowwijzigingen",
|
||||
"empty": "Geen automatiseringsactiviteit geregistreerd."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"badge": {
|
||||
"trigger": "Synthetische demo",
|
||||
"dialogLabel": "Over deze demo-omgeving",
|
||||
"close": "Sluiten",
|
||||
"orgIntro": "<strong>{{orgName}}</strong> is een fictieve organisatie. Alle namen, voertuigen en boekingen zijn synthetisch.",
|
||||
"orgIntroFallback": "Alle namen, voertuigen en boekingen in deze omgeving zijn synthetisch.",
|
||||
"realWorkflows": "De workflows, controles en automatisering zijn echt geïmplementeerd — enkel de gegevens zijn verzonnen.",
|
||||
"lastReset": "Laatste reset: <strong>{{when}}</strong> · deze omgeving is op elk moment herstelbaar.",
|
||||
"aboutLink": "Over deze demo",
|
||||
"unknown": "onbekend"
|
||||
},
|
||||
"guide": {
|
||||
"dialogLabel": "Gegidste demo",
|
||||
"trigger": "Demo-gids",
|
||||
"kicker": "Gegidste demo · stap {{current}} van {{total}}",
|
||||
"whatYouWillSee": "Wat je zal zien",
|
||||
"whyItMatters": "Waarom dit relevant is",
|
||||
"startAction": "Aan de slag",
|
||||
"expectedOutcome": "Verwacht resultaat",
|
||||
"goToStep": "Ga naar deze stap",
|
||||
"next": "Volgende",
|
||||
"close": "Sluiten",
|
||||
"restart": "Demo opnieuw voorbereiden",
|
||||
"restarting": "Bezig met herstellen…",
|
||||
"restartFailed": "De demo kon niet hersteld worden.",
|
||||
"allStepsLabel": "Alle stappen",
|
||||
"progressChip": "Demo-gids · stap {{current}} van {{total}}",
|
||||
"expand": "Demo-gids uitklappen",
|
||||
"collapse": "Demo-gids inklappen",
|
||||
"steps": {
|
||||
"understand-state": {
|
||||
"title": "1. Begrijp de operationele status",
|
||||
"whatYouWillSee": "Het dashboard toont de wagenparkstatus, openstaande aandachtspunten en de bewegingen van vandaag.",
|
||||
"whyItMatters": "Een Operations Manager start elke dag met dit overzicht om te bepalen waar ingrijpen nodig is.",
|
||||
"startAction": "Open het dashboard en bekijk de aandachtslijst en de tijdlijn van vandaag.",
|
||||
"expectedOutcome": "Je ziet welke boekingen, voertuigen of datakwaliteitsproblemen aandacht vragen."
|
||||
},
|
||||
"open-booking": {
|
||||
"title": "2. Open een boeking die aandacht nodig heeft",
|
||||
"whatYouWillSee": "De boeking BK-DEMO-RETURN, actief en klaar voor retour vandaag.",
|
||||
"whyItMatters": "Retours zijn het moment waarop foute kilometerstanden of schade voor het eerst zichtbaar worden.",
|
||||
"startAction": "Open de boeking vanuit het dashboard of de boekingenlijst.",
|
||||
"expectedOutcome": "Je ziet de boekingsdetails en de knop om de retour te verwerken."
|
||||
},
|
||||
"process-return": {
|
||||
"title": "3. Verwerk een retour met een afwijkende kilometerstand",
|
||||
"whatYouWillSee": "Een retourformulier met een vooringevulde, verdachte kilometerstand lager dan de laatst gekende stand.",
|
||||
"whyItMatters": "Een dalende kilometerstand wijst op een foutieve invoer of een verwisseld voertuig — dit moet vóór vrijgave worden opgemerkt.",
|
||||
"startAction": "Vul de retour in met de voorgestelde waarde en bekijk de serverpreview vóór je bevestigt.",
|
||||
"expectedOutcome": "De retour wordt verwerkt, het voertuig krijgt een passende status en er wordt automatisch een datakwaliteitsprobleem aangemaakt."
|
||||
},
|
||||
"handle-quality-issue": {
|
||||
"title": "4. Bekijk en behandel het gecreëerde datakwaliteitsprobleem",
|
||||
"whatYouWillSee": "Een nieuw issue van het type 'kilometerstand-afwijking' bovenaan de werklijst.",
|
||||
"whyItMatters": "Elk gedetecteerd probleem heeft één afgebakende oplossingsstap — niets wordt automatisch stilzwijgend gecorrigeerd.",
|
||||
"startAction": "Open het datakwaliteitsoverzicht en kies het nieuwste issue.",
|
||||
"expectedOutcome": "Je ziet de aanbevolen actie, kiest een oplossing en het issue wordt opgelost met een audit-spoor."
|
||||
},
|
||||
"merge-duplicate": {
|
||||
"title": "5. Beoordeel en behandel een mogelijke dubbele klant",
|
||||
"whatYouWillSee": "Twee klantprofielen met hetzelfde e-mailadres en telefoonnummer, naast elkaar vergeleken.",
|
||||
"whyItMatters": "Dubbele klanten leiden tot verspreide boekingsgeschiedenis en verwarrende communicatie.",
|
||||
"startAction": "Vergelijk beide profielen en kies welk profiel behouden blijft.",
|
||||
"expectedOutcome": "De profielen worden samengevoegd, boekingen worden herverbonden en het verliezende profiel wordt een tombstone."
|
||||
},
|
||||
"ask-knowledge": {
|
||||
"title": "6. Stel een vraag aan de procedureassistent",
|
||||
"whatYouWillSee": "Een antwoord met bronvermelding uit de afgebakende demokennisbank.",
|
||||
"whyItMatters": "Medewerkers moeten snel een onderbouwd antwoord krijgen over procedures, zonder te gokken.",
|
||||
"startAction": "Klik op één van de voorbeeldvragen, in de huidige interfacetaal.",
|
||||
"expectedOutcome": "Je ziet het antwoord, de gebruikte procedure en de brontekst — of een eerlijk 'onvoldoende informatie' als dat niet aanwezig is."
|
||||
},
|
||||
"check-automation-audit": {
|
||||
"title": "7. Controleer automatisering en audit trail",
|
||||
"whatYouWillSee": "De status van de n8n-aflevering voor je retour, en de bijhorende audit-gebeurtenissen.",
|
||||
"whyItMatters": "Elke belangrijke actie moet naspeurbaar zijn: wie deed wat, wanneer, en wat was het gevolg.",
|
||||
"startAction": "Open Integraties om de afleverstatus te zien, en Audit trail voor het volledige spoor.",
|
||||
"expectedOutcome": "Je ziet een geslaagde (of herstelbare) aflevering en een leesbaar audit-overzicht van je acties."
|
||||
},
|
||||
"review-real-vs-simulated": {
|
||||
"title": "8. Bekijk wat echt is, gesimuleerd is, of nog niet gekoppeld",
|
||||
"whatYouWillSee": "Een overzicht van wat in deze demo functioneel geïmplementeerd is, wat synthetisch is, en welke koppelingen nog niet live zijn.",
|
||||
"whyItMatters": "Een demo is pas overtuigend als bezoekers zelf kunnen nagaan wat echt werkt en wat nog toekomstmuziek is.",
|
||||
"startAction": "Lees de pagina 'Over deze demo'.",
|
||||
"expectedOutcome": "Je kan zelf uitleggen wat Fleet Ops wel en niet is, zonder mondelinge toelichting."
|
||||
}
|
||||
}
|
||||
},
|
||||
"scenarios": {
|
||||
"eyebrow": "Demonstratiescenario's",
|
||||
"title": "Probeer een demonstratiescenario",
|
||||
"description": "Vijf afgebakende scenario's die telkens dezelfde vaste boekingen, klanten en voertuigen gebruiken — na een reset zijn ze altijd opnieuw te vinden.",
|
||||
"loading": "Scenario's laden…",
|
||||
"ready": "Klaar voor demo",
|
||||
"notReady": "Niet beschikbaar",
|
||||
"duration": "Duur",
|
||||
"durationValue": "± {{minutes}} min",
|
||||
"role": "Rol",
|
||||
"demonstrates": "Toont aan:",
|
||||
"requiresRole": "Vereist rol: {{roles}}.",
|
||||
"startScenario": "Start scenario",
|
||||
"roleOr": "{{a}} of {{b}}",
|
||||
"roles": {
|
||||
"operations_manager": "Operations Manager",
|
||||
"rental_employee": "Rental Employee"
|
||||
},
|
||||
"items": {
|
||||
"return-anomaly": {
|
||||
"title": "Retour met afwijkende kilometerstand",
|
||||
"problem": "Een voertuig komt terug met een kilometerstand die lager ligt dan de laatst geregistreerde stand — een teken van een foutieve invoer of een verwisseld voertuig.",
|
||||
"demonstrates": "Retourverwerking, automatische detectie van datakwaliteitsproblemen en de audit trail die daaruit ontstaat."
|
||||
},
|
||||
"duplicate-customer": {
|
||||
"title": "Mogelijke dubbele klant samenvoegen",
|
||||
"problem": "Twee klantprofielen delen hetzelfde e-mailadres en telefoonnummer — waarschijnlijk dezelfde persoon, twee keer geregistreerd.",
|
||||
"demonstrates": "Samenvoegen van klanten met behoud van boekingsgeschiedenis en audit trail."
|
||||
},
|
||||
"booking-overlap": {
|
||||
"title": "Overlappende boekingen herstellen",
|
||||
"problem": "Eén voertuig staat dubbel gereserveerd voor overlappende periodes — een planningsfout die vóór vertrek moet worden opgelost.",
|
||||
"demonstrates": "Detectie en gecontroleerde oplossing van planningsconflicten."
|
||||
},
|
||||
"automation-retry": {
|
||||
"title": "Mislukte automatisering opnieuw proberen",
|
||||
"problem": "Eén eerdere gebeurtenis kon niet worden afgeleverd aan de automatisering door een gesimuleerde verbindingsfout.",
|
||||
"demonstrates": "Betrouwbare aflevering met begrensde herpogingen en zichtbare foutstatus."
|
||||
},
|
||||
"knowledge-question": {
|
||||
"title": "Een procedurevraag stellen",
|
||||
"problem": "Een medewerker weet niet zeker welke procedure van toepassing is bij een specifieke operationele situatie.",
|
||||
"demonstrates": "Antwoorden met brongebaseerde onderbouwing uit een afgebakende demokennisbank."
|
||||
}
|
||||
},
|
||||
"blockedReasons": {
|
||||
"bookingNotFound": "Demoboeking BK-DEMO-RETURN niet gevonden. {{resetHint}}",
|
||||
"bookingAlreadyProcessed": "Deze boeking is al verwerkt sinds de laatste reset. {{resetHint}}",
|
||||
"duplicateIssueNotFound": "Demo-issue DQ-DEMO-DUPLICATE niet gevonden. {{resetHint}}",
|
||||
"issueAlreadyResolved": "Dit issue is al opgelost sinds de laatste reset. {{resetHint}}",
|
||||
"overlapIssueNotFound": "Demo-issue DQ-DEMO-OVERLAP niet gevonden. {{resetHint}}",
|
||||
"failedEventNotFound": "Gesimuleerde mislukte gebeurtenis niet gevonden. {{resetHint}}",
|
||||
"eventAlreadyRecovered": "Deze gebeurtenis is al hersteld sinds de laatste reset. {{resetHint}}",
|
||||
"knowledgeUnavailable": "De demokennisbank is momenteel niet beschikbaar.",
|
||||
"resetHint": "Reset de demogegevens om dit scenario opnieuw beschikbaar te maken."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"eyebrow": "Over deze demo",
|
||||
"title": "Wat Fleet Ops wel en niet is",
|
||||
"description": "{{orgName}} is een fictieve verhuurorganisatie die dient om deze demo tastbaar te maken — geen bestaand bedrijf.",
|
||||
"loading": "Demo-informatie laden…",
|
||||
"ctaTitle": "Liever meteen aan de slag?",
|
||||
"ctaBody": "De gegidste demo doorloopt alle acht stappen hierboven in de praktijk.",
|
||||
"ctaButton": "Start begeleide demo",
|
||||
"problemTitle": "Het fictieve probleem",
|
||||
"problemBody": "{{orgName}} verhuurt zo'n 50 campers en bestelwagens vanuit één hoofdlocatie. Boekingen, retours, klantgegevens en onderhoud kwamen tot nu toe uit losse spreadsheets en mondelinge afspraken, waardoor fouten (dubbele klanten, foutieve kilometerstanden, dubbel geboekte voertuigen) laat aan het licht kwamen. Fleet Ops toont hoe één samenhangend systeem die problemen vroeg signaleert en gecontroleerd laat oplossen.",
|
||||
"scopeTitle": "Voor wie en met welke scope",
|
||||
"scopeBody": "Deze demo is bedoeld voor wie wil zien hoe Fleet Ops operationele problemen bij een kleine verhuurder aanpakt: Operations Managers en Rental Employees, en iedereen die de aanpak evalueert. De scope is bewust afgebakend tot één samenhangende proof of concept — geen boekhouding, geen betalingen, geen publieke reservaties, geen volledig CRM of ERP.",
|
||||
"realTitle": "Wat écht werkt",
|
||||
"realBody": "Alles hieronder is functionele code, niet alleen een mockup: rol-gebaseerde toegang en sessies, voertuig- en boekingsbeheer, retourverwerking met serverzijdige validatie, vijf datakwaliteitsregels met elk een eigen oplossingsstap, een volledige audit trail, geautomatiseerde aflevering naar n8n met begrensde herpogingen, Docker-gebaseerde deployment en een geautomatiseerde testsuite (backend en Playwright end-to-end).",
|
||||
"syntheticTitle": "Wat synthetisch is",
|
||||
"syntheticBody": "De organisatie, alle klanten, voertuigen, boekingen, onderhoudsgeschiedenis, procedures in de kennisbank en de vooraf ingerichte scenario's zijn volledig verzonnen. Geen enkel gegeven verwijst naar een bestaand persoon, voertuig of bedrijf; e-mailadressen gebruiken uitsluitend het testdomein {{testDomain}}.",
|
||||
"architectureTitle": "Architectuur in het kort",
|
||||
"architectureBody": "Een React/TypeScript-frontend praat met een FastAPI-backend (PostgreSQL via SQLAlchemy/Alembic-migraties); belangrijke bedrijfsregels leven in de backend, niet in n8n of in prompts. Retours en andere gebeurtenissen worden eerst lokaal gecommit en pas daarna asynchroon via een automatiseringsopdracht aan n8n afgeleverd, zodat een tijdelijke storing in de automatisering nooit een operationele actie blokkeert.",
|
||||
"securityTitle": "Beveiliging en toegang",
|
||||
"securityBody": "Toegang verloopt via ondertekende, HTTP-only sessiecookies per rol; elke rol gebonden aan een set toegestane routes, zowel serverzijdig afgedwongen als in de navigatie weerspiegeld. Belangrijke statuswijzigingen worden altijd gecontroleerd en gelogd — nooit stilzwijgend automatisch gecorrigeerd.",
|
||||
"testingTitle": "Hoe dit getest is",
|
||||
"testingBody": "Een geautomatiseerde backend-testsuite dekt bedrijfsregels en API-contracten; een volledige Playwright-eindtot-eind-suite dekt de gebruikersstromen, inclusief deze demo-ervaring zelf in drie talen. Elke wijziging wordt bovendien tegen een schone checkout (lege database, opnieuw opgebouwd vanaf de seed-data) gevalideerd voor deployment.",
|
||||
"integrationsTitle": "Koppelingen — eerlijk gelabeld",
|
||||
"integrationsDescription": "Wat operationeel is, wat demomodus is, en wat nog niet gekoppeld is.",
|
||||
"resetTitle": "Demo-omgeving herstellen",
|
||||
"resetBodyManager": "De omgeving is op elk moment terug te zetten naar de startsituatie. Laatste reset: <strong>{{when}}</strong>. Gebruik <strong>Demogegevens herstellen</strong> in de zijbalk om opnieuw te beginnen.",
|
||||
"resetBodyEmployee": "De omgeving is op elk moment terug te zetten naar de startsituatie. Laatste reset: <strong>{{when}}</strong>. Een Operations Manager kan de demo-omgeving herstellen via de zijbalk.",
|
||||
"limitationsTitle": "Beperkingen",
|
||||
"limitationsBody": "Dit is een gerichte proof of concept, geen volledig ERP. RAGcore en de ITWorx MCP Hub zijn nog niet live gekoppeld; de kennisassistent gebruikt een lokale, afgebakende demokennisbank in plaats van een live RAGcore-omgeving.",
|
||||
"unknown": "onbekend"
|
||||
},
|
||||
"integrationSummary": {
|
||||
"titles": {
|
||||
"n8n": "Automatisering (n8n)",
|
||||
"ragcore": "Kennisassistent (RAGcore)",
|
||||
"mcp_hub": "ITWorx MCP Hub"
|
||||
},
|
||||
"n8nDetail": "{{succeeded}} geslaagd · {{failed}} mislukt · {{pending}} in wachtrij.",
|
||||
"ragcoreDetail": "{{count}} procedures geïndexeerd in {{collection}}.",
|
||||
"mcpDetailEnabled": "Voorbereid voor toekomstige, gecontroleerde tool-aanroepen vanuit de Hub.",
|
||||
"mcpDetailNotConnected": "Nog niet gekoppeld — voorbereid voor toekomstige, gecontroleerde tool-aanroepen vanuit de Hub."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"generic": "Er is een fout opgetreden. Probeer opnieuw.",
|
||||
"workspaceLoadFailed": "We konden deze werkruimte niet laden.",
|
||||
"unauthorized": "Je sessie is verlopen. Log opnieuw in.",
|
||||
"forbidden": "Je hebt geen toegang tot dit onderdeel.",
|
||||
"notFound": "Dit record kon niet gevonden worden.",
|
||||
"networkUnavailable": "De verbinding met de server is momenteel niet beschikbaar."
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Wagenpark / Register",
|
||||
"title": "Wagenpark",
|
||||
"description": "Live operationele status, locatie en onderhoudsgereedheid.",
|
||||
"searchLabel": "Zoeken",
|
||||
"searchPlaceholder": "Referentie, merk of locatie",
|
||||
"statusLabel": "Status",
|
||||
"statusAll": "Alle statussen",
|
||||
"attentionOnly": "Enkel aandachtspunten",
|
||||
"loading": "Wagenparkregister laden…",
|
||||
"empty": "Geen voertuigen gevonden",
|
||||
"emptyDetail": "Pas de huidige wagenparkfilters aan.",
|
||||
"noMatch": "Geen overeenkomende voertuigen",
|
||||
"noMatchDetail": "Probeer een bredere zoekterm.",
|
||||
"unavailable": "Wagenparklijst is momenteel niet beschikbaar.",
|
||||
"count": "{{count}} voertuigen",
|
||||
"persisted": "Persistente wagenparkgegevens",
|
||||
"columns": {
|
||||
"reference": "Referentie",
|
||||
"makeModel": "Merk / model",
|
||||
"location": "Locatie",
|
||||
"status": "Status",
|
||||
"odometer": "Kilometerstand (km)",
|
||||
"attention": "Aandacht"
|
||||
},
|
||||
"needsAttention": "Vraagt aandacht"
|
||||
},
|
||||
"statuses": {
|
||||
"available": "beschikbaar",
|
||||
"rented": "verhuurd",
|
||||
"cleaning": "reiniging",
|
||||
"maintenance": "onderhoud",
|
||||
"blocked": "geblokkeerd"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Wagenparkregister",
|
||||
"eyebrow": "Wagenpark / Voertuigrecord",
|
||||
"notFound": "Dit voertuig kon niet gevonden worden.",
|
||||
"loading": "Voertuigrecord laden…",
|
||||
"needsAttention": "Vraagt aandacht",
|
||||
"tabs": {
|
||||
"overview": "Overzicht",
|
||||
"bookings": "Boekingen",
|
||||
"inspections": "Inspecties",
|
||||
"maintenance": "Onderhoud",
|
||||
"quality": "Kwaliteit"
|
||||
},
|
||||
"tabsAriaLabel": "Voertuigonderdelen",
|
||||
"overview": {
|
||||
"registration": "Kenteken",
|
||||
"modelYear": "Bouwjaar",
|
||||
"location": "Locatie",
|
||||
"odometer": "Kilometerstand",
|
||||
"nextService": "Volgende onderhoudsbeurt",
|
||||
"active": "Actief"
|
||||
},
|
||||
"yes": "Ja",
|
||||
"no": "Nee",
|
||||
"noBookings": "Geen boekingen geregistreerd.",
|
||||
"noInspections": "Geen inspecties geregistreerd.",
|
||||
"noMaintenance": "Geen onderhoudsgegevens.",
|
||||
"noQualityIssues": "Geen kwaliteitsproblemen geregistreerd.",
|
||||
"fuel": "Brandstof {{percent}}%",
|
||||
"damage": "Schade",
|
||||
"technicalWarning": "Technische melding"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"eyebrow": "Bewaken / Integraties",
|
||||
"title": "Integratiebeheer",
|
||||
"description": "Bewaak afleverkwaliteit, beperkte beschikbaarheid en herprobeerbare workflowgebeurtenissen.",
|
||||
"cards": {
|
||||
"orchestrationKicker": "Orkestratie",
|
||||
"n8nTitle": "n8n-aflevering",
|
||||
"n8nSummary": "{{succeeded}} geslaagd · {{failed}} mislukt · {{pending}} in wachtrij · {{delivering}} bezig",
|
||||
"n8nFallback": "Retourgebeurtenissen worden eerst lokaal verwerkt en pas daarna via de automatiseringsopdracht afgeleverd.",
|
||||
"knowledgeKicker": "Kennis",
|
||||
"knowledgeTitle": "Kennisassistent",
|
||||
"knowledgeSummaryDemo": "Demokennisbank · {{count}} procedures geïndexeerd in {{collection}}.",
|
||||
"knowledgeSummaryRagcore": "RAGcore · {{count}} procedures geïndexeerd in {{collection}}.",
|
||||
"knowledgeUnavailable": "Statusevidentie momenteel niet beschikbaar.",
|
||||
"gatewayKicker": "Tool-gateway",
|
||||
"mcpTitle": "MCP Hub",
|
||||
"mcpEnabled": "Registratie is ingeschakeld voor deze omgeving.",
|
||||
"mcpNotConnected": "Nog niet gekoppeld — voorbereid voor toekomstige, gecontroleerde tool-aanroepen vanuit de Hub."
|
||||
},
|
||||
"statusLabels": {
|
||||
"notConnected": "Niet gekoppeld",
|
||||
"deliveryFailed": "Verwerking mislukt",
|
||||
"retryAvailable": "Opnieuw proberen mogelijk",
|
||||
"operational": "Operationeel",
|
||||
"prepared": "Voorbereid",
|
||||
"demoMode": "Demomodus",
|
||||
"unavailable": "Niet beschikbaar"
|
||||
},
|
||||
"ledger": {
|
||||
"title": "Automatiseringsopdrachten",
|
||||
"description": "Vastgelegde automatiseringspogingen met de recentste foutevidentie.",
|
||||
"filterLabel": "Weergave",
|
||||
"filterNeedsAttention": "Vraagt aandacht",
|
||||
"filterRecent": "Recent",
|
||||
"filterSucceeded": "Geslaagd",
|
||||
"filterAll": "Alle",
|
||||
"statusFilterLabel": "Status",
|
||||
"statusAll": "Alle statussen",
|
||||
"statusPending": "In wachtrij",
|
||||
"statusDelivering": "Bezig",
|
||||
"statusSucceeded": "Geslaagd",
|
||||
"statusFailed": "Mislukt",
|
||||
"unavailable": "Automatiseringsopdrachten zijn momenteel niet beschikbaar.",
|
||||
"managerOnly": "Automatisering is enkel zichtbaar voor Operations Managers.",
|
||||
"loading": "Automatiseringsopdrachten laden…",
|
||||
"empty": "Geen automatiseringsopdrachten voor dit filter.",
|
||||
"count": "{{count}} workflowgebeurtenissen",
|
||||
"boundedRetries": "Begrensde herpogingen",
|
||||
"groupedSucceeded": "{{count}} geslaagde voertuigretourverwerkingen",
|
||||
"showIndividually": "Individuele opdrachten tonen",
|
||||
"hideIndividually": "Individuele opdrachten verbergen",
|
||||
"columns": {
|
||||
"event": "Opdracht",
|
||||
"type": "Type",
|
||||
"booking": "Boeking",
|
||||
"status": "Status",
|
||||
"attempts": "Pogingen",
|
||||
"lastError": "Laatste fout",
|
||||
"when": "Wanneer",
|
||||
"action": "Actie"
|
||||
},
|
||||
"retry": "Opnieuw proberen",
|
||||
"retrying": "Bezig met opnieuw proberen…",
|
||||
"retryFailed": "Kon deze aflevering niet opnieuw proberen.",
|
||||
"noAction": "—",
|
||||
"eventTypes": {
|
||||
"vehicle.returned.v1": "Voertuigretour verwerkt"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"eyebrow": "Bewaken / Onderbouwde kennis",
|
||||
"title": "Procedurekennis",
|
||||
"description": "Stel operationele vragen. Antwoorden verschijnen enkel wanneer {{provider}} voldoende onderbouwde evidentie teruggeeft.",
|
||||
"providerDemo": "de demokennisbank",
|
||||
"providerRagcore": "RAGcore",
|
||||
"statusAvailable": "Beschikbaar",
|
||||
"statusUnavailable": "Niet beschikbaar",
|
||||
"proceduresIndexed": "{{count}} procedures geïndexeerd",
|
||||
"providerNote": "Deze demo beantwoordt vanuit een kleine, vaste set geïndexeerde procedures — geen live RAGcore-koppeling. Een live RAGcore-backend zal later dezelfde interface overnemen, zonder dat deze pagina verandert.",
|
||||
"askHeading": "Stel een procedurevraag",
|
||||
"askSubheading": "Ophalen → evidentiecontrole → onderbouwd antwoord",
|
||||
"questionLabel": "Vraag",
|
||||
"questionPlaceholder": "bv. Wat moet ik doen wanneer een voertuig beschadigd terugkomt?",
|
||||
"ask": "Vraag stellen",
|
||||
"asking": "Bezig met vragen…",
|
||||
"askFailed": "Kon de kennisdienst niet bereiken.",
|
||||
"suggestedLabel": "Probeer:",
|
||||
"suggestedQuestions": [
|
||||
"Wat moet ik doen wanneer een voertuig terugkomt met schade?",
|
||||
"Hoe registreer ik een voertuigretour?",
|
||||
"Wanneer mag een voertuig opnieuw beschikbaar gezet worden?",
|
||||
"Wie beoordeelt een ongewone kilometerstand?",
|
||||
"Welke controles zijn verplicht vóór vertrek?"
|
||||
],
|
||||
"emptyTitle": "Evidentie voor antwoorden",
|
||||
"emptyDescription": "Vraag naar retours, schade, inspecties of een andere geïndexeerde procedure. Fleet Ops verzint geen antwoord wanneer evidentie ontbreekt.",
|
||||
"retrievalFlow": {
|
||||
"question": "Vraag",
|
||||
"sources": "Bronnen",
|
||||
"answer": "Antwoord"
|
||||
},
|
||||
"questionLabelExchange": "Vraag",
|
||||
"evidenceStates": {
|
||||
"grounded": "Onderbouwd met geciteerde procedures",
|
||||
"insufficient": "Onvoldoende evidentie",
|
||||
"unavailable": "Kennisdienst niet beschikbaar"
|
||||
},
|
||||
"unavailableBody": "De kennisdienst is momenteel niet bereikbaar. Operationele functies zijn hier niet door beïnvloed — probeer later opnieuw.",
|
||||
"sourceVersion": "v{{version}}"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"skipToContent": "Ga naar hoofdinhoud",
|
||||
"groups": {
|
||||
"operate": "Uitvoeren",
|
||||
"assure": "Bewaken"
|
||||
},
|
||||
"items": {
|
||||
"overview": "Overzicht",
|
||||
"fleet": "Wagenpark",
|
||||
"bookings": "Boekingen",
|
||||
"quality": "Datakwaliteit",
|
||||
"knowledge": "Kennis",
|
||||
"integrations": "Integraties",
|
||||
"audit": "Audit trail"
|
||||
},
|
||||
"primaryNavLabel": "Hoofdnavigatie",
|
||||
"mobileNavLabel": "Mobiele navigatie",
|
||||
"more": "Meer",
|
||||
"openNavigation": "Navigatie openen",
|
||||
"closeNavigation": "Navigatie sluiten",
|
||||
"sidebarEnvironment": "Demo-omgeving",
|
||||
"sidebarEnvironmentDetail": "Enkel synthetische gegevens",
|
||||
"resetDemoData": "Demogegevens herstellen",
|
||||
"resetConfirmTitle": "Demoreset bevestigen",
|
||||
"resetConfirmBody": "Alle synthetische wijzigingen worden ongedaan gemaakt en de deterministische demogegevens worden hersteld. Je wordt uitgelogd.",
|
||||
"resetting": "Bezig met herstellen…",
|
||||
"resetConfirmYes": "Ja, herstellen",
|
||||
"resetCancel": "Annuleren",
|
||||
"resetFailed": "Demogegevens konden niet hersteld worden.",
|
||||
"searchLabel": "Zoek in Fleet Ops",
|
||||
"searchPlaceholder": "Zoek wagenpark, boeking of onderdeel…",
|
||||
"searchShortcutHint": "Ctrl K",
|
||||
"searchSearching": "Zoeken…",
|
||||
"searchUnavailable": "Zoeken is momenteel niet beschikbaar.",
|
||||
"searchNoResults": "Geen resultaten voor \"{{query}}\".",
|
||||
"switchRole": "Wissel van rol",
|
||||
"switchRoleTitle": "Wissel van demo-rol",
|
||||
"languageSwitcherLabel": "Taal wijzigen"
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
{
|
||||
"list": {
|
||||
"eyebrow": "Bewaken / Werkbank",
|
||||
"title": "Datakwaliteit",
|
||||
"description": "Los evidentie-onderbouwde uitzonderingen op voor ze de werking verstoren.",
|
||||
"runScan": "Kwaliteitscontrole uitvoeren",
|
||||
"confirmScanTitle": "Kwaliteitscontrole bevestigen",
|
||||
"confirmScanBody": "Nu de deterministische controle over alle vijf regeltypes uitvoeren?",
|
||||
"scanning": "Bezig met controleren…",
|
||||
"confirmScanYes": "Ja, uitvoeren",
|
||||
"cancel": "Annuleren",
|
||||
"scanComplete": "Controle voltooid: {{summary}}",
|
||||
"scanNoNew": "geen nieuwe problemen gevonden (bestaande open problemen worden niet opnieuw aangemaakt).",
|
||||
"scanFailed": "Kwaliteitscontrole kon niet uitgevoerd worden.",
|
||||
"statusLabel": "Status",
|
||||
"statusAll": "Alle statussen",
|
||||
"statusOpen": "Open",
|
||||
"statusDeferred": "Uitgesteld",
|
||||
"statusResolved": "Opgelost",
|
||||
"statusRejected": "Verworpen",
|
||||
"ruleTypeLabel": "Regeltype",
|
||||
"ruleTypeAll": "Alle regeltypes",
|
||||
"demoScenariosOnly": "Enkel demoscenario's",
|
||||
"loading": "Kwaliteitswerkbank laden…",
|
||||
"queueClear": "Wachtrij is leeg",
|
||||
"noIssuesMatch": "Geen problemen komen overeen met de huidige filters.",
|
||||
"noDemoIssuesMatch": "Geen demoscenario-problemen komen overeen",
|
||||
"noDemoIssuesMatchDetail": "Vink 'Enkel demoscenario's' uit om de volledige wachtrij te zien.",
|
||||
"unavailable": "Datakwaliteitsproblemen zijn momenteel niet beschikbaar.",
|
||||
"count": "{{count}} problemen",
|
||||
"evidenceBacked": "Evidentie-onderbouwde detectie",
|
||||
"columns": {
|
||||
"reference": "Referentie",
|
||||
"rule": "Regel",
|
||||
"entity": "Entiteit",
|
||||
"severity": "Ernst",
|
||||
"status": "Status"
|
||||
}
|
||||
},
|
||||
"ruleTypes": {
|
||||
"possible_duplicate_customer": "Mogelijke dubbele klant",
|
||||
"missing_required_field": "Ontbrekend verplicht veld",
|
||||
"odometer_regression": "Afwijkende kilometerstand",
|
||||
"booking_overlap": "Overlappende boeking",
|
||||
"vehicle_status_conflict": "Statusconflict voertuig"
|
||||
},
|
||||
"severities": {
|
||||
"high": "Kritiek",
|
||||
"medium": "Waarschuwing",
|
||||
"low": "Info"
|
||||
},
|
||||
"detail": {
|
||||
"backLink": "Kwaliteitswerkbank",
|
||||
"eyebrow": "Kwaliteit / {{rule}}",
|
||||
"title": "Bekijk vastgelegde evidentie en registreer een geauditeerde oplossing.",
|
||||
"notFound": "Dit probleem kon niet gevonden worden.",
|
||||
"loading": "Probleemevidentie laden…",
|
||||
"managerOnly": "De kwaliteitswerkbank is enkel zichtbaar voor Operations Managers.",
|
||||
"managerOnlyDetail": "Datakwaliteitsevidentie en -oplossingen zijn enkel zichtbaar voor Operations Managers.",
|
||||
"summary": {
|
||||
"rule": "Regel",
|
||||
"entity": "Entiteit",
|
||||
"evidenceSummary": "Evidentiesamenvatting"
|
||||
},
|
||||
"resolved": {
|
||||
"title": "Probleem {{ref}} opgelost",
|
||||
"body": "De wijziging is doorgevoerd en vastgelegd in de audit trail.",
|
||||
"viewAudit": "Audit trail bekijken",
|
||||
"viewVehicle": "Voertuig bekijken",
|
||||
"continueDemo": "Ga verder met de demo"
|
||||
},
|
||||
"deferOrReject": {
|
||||
"heading": "Uitstellen of verwerpen",
|
||||
"description": "Stel uit om later opnieuw te bekijken, of verwerp als dit geen echt probleem is.",
|
||||
"defer": "Uitstellen",
|
||||
"reject": "Verwerpen",
|
||||
"deferFailed": "Kon dit probleem niet uitstellen.",
|
||||
"rejectFailed": "Kon dit probleem niet verwerpen."
|
||||
},
|
||||
"explainer": {
|
||||
"whatIsWrong": "Wat is er mis",
|
||||
"whyItMatters": "Waarom dit belangrijk is",
|
||||
"possible_duplicate_customer": {
|
||||
"whatIsWrong": "Twee klantprofielen delen identificerende gegevens (e-mail, telefoon of een erg gelijkende naam) sterk genoeg om waarschijnlijk dezelfde persoon te zijn, twee keer geregistreerd.",
|
||||
"whyItMatters": "Dubbele klanten verdelen de boekingsgeschiedenis over twee records, riskeren dubbele facturatie en verwarren klantcontacten."
|
||||
},
|
||||
"missing_required_field": {
|
||||
"whatIsWrong": "Dit record mist gegevens die vereist zijn voor normale werking (bijvoorbeeld een klant zonder e-mail of telefoonnummer).",
|
||||
"whyItMatters": "Zonder deze gegevens kan het bedrijf de klant niet bereiken, of het voertuig niet betrouwbaar identificeren voor compliance- en overdrachtscontroles."
|
||||
},
|
||||
"odometer_regression": {
|
||||
"whatIsWrong": "Een ingevoerde kilometerstand ligt lager dan de laatst bevestigde (canonieke) stand van het voertuig.",
|
||||
"whyItMatters": "Een dalende kilometerstand wijst meestal op een invoerfout of een verwisseld voertuig. Dit stilzwijgend doorlaten zou de onderhoudsplanning en de kilometerhistoriek bij wederverkoop verstoren."
|
||||
},
|
||||
"booking_overlap": {
|
||||
"whatIsWrong": "Hetzelfde voertuig is toegewezen aan twee boekingen met overlappende periodes.",
|
||||
"whyItMatters": "Slechts één van deze boekingen kan effectief worden nagekomen. Onopgelost zou een klant aankomen en merken dat zijn voertuig al bij iemand anders is."
|
||||
},
|
||||
"vehicle_status_conflict": {
|
||||
"whatIsWrong": "De opgeslagen operationele status van dit voertuig komt niet overeen met wat de eigen boekings- en inspectiegeschiedenis impliceert.",
|
||||
"whyItMatters": "Een foutieve status kan een niet-beschikbaar voertuig boekbaar laten lijken, of een beschikbaar voertuig verbergen voor het wagenpark."
|
||||
}
|
||||
},
|
||||
"duplicateCustomer": {
|
||||
"heading": "Vergelijken en samenvoegen",
|
||||
"description": "Kies de klant die behouden blijft en bekijk elk afwijkend veld.",
|
||||
"keepAsSurvivor": "Behouden als hoofdprofiel",
|
||||
"differs": "Verschilt",
|
||||
"match": "Gelijk",
|
||||
"mergePreview": "{{loser}} wordt een tombstone gekoppeld aan {{survivor}}; de boekingen worden herverbonden.",
|
||||
"mergeInto": "Samenvoegen met {{ref}}",
|
||||
"confirmMergeTitle": "Samenvoegen bevestigen",
|
||||
"confirmMergeBody": "{{loser}} samenvoegen met {{survivor}}? Dit kan niet ongedaan gemaakt worden.",
|
||||
"merging": "Bezig met samenvoegen…",
|
||||
"confirmMergeYes": "Ja, samenvoegen",
|
||||
"mergeFailed": "Kon deze klanten niet samenvoegen.",
|
||||
"bothMissing": "Beide klanten in deze vergelijking konden niet geladen worden.",
|
||||
"fieldColumn": "Veld",
|
||||
"fields": {
|
||||
"first_name": "Voornaam",
|
||||
"last_name": "Achternaam",
|
||||
"email": "E-mail",
|
||||
"phone": "Telefoon",
|
||||
"postal_code": "Postcode",
|
||||
"city": "Stad"
|
||||
}
|
||||
},
|
||||
"missingField": {
|
||||
"heading": "Ontbrekende velden invullen",
|
||||
"description": "Vervolledig het record voor {{ref}}. Het probleem wordt automatisch opgelost zodra niets verplichts meer ontbreekt.",
|
||||
"atLeastOne": "Minstens één van e-mail of telefoon is vereist.",
|
||||
"saveAndRecheck": "Opslaan en herchecken",
|
||||
"saving": "Opslaan…",
|
||||
"saveFailed": "Kon deze velden niet opslaan.",
|
||||
"fields": {
|
||||
"first_name": "Voornaam",
|
||||
"last_name": "Achternaam",
|
||||
"email": "E-mail",
|
||||
"phone": "Telefoon",
|
||||
"registration_number": "Kenteken",
|
||||
"make": "Merk",
|
||||
"model": "Model",
|
||||
"location": "Locatie"
|
||||
}
|
||||
},
|
||||
"odometerRegression": {
|
||||
"heading": "Kilometerafwijking oplossen",
|
||||
"description": "De laatst bevestigde kilometerstand wordt nooit automatisch verlaagd — kies hoe dit te verwerken.",
|
||||
"canonicalOdometer": "Laatst bevestigde kilometerstand",
|
||||
"decisionLegend": "Beslissing",
|
||||
"retainCanonical": "Laatst bevestigde stand behouden",
|
||||
"retainCanonicalDetail": "Behandel de ingevoerde stand als foutief; er verandert niets aan het voertuigrecord.",
|
||||
"correctReading": "Stand corrigeren",
|
||||
"correctReadingDetail": "Werk zowel de boeking als de laatst bevestigde kilometerstand bij met de juiste waarde.",
|
||||
"noBookingAttached": "Geen gekoppelde boeking bij dit probleem, dus enkel 'laatst bevestigde stand behouden' is beschikbaar.",
|
||||
"booking": "Boeking",
|
||||
"correctedOdometer": "Gecorrigeerde kilometerstand (km)",
|
||||
"note": "Notitie",
|
||||
"resolving": "Bezig met oplossen…",
|
||||
"resolveIssue": "Probleem oplossen",
|
||||
"resolveFailed": "Kon dit probleem niet oplossen."
|
||||
},
|
||||
"bookingOverlap": {
|
||||
"heading": "Boekingsoverlap oplossen",
|
||||
"description": "Blokkeer één van de twee overlappende verbintenissen. De andere behoudt zijn huidige status.",
|
||||
"columns": {
|
||||
"booking": "Boeking",
|
||||
"window": "Periode",
|
||||
"status": "Status",
|
||||
"blockThis": "Deze blokkeren"
|
||||
},
|
||||
"blockLabel": "{{ref}} blokkeren",
|
||||
"note": "Notitie",
|
||||
"resolving": "Bezig met oplossen…",
|
||||
"blockButton": "{{ref}} blokkeren",
|
||||
"blockButtonFallback": "Boeking blokkeren",
|
||||
"resolveFailed": "Kon deze overlap niet oplossen."
|
||||
},
|
||||
"vehicleStatusConflict": {
|
||||
"heading": "Statusconflict oplossen",
|
||||
"description": "Eén gezaghebbende regel beveelt een gecorrigeerde operationele status voor dit voertuig aan.",
|
||||
"currentStatus": "Huidige status",
|
||||
"calculateAndApply": "Aanbevolen status berekenen en toepassen",
|
||||
"confirmTitle": "Statuswijziging bevestigen",
|
||||
"confirmBody": "De gezaghebbende aanbevolen status voor dit voertuig toepassen?",
|
||||
"applying": "Bezig met toepassen…",
|
||||
"confirmYes": "Ja, toepassen",
|
||||
"applied": "Toegepast {{status}} — {{reason}}",
|
||||
"applyFailed": "Kon geen aanbevolen status toepassen."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"progress": {
|
||||
"capture": "Vastleggen",
|
||||
"review": "Nakijken",
|
||||
"result": "Resultaat",
|
||||
"ariaLabel": "Voortgang retourregistratie"
|
||||
},
|
||||
"capture": {
|
||||
"heading": "Voertuigretour registreren",
|
||||
"description": "Leg de staat bij inlevering vast. De volgende stap evalueert de exacte operationele gevolgen voor er iets wordt bevestigd.",
|
||||
"endOdometer": "Eindkilometerstand (km)",
|
||||
"fuelLevel": "Brandstofniveau (%)",
|
||||
"conditionLegend": "Voertuigstaat",
|
||||
"cleanlinessOk": "Netheid aanvaardbaar",
|
||||
"damageReported": "Schade gemeld",
|
||||
"technicalWarning": "Technische melding",
|
||||
"notes": "Notities",
|
||||
"evaluating": "Evalueren…",
|
||||
"reviewReturn": "Retour nakijken"
|
||||
},
|
||||
"review": {
|
||||
"heading": "Retourimpact nakijken",
|
||||
"description": "Dit is de gezaghebbende serverevaluatie van wat bevestigen zal doen — controleer dit voor het de wagenparkstatus bijwerkt en automatisering start.",
|
||||
"odometer": "Kilometerstand",
|
||||
"fuel": "Brandstof",
|
||||
"cleanliness": "Netheid",
|
||||
"cleanlinessAccepted": "Aanvaard",
|
||||
"cleanlinessFollowUp": "Opvolging nodig",
|
||||
"damage": "Schade",
|
||||
"damageReported": "Gemeld",
|
||||
"damageNone": "Niet gemeld",
|
||||
"technicalWarning": "Technische melding",
|
||||
"technicalWarningReported": "Gemeld",
|
||||
"technicalWarningNone": "Niet gemeld",
|
||||
"expectedState": "Verwachte wagenparkstatus:",
|
||||
"odometerRegressionWarning": "De ingevoerde kilometerstand ({{submitted}} km) ligt onder de laatst bevestigde stand ({{canonical}} km). De laatst bevestigde kilometerstand wijzigt niet en er wordt een datakwaliteitsprobleem geopend.",
|
||||
"nextBookingRisk": "Volgende boeking {{ref}} start {{when}} — mogelijk beïnvloed door deze retour.",
|
||||
"nextBookingLowRisk": "Volgende boeking {{ref}} start {{when}} — laag risico.",
|
||||
"commitList": {
|
||||
"inspection": "Retourinspectie aanmaken",
|
||||
"updateAtomic": "Boeking en voertuig atomair bijwerken",
|
||||
"queueAutomation": "Automatisering inplannen na de lokale verwerking"
|
||||
},
|
||||
"editDetails": "Gegevens bewerken",
|
||||
"registering": "Registreren…",
|
||||
"confirmReturn": "Retour bevestigen"
|
||||
},
|
||||
"result": {
|
||||
"committedLocally": "Lokaal verwerkt",
|
||||
"heading": "Retour geregistreerd",
|
||||
"inspection": "Inspectie",
|
||||
"resultingStatus": "Resulterende wagenparkstatus",
|
||||
"qualityIssue": "Datakwaliteitsprobleem",
|
||||
"noneCreated": "Geen aangemaakt",
|
||||
"automationEvent": "Automatiseringsopdracht",
|
||||
"queuedForDelivery": "Klaargezet voor verwerking ({{ref}}) — lokale verwerking gelukt; aflevering via automatisering gebeurt asynchroon en is nog niet bevestigd.",
|
||||
"nextBookingRisk": "Risico volgende boeking",
|
||||
"nextBookingRiskValue": "{{ref}} {{status}}",
|
||||
"atRisk": "— mogelijk beïnvloed",
|
||||
"lowRisk": "— laag risico",
|
||||
"noUpcomingBooking": "Geen aankomende boeking voor dit voertuig",
|
||||
"odometerRegressionNotice": "De ingevoerde kilometerstand lag onder de laatst bevestigde stand van het voertuig. Ze werd zo geregistreerd; de laatst bevestigde kilometerstand is niet gewijzigd en er is een datakwaliteitsprobleem geopend ter controle.",
|
||||
"viewVehicle": "Voertuig {{ref}} bekijken",
|
||||
"viewAutomation": "Automatiseringsstatus bekijken",
|
||||
"viewAudit": "Audit trail bekijken",
|
||||
"continueDemo": "Ga verder met de demo"
|
||||
},
|
||||
"scenario": {
|
||||
"title": "Demonstratiescenario: afwijkende kilometerstand",
|
||||
"body": "Dit voertuig staat momenteel op {{odometer}} km. Het onderstaande formulier is vooraf ingevuld met een retourstand die daaronder ligt — een teken van een foutieve invoer of een verwisseld voertuig. Bevestig de retour om te zien hoe Fleet Ops dit detecteert en afhandelt.",
|
||||
"preparing": "Scenario voorbereiden…"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user