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": "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…"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user