# Internationalisation (enso-front) ## Catalogues et locale - **Référence des clés** : `enso/enso-front/src/i18n/messages.fr.ts` (littéraux `as const`). Les chemins valides pour `translate()` / `t()` sont typés via `MessagePath` (`enso/enso-front/src/i18n/messagePath.ts`). - **Second catalogue** : `enso/enso-front/src/i18n/messages.en.ts`, même forme typée avec `MessageCatalog` (`DeepStringMap` dans `messages.fr.ts`). - **Locale par défaut (sans stockage)** : `DEFAULT_LOCALE` (`fr`) dans `enso/enso-front/src/i18n/catalog.ts`. - **Préférence utilisateur** : `enso/enso-front/src/i18n/localeStorage.ts` — clé `localStorage` `APP_LOCALE_STORAGE_KEY` (`enso-front-app-locale`), valeurs `fr` | `en`. - **React** : `I18nProvider` (`enso/enso-front/src/i18n/context.tsx`) lit la valeur au montage (`useLayoutEffect`), expose `locale`, `setLocale` (persiste), et `t` sur `getMessages(locale)`. Composant `DocumentLangSync` : `document.documentElement.lang` = préfixe BCP 47 (`fr` ou `en`). Écoute `storage` pour les autres ondulations. - **Hors React (formatters, messages docv/OAuth)** : `getActiveAppLocale()` / `setActiveAppLocale()` dans `enso/enso-front/src/i18n/activeLocale.ts`, synchronisés avec le provider. - **BCP 47 pour `Intl`** : `bcp47ForAppLocale()` — `fr` → `fr-FR`, `en` → `en-US` (`catalog.ts`). - **Métadonnées Next (serveur)** : `app/layout.tsx` utilise encore `getMessages(DEFAULT_LOCALE)` pour `metadata` ; le `` statique est complété côté client par `DocumentLangSync`. - **Résolution** : `translate()` lève si la clé est absente (`enso/enso-front/src/i18n/translate.ts`). ## Libellés partagés - Clés sous `shared.*` pour éviter les doublons (ex. `shared.labelActiveCasesShort`, `shared.labelPermanentInfoShort`) : stats tableau de bord, barre latérale, onglets société. ## Menu utilisateur et 404 - **Langue** : `AppLayoutUserMenu` — `layout.menuLanguage`, `layout.languageFr`, `layout.languageEn`, groupe radio relié à `setLocale`. - **404** : `NotFoundContent` — `layout.notFoundTitle`, `layout.notFoundBackToDashboard`. ## Erreurs docv (pas de texte serveur brut à l’écran) - `translateDocvFailure()` (`enso/enso-front/src/i18n/docvErrorMessage.ts`) mappe statuts HTTP, configuration manquante, et erreurs réseau vers `errors.docv*` du catalogue **actif** (`getActiveAppLocale()`). - Utilisé par : `loadStubListsOnce`, `useOfficesCatalog`, `resolveOfficePageLoad`, `resolveCasePageLoad`. ## OAuth / docv callback - `runDocvCallbackExchange` : union discriminée (`enso/enso-front/src/lib/docvOAuthBrowser.ts`), messages via `getMessages(getActiveAppLocale())`. ## Données métier - `Company.siren` / `address` : `null` si l’API ne les fournit pas ; affichage `common.notProvided`. - **Société vs dossier d’opération** : une **société** (écran + `DocvOffice`) correspond au **dossier permanent** et **n’est pas** une opération ; les lignes **Dossiers** sous la fiche société sont les **opérations / demandes** (ressource API `folders`, type `Case`). Libellés orientés utilisateur : `dashboard.companiesDescription`, `company.permanentDescription`, `shared.labelPermanentInfoShort`. Référence : [MODELE_SOCIETES_ET_DOSSIERS_DOPERATION.md](MODELE_SOCIETES_ET_DOSSIERS_DOPERATION.md). - **Type d’opération** : préfixes `case.operationType.*` (presets, section démo, formulaire nouveau dossier, fiche dossier). **Checklists métier par slug** : `case.operationChecklist..*` (`title`, `description`, `sourceLine`, `legendTitle`, `suggestedTitle` — ce dernier pour le dialogue nouveau dossier si le slug est enregistré dans `suggestedFolderTitles.ts`). Référence : [OPERATION_CHECKLISTS.md](OPERATION_CHECKLISTS.md). **Messagerie** : `messaging.description` (sociétés + opérations). ## Formatters et `Intl` partagé - Module **`enso/enso-front/src/lib/intlAppLocale.ts`** : `appIntlBcp47()` (BCP 47 = `bcp47ForAppLocale(getActiveAppLocale())`), `formatNumberForAppLocale()` pour les nombres à l’écran. - **Hors enso-front** : pas de runtime JavaScript/`Intl` dans `enso-back` ou `docv` (Rust) ; seul le front consomme ce module. - Types de pièces, statuts de dossier, tailles fichiers, archétype DP : `translate(getMessages(getActiveAppLocale()), …)` dans `enso/enso-front/src/lib/formatters.ts` (ex. `company.dpArchetypeDemoEnterprise` pour `dp_archetype = entreprise_demo`). - **Dates courtes** : `formatDate()` utilise `toLocaleDateString(appIntlBcp47(), …)`. - **Sidebar** : tri des sociétés et listes de dossiers actifs dans `appSidebarModel.ts` via `localeCompare(..., appIntlBcp47())` ; ordre secondaire société / titre lorsque le statut « action en attente » est identique. - **Graphiques** : tooltip Recharts (`components/ui/chart.tsx`) formate les valeurs numériques avec `formatNumberForAppLocale` lorsque la valeur est un nombre fini. ## Suspense - Repli React explicite traduit : `I18nSuspenseFallback` (`enso/enso-front/src/components/i18n/I18nSuspenseFallback.tsx`). ## Recherche sidebar - `AppSidebarSearchResults` : `layout.searchNoResults`, `layout.searchContextSeparator` (séparation société / dossier dans la ligne secondaire).