@object-ui/i18n 17.3.0 → 17.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +1295 -1
  2. package/README.md +0 -13
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +11 -1
  5. package/dist/locales/ar.d.ts +466 -107
  6. package/dist/locales/ar.js +559 -153
  7. package/dist/locales/de.d.ts +466 -107
  8. package/dist/locales/de.js +574 -175
  9. package/dist/locales/en.d.ts +502 -143
  10. package/dist/locales/en.js +678 -145
  11. package/dist/locales/es.d.ts +466 -107
  12. package/dist/locales/es.js +553 -155
  13. package/dist/locales/fr.d.ts +466 -107
  14. package/dist/locales/fr.js +553 -152
  15. package/dist/locales/index.d.ts +4734 -1144
  16. package/dist/locales/ja.d.ts +466 -107
  17. package/dist/locales/ja.js +545 -146
  18. package/dist/locales/ko.d.ts +466 -107
  19. package/dist/locales/ko.js +551 -153
  20. package/dist/locales/pt.d.ts +466 -107
  21. package/dist/locales/pt.js +552 -154
  22. package/dist/locales/ru.d.ts +466 -107
  23. package/dist/locales/ru.js +563 -153
  24. package/dist/locales/zh.d.ts +501 -142
  25. package/dist/locales/zh.js +542 -142
  26. package/dist/pickLocalized.d.ts +21 -0
  27. package/dist/pickLocalized.js +40 -7
  28. package/dist/provider.d.ts +83 -1
  29. package/dist/provider.js +303 -29
  30. package/dist/useDisplayLocale.d.ts +49 -0
  31. package/dist/useDisplayLocale.js +55 -0
  32. package/dist/useObjectLabel.d.ts +8 -2
  33. package/dist/useObjectLabel.js +28 -8
  34. package/dist/useSafeTranslation.js +50 -2
  35. package/dist/utils/index.d.ts +1 -0
  36. package/dist/utils/index.js +1 -0
  37. package/dist/utils/number-display.d.ts +32 -0
  38. package/dist/utils/number-display.js +32 -0
  39. package/dist/utils/spec-formatters.d.ts +39 -13
  40. package/dist/utils/spec-formatters.js +3 -3
  41. package/package.json +4 -3
@@ -1,4 +1,18 @@
1
1
  const fr = {
2
+ // objectui#4467 — the impersonation banner (app-shell ImpersonationBanner).
3
+ // Raised by `session.impersonatedBy`, so it survives SPA reboots; it names
4
+ // BOTH parties because the audit trail attributes the work to the impersonated
5
+ // user, and the exit states its own failure rather than appearing to succeed.
6
+ impersonation: {
7
+ banner: {
8
+ message: 'Vous incarnez {{user}} — chaque action est enregistrée en son nom.',
9
+ startedBy: 'Démarré par l’administrateur {{admin}}.',
10
+ stop: 'Arrêter l’usurpation',
11
+ stopping: 'Arrêt en cours…',
12
+ stopFailed: 'Impossible d’arrêter l’usurpation : {{reason}}',
13
+ notRestored: 'Le serveur a accepté la demande mais n’a pas restauré votre session administrateur — vous incarnez toujours {{user}}. Déconnectez-vous puis reconnectez-vous pour y mettre fin.',
14
+ },
15
+ },
2
16
  // objectui#2600 B5 — capability picker scope group headers (labels come from the sys_capability registry).
3
17
  capability: {
4
18
  label: {
@@ -16,6 +30,26 @@ const fr = {
16
30
  other: 'Autre',
17
31
  },
18
32
  },
33
+ // objectui#3546 slice six — le résumé en lecture seule des facettes
34
+ // d'autorisation de PermissionFacetLink. Apostrophe droite U+0027 comme dans
35
+ // le reste du paquet, et espace avant les deux-points.
36
+ perm: {
37
+ facet: {
38
+ none: "Aucun",
39
+ more: "+{{count}} de plus",
40
+ objects: "{{count}} objets",
41
+ objects_one: "{{count}} objet",
42
+ fields: "{{count}} règles de champ",
43
+ fields_one: "{{count}} règle de champ",
44
+ rls: "{{count}} politiques RLS",
45
+ rls_one: "{{count}} politique RLS",
46
+ tabs: "{{count}} règles d'onglet",
47
+ tabs_one: "{{count}} règle d'onglet",
48
+ adminScope: "Administration déléguée configurée",
49
+ designInStudio: "Concevoir dans Studio →",
50
+ designInStudioHint: "Concevoir dans Studio",
51
+ },
52
+ },
19
53
  lookup: {
20
54
  recentlyUsed: 'Récemment utilisés',
21
55
  allResults: 'Tous les résultats',
@@ -46,13 +80,12 @@ const fr = {
46
80
  common: {
47
81
  addToFavorites: "Ajouter aux favoris",
48
82
  removeFromFavorites: "Retirer des favoris",
49
- loading: "Chargement...",
83
+ loading: "Chargement…",
50
84
  save: "Enregistrer",
51
85
  cancel: "Annuler",
52
86
  delete: "Supprimer",
53
87
  edit: "Modifier",
54
88
  create: "Créer",
55
- search: "Rechercher",
56
89
  filter: "Filtrer",
57
90
  reset: "Réinitialiser",
58
91
  confirm: "Confirmer",
@@ -76,7 +109,7 @@ const fr = {
76
109
  required: "Obligatoire",
77
110
  optional: "Facultatif",
78
111
  selectOption: "Sélectionner une option",
79
- select: "Sélectionner...",
112
+ select: "Sélectionner…",
80
113
  openChat: "Ouvrir le chat",
81
114
  closeChat: "Fermer le chat",
82
115
  closePanel: "Fermer le panneau",
@@ -85,6 +118,11 @@ const fr = {
85
118
  itemCountOne: "{{count}} élément",
86
119
  toggleSidebar: "Basculer la barre latérale",
87
120
  package: "Package",
121
+ done: "Terminé",
122
+ editInStudio: "Modifier dans Studio",
123
+ record: "Enregistrement",
124
+ retry: "Réessayer",
125
+ printDialogHint: "Ouvre la boîte de dialogue d'impression de votre navigateur (ce n'est pas un export PDF)",
88
126
  },
89
127
  actions: {
90
128
  decisionOutput: {
@@ -116,6 +154,9 @@ const fr = {
116
154
  submitFailed: "Échec de l'enregistrement. Veuillez réessayer.",
117
155
  discardTitle: "Abandonner les modifications ?",
118
156
  discardMessage: "Vous avez des modifications non enregistrées. Si vous fermez ce formulaire maintenant, vos modifications seront perdues.",
157
+ // objectui#4024 — the create/edit dialog's `sr-only` accessible
158
+ // description, used when the form declares no `description` of its own.
159
+ dialogDescriptionFallback: "Remplissez les champs du formulaire, puis envoyez ou annulez.",
119
160
  keepEditing: "Continuer l'édition",
120
161
  discard: "Abandonner",
121
162
  conflictTitle: "Conflit d'enregistrement",
@@ -184,7 +225,7 @@ const fr = {
184
225
  richText: {
185
226
  format: "Format : {{format}}",
186
227
  basicEditorHint: "Éditeur de texte enrichi (basique)",
187
- placeholder: "Écrivez quelque chose...",
228
+ placeholder: "Écrivez quelque chose…",
188
229
  },
189
230
  options: {
190
231
  empty: "Aucune option disponible",
@@ -250,7 +291,7 @@ const fr = {
250
291
  saveAll: "Tout enregistrer ({{count}})",
251
292
  addRecord: "Ajouter un enregistrement",
252
293
  open: "Ouvrir",
253
- search: "Rechercher...",
294
+ search: "Rechercher…",
254
295
  modified: "{{count}} ligne(s) modifiée(s)",
255
296
  saveFailed: 'Échec de l’enregistrement',
256
297
  selected: "{{count}} sélectionné(s)",
@@ -294,7 +335,7 @@ const fr = {
294
335
  delete: "Supprimer",
295
336
  export: "Exporter",
296
337
  exportAs: "Exporter en {{format}}",
297
- loading: "Chargement de la grille...",
338
+ loading: "Chargement de la grille…",
298
339
  errorLoading: "Erreur de chargement de la grille",
299
340
  pullToRefresh: "Tirer pour actualiser",
300
341
  refreshing: "Actualisation…",
@@ -305,6 +346,22 @@ const fr = {
305
346
  yes: "Oui",
306
347
  no: "Non",
307
348
  systemFields: "Système",
349
+ // objectui#4024 — column-footer aggregate prefixes, keyed by the spec's
350
+ // `ColumnSummary` vocabulary. `pattern` owns the label/value join so this
351
+ // pack controls its own separator and word order.
352
+ summary: {
353
+ pattern: "{{label}} : {{value}}",
354
+ count: "Nombre",
355
+ countEmpty: "Vides",
356
+ countFilled: "Remplis",
357
+ countUnique: "Uniques",
358
+ percentEmpty: "Vides",
359
+ percentFilled: "Remplis",
360
+ sum: "Somme",
361
+ avg: "Moyenne",
362
+ min: "Min",
363
+ max: "Max",
364
+ },
308
365
  toolbar: {
309
366
  densityMode: "Densité",
310
367
  densityCompact: "Compact",
@@ -418,12 +475,12 @@ const fr = {
418
475
  templateName: "Nom du modèle",
419
476
  save: "Enregistrer",
420
477
  deleteTemplate: "Supprimer le modèle",
421
- savedMapping: 'Saved mapping:',
422
- chooseSavedMapping: 'Choose a saved mapping…',
423
- manualMapping: '— Map columns manually —',
424
- transform: 'Transform',
425
- savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
426
- savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
478
+ savedMapping: "Correspondance enregistrée :",
479
+ chooseSavedMapping: "Choisir une correspondance enregistrée…",
480
+ manualMapping: "— Faire correspondre les colonnes manuellement —",
481
+ transform: 'Transformation',
482
+ savedMappingHint: "La correspondance « {{name}} » applique le renommage + les transformations + la conversion de type côté serveur. La correspondance des colonnes est en lecture seule.",
483
+ savedMappingPreviewNote: "L'aperçu affiche vos colonnes source ; à l'import, la correspondance « {{name}} » applique le renommage, les transformations et la conversion de type côté serveur.",
427
484
  csvColumn: "Colonne",
428
485
  mapsTo: "Correspond à",
429
486
  typeMismatch: "Ressemble à {{type}}",
@@ -483,6 +540,8 @@ const fr = {
483
540
  loadErrorUnauthorizedMessage: "Votre session a expiré ou vous êtes déconnecté. Reconnectez-vous pour consulter ces enregistrements.",
484
541
  loadErrorRejectedTitle: "La requête de cette vue a été rejetée",
485
542
  loadErrorRejectedMessage: "Le serveur n’a pas pu traiter le filtre ou les options de requête de cette vue. Effacer les filtres suffit généralement ; si la vue est enregistrée ainsi, un administrateur doit la corriger.",
543
+ loadErrorApiDisabledTitle: "Cet objet n’est pas disponible via l’API",
544
+ loadErrorApiDisabledMessage: "Cette page ne peut pas charger ses enregistrements car l’objet n’est pas exposé via l’API. Il s’agit d’un paramètre de l’objet lui-même, pas d’une autorisation : un administrateur doit activer l’accès API pour que cette page fonctionne.",
486
545
  retry: "Réessayer",
487
546
  managedBy: {
488
547
  system: {
@@ -507,7 +566,7 @@ const fr = {
507
566
  },
508
567
  },
509
568
  refresh: "Actualiser",
510
- loading: 'Loading records...',
569
+ loading: "Chargement des enregistrements…",
511
570
  recordCount: "{{count}} enregistrements",
512
571
  recordCountOne: "{{count}} enregistrement",
513
572
  addRecord: "Ajouter un enregistrement",
@@ -519,7 +578,8 @@ const fr = {
519
578
  sort: "Trier",
520
579
  sortRecords: "Trier les enregistrements",
521
580
  sortByIdSuffix: "(par ID)",
522
- sortRelationalHint: "Les colonnes qui pointent vers un autre enregistrement ne sont pas listées : elles ne peuvent être triées que par l'ID stocké, et non par le nom affiché dans la cellule. Pour trier par ce nom, ajoutez un champ de formule qui le contient.",
581
+ sortRelationalHint: "Les colonnes qui pointent vers un autre enregistrement ne sont pas listées : elles ne peuvent être triées que par l'ID stocké, et non par le nom affiché dans la cellule. Pour trier par ce nom, dénormalisez-le sur cet objet sous la forme d'un champ stocké, écrit à chaque modification de la source, puis triez sur ce champ. Pas un champ de formule : il est virtuel, aucune colonne n'est stockée pour lui et le serveur refuse de trier dessus.",
582
+ resetSortToDefault: "Réinitialiser au tri par défaut de la vue",
523
583
  group: "Grouper",
524
584
  groupBy: "Grouper par",
525
585
  export: "Exporter",
@@ -577,13 +637,16 @@ const fr = {
577
637
  },
578
638
  kanban: {
579
639
  uncategorized: "Non catégorisé",
640
+ columns: "colonnes",
580
641
  addCard: "Ajouter une carte",
581
642
  addColumn: "Ajouter une colonne",
582
643
  moveCard: "Déplacer la carte",
583
644
  deleteCard: "Supprimer la carte",
584
645
  deleteColumn: "Supprimer la colonne",
585
646
  noCards: "Aucune carte",
586
- cardTitlePlaceholder: "Saisir le titre de la carte...",
647
+ cardTitlePlaceholder: "Saisir le titre de la carte…",
648
+ requiredFieldsTitle: "Compléter les champs obligatoires",
649
+ requiredFieldsDescription: "Ce déplacement rend les champs ci-dessous obligatoires. Remplissez-les pour continuer.",
587
650
  },
588
651
  timeline: {
589
652
  bucket: {
@@ -596,6 +659,13 @@ const fr = {
596
659
  noDate: "Sans date",
597
660
  unassigned: "Non attribué",
598
661
  },
662
+ scale: {
663
+ week: "Semaine {{n}}",
664
+ quarter: "T{{quarter}} {{year}}",
665
+ },
666
+ gantt: {
667
+ rowLabel: "Éléments",
668
+ },
599
669
  },
600
670
  gantt: {
601
671
  viewMode: {
@@ -642,6 +712,18 @@ const fr = {
642
712
  ff: "Fin → Fin",
643
713
  sf: "Début → Fin",
644
714
  },
715
+ linkEnd: {
716
+ start: "Début",
717
+ end: "Fin",
718
+ },
719
+ link: {
720
+ rejected: {
721
+ self: "Une tâche ne peut pas dépendre d’elle-même.",
722
+ locked: "Cette ligne est verrouillée et ne peut pas recevoir de nouvelle dépendance.",
723
+ group: "Une ligne récapitulative ne peut pas recevoir de dépendance — reliez plutôt l’une de ses tâches.",
724
+ cycle: "Ce lien créerait une dépendance circulaire.",
725
+ },
726
+ },
645
727
  conflict: {
646
728
  title: "Conflit de planning",
647
729
  body: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche(s) concernée(s) ?",
@@ -650,8 +732,8 @@ const fr = {
650
732
  },
651
733
  autoScheduleDlg: {
652
734
  title: "Planification automatique",
653
- body: "Décaler {count} tâche(s) plus tard pour respecter les liens de dépendance ?",
654
- skipped: "{count} tâche(s) verrouillée(s) violent aussi les liens et ont été ignorées.",
735
+ body: "Décaler {{count}} tâche(s) plus tard pour respecter les liens de dépendance ?",
736
+ skipped: "{{count}} tâche(s) verrouillée(s) violent aussi les liens et ont été ignorées.",
655
737
  confirm: "Appliquer",
656
738
  cancel: "Annuler",
657
739
  none: "Toutes les dépendances sont respectées — rien à replanifier.",
@@ -688,6 +770,7 @@ const fr = {
688
770
  exportPng: "Exporter en PNG",
689
771
  exportPdf: "Exporter en PDF",
690
772
  saveLayout: "Enregistrer la disposition",
773
+ refresh: "Actualiser",
691
774
  undo: "Annuler",
692
775
  redo: "Rétablir",
693
776
  prevPeriod: "Période précédente",
@@ -728,11 +811,11 @@ const fr = {
728
811
  defaultBadge: "par défaut",
729
812
  tabActionsFor: "Actions de vue pour {{name}}",
730
813
  readonlyAriaLabel: "Vue en lecture seule",
731
- readonlyTooltip: "Vue système — dupliquer pour personnaliser.",
814
+ readonlyTooltip: "Vue système — définie dans le code, en lecture seule.",
732
815
  },
733
816
  designer: {
734
- undo: 'Undo',
735
- redo: 'Redo',
817
+ undo: "Annuler",
818
+ redo: "Rétablir",
736
819
  },
737
820
  detail: {
738
821
  editInlineHint: "Double-cliquez pour modifier",
@@ -774,13 +857,15 @@ const fr = {
774
857
  relatedRecords: "{{count}} enregistrements",
775
858
  relatedRecordOne: "{{count}} enregistrement",
776
859
  noRelatedRecords: "Aucun enregistrement associé trouvé",
777
- loading: "Chargement...",
860
+ loading: "Chargement…",
778
861
  copyToClipboard: "Copier dans le presse-papiers",
779
862
  copied: "Copié !",
780
863
  deleteConfirmation: "Êtes-vous sûr de vouloir supprimer cet enregistrement ?",
864
+ deleted: "Enregistrement supprimé",
781
865
  editRecord: "Modifier l'enregistrement",
782
866
  viewAll: "Tout afficher",
783
867
  new: "Nouveau",
868
+ add: "Ajouter",
784
869
  emptyValue: "—",
785
870
  comments: "Commentaires",
786
871
  searchComments: "Rechercher des commentaires…",
@@ -845,6 +930,7 @@ const fr = {
845
930
  loadMore: "Charger plus",
846
931
  edited: "(modifié)",
847
932
  via: "via {{source}}",
933
+ viewSource: "Voir la source",
848
934
  replyCount: "{{count}} réponse",
849
935
  replyCountPlural: "{{count}} réponses",
850
936
  replyPlaceholder: "Répondre…",
@@ -886,9 +972,11 @@ const fr = {
886
972
  concurrentUpdateReload: "Charger la version actuelle",
887
973
  concurrentUpdateOverwrite: "Écraser quand même",
888
974
  concurrentUpdateCancel: "Annuler",
975
+ concurrentUpdateRecordLabel: "cet enregistrement",
889
976
  openInNewTab: "Ouvrir dans un nouvel onglet",
890
977
  activity: "Activité",
891
978
  history: "Historique",
979
+ historyEmpty: "Aucun historique pour le moment",
892
980
  editRow: "Modifier",
893
981
  deleteRow: "Supprimer",
894
982
  deleteRowConfirmation: "Supprimer cet enregistrement ?",
@@ -898,10 +986,15 @@ const fr = {
898
986
  nextPage: "Suivant",
899
987
  pageOf: "Page {{current}} sur {{total}}",
900
988
  sortBy: "Trier par",
901
- filterPlaceholder: "Filtrer...",
989
+ filterPlaceholder: "Filtrer…",
902
990
  highlightFields: "Champs clés",
903
991
  createdBy: "Créé par",
904
992
  updatedBy: "Mis à jour par",
993
+ // objectui#3863 — base key. fr has a third category, `many`, which CLDR uses from
994
+ // a million up; the plural form is correct there, so the base repeats `_other`
995
+ // rather than restructuring (unlike ru/ar, whose unenumerated categories cover
996
+ // everyday counts).
997
+ showEmptyRelated: "+ {{count}} vides",
905
998
  showEmptyRelated_one: "+ {{count}} vide",
906
999
  showEmptyRelated_other: "+ {{count}} vides",
907
1000
  copyEmail: "Copier l'e-mail",
@@ -913,7 +1006,8 @@ const fr = {
913
1006
  },
914
1007
  chart: {
915
1008
  noData: "Aucune donnée de graphique disponible",
916
- loading: "Chargement du graphique...",
1009
+ loading: "Chargement du graphique…",
1010
+ nullCategory: "(Non défini)",
917
1011
  },
918
1012
  map: {
919
1013
  searchLocations: "Rechercher des lieux…",
@@ -935,8 +1029,8 @@ const fr = {
935
1029
  properties: "Propriétés",
936
1030
  connections: "Connexions",
937
1031
  quickConnect: "Connexion rapide",
938
- fromPlaceholder: "De...",
939
- toPlaceholder: "Vers...",
1032
+ fromPlaceholder: "De…",
1033
+ toPlaceholder: "Vers…",
940
1034
  connect: "Connecter",
941
1035
  label: "Libellé",
942
1036
  type: "Type",
@@ -984,6 +1078,7 @@ const fr = {
984
1078
  },
985
1079
  dashboard: {
986
1080
  noRows: "Aucune ligne",
1081
+ loading: "Chargement…",
987
1082
  pickMeasures: "Choisissez des mesures (valeurs) pour ce widget de dataset.",
988
1083
  datasetUnsupported: "Cette source de données ne prend pas en charge les requêtes de dataset.",
989
1084
  details: "Détails",
@@ -1241,6 +1336,7 @@ const fr = {
1241
1336
  },
1242
1337
  },
1243
1338
  console: {
1339
+ saveAdvisoryTitle: "Enregistré — le contrôle de création a signalé {{count}} recommandation(s)",
1244
1340
  settingsHub: {
1245
1341
  title: "Paramètres",
1246
1342
  subtitle: "Configurez votre espace de travail, vos intégrations et vos indicateurs de fonctionnalité.",
@@ -1307,7 +1403,7 @@ const fr = {
1307
1403
  shareTitle: "Partager cette conversation",
1308
1404
  shareDisabledTitle: "Commencez à discuter pour activer le partage",
1309
1405
  newChat: "Nouveau",
1310
- searchChats: "Rechercher des discussions...",
1406
+ searchChats: "Rechercher des discussions…",
1311
1407
  noChatsYet: "Aucune discussion pour l'instant",
1312
1408
  noChatsDescription: "Démarrez une nouvelle conversation pour la voir ici.",
1313
1409
  noMatchingChats: "Aucune discussion correspondante.",
@@ -1316,18 +1412,18 @@ const fr = {
1316
1412
  deleteConversation: "Supprimer la conversation",
1317
1413
  saveRename: "Enregistrer le nom",
1318
1414
  cancelRename: "Annuler le changement de nom",
1319
- loadingHistory: "Chargement de l'historique de la conversation...",
1415
+ loadingHistory: "Chargement de l'historique de la conversation…",
1320
1416
  conversationReady: "Conversation prête",
1321
1417
  preparingConversation: "Préparation d'une nouvelle conversation",
1322
1418
  offlineDemoMode: "Mode démo hors ligne — liste des agents indisponible",
1323
1419
  sendFailedRateLimited: "Vous envoyez des messages trop rapidement. Votre message est conservé ci-dessous — patientez un instant puis réessayez.",
1324
1420
  sendFailedGeneric: "Impossible d'envoyer votre message. Il est conservé ci-dessous — veuillez réessayer.",
1325
- askAgent: "Demander à {{agent}}...",
1421
+ askAgent: "Demander à {{agent}}…",
1326
1422
  assistant: "Assistant",
1327
1423
  liveCanvas: "Aperçu en direct — {{app}} (brouillon)",
1328
1424
  liveCanvasUnlisted: "Application en direct — {{app}} (non répertoriée jusqu'à publication)",
1329
- loadingAgents: "Chargement des agents...",
1330
- askAnything: "Posez n'importe quelle question...",
1425
+ loadingAgents: "Chargement des agents…",
1426
+ askAnything: "Posez n'importe quelle question…",
1331
1427
  emptyTitle: "Démarrer une conversation",
1332
1428
  emptyDescription: "Posez n'importe quelle question — l'assistant a accès au contexte de votre application actuelle.",
1333
1429
  switchAssistant: "Changer d'assistant",
@@ -1430,9 +1526,60 @@ const fr = {
1430
1526
  createSeed: "Générer des données d'exemple",
1431
1527
  createPackage: "Créer un package d'application",
1432
1528
  },
1529
+ // objectui#3546 slice four — the AI console surfaces: the /ai chat page's app switcher,
1530
+ // connection banner and plan/publish cards, the ChatDock chrome, and the
1531
+ // conversation-list date buckets. `group.*` is the template-key family
1532
+ // `console.ai.group.${key}` (ConversationsSidebar), enumerated from the
1533
+ // ConversationGroupKey union — all five members, no wildcard.
1534
+ collapseToDock: "Réduire dans le panneau latéral",
1535
+ switchApp: "Changer d'application",
1536
+ switchAppLabel: "Conversations de création par application",
1537
+ newApp: "Nouvelle application",
1538
+ connectionWaiting: "En attente du serveur…",
1539
+ connectionStalled: "Toujours en cours…",
1540
+ connectionOffline: "Connexion perdue — reconnexion…",
1541
+ designingPlan: "Conception de votre application…",
1542
+ designingPlanHint: {
1543
+ data: "Cartographie des données que vous allez suivre…",
1544
+ objects: "Définition des objets et de leurs champs…",
1545
+ relations: "Connexion des enregistrements liés…",
1546
+ lookups: "Configuration des relations et des champs de recherche…",
1547
+ views: "Planification des écrans et des vues…",
1548
+ forms: "Mise en page des formulaires et des listes…",
1549
+ defaults: "Ajout de valeurs par défaut et de validations pertinentes…",
1550
+ dashboard: "Esquisse d'un tableau de bord pour le suivi…",
1551
+ review: "Vérification de la cohérence de la structure…",
1552
+ finalize: "Assemblage du plan…",
1553
+ },
1554
+ planBuilding: "Création…",
1555
+ planBuilt: "Créé",
1556
+ planDeferred: "Pas encore créé",
1557
+ planReady: "Le plan est prêt. Créez-le maintenant, ou dites-moi ce qu'il faut ajuster.",
1558
+ published: "Publié",
1559
+ publishFailed: "Échec de la publication",
1560
+ unavailableTitle: "Assistant IA non disponible",
1561
+ unavailableDescription: "Cette instance n'a pas d'assistant IA activé. Tout le reste fonctionne normalement.",
1562
+ unavailableError: "Impossible de joindre le service IA. Il est peut-être temporairement hors ligne — réessayez, ou retournez à l'accueil.",
1563
+ unavailableRetry: "Réessayer",
1564
+ unavailableHome: "Retour à l'accueil",
1565
+ dock: {
1566
+ title: "Assistant",
1567
+ description: "Discussion avec l'assistant IA",
1568
+ resize: "Redimensionner la discussion",
1569
+ collapse: "Réduire la discussion",
1570
+ maximize: "Ouvrir en pleine page",
1571
+ open: "Ouvrir l'assistant",
1572
+ },
1573
+ group: {
1574
+ today: "Aujourd'hui",
1575
+ yesterday: "Hier",
1576
+ previous7Days: "7 jours précédents",
1577
+ previous30Days: "30 jours précédents",
1578
+ older: "Plus anciennes",
1579
+ },
1433
1580
  },
1434
1581
  title: "Console ObjectStack",
1435
- initializing: "Initialisation de l'application...",
1582
+ initializing: "Initialisation de l'application…",
1436
1583
  loadingHint: "La configuration d'un nouvel environnement peut prendre quelques instants.",
1437
1584
  breadcrumb: {
1438
1585
  dashboards: "Tableaux de bord",
@@ -1440,6 +1587,31 @@ const fr = {
1440
1587
  reports: "Rapports",
1441
1588
  system: "Système",
1442
1589
  },
1590
+ // objectui#4024 — the single-namespace settings screen. Its sibling
1591
+ // `settingsHub` above already resolved through this pack; the view was the
1592
+ // one file still carrying English literals.
1593
+ settingsView: {
1594
+ backToHub: "Tous les paramètres",
1595
+ back: "Retour",
1596
+ noNamespace: "Aucun espace de noms sélectionné.",
1597
+ loadError: "Échec du chargement des paramètres",
1598
+ saved: "Paramètres enregistrés",
1599
+ saveFailed: "Échec de l'enregistrement",
1600
+ lockedByEnv: "Verrouillé par l'environnement : {{key}}",
1601
+ lockedByEnvNoKey: "Verrouillé par l'environnement",
1602
+ actionSucceeded: "Action réussie",
1603
+ actionFailed: "Échec de l'action",
1604
+ discard: "Abandonner",
1605
+ saveChanges: "Enregistrer les modifications",
1606
+ unsavedCount: "{{count}} modifications non enregistrées",
1607
+ unsavedCount_one: "{{count}} modification non enregistrée",
1608
+ unsavedCount_other: "{{count}} modifications non enregistrées",
1609
+ cryptoRefusalTitle: "Ce déploiement ne peut pas chiffrer les secrets",
1610
+ cryptoRefusalSubjectSuffix: "est déclaré chiffré, aucune écriture n'a donc eu lieu.",
1611
+ cryptoRefusalNoSubject: "La valeur déclarée chiffrée a été refusée, aucune écriture n'a donc eu lieu.",
1612
+ cryptoRefusalToast: "Impossible de chiffrer les secrets : {{subject}}",
1613
+ cryptoRefusalToastNoSubject: "Impossible de chiffrer les secrets",
1614
+ },
1443
1615
  loadingSteps: {
1444
1616
  connecting: "Connexion à la source de données",
1445
1617
  loadingConfig: "Chargement de la configuration",
@@ -1469,6 +1641,7 @@ const fr = {
1469
1641
  general: "Général",
1470
1642
  navigation: "Navigation",
1471
1643
  dataViews: "Vues de données",
1644
+ aiChat: "Assistant IA",
1472
1645
  preferences: "Préférences",
1473
1646
  },
1474
1647
  openCommandPalette: "Ouvrir la palette de commandes",
@@ -1479,11 +1652,13 @@ const fr = {
1479
1652
  createRecord: "Créer un nouvel enregistrement",
1480
1653
  refreshData: "Actualiser les données",
1481
1654
  editRecord: "Modifier l'enregistrement sélectionné",
1655
+ newChat: "Nouvelle discussion",
1656
+ toggleChatsList: "Basculer la liste des discussions",
1482
1657
  toggleDarkMode: "Basculer le mode sombre",
1483
1658
  },
1484
1659
  commandPalette: {
1485
1660
  title: "Palette de commandes",
1486
- placeholder: "Tapez une commande ou recherchez...",
1661
+ placeholder: "Tapez une commande ou recherchez…",
1487
1662
  noResults: "Aucun résultat trouvé.",
1488
1663
  objects: "Objets",
1489
1664
  dashboards: "Tableaux de bord",
@@ -1509,6 +1684,12 @@ const fr = {
1509
1684
  goHome: "Retour à l'accueil",
1510
1685
  errorDetails: "Détails de l'erreur (développement uniquement)",
1511
1686
  },
1687
+ // objectui#3546 slice four — the console's catch-all route (AppContent `RouteNotFound`).
1688
+ notFound: {
1689
+ title: "Page introuvable",
1690
+ description: "L'URL que vous avez suivie ne correspond à aucune vue de cette application.",
1691
+ back: "Retour",
1692
+ },
1512
1693
  theme: {
1513
1694
  toggle: "Changer de thème",
1514
1695
  light: "Clair",
@@ -1524,8 +1705,10 @@ const fr = {
1524
1705
  viewNameHelp: "Clé technique (snake_case). Remplie automatiquement à partir du titre — modifiable si vous le souhaitez.",
1525
1706
  viewNameRequired: "Saisissez une clé (minuscules, chiffres, tiret bas). Non remplie automatiquement pour les titres non latins.",
1526
1707
  viewNameInvalid: "Utilisez des minuscules, des chiffres et des tirets bas ; commencez par une lettre ou un tiret bas.",
1527
- systemViewReadonly: 'System view defined in code - duplicate to customize.',
1528
- expandToPage: 'Open as full page',
1708
+ systemViewReadonly: "Vue système définie dans le code — en lecture seule.",
1709
+ cannotEditMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être modifiée.",
1710
+ cannotDeleteMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être supprimée.",
1711
+ expandToPage: "Ouvrir en pleine page",
1529
1712
  objectNotFound: "Objet introuvable",
1530
1713
  objectNotFoundDescription: "L'objet « {{objectName}} » n'existe pas dans la configuration actuelle.",
1531
1714
  objectNotFoundHint: "Vérifiez les paramètres de navigation de votre application ou sélectionnez un autre objet dans la barre latérale.",
@@ -1557,7 +1740,7 @@ const fr = {
1557
1740
  exportPrintHint: "Formats d'export, impression et affichage du nombre d'enregistrements",
1558
1741
  showAllFields: "Tout afficher",
1559
1742
  hideAllFields: "Tout masquer",
1560
- searchFields: "Rechercher des champs...",
1743
+ searchFields: "Rechercher des champs…",
1561
1744
  title: "Titre",
1562
1745
  description: "Description",
1563
1746
  data: "Données",
@@ -1596,7 +1779,7 @@ const fr = {
1596
1779
  longitudeField: "Champ de longitude",
1597
1780
  imageField: "Champ d'image",
1598
1781
  dateField: "Champ de date",
1599
- selectField: "Sélectionner un champ...",
1782
+ selectField: "Sélectionner un champ…",
1600
1783
  gridOptionsHint: "La vue grille utilise les colonnes configurées ci-dessus.",
1601
1784
  groupBy: "Regrouper par",
1602
1785
  prefixField: "Champ de préfixe",
@@ -1659,7 +1842,7 @@ const fr = {
1659
1842
  latitudeFieldHelp: "Champ contenant la latitude (champs géo uniquement).",
1660
1843
  longitudeFieldHelp: "Champ contenant la longitude (champs géo uniquement).",
1661
1844
  imageFieldHelp: "La couverture de la galerie provient de ce champ image ou pièce jointe.",
1662
- selectOption: "Sélectionner...",
1845
+ selectOption: "Sélectionner…",
1663
1846
  noEligibleFieldForType: "Aucun champ éligible de ce type. Ajoutez-en un à l'objet d'abord.",
1664
1847
  viewTypeUnavailable: "Cet objet n'a pas de champ pouvant servir de \"{{field}}\".",
1665
1848
  viewTypeUnavailableShort: "Non pris en charge par cet objet.",
@@ -1709,7 +1892,7 @@ const fr = {
1709
1892
  ufDropdown: "Liste déroulante",
1710
1893
  ufTabs: "Onglets",
1711
1894
  ufToggle: "Bascule",
1712
- ufAddField: "+ Ajouter un champ de filtre...",
1895
+ ufAddField: "+ Ajouter un champ de filtre…",
1713
1896
  ufNoFields: "Aucun champ disponible",
1714
1897
  ufAddTab: "+ Ajouter un onglet",
1715
1898
  ufTabLabel: "Étiquette",
@@ -1769,7 +1952,7 @@ const fr = {
1769
1952
  passwordPlaceholder: "Entrez votre mot de passe",
1770
1953
  forgotPasswordText: "Mot de passe oublié ?",
1771
1954
  submitButton: "Se connecter",
1772
- submittingButton: "Connexion en cours...",
1955
+ submittingButton: "Connexion en cours…",
1773
1956
  noAccountText: "Vous n'avez pas de compte ?",
1774
1957
  signUpText: "S'inscrire",
1775
1958
  errors: {
@@ -1777,6 +1960,18 @@ const fr = {
1777
1960
  invalidCredentials: "E-mail ou mot de passe invalide. Veuillez réessayer.",
1778
1961
  emailNotVerified: "Veuillez vérifier votre adresse e-mail avant de vous connecter.",
1779
1962
  },
1963
+ // objectui#3546 slice three — phone/OTP sign-in. `{seconds}` is LoginForm's own
1964
+ // literal `.replace()` hole, not i18next interpolation: keep the single braces.
1965
+ emailOrPhoneLabel: "E-mail ou numéro de téléphone",
1966
+ emailOrPhonePlaceholder: "name@example.com ou +1 555 000 0000",
1967
+ phoneLabel: "Numéro de téléphone",
1968
+ phonePlaceholder: "+1 555 000 0000",
1969
+ otpCodeLabel: "Code de vérification",
1970
+ otpCodePlaceholder: "Code à 6 chiffres",
1971
+ sendOtpButton: "Obtenir un code",
1972
+ resendOtpCountdownText: "Renvoyer dans {seconds} s",
1973
+ usePhoneOtpText: "Se connecter avec un code de vérification",
1974
+ usePasswordSignInText: "Se connecter avec un mot de passe à la place",
1780
1975
  },
1781
1976
  register: {
1782
1977
  title: "Créer un compte",
@@ -1792,7 +1987,7 @@ const fr = {
1792
1987
  passwordMismatchError: "Les mots de passe ne correspondent pas",
1793
1988
  passwordTooShortError: "Le mot de passe doit contenir au moins 8 caractères",
1794
1989
  submitButton: "Créer un compte",
1795
- submittingButton: "Création du compte...",
1990
+ submittingButton: "Création du compte…",
1796
1991
  hasAccountText: "Vous avez déjà un compte ?",
1797
1992
  signInText: "Se connecter",
1798
1993
  errors: {
@@ -1813,12 +2008,26 @@ const fr = {
1813
2008
  emailLabel: "E-mail",
1814
2009
  emailPlaceholder: "name@example.com",
1815
2010
  submitButton: "Envoyer le lien de réinitialisation",
1816
- submittingButton: "Envoi en cours...",
2011
+ submittingButton: "Envoi en cours…",
1817
2012
  successTitle: "Vérifiez vos e-mails",
1818
2013
  successDescription: "Nous avons envoyé un lien de réinitialisation du mot de passe à {{email}}. Veuillez vérifier votre boîte de réception.",
1819
2014
  backToSignInText: "Retour à la connexion",
1820
2015
  rememberPasswordText: "Vous vous souvenez de votre mot de passe ?",
1821
2016
  signInText: "Se connecter",
2017
+ // objectui#3546 slice three — the SMS reset branch of the same form.
2018
+ phoneLabel: "Numéro de téléphone",
2019
+ phonePlaceholder: "+1 555 000 0000",
2020
+ otpCodeLabel: "Code de vérification",
2021
+ otpCodePlaceholder: "Code à 6 chiffres",
2022
+ sendOtpButton: "Obtenir un code",
2023
+ resendOtpCountdownText: "Renvoyer dans {seconds} s",
2024
+ newPasswordLabel: "Nouveau mot de passe",
2025
+ newPasswordPlaceholder: "Entrez un nouveau mot de passe",
2026
+ resetButton: "Réinitialiser le mot de passe",
2027
+ usePhoneResetText: "Réinitialiser par code SMS",
2028
+ useEmailResetText: "Réinitialiser par e-mail à la place",
2029
+ phoneSuccessTitle: "Mot de passe réinitialisé",
2030
+ phoneSuccessDescription: "Votre mot de passe a été réinitialisé. Vous pouvez maintenant vous connecter avec votre nouveau mot de passe.",
1822
2031
  },
1823
2032
  resetPassword: {
1824
2033
  title: "Définir un nouveau mot de passe",
@@ -1857,6 +2066,8 @@ const fr = {
1857
2066
  backToLogin: "Retour à la connexion",
1858
2067
  checkSpam: "E-mail non reçu ? Vérifiez votre dossier spam ou contactez le support.",
1859
2068
  or: "Ou",
2069
+ // objectui#3546 slice three.
2070
+ resendUnavailable: "L'envoi d'e-mails n'est peut-être pas configuré pour cet environnement. Contactez le support si le problème persiste.",
1860
2071
  },
1861
2072
  setup: {
1862
2073
  welcomeTitle: "Bienvenue sur ObjectStack",
@@ -1895,6 +2106,9 @@ const fr = {
1895
2106
  invalidDescription: "Aucun code d'appareil n'a été fourni dans l'URL.",
1896
2107
  loading: "Chargement…",
1897
2108
  cancel: "Annuler",
2109
+ // objectui#3546 slice three — device-authorization plugin switched off.
2110
+ disabledTitle: "Autorisation d'appareil non activée",
2111
+ disabledDescription: "L'autorisation d'appareil n'est pas activée sur ce déploiement, cet appareil ne peut donc pas être approuvé ici.",
1898
2112
  },
1899
2113
  shell: {
1900
2114
  tenantHostHint: "Vous vous connectez à cet espace de travail",
@@ -1934,6 +2148,29 @@ const fr = {
1934
2148
  },
1935
2149
  },
1936
2150
  },
2151
+ // objectui#3546 slice three — the /oauth/consent screen.
2152
+ oauth: {
2153
+ consent: {
2154
+ title: "{{appName}} souhaite accéder à votre compte",
2155
+ request: "{{appName}} demande une autorisation{{suffix}}.",
2156
+ unknownApp: "une application",
2157
+ willAllow: "Cette application pourra :",
2158
+ scope: {
2159
+ openid: "Confirmer votre identité",
2160
+ profile: "Lire votre profil de base (nom, photo)",
2161
+ email: "Lire votre adresse e-mail",
2162
+ offlineAccess: "Rester connecté (renouveler l'accès)",
2163
+ },
2164
+ deny: "Refuser",
2165
+ authorize: "Autoriser",
2166
+ submitting: "Autorisation…",
2167
+ granted: "Accès accordé",
2168
+ denied: "Accès refusé",
2169
+ noRedirect: "Le serveur n'a renvoyé aucune URL de redirection.",
2170
+ failed: "Échec du consentement",
2171
+ footer: "Vous pouvez révoquer cet accès à tout moment dans les paramètres de votre compte.",
2172
+ },
2173
+ },
1937
2174
  profile: {
1938
2175
  title: "Profil",
1939
2176
  subtitle: "Gérez les paramètres de votre compte",
@@ -1995,6 +2232,8 @@ const fr = {
1995
2232
  invite: "Inviter un membre",
1996
2233
  members: "Membres",
1997
2234
  settings: "Paramètres de l'espace de travail",
2235
+ multiOrgDisabled: "La création de nouvelles organisations est désactivée sur cette instance.",
2236
+ createFailed: "Échec de la création de l'espace de travail",
1998
2237
  },
1999
2238
  help: {
2000
2239
  onThisPage: "Sur cette page",
@@ -2005,7 +2244,7 @@ const fr = {
2005
2244
  },
2006
2245
  sidebar: {
2007
2246
  packageManagement: "Gestion des packages",
2008
- searchNavigation: "Rechercher dans la navigation...",
2247
+ searchNavigation: "Rechercher dans la navigation…",
2009
2248
  settings: "Paramètres",
2010
2249
  help: "Aide",
2011
2250
  helpTooltip: "Aide et documentation",
@@ -2029,8 +2268,8 @@ const fr = {
2029
2268
  switchObject: "Changer d'objet",
2030
2269
  connection: {
2031
2270
  connected: "Connecté",
2032
- connecting: "Connexion...",
2033
- reconnecting: "Reconnexion...",
2271
+ connecting: "Connexion…",
2272
+ reconnecting: "Reconnexion…",
2034
2273
  disconnected: "Déconnecté",
2035
2274
  error: "Erreur de connexion",
2036
2275
  },
@@ -2069,6 +2308,14 @@ const fr = {
2069
2308
  publishing: "Publication…",
2070
2309
  published: "Publié ! Vos modifications sont actives.",
2071
2310
  publishFailed: "Échec de la publication",
2311
+ // objectui#3546 slice six — seedWarn reprend mot pour mot la traduction de
2312
+ // console.ai.seedWarn (même phrase anglaise). Marqueur "(s)" comme
2313
+ // home.pendingDrafts.message dans cette même famille.
2314
+ nothing: "Rien à publier.",
2315
+ probeWarn: "Publié, mais la vérification a détecté des problèmes.",
2316
+ seedWarn: "Publié, mais certaines données d'exemple n'ont pas pu être chargées.",
2317
+ publishedVerified: "Publié et vérifié — {{count}} ligne(s) d'exemple active(s).",
2318
+ capabilityWarn: "Contrôle de conception : {{count}} référence(s) de capacité ne mènent à rien.",
2072
2319
  },
2073
2320
  title: "Accueil",
2074
2321
  subtitle: "Tableau de bord de votre espace de travail",
@@ -2082,7 +2329,7 @@ const fr = {
2082
2329
  title: "Nécessite votre attention",
2083
2330
  empty: "Vous êtes à jour",
2084
2331
  },
2085
- loading: "Chargement de l'espace de travail...",
2332
+ loading: "Chargement de l'espace de travail…",
2086
2333
  recent: "Récent",
2087
2334
  starred: "Favoris",
2088
2335
  welcome: "Bienvenue dans ObjectUI",
@@ -2143,6 +2390,9 @@ const fr = {
2143
2390
  roles: "Rôles",
2144
2391
  configuration: "Configuration",
2145
2392
  createApp: "Créer une application",
2393
+ administration: "Administration",
2394
+ datasources: "Sources de données",
2395
+ documentation: "Documentation",
2146
2396
  },
2147
2397
  appSwitcher: {
2148
2398
  switchApplication: "Changer d'application",
@@ -2182,7 +2432,7 @@ const fr = {
2182
2432
  search: {
2183
2433
  title: "Rechercher",
2184
2434
  back: "Retour",
2185
- placeholder: "Rechercher des objets, tableaux de bord, pages, rapports...",
2435
+ placeholder: "Rechercher des objets, tableaux de bord, pages, rapports…",
2186
2436
  inputAriaLabel: "Rechercher des objets, tableaux de bord, pages, rapports",
2187
2437
  resultsCount: "{{count}} résultat pour \"{{query}}\"",
2188
2438
  resultsCountPlural: "{{count}} résultats pour \"{{query}}\"",
@@ -2201,6 +2451,7 @@ const fr = {
2201
2451
  empty: {
2202
2452
  objectNotFound: "Objet introuvable",
2203
2453
  objectNotFoundDescription: "La définition de l'objet \"{{name}}\" est manquante. Vérifiez votre configuration ou revenez en arrière.",
2454
+ interfacePageSourceMissing: "Cette page d'interface référence \"{{name}}\", qui n'est pas disponible.",
2204
2455
  pageNotFound: "Page introuvable",
2205
2456
  pageNotFoundDescription: "La page \"{{name}}\" est introuvable. Elle a peut-être été supprimée ou renommée.",
2206
2457
  dashboardNotFound: "Tableau de bord introuvable",
@@ -2209,6 +2460,11 @@ const fr = {
2209
2460
  reportNotFoundDescription: "Le rapport \"{{name}}\" est introuvable. Il a peut-être été supprimé ou renommé.",
2210
2461
  noAppsConfigured: "Aucune application configurée",
2211
2462
  noAppsConfiguredDescription: "Aucune application n'est enregistrée. Créez votre première application ou visitez les paramètres système.",
2463
+ appNotAvailable: "Application non disponible",
2464
+ appNotAvailableDescription: "Cette application n'est pas encore disponible — sa publication est peut-être en cours. Réessayez dans un instant.",
2465
+ appAccessDenied: "Vous n'avez pas accès à cette application",
2466
+ appAccessDeniedDescription: "Cette application existe, mais votre compte n'est pas autorisé à l'ouvrir. Demandez l'accès à un administrateur.",
2467
+ appAccessDeniedHome: "Retour à l'accueil",
2212
2468
  createFirstApp: "Créer la première application",
2213
2469
  systemSettings: "Paramètres système",
2214
2470
  back: "Retour",
@@ -2280,7 +2536,7 @@ const fr = {
2280
2536
  deleteFailed: "Impossible de supprimer la vue",
2281
2537
  },
2282
2538
  dashboardActions: {
2283
- pdfPreparing: "Préparation de l'export PDF…",
2539
+ printDialogOpening: "Ouverture de la boîte de dialogue d'impression de votre navigateur (ce n'est pas un export PDF)",
2284
2540
  exportFailed: "Échec de l'export : {{message}}",
2285
2541
  forecastSoon: "La vue de prévision arrive bientôt",
2286
2542
  },
@@ -2324,111 +2580,7 @@ const fr = {
2324
2580
  first: "Premier",
2325
2581
  },
2326
2582
  editor: {
2327
- breadcrumb: "Configuration",
2328
- basic: "Général",
2329
- title: "Titre",
2330
- titlePlaceholder: "ex. Pipeline par trimestre",
2331
- description: "Description",
2332
- descriptionPlaceholder: "Que montre ce rapport ?",
2333
- type: "Type de rapport",
2334
- typeTabular: "Tableau — liste à plat",
2335
- typeSummary: "Résumé — regroupé avec totaux",
2336
- typeMatrix: "Matrice — pivot lignes × colonnes",
2337
- typeJoined: "Combiné — plusieurs blocs",
2338
- typeHelp: "Choisissez la mise en page correspondant à ce que vous voulez voir.",
2339
- data: "Données",
2340
- objectName: "Source de données",
2341
- objectNamePlaceholder: "ex. opportunity",
2342
- objectNameHelp: "Quel objet ce rapport doit-il interroger ?",
2343
- limit: "Limite de lignes",
2344
- limitPlaceholder: "ex. 100",
2345
- columns: "Colonnes",
2346
- columnsHint: "Choisissez les champs à afficher en colonnes. Ajoutez une agrégation (Somme, Nombre…) dans les rapports Résumé ou Matrice.",
2347
- filters: "Filtres",
2348
- filtersHint: "Limitez les lignes incluses dans ce rapport.",
2349
- filtersComplex: "Ce rapport utilise un filtre avancé qui ne peut pas être édité ici. L’enregistrement le conservera tel quel.",
2350
- groupBy: "Grouper par",
2351
- groupByHint: "Regrouper les données et calculer les sous-totaux.",
2352
- rows: "Lignes",
2353
- rowsHint: "Grouper les lignes par ces champs.",
2354
- columnsAxis: "Colonnes",
2355
- columnsAxisHint: "Pivoter ces champs en haut.",
2356
- values: "Valeurs",
2357
- valuesHint: "Nombres affichés dans chaque cellule. Choisissez un ou plusieurs champs et ajoutez une agrégation (Somme, Nombre…).",
2358
- grouping: "Groupement",
2359
- addGrouping: "Ajouter un groupement",
2360
- dateGranularity: "Granularité de la date",
2361
- dateGranularityNone: "(valeur brute)",
2362
- day: "Jour",
2363
- week: "Semaine",
2364
- month: "Mois",
2365
- quarter: "Trimestre",
2366
- year: "Année",
2367
- sortAsc: "Croissant",
2368
- sortDesc: "Décroissant",
2369
- chart: "Graphique",
2370
- chartHint: "Visualisation optionnelle affichée à côté du tableau.",
2371
- chartType: "Type de graphique",
2372
- chartTitle: "Titre du graphique",
2373
- chartTitlePlaceholder: "Par défaut, le titre du rapport",
2374
- chartXAxis: "Axe X (catégorie)",
2375
- chartYAxis: "Axe Y (valeur)",
2376
- chartShowLegend: "Afficher la légende",
2377
- chartShowDataLabels: "Afficher les étiquettes",
2378
- chartNone: "(aucun graphique)",
2379
- chartBar: "Barres",
2380
- chartLine: "Courbe",
2381
- chartArea: "Aires",
2382
- chartPie: "Camembert",
2383
- chartDonut: "Anneau",
2384
- chartFunnel: "Entonnoir",
2385
- validationNeedsObject: "Sélectionnez une source de données avant d’ajouter des colonnes.",
2386
- validationMatrixNeedsRowsCols: "Les rapports matriciels nécessitent au moins une ligne et une colonne.",
2387
- validationSummaryNeedsRows: "Les rapports résumés nécessitent au moins un champ de regroupement.",
2388
- blocks: "Blocs",
2389
- blocksHint: "Chaque bloc est son propre tableau ou graphique. Les filtres de bloc sont combinés (ET) avec le filtre du rapport.",
2390
- addBlock: "Ajouter un bloc",
2391
- removeBlock: "Supprimer le bloc",
2392
- blockName: "Nom du bloc",
2393
- blockNamePlaceholder: "nom_unique_du_bloc",
2394
- blockLabel: "Libellé d’affichage",
2395
- blockLabelPlaceholder: "Affiché au-dessus du bloc",
2396
- blockDescription: "Description",
2397
- blockDescriptionPlaceholder: "Contexte optionnel pour ce bloc",
2398
- validationJoinedNeedsBlocks: "Les rapports combinés nécessitent au moins un bloc.",
2399
- validationBlockNameRequired: "Chaque bloc doit avoir un nom non vide.",
2400
- validationBlockNameDuplicate: "Les noms de bloc doivent être uniques dans le rapport.",
2401
- validationBlockNeedsColumns: "Chaque bloc doit avoir au moins une colonne.",
2402
- noneOption: "(aucun)",
2403
- addCondition: "Ajouter une condition",
2404
- combineLogic: "Combiner avec",
2405
- opContains: "contient",
2406
- opIsEmpty: "est vide",
2407
- opIsNotEmpty: "n’est pas vide",
2408
- formatAuto: "Auto",
2409
- formatCurrency: "Devise",
2410
- formatPercent: "Pourcentage",
2411
- formatInteger: "Entier",
2412
- formatDate: "Date",
2413
- formatDatetime: "Date et heure",
2414
- columnLabelPlaceholder: "Remplacer le libellé",
2415
- aggregateColumn: "Agrégation",
2416
- formatColumn: "Format",
2417
- addColumns: "Ajouter des colonnes",
2418
- searchFields: "Rechercher des champs…",
2419
- noMatchingFields: "Aucun champ ne correspond à votre recherche.",
2420
- noFieldsAvailable: "Aucun champ disponible.",
2421
- columnsCount: "{n} colonne(s) sélectionnée(s)",
2422
- columnsEmpty: "Aucune colonne sélectionnée pour l'instant.",
2423
- fieldPickerTitle: "Sélectionner des champs",
2424
- fieldPickerDescription: "Choisissez un ou plusieurs champs à ajouter. Utilisez le champ de recherche pour filtrer la liste.",
2425
- fieldPickerChangeTitle: "Changer le champ",
2426
- fieldPickerAddGroupingTitle: "Ajouter un regroupement",
2427
- fieldPickerEmpty: "(Sélectionner un champ)",
2428
- fieldPickerSelected: "{n} sélectionné(s)",
2429
- fieldPickerClear: "Effacer la sélection",
2430
- fieldPickerAdd: "Ajouter",
2431
- fieldPickerAddN: "Ajouter {n}",
2583
+ panelTitle: "Modifier le rapport",
2432
2584
  },
2433
2585
  },
2434
2586
  organizations: {
@@ -2445,6 +2597,140 @@ const fr = {
2445
2597
  emptyDescription: "Créez votre première organisation pour commencer.",
2446
2598
  noMatches: "Aucune organisation ne correspond à votre recherche.",
2447
2599
  },
2600
+ organization: {
2601
+ roles: {
2602
+ owner: 'Propriétaire',
2603
+ admin: 'Administrateur',
2604
+ delegatedAdmin: 'Administrateur délégué',
2605
+ member: 'Membre',
2606
+ },
2607
+ errors: {
2608
+ notAllowedToInvite: "Vous n'êtes pas autorisé à inviter des utilisateurs dans cette organisation.",
2609
+ notAllowedToInviteWithRole: "Vous n'êtes pas autorisé à inviter un utilisateur avec ce rôle.",
2610
+ alreadyInvited: 'Cet utilisateur a déjà été invité dans cette organisation.',
2611
+ organizationExists: 'Cette organisation existe déjà.',
2612
+ slugTaken: 'Ce slug est déjà utilisé.',
2613
+ notAllowedToCreate: "Vous n'êtes pas autorisé à créer une nouvelle organisation.",
2614
+ notTheRecipient: "Vous n'êtes pas le destinataire de cette invitation.",
2615
+ invitationNotFound: "Cette invitation n'existe plus ou a expiré.",
2616
+ unknown: 'Une erreur est survenue. Veuillez réessayer.',
2617
+ },
2618
+ backToList: "Retour aux organisations",
2619
+ notFound: "Organisation introuvable",
2620
+ notFoundDescription: "Cette organisation n'existe pas ou vous n'y avez pas accès.",
2621
+ tabs: {
2622
+ members: "Membres",
2623
+ invitations: "Invitations",
2624
+ settings: "Paramètres",
2625
+ },
2626
+ members: {
2627
+ title: "Membres",
2628
+ inviteMember: "Inviter un membre",
2629
+ inviteRestrictedNote: "Seuls les administrateurs de l'organisation peuvent inviter des membres.",
2630
+ removeMember: "Retirer le membre",
2631
+ removeConfirmTitle: "Retirer ce membre ?",
2632
+ removeConfirmDescription: "{{name}} sera retiré de l'organisation et perdra immédiatement son accès.",
2633
+ removeConfirmAction: "Retirer",
2634
+ memberRemoved: "Membre retiré",
2635
+ removeFailed: "Impossible de retirer le membre",
2636
+ roleUpdated: "Rôle mis à jour",
2637
+ roleUpdateFailed: "Impossible de mettre à jour le rôle",
2638
+ memberActions: 'Actions du membre',
2639
+ loadFailed: 'Échec du chargement des membres',
2640
+ },
2641
+ invitations: {
2642
+ title: "Invitations",
2643
+ empty: "Aucune invitation.",
2644
+ expiresAt: "Expire le",
2645
+ linkCopied: "Lien d'invitation copié",
2646
+ copyFailed: "Impossible de copier le lien",
2647
+ canceled: "Invitation annulée",
2648
+ cancelFailed: "Impossible d'annuler l'invitation",
2649
+ cancelTitle: "Annuler l'invitation ?",
2650
+ cancelDescription: "L'invitation de {{email}} sera révoquée.",
2651
+ cancelAction: "Annuler l'invitation",
2652
+ inviteTitle: "Inviter un membre",
2653
+ inviteDescription: "La personne recevra une invitation à rejoindre cette organisation.",
2654
+ emailLabel: "E-mail",
2655
+ roleLabel: "Rôle",
2656
+ placementLabel: "Affectation (facultatif)",
2657
+ placementDescription: "Appliquée lorsque l'invitation est acceptée. Seuls les unités et les postes que vous pouvez déléguer sont listés.",
2658
+ businessUnitLabel: "Unité opérationnelle",
2659
+ businessUnitPlaceholder: "Aucune affectation",
2660
+ positionsLabel: "Postes",
2661
+ sendInvite: "Envoyer l'invitation",
2662
+ sentTitle: "Invitation créée",
2663
+ sentDescription: "Partagez le lien ci-dessous avec la personne invitée. Elle devra se connecter pour accepter.",
2664
+ linkLabel: "Lien d'acceptation",
2665
+ invitedAs: "{{email}} invité en tant que {{role}}",
2666
+ copyLinkLabel: "Copier le lien d'invitation",
2667
+ loadFailed: 'Échec du chargement des invitations',
2668
+ inviteFailed: "Échec de l'invitation du membre",
2669
+ status: {
2670
+ all: "Toutes",
2671
+ pending: "En attente",
2672
+ accepted: "Acceptée",
2673
+ rejected: "Refusée",
2674
+ canceled: "Annulée",
2675
+ },
2676
+ },
2677
+ settings: {
2678
+ generalTitle: "Général",
2679
+ generalDescription: "Mettez à jour les informations de votre organisation.",
2680
+ readOnlyNote: "Seuls les propriétaires peuvent modifier les paramètres.",
2681
+ nameLabel: "Nom de l'organisation",
2682
+ slugLabel: "Slug",
2683
+ logoLabel: "Logo",
2684
+ logoUpload: "Téléverser",
2685
+ logoReplace: "Remplacer",
2686
+ logoClear: "Retirer",
2687
+ logoUploaded: "Logo téléversé — enregistrez pour appliquer",
2688
+ logoUploadFailed: "Impossible de téléverser le logo",
2689
+ save: "Enregistrer les modifications",
2690
+ saved: "Paramètres enregistrés",
2691
+ saveFailed: "Impossible d'enregistrer les paramètres",
2692
+ leaveTitle: "Quitter l'organisation",
2693
+ leaveDescription: "Vous perdrez l'accès à cette organisation.",
2694
+ leaveAction: "Quitter",
2695
+ leaveConfirmTitle: "Quitter l'organisation ?",
2696
+ leaveConfirmDescription: "Voulez-vous vraiment quitter {{name}} ? Vous perdrez immédiatement votre accès.",
2697
+ leaveConfirmAction: "Quitter",
2698
+ leftOrg: "Vous avez quitté l'organisation",
2699
+ leaveFailed: "Impossible de quitter l'organisation",
2700
+ dangerZone: "Zone de danger",
2701
+ deleteTitle: "Supprimer l'organisation",
2702
+ deleteDescription: "Supprimez définitivement cette organisation et toutes ses données.",
2703
+ deleteAction: "Supprimer",
2704
+ deleteConfirmTitle: "Supprimer l'organisation ?",
2705
+ deleteConfirmDescription: "Cette action est irréversible. Toutes les données seront définitivement supprimées. Saisissez le slug de l'organisation pour confirmer.",
2706
+ deleteConfirmSlugLabel: "Saisissez « {{slug}} » pour confirmer",
2707
+ deleteConfirmAction: "Supprimer l'organisation",
2708
+ deleted: "Organisation supprimée",
2709
+ deleteFailed: "Impossible de supprimer l'organisation",
2710
+ },
2711
+ accept: {
2712
+ title: "Vous avez été invité",
2713
+ description: "Vous avez été invité à rejoindre {{orgName}} en tant que {{role}}.",
2714
+ errorTitle: "Invitation indisponible",
2715
+ goToOrgs: "Aller aux organisations",
2716
+ loading: "Chargement de l'invitation…",
2717
+ organization: "Organisation",
2718
+ role: "Rôle",
2719
+ expiresAt: "Expire le",
2720
+ accept: "Accepter l'invitation",
2721
+ accepted: "Invitation acceptée",
2722
+ acceptFailed: "Impossible d'accepter l'invitation",
2723
+ decline: "Refuser",
2724
+ declined: "Invitation refusée",
2725
+ declineFailed: "Impossible de refuser l'invitation",
2726
+ },
2727
+ switcher: {
2728
+ label: "Changer d'organisation",
2729
+ groupLabel: "Organisation de travail",
2730
+ groupHint: "Les nouveaux enregistrements sont créés ici. Les vues affichent les données de toutes vos organisations.",
2731
+ manageMembers: "Gérer les membres",
2732
+ },
2733
+ },
2448
2734
  notifications: {
2449
2735
  regionLabel: "Notifications",
2450
2736
  groupCount: "{{count}} notifications",
@@ -2458,6 +2744,9 @@ const fr = {
2458
2744
  viewApprovals: "Voir les approbations",
2459
2745
  noPendingApprovals: "Aucune approbation en attente",
2460
2746
  openApprovalsInbox: "Ouvrir la boîte d'approbations",
2747
+ badgeTotal: "{{total}} au total",
2748
+ badgeNotifications: "{{unread}} notifications",
2749
+ badgeApprovals: "{{approvals}} approbations en attente",
2461
2750
  emptyUnread: "Tout est lu",
2462
2751
  filterUnread: "Non lus",
2463
2752
  filterAll: "Tous",
@@ -2744,6 +3033,7 @@ const fr = {
2744
3033
  dismiss: "Fermer",
2745
3034
  openOnCloud: "Ouvrir dans le cloud",
2746
3035
  backHome: "Retour à l'accueil",
3036
+ updateTo: "Mettre à jour",
2747
3037
  },
2748
3038
  install: {
2749
3039
  dialogTitle: "Installer {{name}}",
@@ -2760,6 +3050,37 @@ const fr = {
2760
3050
  localManifestConflict: "{{message}}\nRemarque : Une application locale possède déjà ce manifest_id. Supprimez-la d'abord de objectstack.config.ts.",
2761
3051
  localUnauthorized: "Connectez-vous d'abord à ce runtime.",
2762
3052
  localMarketplaceUnavailable: "Ce runtime n'a pas de OS_CLOUD_URL configuré.",
3053
+ updateTo: "Mettre à jour → v{{version}}",
3054
+ installedVersion: "Installé v{{version}}",
3055
+ },
3056
+ // objectui#3546 — the MarketplacePage "Your organization" strip.
3057
+ org: {
3058
+ heading: "Votre organisation",
3059
+ install: "Installer",
3060
+ installed: "{{name}} installé",
3061
+ installedBadge: "Installé",
3062
+ installing: "Installation…",
3063
+ },
3064
+ // ADR-0025 PD4 §3.5/§3.11 — the pre-install consent panel
3065
+ // (PluginDisclosure.tsx). `runtime` is a CLOSED enum: spec
3066
+ // PluginRuntimeSchema = z.enum(['node', 'sandbox', 'worker']).
3067
+ disclosure: {
3068
+ containsCode: "Ce paquet contient du code",
3069
+ reviewed: "Examiné et approuvé",
3070
+ unreviewed: "Pas encore examiné",
3071
+ signed: "Signé",
3072
+ grantsIntro: "À l'installation, ce paquet obtiendra :",
3073
+ services: "Services de la plateforme",
3074
+ hooks: "Hooks de cycle de vie",
3075
+ network: "Accès réseau",
3076
+ fs: "Accès au système de fichiers",
3077
+ noPermissions: "Ne demande aucune autorisation particulière.",
3078
+ acknowledge: "Je comprends que ce paquet exécute du code et obtient les autorisations ci-dessus.",
3079
+ runtime: {
3080
+ node: "Dans le processus · confiance totale",
3081
+ sandbox: "Bac à sable",
3082
+ worker: "Hors processus",
3083
+ },
2763
3084
  },
2764
3085
  uninstall: {
2765
3086
  confirm: "Désinstaller {{manifestId}} v{{version}} de ce runtime ?\n\nLe manifeste en cache sera supprimé.",
@@ -3009,6 +3330,34 @@ const fr = {
3009
3330
  confirmNote: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
3010
3331
  publishConfirm: 'Tout publier',
3011
3332
  },
3333
+ // ADR-0045 — the materialized-but-unlisted app banner
3334
+ // (UnpublishedAppBar.tsx), sibling of draftBar above.
3335
+ unpublishedBar: {
3336
+ message: 'Application non publiée — entièrement fonctionnelle, mais visible seulement par les créateurs. Publiez-la pour la rendre visible à vos utilisateurs.',
3337
+ publish: 'Publier',
3338
+ publishing: 'Publication…',
3339
+ published: 'Publié ! L\'application est maintenant visible par vos utilisateurs.',
3340
+ publishFailed: 'Échec de la publication',
3341
+ },
3342
+ // ADR-0067 — the append-only build/revert timeline (CommitTimeline.tsx);
3343
+ // `button` is the banner's entry point into it.
3344
+ history: {
3345
+ button: 'Historique',
3346
+ title: 'Historique des générations',
3347
+ description: 'Toutes les modifications de cette application, les plus récentes d\'abord. Annulez n\'importe quelle étape — aucune confirmation de publication n\'est nécessaire.',
3348
+ loadFailed: 'Impossible de charger l\'historique :',
3349
+ loadFailedUnavailable: 'Magasin de commits temporairement injoignable — cette lecture n\'a pas eu lieu, aucun historique n\'est donc affiché. Réessayez dans un instant.',
3350
+ loading: 'Chargement de l\'historique…',
3351
+ empty: 'Aucun historique pour cette application.',
3352
+ revertLabel: 'Modification annulée',
3353
+ applyLabel: 'Modification de génération',
3354
+ revert: 'annulation',
3355
+ items: 'éléments',
3356
+ revertAction: 'Annuler',
3357
+ reverted: 'Annulé — la modification a été retirée.',
3358
+ revertFailed: 'Échec de l\'annulation',
3359
+ revertUnavailable: 'Magasin de commits temporairement injoignable — l\'annulation n\'a peut-être pas été appliquée. Rouvrez cet historique pour le vérifier avant de réessayer.',
3360
+ },
3012
3361
  },
3013
3362
  filterBuilder: {
3014
3363
  where: "Où",
@@ -3087,5 +3436,57 @@ const fr = {
3087
3436
  statusIdle: "inactif",
3088
3437
  statusAway: "absent",
3089
3438
  },
3439
+ wizard: {
3440
+ missingRequired: "Veuillez renseigner les champs obligatoires : {{fields}}",
3441
+ },
3442
+ appManagement: {
3443
+ title: "Applications",
3444
+ subtitle: "Gérer toutes les applications configurées",
3445
+ newApp: "Nouvelle application",
3446
+ searchLabel: "Rechercher des applications",
3447
+ searchPlaceholder: "Rechercher des applications…",
3448
+ selectedCount: "{{n}} sélectionnées",
3449
+ bulkEnable: "Activer",
3450
+ bulkDisable: "Désactiver",
3451
+ selectAll: "Tout sélectionner ({{n}})",
3452
+ empty: "Aucune application trouvée.",
3453
+ defaultBadge: "Par défaut",
3454
+ active: "Active",
3455
+ inactive: "Inactive",
3456
+ selectApp: "Sélectionner {{name}}",
3457
+ openApp: "Ouvrir l'application",
3458
+ openAppNamed: "Ouvrir {{name}}",
3459
+ editApp: "Modifier l'application",
3460
+ editAppNamed: "Modifier {{name}}",
3461
+ editWithAi: "Modifier avec l'IA",
3462
+ editWithAiNamed: "Modifier {{name}} avec l'IA",
3463
+ enableApp: "Activer l'application",
3464
+ disableApp: "Désactiver l'application",
3465
+ enableAppNamed: "Activer {{name}}",
3466
+ disableAppNamed: "Désactiver {{name}}",
3467
+ setDefault: "Définir par défaut",
3468
+ setDefaultNamed: "Définir {{name}} par défaut",
3469
+ deleteApp: "Supprimer l'application",
3470
+ deleteAppNamed: "Supprimer {{name}}",
3471
+ confirmDelete: "Cliquez à nouveau pour confirmer la suppression",
3472
+ confirmDeleteNamed: "Confirmer la suppression de {{name}}",
3473
+ toast: {
3474
+ noClient: "Impossible de joindre le service de métadonnées",
3475
+ unknownError: "erreur inconnue",
3476
+ appEnabled: "{{name}} activée",
3477
+ appDisabled: "{{name}} désactivée",
3478
+ toggleFailed: "Échec du changement d'état de l'application : {{reason}}",
3479
+ setDefaultDone: "{{name}} définie par défaut",
3480
+ setDefaultFailed: "Échec de la définition de l'application par défaut : {{reason}}",
3481
+ appDeleted: "{{name}} supprimée",
3482
+ deleteFailed: "Échec de la suppression de l'application : {{reason}}",
3483
+ bulkEnabled: "{{n}} applications activées",
3484
+ bulkDisabled: "{{n}} applications désactivées",
3485
+ bulkFailed: "Échec pour {{n}} : {{details}}",
3486
+ bulkFailureEntry: "{{name}} ({{reason}})",
3487
+ bulkFailureJoiner: " ; ",
3488
+ bulkOperationFailed: "Échec de l'opération groupée : {{reason}}",
3489
+ },
3490
+ },
3090
3491
  };
3091
3492
  export default fr;