@object-ui/i18n 17.2.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 +1817 -1
  2. package/README.md +26 -13
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +14 -1
  5. package/dist/locales/ar.d.ts +550 -107
  6. package/dist/locales/ar.js +646 -156
  7. package/dist/locales/de.d.ts +550 -107
  8. package/dist/locales/de.js +661 -178
  9. package/dist/locales/en.d.ts +586 -143
  10. package/dist/locales/en.js +851 -143
  11. package/dist/locales/es.d.ts +550 -107
  12. package/dist/locales/es.js +647 -160
  13. package/dist/locales/fr.d.ts +550 -107
  14. package/dist/locales/fr.js +640 -155
  15. package/dist/locales/index.d.ts +5587 -1157
  16. package/dist/locales/ja.d.ts +550 -107
  17. package/dist/locales/ja.js +632 -149
  18. package/dist/locales/ko.d.ts +550 -107
  19. package/dist/locales/ko.js +638 -156
  20. package/dist/locales/pt.d.ts +550 -107
  21. package/dist/locales/pt.js +639 -157
  22. package/dist/locales/ru.d.ts +550 -107
  23. package/dist/locales/ru.js +650 -156
  24. package/dist/locales/zh.d.ts +588 -145
  25. package/dist/locales/zh.js +629 -145
  26. package/dist/pickLocalized.d.ts +21 -0
  27. package/dist/pickLocalized.js +40 -7
  28. package/dist/provider.d.ts +125 -1
  29. package/dist/provider.js +380 -4
  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 +67 -3
  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 +5 -4
@@ -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,11 +109,20 @@ 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",
115
+ closePanel: "Fermer le panneau",
116
+ resizeDrawer: "Redimensionner le panneau",
117
+ itemCount: "{{count}} éléments",
118
+ itemCountOne: "{{count}} élément",
82
119
  toggleSidebar: "Basculer la barre latérale",
83
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)",
84
126
  },
85
127
  actions: {
86
128
  decisionOutput: {
@@ -103,6 +145,7 @@ const fr = {
103
145
  url: "Veuillez saisir une URL valide",
104
146
  pattern: "Le format de {{field}} est invalide",
105
147
  formInvalid: "Veuillez vérifier les champs en surbrillance : {{fields}}",
148
+ formInvalidJoiner: ", ",
106
149
  unique: "{{field}} doit être unique",
107
150
  type: "{{field}} doit être un {{type}} valide",
108
151
  },
@@ -111,6 +154,9 @@ const fr = {
111
154
  submitFailed: "Échec de l'enregistrement. Veuillez réessayer.",
112
155
  discardTitle: "Abandonner les modifications ?",
113
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.",
114
160
  keepEditing: "Continuer l'édition",
115
161
  discard: "Abandonner",
116
162
  conflictTitle: "Conflit d'enregistrement",
@@ -127,12 +173,21 @@ const fr = {
127
173
  stepOf: "Étape {{current}} sur {{total}}",
128
174
  createTitle: "Créer {{object}}",
129
175
  editTitle: "Modifier {{object}}",
176
+ viewTitle: "Afficher {{object}}",
177
+ createTargetOrg: "Création dans {{org}}",
130
178
  saveRecord: "Enregistrer",
131
179
  create: "Créer",
132
180
  update: "Mettre à jour",
133
181
  createSuccess: "{{object}} créé",
134
182
  updateSuccess: "{{object}} mis à jour",
135
183
  deleteSuccess: "{{object}} supprimé",
184
+ fullscreen: {
185
+ title: "Modifier le texte",
186
+ description: "Modifiez la valeur texte complète, puis enregistrez ou annulez vos modifications.",
187
+ done: "Terminé",
188
+ toggle: "Modifier {{label}} en plein écran",
189
+ textFallback: "le texte",
190
+ },
136
191
  },
137
192
  fields: {
138
193
  image: {
@@ -170,7 +225,11 @@ const fr = {
170
225
  richText: {
171
226
  format: "Format : {{format}}",
172
227
  basicEditorHint: "Éditeur de texte enrichi (basique)",
173
- placeholder: "Écrivez quelque chose...",
228
+ placeholder: "Écrivez quelque chose…",
229
+ },
230
+ options: {
231
+ empty: "Aucune option disponible",
232
+ selectFirst: "Sélectionnez d’abord {{fields}}",
174
233
  },
175
234
  objectRef: {
176
235
  loading: "Chargement des objets…",
@@ -199,6 +258,13 @@ const fr = {
199
258
  editAsJson: "Modifier en JSON",
200
259
  useVisualBuilder: "Utiliser le constructeur visuel",
201
260
  },
261
+ tags: {
262
+ placeholder: "Saisissez puis appuyez sur Entrée pour ajouter…",
263
+ },
264
+ textarea: {
265
+ characterCount: "Nombre de caractères : {{count}} sur {{max}}",
266
+ charactersRemaining: "Caractères restants : {{count}}",
267
+ },
202
268
  },
203
269
  table: {
204
270
  rowsPerPage: "Lignes par page",
@@ -225,7 +291,7 @@ const fr = {
225
291
  saveAll: "Tout enregistrer ({{count}})",
226
292
  addRecord: "Ajouter un enregistrement",
227
293
  open: "Ouvrir",
228
- search: "Rechercher...",
294
+ search: "Rechercher…",
229
295
  modified: "{{count}} ligne(s) modifiée(s)",
230
296
  saveFailed: 'Échec de l’enregistrement',
231
297
  selected: "{{count}} sélectionné(s)",
@@ -269,7 +335,7 @@ const fr = {
269
335
  delete: "Supprimer",
270
336
  export: "Exporter",
271
337
  exportAs: "Exporter en {{format}}",
272
- loading: "Chargement de la grille...",
338
+ loading: "Chargement de la grille…",
273
339
  errorLoading: "Erreur de chargement de la grille",
274
340
  pullToRefresh: "Tirer pour actualiser",
275
341
  refreshing: "Actualisation…",
@@ -280,6 +346,22 @@ const fr = {
280
346
  yes: "Oui",
281
347
  no: "Non",
282
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
+ },
283
365
  toolbar: {
284
366
  densityMode: "Densité",
285
367
  densityCompact: "Compact",
@@ -393,12 +475,12 @@ const fr = {
393
475
  templateName: "Nom du modèle",
394
476
  save: "Enregistrer",
395
477
  deleteTemplate: "Supprimer le modèle",
396
- savedMapping: 'Saved mapping:',
397
- chooseSavedMapping: 'Choose a saved mapping…',
398
- manualMapping: '— Map columns manually —',
399
- transform: 'Transform',
400
- savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
401
- 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.",
402
484
  csvColumn: "Colonne",
403
485
  mapsTo: "Correspond à",
404
486
  typeMismatch: "Ressemble à {{type}}",
@@ -458,6 +540,8 @@ const fr = {
458
540
  loadErrorUnauthorizedMessage: "Votre session a expiré ou vous êtes déconnecté. Reconnectez-vous pour consulter ces enregistrements.",
459
541
  loadErrorRejectedTitle: "La requête de cette vue a été rejetée",
460
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.",
461
545
  retry: "Réessayer",
462
546
  managedBy: {
463
547
  system: {
@@ -482,7 +566,7 @@ const fr = {
482
566
  },
483
567
  },
484
568
  refresh: "Actualiser",
485
- loading: 'Loading records...',
569
+ loading: "Chargement des enregistrements…",
486
570
  recordCount: "{{count}} enregistrements",
487
571
  recordCountOne: "{{count}} enregistrement",
488
572
  addRecord: "Ajouter un enregistrement",
@@ -494,7 +578,8 @@ const fr = {
494
578
  sort: "Trier",
495
579
  sortRecords: "Trier les enregistrements",
496
580
  sortByIdSuffix: "(par ID)",
497
- 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",
498
583
  group: "Grouper",
499
584
  groupBy: "Grouper par",
500
585
  export: "Exporter",
@@ -552,13 +637,16 @@ const fr = {
552
637
  },
553
638
  kanban: {
554
639
  uncategorized: "Non catégorisé",
640
+ columns: "colonnes",
555
641
  addCard: "Ajouter une carte",
556
642
  addColumn: "Ajouter une colonne",
557
643
  moveCard: "Déplacer la carte",
558
644
  deleteCard: "Supprimer la carte",
559
645
  deleteColumn: "Supprimer la colonne",
560
646
  noCards: "Aucune carte",
561
- 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.",
562
650
  },
563
651
  timeline: {
564
652
  bucket: {
@@ -571,6 +659,13 @@ const fr = {
571
659
  noDate: "Sans date",
572
660
  unassigned: "Non attribué",
573
661
  },
662
+ scale: {
663
+ week: "Semaine {{n}}",
664
+ quarter: "T{{quarter}} {{year}}",
665
+ },
666
+ gantt: {
667
+ rowLabel: "Éléments",
668
+ },
574
669
  },
575
670
  gantt: {
576
671
  viewMode: {
@@ -617,6 +712,18 @@ const fr = {
617
712
  ff: "Fin → Fin",
618
713
  sf: "Début → Fin",
619
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
+ },
620
727
  conflict: {
621
728
  title: "Conflit de planning",
622
729
  body: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche(s) concernée(s) ?",
@@ -625,8 +732,8 @@ const fr = {
625
732
  },
626
733
  autoScheduleDlg: {
627
734
  title: "Planification automatique",
628
- body: "Décaler {count} tâche(s) plus tard pour respecter les liens de dépendance ?",
629
- 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.",
630
737
  confirm: "Appliquer",
631
738
  cancel: "Annuler",
632
739
  none: "Toutes les dépendances sont respectées — rien à replanifier.",
@@ -637,6 +744,12 @@ const fr = {
637
744
  over: "surchargée",
638
745
  empty: "Aucune tâche à affecter.",
639
746
  },
747
+ quickFilter: {
748
+ all: "Tous",
749
+ clear: "Effacer les filtres",
750
+ empty: "Aucune option",
751
+ resultSummary: "Affichage de {shown} / {total} tâches",
752
+ },
640
753
  readOnly: "Lecture seule",
641
754
  readOnlyHint: "L'édition est désactivée pour cette vue.",
642
755
  lockedHint: "Aucune autorisation de modification",
@@ -657,6 +770,7 @@ const fr = {
657
770
  exportPng: "Exporter en PNG",
658
771
  exportPdf: "Exporter en PDF",
659
772
  saveLayout: "Enregistrer la disposition",
773
+ refresh: "Actualiser",
660
774
  undo: "Annuler",
661
775
  redo: "Rétablir",
662
776
  prevPeriod: "Période précédente",
@@ -697,11 +811,11 @@ const fr = {
697
811
  defaultBadge: "par défaut",
698
812
  tabActionsFor: "Actions de vue pour {{name}}",
699
813
  readonlyAriaLabel: "Vue en lecture seule",
700
- readonlyTooltip: "Vue système — dupliquer pour personnaliser.",
814
+ readonlyTooltip: "Vue système — définie dans le code, en lecture seule.",
701
815
  },
702
816
  designer: {
703
- undo: 'Undo',
704
- redo: 'Redo',
817
+ undo: "Annuler",
818
+ redo: "Rétablir",
705
819
  },
706
820
  detail: {
707
821
  editInlineHint: "Double-cliquez pour modifier",
@@ -721,6 +835,15 @@ const fr = {
721
835
  viewHistory: "Voir l'historique",
722
836
  delete: "Supprimer",
723
837
  moreActions: "Plus d'actions",
838
+ addReaction: "Ajouter une réaction",
839
+ pageHeaderActions: "Actions de l'en-tête de page",
840
+ emojiPicker: "Sélecteur d'émojis",
841
+ reactionCount: "{{emoji}} {{count}} réactions",
842
+ reactionCountOne: "{{emoji}} {{count}} réaction",
843
+ recordDetail: "Détail de l'enregistrement",
844
+ recordDetailWithLabel: "Détail — {{label}}",
845
+ openAsFullPage: "Ouvrir en pleine page",
846
+ recordDetailOverlay: "Panneau de détail de l'enregistrement pour {{title}}.",
724
847
  addToFavorites: "Ajouter aux favoris",
725
848
  removeFromFavorites: "Retirer des favoris",
726
849
  previousRecord: "Enregistrement précédent",
@@ -734,13 +857,15 @@ const fr = {
734
857
  relatedRecords: "{{count}} enregistrements",
735
858
  relatedRecordOne: "{{count}} enregistrement",
736
859
  noRelatedRecords: "Aucun enregistrement associé trouvé",
737
- loading: "Chargement...",
860
+ loading: "Chargement…",
738
861
  copyToClipboard: "Copier dans le presse-papiers",
739
862
  copied: "Copié !",
740
863
  deleteConfirmation: "Êtes-vous sûr de vouloir supprimer cet enregistrement ?",
864
+ deleted: "Enregistrement supprimé",
741
865
  editRecord: "Modifier l'enregistrement",
742
866
  viewAll: "Tout afficher",
743
867
  new: "Nouveau",
868
+ add: "Ajouter",
744
869
  emptyValue: "—",
745
870
  comments: "Commentaires",
746
871
  searchComments: "Rechercher des commentaires…",
@@ -805,6 +930,7 @@ const fr = {
805
930
  loadMore: "Charger plus",
806
931
  edited: "(modifié)",
807
932
  via: "via {{source}}",
933
+ viewSource: "Voir la source",
808
934
  replyCount: "{{count}} réponse",
809
935
  replyCountPlural: "{{count}} réponses",
810
936
  replyPlaceholder: "Répondre…",
@@ -817,14 +943,15 @@ const fr = {
817
943
  saving: "Enregistrement…",
818
944
  lockedByApproval: "Verrouillé pour approbation",
819
945
  lockedTooltip: "Cet enregistrement a une demande d'approbation en attente ; la modification est verrouillée",
820
- writeStrippedTitle: "Certains champs n'ont pas été enregistrés",
821
- writeStrippedReadonly: "En lecture seule, donc non enregistré : {{fields}}",
822
- writeStrippedByState: "Non modifiable dans l'état actuel de cet enregistrement, donc non enregistré : {{fields}}",
946
+ writeStrippedTitle: "Enregistré — mais certains champs n'ont pas été appliqués",
947
+ writeStrippedReadonly: "En lecture seule, donc non appliqué : {{fields}}",
948
+ writeStrippedByState: "Non modifiable dans l'état actuel de cet enregistrement, donc non appliqué : {{fields}}",
823
949
  approvalPendingEditable: "En approbation · modifiable",
824
950
  approvalPendingTooltip: "Cet enregistrement a une demande d'approbation en attente ; cette étape autorise encore la modification",
825
951
  approvalProgress: "Approbations — {{got}} sur {{need}}",
826
952
  approvalProgressGroups: "Validation — {{got}} sur {{need}} groupes",
827
953
  approvalProgressLabel: "Progression de l'approbation",
954
+ approvalsPanelTitle: "Approbations",
828
955
  cancelApproval: "Annuler l'approbation",
829
956
  cancelApprovalInFlight: "Annulation…",
830
957
  cancelApprovalTooltip: "Annuler la demande d'approbation en attente pour déverrouiller l'enregistrement",
@@ -845,9 +972,11 @@ const fr = {
845
972
  concurrentUpdateReload: "Charger la version actuelle",
846
973
  concurrentUpdateOverwrite: "Écraser quand même",
847
974
  concurrentUpdateCancel: "Annuler",
975
+ concurrentUpdateRecordLabel: "cet enregistrement",
848
976
  openInNewTab: "Ouvrir dans un nouvel onglet",
849
977
  activity: "Activité",
850
978
  history: "Historique",
979
+ historyEmpty: "Aucun historique pour le moment",
851
980
  editRow: "Modifier",
852
981
  deleteRow: "Supprimer",
853
982
  deleteRowConfirmation: "Supprimer cet enregistrement ?",
@@ -857,10 +986,15 @@ const fr = {
857
986
  nextPage: "Suivant",
858
987
  pageOf: "Page {{current}} sur {{total}}",
859
988
  sortBy: "Trier par",
860
- filterPlaceholder: "Filtrer...",
989
+ filterPlaceholder: "Filtrer…",
861
990
  highlightFields: "Champs clés",
862
991
  createdBy: "Créé par",
863
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",
864
998
  showEmptyRelated_one: "+ {{count}} vide",
865
999
  showEmptyRelated_other: "+ {{count}} vides",
866
1000
  copyEmail: "Copier l'e-mail",
@@ -872,7 +1006,8 @@ const fr = {
872
1006
  },
873
1007
  chart: {
874
1008
  noData: "Aucune donnée de graphique disponible",
875
- loading: "Chargement du graphique...",
1009
+ loading: "Chargement du graphique…",
1010
+ nullCategory: "(Non défini)",
876
1011
  },
877
1012
  map: {
878
1013
  searchLocations: "Rechercher des lieux…",
@@ -894,8 +1029,8 @@ const fr = {
894
1029
  properties: "Propriétés",
895
1030
  connections: "Connexions",
896
1031
  quickConnect: "Connexion rapide",
897
- fromPlaceholder: "De...",
898
- toPlaceholder: "Vers...",
1032
+ fromPlaceholder: "De…",
1033
+ toPlaceholder: "Vers…",
899
1034
  connect: "Connecter",
900
1035
  label: "Libellé",
901
1036
  type: "Type",
@@ -943,6 +1078,7 @@ const fr = {
943
1078
  },
944
1079
  dashboard: {
945
1080
  noRows: "Aucune ligne",
1081
+ loading: "Chargement…",
946
1082
  pickMeasures: "Choisissez des mesures (valeurs) pour ce widget de dataset.",
947
1083
  datasetUnsupported: "Cette source de données ne prend pas en charge les requêtes de dataset.",
948
1084
  details: "Détails",
@@ -1200,6 +1336,7 @@ const fr = {
1200
1336
  },
1201
1337
  },
1202
1338
  console: {
1339
+ saveAdvisoryTitle: "Enregistré — le contrôle de création a signalé {{count}} recommandation(s)",
1203
1340
  settingsHub: {
1204
1341
  title: "Paramètres",
1205
1342
  subtitle: "Configurez votre espace de travail, vos intégrations et vos indicateurs de fonctionnalité.",
@@ -1266,7 +1403,7 @@ const fr = {
1266
1403
  shareTitle: "Partager cette conversation",
1267
1404
  shareDisabledTitle: "Commencez à discuter pour activer le partage",
1268
1405
  newChat: "Nouveau",
1269
- searchChats: "Rechercher des discussions...",
1406
+ searchChats: "Rechercher des discussions…",
1270
1407
  noChatsYet: "Aucune discussion pour l'instant",
1271
1408
  noChatsDescription: "Démarrez une nouvelle conversation pour la voir ici.",
1272
1409
  noMatchingChats: "Aucune discussion correspondante.",
@@ -1275,18 +1412,18 @@ const fr = {
1275
1412
  deleteConversation: "Supprimer la conversation",
1276
1413
  saveRename: "Enregistrer le nom",
1277
1414
  cancelRename: "Annuler le changement de nom",
1278
- loadingHistory: "Chargement de l'historique de la conversation...",
1415
+ loadingHistory: "Chargement de l'historique de la conversation…",
1279
1416
  conversationReady: "Conversation prête",
1280
1417
  preparingConversation: "Préparation d'une nouvelle conversation",
1281
1418
  offlineDemoMode: "Mode démo hors ligne — liste des agents indisponible",
1282
1419
  sendFailedRateLimited: "Vous envoyez des messages trop rapidement. Votre message est conservé ci-dessous — patientez un instant puis réessayez.",
1283
1420
  sendFailedGeneric: "Impossible d'envoyer votre message. Il est conservé ci-dessous — veuillez réessayer.",
1284
- askAgent: "Demander à {{agent}}...",
1421
+ askAgent: "Demander à {{agent}}…",
1285
1422
  assistant: "Assistant",
1286
1423
  liveCanvas: "Aperçu en direct — {{app}} (brouillon)",
1287
1424
  liveCanvasUnlisted: "Application en direct — {{app}} (non répertoriée jusqu'à publication)",
1288
- loadingAgents: "Chargement des agents...",
1289
- askAnything: "Posez n'importe quelle question...",
1425
+ loadingAgents: "Chargement des agents…",
1426
+ askAnything: "Posez n'importe quelle question…",
1290
1427
  emptyTitle: "Démarrer une conversation",
1291
1428
  emptyDescription: "Posez n'importe quelle question — l'assistant a accès au contexte de votre application actuelle.",
1292
1429
  switchAssistant: "Changer d'assistant",
@@ -1389,9 +1526,60 @@ const fr = {
1389
1526
  createSeed: "Générer des données d'exemple",
1390
1527
  createPackage: "Créer un package d'application",
1391
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
+ },
1392
1580
  },
1393
1581
  title: "Console ObjectStack",
1394
- initializing: "Initialisation de l'application...",
1582
+ initializing: "Initialisation de l'application…",
1395
1583
  loadingHint: "La configuration d'un nouvel environnement peut prendre quelques instants.",
1396
1584
  breadcrumb: {
1397
1585
  dashboards: "Tableaux de bord",
@@ -1399,6 +1587,31 @@ const fr = {
1399
1587
  reports: "Rapports",
1400
1588
  system: "Système",
1401
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
+ },
1402
1615
  loadingSteps: {
1403
1616
  connecting: "Connexion à la source de données",
1404
1617
  loadingConfig: "Chargement de la configuration",
@@ -1414,6 +1627,13 @@ const fr = {
1414
1627
  retry: "Réessayer",
1415
1628
  retrying: "Nouvelle tentative…",
1416
1629
  },
1630
+ serverAction: {
1631
+ openingTitle: "Ouverture…",
1632
+ openingBody: "Ouverture… cela peut prendre un moment.",
1633
+ popupBlockedTitle: "Fenêtre contextuelle bloquée",
1634
+ popupBlockedDescription: "Le navigateur a bloqué l'ouverture du nouvel onglet.",
1635
+ popupBlockedAction: "Ouvrir dans un nouvel onglet",
1636
+ },
1417
1637
  shortcuts: {
1418
1638
  title: "Raccourcis clavier",
1419
1639
  description: "Référence rapide de tous les raccourcis clavier disponibles.",
@@ -1421,6 +1641,7 @@ const fr = {
1421
1641
  general: "Général",
1422
1642
  navigation: "Navigation",
1423
1643
  dataViews: "Vues de données",
1644
+ aiChat: "Assistant IA",
1424
1645
  preferences: "Préférences",
1425
1646
  },
1426
1647
  openCommandPalette: "Ouvrir la palette de commandes",
@@ -1431,11 +1652,13 @@ const fr = {
1431
1652
  createRecord: "Créer un nouvel enregistrement",
1432
1653
  refreshData: "Actualiser les données",
1433
1654
  editRecord: "Modifier l'enregistrement sélectionné",
1655
+ newChat: "Nouvelle discussion",
1656
+ toggleChatsList: "Basculer la liste des discussions",
1434
1657
  toggleDarkMode: "Basculer le mode sombre",
1435
1658
  },
1436
1659
  commandPalette: {
1437
1660
  title: "Palette de commandes",
1438
- placeholder: "Tapez une commande ou recherchez...",
1661
+ placeholder: "Tapez une commande ou recherchez…",
1439
1662
  noResults: "Aucun résultat trouvé.",
1440
1663
  objects: "Objets",
1441
1664
  dashboards: "Tableaux de bord",
@@ -1461,6 +1684,12 @@ const fr = {
1461
1684
  goHome: "Retour à l'accueil",
1462
1685
  errorDetails: "Détails de l'erreur (développement uniquement)",
1463
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
+ },
1464
1693
  theme: {
1465
1694
  toggle: "Changer de thème",
1466
1695
  light: "Clair",
@@ -1476,11 +1705,15 @@ const fr = {
1476
1705
  viewNameHelp: "Clé technique (snake_case). Remplie automatiquement à partir du titre — modifiable si vous le souhaitez.",
1477
1706
  viewNameRequired: "Saisissez une clé (minuscules, chiffres, tiret bas). Non remplie automatiquement pour les titres non latins.",
1478
1707
  viewNameInvalid: "Utilisez des minuscules, des chiffres et des tirets bas ; commencez par une lettre ou un tiret bas.",
1479
- systemViewReadonly: 'System view defined in code - duplicate to customize.',
1480
- 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",
1481
1712
  objectNotFound: "Objet introuvable",
1482
1713
  objectNotFoundDescription: "L'objet « {{objectName}} » n'existe pas dans la configuration actuelle.",
1483
1714
  objectNotFoundHint: "Vérifiez les paramètres de navigation de votre application ou sélectionnez un autre objet dans la barre latérale.",
1715
+ filterOrNotSavable: "Ce filtre relie les conditions par OU, ce qu'une vue enregistrée ne peut pas encore stocker. Il s'applique toujours à cette liste — supprimez le groupement OU pour l'enregistrer dans la vue.",
1716
+ filterNestedNotSavable: "Ce filtre utilise des groupes de conditions imbriqués, qu'une vue enregistrée ne peut pas stocker. Aplatissez-le en une seule liste de conditions pour l'enregistrer dans la vue.",
1484
1717
  allRecords: "Tous les enregistrements",
1485
1718
  exitDesignMode: "Quitter le mode conception",
1486
1719
  enterDesignMode: "Entrer en mode conception",
@@ -1507,7 +1740,7 @@ const fr = {
1507
1740
  exportPrintHint: "Formats d'export, impression et affichage du nombre d'enregistrements",
1508
1741
  showAllFields: "Tout afficher",
1509
1742
  hideAllFields: "Tout masquer",
1510
- searchFields: "Rechercher des champs...",
1743
+ searchFields: "Rechercher des champs…",
1511
1744
  title: "Titre",
1512
1745
  description: "Description",
1513
1746
  data: "Données",
@@ -1546,7 +1779,7 @@ const fr = {
1546
1779
  longitudeField: "Champ de longitude",
1547
1780
  imageField: "Champ d'image",
1548
1781
  dateField: "Champ de date",
1549
- selectField: "Sélectionner un champ...",
1782
+ selectField: "Sélectionner un champ…",
1550
1783
  gridOptionsHint: "La vue grille utilise les colonnes configurées ci-dessus.",
1551
1784
  groupBy: "Regrouper par",
1552
1785
  prefixField: "Champ de préfixe",
@@ -1609,7 +1842,7 @@ const fr = {
1609
1842
  latitudeFieldHelp: "Champ contenant la latitude (champs géo uniquement).",
1610
1843
  longitudeFieldHelp: "Champ contenant la longitude (champs géo uniquement).",
1611
1844
  imageFieldHelp: "La couverture de la galerie provient de ce champ image ou pièce jointe.",
1612
- selectOption: "Sélectionner...",
1845
+ selectOption: "Sélectionner…",
1613
1846
  noEligibleFieldForType: "Aucun champ éligible de ce type. Ajoutez-en un à l'objet d'abord.",
1614
1847
  viewTypeUnavailable: "Cet objet n'a pas de champ pouvant servir de \"{{field}}\".",
1615
1848
  viewTypeUnavailableShort: "Non pris en charge par cet objet.",
@@ -1659,7 +1892,7 @@ const fr = {
1659
1892
  ufDropdown: "Liste déroulante",
1660
1893
  ufTabs: "Onglets",
1661
1894
  ufToggle: "Bascule",
1662
- ufAddField: "+ Ajouter un champ de filtre...",
1895
+ ufAddField: "+ Ajouter un champ de filtre…",
1663
1896
  ufNoFields: "Aucun champ disponible",
1664
1897
  ufAddTab: "+ Ajouter un onglet",
1665
1898
  ufTabLabel: "Étiquette",
@@ -1719,7 +1952,7 @@ const fr = {
1719
1952
  passwordPlaceholder: "Entrez votre mot de passe",
1720
1953
  forgotPasswordText: "Mot de passe oublié ?",
1721
1954
  submitButton: "Se connecter",
1722
- submittingButton: "Connexion en cours...",
1955
+ submittingButton: "Connexion en cours…",
1723
1956
  noAccountText: "Vous n'avez pas de compte ?",
1724
1957
  signUpText: "S'inscrire",
1725
1958
  errors: {
@@ -1727,6 +1960,18 @@ const fr = {
1727
1960
  invalidCredentials: "E-mail ou mot de passe invalide. Veuillez réessayer.",
1728
1961
  emailNotVerified: "Veuillez vérifier votre adresse e-mail avant de vous connecter.",
1729
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",
1730
1975
  },
1731
1976
  register: {
1732
1977
  title: "Créer un compte",
@@ -1742,7 +1987,7 @@ const fr = {
1742
1987
  passwordMismatchError: "Les mots de passe ne correspondent pas",
1743
1988
  passwordTooShortError: "Le mot de passe doit contenir au moins 8 caractères",
1744
1989
  submitButton: "Créer un compte",
1745
- submittingButton: "Création du compte...",
1990
+ submittingButton: "Création du compte…",
1746
1991
  hasAccountText: "Vous avez déjà un compte ?",
1747
1992
  signInText: "Se connecter",
1748
1993
  errors: {
@@ -1763,12 +2008,26 @@ const fr = {
1763
2008
  emailLabel: "E-mail",
1764
2009
  emailPlaceholder: "name@example.com",
1765
2010
  submitButton: "Envoyer le lien de réinitialisation",
1766
- submittingButton: "Envoi en cours...",
2011
+ submittingButton: "Envoi en cours…",
1767
2012
  successTitle: "Vérifiez vos e-mails",
1768
2013
  successDescription: "Nous avons envoyé un lien de réinitialisation du mot de passe à {{email}}. Veuillez vérifier votre boîte de réception.",
1769
2014
  backToSignInText: "Retour à la connexion",
1770
2015
  rememberPasswordText: "Vous vous souvenez de votre mot de passe ?",
1771
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.",
1772
2031
  },
1773
2032
  resetPassword: {
1774
2033
  title: "Définir un nouveau mot de passe",
@@ -1807,6 +2066,8 @@ const fr = {
1807
2066
  backToLogin: "Retour à la connexion",
1808
2067
  checkSpam: "E-mail non reçu ? Vérifiez votre dossier spam ou contactez le support.",
1809
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.",
1810
2071
  },
1811
2072
  setup: {
1812
2073
  welcomeTitle: "Bienvenue sur ObjectStack",
@@ -1845,6 +2106,9 @@ const fr = {
1845
2106
  invalidDescription: "Aucun code d'appareil n'a été fourni dans l'URL.",
1846
2107
  loading: "Chargement…",
1847
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.",
1848
2112
  },
1849
2113
  shell: {
1850
2114
  tenantHostHint: "Vous vous connectez à cet espace de travail",
@@ -1884,6 +2148,29 @@ const fr = {
1884
2148
  },
1885
2149
  },
1886
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
+ },
1887
2174
  profile: {
1888
2175
  title: "Profil",
1889
2176
  subtitle: "Gérez les paramètres de votre compte",
@@ -1945,6 +2232,8 @@ const fr = {
1945
2232
  invite: "Inviter un membre",
1946
2233
  members: "Membres",
1947
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",
1948
2237
  },
1949
2238
  help: {
1950
2239
  onThisPage: "Sur cette page",
@@ -1955,7 +2244,7 @@ const fr = {
1955
2244
  },
1956
2245
  sidebar: {
1957
2246
  packageManagement: "Gestion des packages",
1958
- searchNavigation: "Rechercher dans la navigation...",
2247
+ searchNavigation: "Rechercher dans la navigation…",
1959
2248
  settings: "Paramètres",
1960
2249
  help: "Aide",
1961
2250
  helpTooltip: "Aide et documentation",
@@ -1979,8 +2268,8 @@ const fr = {
1979
2268
  switchObject: "Changer d'objet",
1980
2269
  connection: {
1981
2270
  connected: "Connecté",
1982
- connecting: "Connexion...",
1983
- reconnecting: "Reconnexion...",
2271
+ connecting: "Connexion…",
2272
+ reconnecting: "Reconnexion…",
1984
2273
  disconnected: "Déconnecté",
1985
2274
  error: "Erreur de connexion",
1986
2275
  },
@@ -2019,6 +2308,14 @@ const fr = {
2019
2308
  publishing: "Publication…",
2020
2309
  published: "Publié ! Vos modifications sont actives.",
2021
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.",
2022
2319
  },
2023
2320
  title: "Accueil",
2024
2321
  subtitle: "Tableau de bord de votre espace de travail",
@@ -2032,7 +2329,7 @@ const fr = {
2032
2329
  title: "Nécessite votre attention",
2033
2330
  empty: "Vous êtes à jour",
2034
2331
  },
2035
- loading: "Chargement de l'espace de travail...",
2332
+ loading: "Chargement de l'espace de travail…",
2036
2333
  recent: "Récent",
2037
2334
  starred: "Favoris",
2038
2335
  welcome: "Bienvenue dans ObjectUI",
@@ -2093,6 +2390,9 @@ const fr = {
2093
2390
  roles: "Rôles",
2094
2391
  configuration: "Configuration",
2095
2392
  createApp: "Créer une application",
2393
+ administration: "Administration",
2394
+ datasources: "Sources de données",
2395
+ documentation: "Documentation",
2096
2396
  },
2097
2397
  appSwitcher: {
2098
2398
  switchApplication: "Changer d'application",
@@ -2132,7 +2432,7 @@ const fr = {
2132
2432
  search: {
2133
2433
  title: "Rechercher",
2134
2434
  back: "Retour",
2135
- placeholder: "Rechercher des objets, tableaux de bord, pages, rapports...",
2435
+ placeholder: "Rechercher des objets, tableaux de bord, pages, rapports…",
2136
2436
  inputAriaLabel: "Rechercher des objets, tableaux de bord, pages, rapports",
2137
2437
  resultsCount: "{{count}} résultat pour \"{{query}}\"",
2138
2438
  resultsCountPlural: "{{count}} résultats pour \"{{query}}\"",
@@ -2151,6 +2451,7 @@ const fr = {
2151
2451
  empty: {
2152
2452
  objectNotFound: "Objet introuvable",
2153
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.",
2154
2455
  pageNotFound: "Page introuvable",
2155
2456
  pageNotFoundDescription: "La page \"{{name}}\" est introuvable. Elle a peut-être été supprimée ou renommée.",
2156
2457
  dashboardNotFound: "Tableau de bord introuvable",
@@ -2159,6 +2460,11 @@ const fr = {
2159
2460
  reportNotFoundDescription: "Le rapport \"{{name}}\" est introuvable. Il a peut-être été supprimé ou renommé.",
2160
2461
  noAppsConfigured: "Aucune application configurée",
2161
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",
2162
2468
  createFirstApp: "Créer la première application",
2163
2469
  systemSettings: "Paramètres système",
2164
2470
  back: "Retour",
@@ -2230,7 +2536,7 @@ const fr = {
2230
2536
  deleteFailed: "Impossible de supprimer la vue",
2231
2537
  },
2232
2538
  dashboardActions: {
2233
- 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)",
2234
2540
  exportFailed: "Échec de l'export : {{message}}",
2235
2541
  forecastSoon: "La vue de prévision arrive bientôt",
2236
2542
  },
@@ -2274,111 +2580,7 @@ const fr = {
2274
2580
  first: "Premier",
2275
2581
  },
2276
2582
  editor: {
2277
- breadcrumb: "Configuration",
2278
- basic: "Général",
2279
- title: "Titre",
2280
- titlePlaceholder: "ex. Pipeline par trimestre",
2281
- description: "Description",
2282
- descriptionPlaceholder: "Que montre ce rapport ?",
2283
- type: "Type de rapport",
2284
- typeTabular: "Tableau — liste à plat",
2285
- typeSummary: "Résumé — regroupé avec totaux",
2286
- typeMatrix: "Matrice — pivot lignes × colonnes",
2287
- typeJoined: "Combiné — plusieurs blocs",
2288
- typeHelp: "Choisissez la mise en page correspondant à ce que vous voulez voir.",
2289
- data: "Données",
2290
- objectName: "Source de données",
2291
- objectNamePlaceholder: "ex. opportunity",
2292
- objectNameHelp: "Quel objet ce rapport doit-il interroger ?",
2293
- limit: "Limite de lignes",
2294
- limitPlaceholder: "ex. 100",
2295
- columns: "Colonnes",
2296
- columnsHint: "Choisissez les champs à afficher en colonnes. Ajoutez une agrégation (Somme, Nombre…) dans les rapports Résumé ou Matrice.",
2297
- filters: "Filtres",
2298
- filtersHint: "Limitez les lignes incluses dans ce rapport.",
2299
- filtersComplex: "Ce rapport utilise un filtre avancé qui ne peut pas être édité ici. L’enregistrement le conservera tel quel.",
2300
- groupBy: "Grouper par",
2301
- groupByHint: "Regrouper les données et calculer les sous-totaux.",
2302
- rows: "Lignes",
2303
- rowsHint: "Grouper les lignes par ces champs.",
2304
- columnsAxis: "Colonnes",
2305
- columnsAxisHint: "Pivoter ces champs en haut.",
2306
- values: "Valeurs",
2307
- valuesHint: "Nombres affichés dans chaque cellule. Choisissez un ou plusieurs champs et ajoutez une agrégation (Somme, Nombre…).",
2308
- grouping: "Groupement",
2309
- addGrouping: "Ajouter un groupement",
2310
- dateGranularity: "Granularité de la date",
2311
- dateGranularityNone: "(valeur brute)",
2312
- day: "Jour",
2313
- week: "Semaine",
2314
- month: "Mois",
2315
- quarter: "Trimestre",
2316
- year: "Année",
2317
- sortAsc: "Croissant",
2318
- sortDesc: "Décroissant",
2319
- chart: "Graphique",
2320
- chartHint: "Visualisation optionnelle affichée à côté du tableau.",
2321
- chartType: "Type de graphique",
2322
- chartTitle: "Titre du graphique",
2323
- chartTitlePlaceholder: "Par défaut, le titre du rapport",
2324
- chartXAxis: "Axe X (catégorie)",
2325
- chartYAxis: "Axe Y (valeur)",
2326
- chartShowLegend: "Afficher la légende",
2327
- chartShowDataLabels: "Afficher les étiquettes",
2328
- chartNone: "(aucun graphique)",
2329
- chartBar: "Barres",
2330
- chartLine: "Courbe",
2331
- chartArea: "Aires",
2332
- chartPie: "Camembert",
2333
- chartDonut: "Anneau",
2334
- chartFunnel: "Entonnoir",
2335
- validationNeedsObject: "Sélectionnez une source de données avant d’ajouter des colonnes.",
2336
- validationMatrixNeedsRowsCols: "Les rapports matriciels nécessitent au moins une ligne et une colonne.",
2337
- validationSummaryNeedsRows: "Les rapports résumés nécessitent au moins un champ de regroupement.",
2338
- blocks: "Blocs",
2339
- blocksHint: "Chaque bloc est son propre tableau ou graphique. Les filtres de bloc sont combinés (ET) avec le filtre du rapport.",
2340
- addBlock: "Ajouter un bloc",
2341
- removeBlock: "Supprimer le bloc",
2342
- blockName: "Nom du bloc",
2343
- blockNamePlaceholder: "nom_unique_du_bloc",
2344
- blockLabel: "Libellé d’affichage",
2345
- blockLabelPlaceholder: "Affiché au-dessus du bloc",
2346
- blockDescription: "Description",
2347
- blockDescriptionPlaceholder: "Contexte optionnel pour ce bloc",
2348
- validationJoinedNeedsBlocks: "Les rapports combinés nécessitent au moins un bloc.",
2349
- validationBlockNameRequired: "Chaque bloc doit avoir un nom non vide.",
2350
- validationBlockNameDuplicate: "Les noms de bloc doivent être uniques dans le rapport.",
2351
- validationBlockNeedsColumns: "Chaque bloc doit avoir au moins une colonne.",
2352
- noneOption: "(aucun)",
2353
- addCondition: "Ajouter une condition",
2354
- combineLogic: "Combiner avec",
2355
- opContains: "contient",
2356
- opIsEmpty: "est vide",
2357
- opIsNotEmpty: "n’est pas vide",
2358
- formatAuto: "Auto",
2359
- formatCurrency: "Devise",
2360
- formatPercent: "Pourcentage",
2361
- formatInteger: "Entier",
2362
- formatDate: "Date",
2363
- formatDatetime: "Date et heure",
2364
- columnLabelPlaceholder: "Remplacer le libellé",
2365
- aggregateColumn: "Agrégation",
2366
- formatColumn: "Format",
2367
- addColumns: "Ajouter des colonnes",
2368
- searchFields: "Rechercher des champs…",
2369
- noMatchingFields: "Aucun champ ne correspond à votre recherche.",
2370
- noFieldsAvailable: "Aucun champ disponible.",
2371
- columnsCount: "{n} colonne(s) sélectionnée(s)",
2372
- columnsEmpty: "Aucune colonne sélectionnée pour l'instant.",
2373
- fieldPickerTitle: "Sélectionner des champs",
2374
- fieldPickerDescription: "Choisissez un ou plusieurs champs à ajouter. Utilisez le champ de recherche pour filtrer la liste.",
2375
- fieldPickerChangeTitle: "Changer le champ",
2376
- fieldPickerAddGroupingTitle: "Ajouter un regroupement",
2377
- fieldPickerEmpty: "(Sélectionner un champ)",
2378
- fieldPickerSelected: "{n} sélectionné(s)",
2379
- fieldPickerClear: "Effacer la sélection",
2380
- fieldPickerAdd: "Ajouter",
2381
- fieldPickerAddN: "Ajouter {n}",
2583
+ panelTitle: "Modifier le rapport",
2382
2584
  },
2383
2585
  },
2384
2586
  organizations: {
@@ -2395,6 +2597,140 @@ const fr = {
2395
2597
  emptyDescription: "Créez votre première organisation pour commencer.",
2396
2598
  noMatches: "Aucune organisation ne correspond à votre recherche.",
2397
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
+ },
2398
2734
  notifications: {
2399
2735
  regionLabel: "Notifications",
2400
2736
  groupCount: "{{count}} notifications",
@@ -2408,6 +2744,9 @@ const fr = {
2408
2744
  viewApprovals: "Voir les approbations",
2409
2745
  noPendingApprovals: "Aucune approbation en attente",
2410
2746
  openApprovalsInbox: "Ouvrir la boîte d'approbations",
2747
+ badgeTotal: "{{total}} au total",
2748
+ badgeNotifications: "{{unread}} notifications",
2749
+ badgeApprovals: "{{approvals}} approbations en attente",
2411
2750
  emptyUnread: "Tout est lu",
2412
2751
  filterUnread: "Non lus",
2413
2752
  filterAll: "Tous",
@@ -2694,6 +3033,7 @@ const fr = {
2694
3033
  dismiss: "Fermer",
2695
3034
  openOnCloud: "Ouvrir dans le cloud",
2696
3035
  backHome: "Retour à l'accueil",
3036
+ updateTo: "Mettre à jour",
2697
3037
  },
2698
3038
  install: {
2699
3039
  dialogTitle: "Installer {{name}}",
@@ -2710,6 +3050,37 @@ const fr = {
2710
3050
  localManifestConflict: "{{message}}\nRemarque : Une application locale possède déjà ce manifest_id. Supprimez-la d'abord de objectstack.config.ts.",
2711
3051
  localUnauthorized: "Connectez-vous d'abord à ce runtime.",
2712
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
+ },
2713
3084
  },
2714
3085
  uninstall: {
2715
3086
  confirm: "Désinstaller {{manifestId}} v{{version}} de ce runtime ?\n\nLe manifeste en cache sera supprimé.",
@@ -2959,6 +3330,34 @@ const fr = {
2959
3330
  confirmNote: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
2960
3331
  publishConfirm: 'Tout publier',
2961
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
+ },
2962
3361
  },
2963
3362
  filterBuilder: {
2964
3363
  where: "Où",
@@ -3003,5 +3402,91 @@ const fr = {
3003
3402
  addSort: "Ajouter un tri",
3004
3403
  removeSort: "Supprimer le tri",
3005
3404
  },
3405
+ collaboration: {
3406
+ commentCount: "{{count}} commentaires",
3407
+ commentCountOne: "{{count}} commentaire",
3408
+ resolvedSuffix: " · Résolu",
3409
+ sortComments: "Trier les commentaires",
3410
+ sortOldest: "Plus anciens",
3411
+ sortNewest: "Plus récents",
3412
+ resolve: "Résoudre",
3413
+ reopen: "Rouvrir",
3414
+ justNow: "à l'instant",
3415
+ minutesAgo: "il y a {{count}} min",
3416
+ hoursAgo: "il y a {{count}} h",
3417
+ daysAgo: "il y a {{count}} j",
3418
+ edited: "(modifié)",
3419
+ reactionCount: "{{count}} réactions",
3420
+ reactionCountOne: "{{count}} réaction",
3421
+ addThumbsUp: "Ajouter un pouce levé",
3422
+ reply: "Répondre",
3423
+ reactThumbsUp: "Réagir avec un pouce levé",
3424
+ reactHeart: "Réagir avec un cœur",
3425
+ cancelReply: "Annuler la réponse",
3426
+ replyingTo: "Réponse à {{name}}…",
3427
+ replyingToComment: "Réponse au commentaire…",
3428
+ commentPlaceholder: "Ajouter un commentaire… (utilisez @ pour mentionner)",
3429
+ send: "Envoyer",
3430
+ presentUserCount: "{{count}} utilisateurs présents",
3431
+ presentUserCountOne: "{{count}} utilisateur présent",
3432
+ moreUserCount: "{{count}} autres utilisateurs",
3433
+ moreUserCountOne: "{{count}} autre utilisateur",
3434
+ userStatusTitle: "{{name}} ({{status}})",
3435
+ statusActive: "actif",
3436
+ statusIdle: "inactif",
3437
+ statusAway: "absent",
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
+ },
3006
3491
  };
3007
3492
  export default fr;