@object-ui/i18n 17.3.0 → 17.6.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 (44) hide show
  1. package/CHANGELOG.md +1929 -1
  2. package/README.md +41 -12
  3. package/dist/i18n.d.ts +1 -1
  4. package/dist/i18n.js +1 -2
  5. package/dist/index.d.ts +23 -21
  6. package/dist/index.js +31 -21
  7. package/dist/locales/ar.d.ts +638 -369
  8. package/dist/locales/ar.js +744 -424
  9. package/dist/locales/de.d.ts +638 -369
  10. package/dist/locales/de.js +759 -446
  11. package/dist/locales/en.d.ts +673 -404
  12. package/dist/locales/en.js +899 -406
  13. package/dist/locales/es.d.ts +638 -369
  14. package/dist/locales/es.js +739 -427
  15. package/dist/locales/fr.d.ts +638 -369
  16. package/dist/locales/fr.js +738 -423
  17. package/dist/locales/index.d.ts +6476 -3786
  18. package/dist/locales/index.js +20 -20
  19. package/dist/locales/ja.d.ts +638 -369
  20. package/dist/locales/ja.js +732 -417
  21. package/dist/locales/ko.d.ts +638 -369
  22. package/dist/locales/ko.js +736 -424
  23. package/dist/locales/pt.d.ts +638 -369
  24. package/dist/locales/pt.js +737 -425
  25. package/dist/locales/ru.d.ts +638 -369
  26. package/dist/locales/ru.js +750 -424
  27. package/dist/locales/zh.d.ts +672 -403
  28. package/dist/locales/zh.js +720 -403
  29. package/dist/pickLocalized.d.ts +58 -0
  30. package/dist/pickLocalized.js +115 -7
  31. package/dist/provider.d.ts +84 -2
  32. package/dist/provider.js +305 -31
  33. package/dist/useDisplayLocale.d.ts +49 -0
  34. package/dist/useDisplayLocale.js +55 -0
  35. package/dist/useObjectLabel.d.ts +94 -14
  36. package/dist/useObjectLabel.js +134 -21
  37. package/dist/useSafeTranslation.js +51 -3
  38. package/dist/utils/index.d.ts +4 -3
  39. package/dist/utils/index.js +4 -3
  40. package/dist/utils/number-display.d.ts +32 -0
  41. package/dist/utils/number-display.js +32 -0
  42. package/dist/utils/spec-formatters.d.ts +39 -13
  43. package/dist/utils/spec-formatters.js +3 -3
  44. 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,13 @@ 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",
85
+ discard: "Abandonner",
51
86
  cancel: "Annuler",
52
87
  delete: "Supprimer",
53
88
  edit: "Modifier",
54
89
  create: "Créer",
55
- search: "Rechercher",
56
90
  filter: "Filtrer",
57
91
  reset: "Réinitialiser",
58
92
  confirm: "Confirmer",
@@ -76,7 +110,7 @@ const fr = {
76
110
  required: "Obligatoire",
77
111
  optional: "Facultatif",
78
112
  selectOption: "Sélectionner une option",
79
- select: "Sélectionner...",
113
+ select: "Sélectionner…",
80
114
  openChat: "Ouvrir le chat",
81
115
  closeChat: "Fermer le chat",
82
116
  closePanel: "Fermer le panneau",
@@ -85,6 +119,11 @@ const fr = {
85
119
  itemCountOne: "{{count}} élément",
86
120
  toggleSidebar: "Basculer la barre latérale",
87
121
  package: "Package",
122
+ done: "Terminé",
123
+ editInStudio: "Modifier dans Studio",
124
+ record: "Enregistrement",
125
+ retry: "Réessayer",
126
+ printDialogHint: "Ouvre la boîte de dialogue d'impression de votre navigateur (ce n'est pas un export PDF)",
88
127
  },
89
128
  actions: {
90
129
  decisionOutput: {
@@ -116,6 +155,9 @@ const fr = {
116
155
  submitFailed: "Échec de l'enregistrement. Veuillez réessayer.",
117
156
  discardTitle: "Abandonner les modifications ?",
118
157
  discardMessage: "Vous avez des modifications non enregistrées. Si vous fermez ce formulaire maintenant, vos modifications seront perdues.",
158
+ // objectui#4024 — the create/edit dialog's `sr-only` accessible
159
+ // description, used when the form declares no `description` of its own.
160
+ dialogDescriptionFallback: "Remplissez les champs du formulaire, puis envoyez ou annulez.",
119
161
  keepEditing: "Continuer l'édition",
120
162
  discard: "Abandonner",
121
163
  conflictTitle: "Conflit d'enregistrement",
@@ -184,7 +226,7 @@ const fr = {
184
226
  richText: {
185
227
  format: "Format : {{format}}",
186
228
  basicEditorHint: "Éditeur de texte enrichi (basique)",
187
- placeholder: "Écrivez quelque chose...",
229
+ placeholder: "Écrivez quelque chose…",
188
230
  },
189
231
  options: {
190
232
  empty: "Aucune option disponible",
@@ -220,6 +262,14 @@ const fr = {
220
262
  tags: {
221
263
  placeholder: "Saisissez puis appuyez sur Entrée pour ajouter…",
222
264
  },
265
+ // objectui#4028 — `AddressField`'s five sub-labels.
266
+ address: {
267
+ street: "Adresse (rue)",
268
+ city: "Ville",
269
+ state: "État / Province",
270
+ postalCode: "Code postal",
271
+ country: "Pays",
272
+ },
223
273
  textarea: {
224
274
  characterCount: "Nombre de caractères : {{count}} sur {{max}}",
225
275
  charactersRemaining: "Caractères restants : {{count}}",
@@ -250,7 +300,7 @@ const fr = {
250
300
  saveAll: "Tout enregistrer ({{count}})",
251
301
  addRecord: "Ajouter un enregistrement",
252
302
  open: "Ouvrir",
253
- search: "Rechercher...",
303
+ search: "Rechercher…",
254
304
  modified: "{{count}} ligne(s) modifiée(s)",
255
305
  saveFailed: 'Échec de l’enregistrement',
256
306
  selected: "{{count}} sélectionné(s)",
@@ -294,7 +344,7 @@ const fr = {
294
344
  delete: "Supprimer",
295
345
  export: "Exporter",
296
346
  exportAs: "Exporter en {{format}}",
297
- loading: "Chargement de la grille...",
347
+ loading: "Chargement de la grille…",
298
348
  errorLoading: "Erreur de chargement de la grille",
299
349
  pullToRefresh: "Tirer pour actualiser",
300
350
  refreshing: "Actualisation…",
@@ -305,6 +355,22 @@ const fr = {
305
355
  yes: "Oui",
306
356
  no: "Non",
307
357
  systemFields: "Système",
358
+ // objectui#4024 — column-footer aggregate prefixes, keyed by the spec's
359
+ // `ColumnSummary` vocabulary. `pattern` owns the label/value join so this
360
+ // pack controls its own separator and word order.
361
+ summary: {
362
+ pattern: "{{label}} : {{value}}",
363
+ count: "Nombre",
364
+ countEmpty: "Vides",
365
+ countFilled: "Remplis",
366
+ countUnique: "Uniques",
367
+ percentEmpty: "Vides",
368
+ percentFilled: "Remplis",
369
+ sum: "Somme",
370
+ avg: "Moyenne",
371
+ min: "Min",
372
+ max: "Max",
373
+ },
308
374
  toolbar: {
309
375
  densityMode: "Densité",
310
376
  densityCompact: "Compact",
@@ -418,12 +484,12 @@ const fr = {
418
484
  templateName: "Nom du modèle",
419
485
  save: "Enregistrer",
420
486
  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.',
487
+ savedMapping: "Correspondance enregistrée :",
488
+ chooseSavedMapping: "Choisir une correspondance enregistrée…",
489
+ manualMapping: "— Faire correspondre les colonnes manuellement —",
490
+ transform: 'Transformation',
491
+ savedMappingHint: "La correspondance « {{name}} » applique le renommage + les transformations + la conversion de type côté serveur. La correspondance des colonnes est en lecture seule.",
492
+ 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
493
  csvColumn: "Colonne",
428
494
  mapsTo: "Correspond à",
429
495
  typeMismatch: "Ressemble à {{type}}",
@@ -483,6 +549,8 @@ const fr = {
483
549
  loadErrorUnauthorizedMessage: "Votre session a expiré ou vous êtes déconnecté. Reconnectez-vous pour consulter ces enregistrements.",
484
550
  loadErrorRejectedTitle: "La requête de cette vue a été rejetée",
485
551
  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.",
552
+ loadErrorApiDisabledTitle: "Cet objet n’est pas disponible via l’API",
553
+ 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
554
  retry: "Réessayer",
487
555
  managedBy: {
488
556
  system: {
@@ -507,7 +575,7 @@ const fr = {
507
575
  },
508
576
  },
509
577
  refresh: "Actualiser",
510
- loading: 'Loading records...',
578
+ loading: "Chargement des enregistrements…",
511
579
  recordCount: "{{count}} enregistrements",
512
580
  recordCountOne: "{{count}} enregistrement",
513
581
  addRecord: "Ajouter un enregistrement",
@@ -519,7 +587,8 @@ const fr = {
519
587
  sort: "Trier",
520
588
  sortRecords: "Trier les enregistrements",
521
589
  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.",
590
+ 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.",
591
+ resetSortToDefault: "Réinitialiser au tri par défaut de la vue",
523
592
  group: "Grouper",
524
593
  groupBy: "Grouper par",
525
594
  export: "Exporter",
@@ -577,13 +646,16 @@ const fr = {
577
646
  },
578
647
  kanban: {
579
648
  uncategorized: "Non catégorisé",
649
+ columns: "colonnes",
580
650
  addCard: "Ajouter une carte",
581
651
  addColumn: "Ajouter une colonne",
582
652
  moveCard: "Déplacer la carte",
583
653
  deleteCard: "Supprimer la carte",
584
654
  deleteColumn: "Supprimer la colonne",
585
655
  noCards: "Aucune carte",
586
- cardTitlePlaceholder: "Saisir le titre de la carte...",
656
+ cardTitlePlaceholder: "Saisir le titre de la carte…",
657
+ requiredFieldsTitle: "Compléter les champs obligatoires",
658
+ requiredFieldsDescription: "Ce déplacement rend les champs ci-dessous obligatoires. Remplissez-les pour continuer.",
587
659
  },
588
660
  timeline: {
589
661
  bucket: {
@@ -596,6 +668,13 @@ const fr = {
596
668
  noDate: "Sans date",
597
669
  unassigned: "Non attribué",
598
670
  },
671
+ scale: {
672
+ week: "Semaine {{n}}",
673
+ quarter: "T{{quarter}} {{year}}",
674
+ },
675
+ gantt: {
676
+ rowLabel: "Éléments",
677
+ },
599
678
  },
600
679
  gantt: {
601
680
  viewMode: {
@@ -642,6 +721,18 @@ const fr = {
642
721
  ff: "Fin → Fin",
643
722
  sf: "Début → Fin",
644
723
  },
724
+ linkEnd: {
725
+ start: "Début",
726
+ end: "Fin",
727
+ },
728
+ link: {
729
+ rejected: {
730
+ self: "Une tâche ne peut pas dépendre d’elle-même.",
731
+ locked: "Cette ligne est verrouillée et ne peut pas recevoir de nouvelle dépendance.",
732
+ group: "Une ligne récapitulative ne peut pas recevoir de dépendance — reliez plutôt l’une de ses tâches.",
733
+ cycle: "Ce lien créerait une dépendance circulaire.",
734
+ },
735
+ },
645
736
  conflict: {
646
737
  title: "Conflit de planning",
647
738
  body: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche(s) concernée(s) ?",
@@ -650,8 +741,8 @@ const fr = {
650
741
  },
651
742
  autoScheduleDlg: {
652
743
  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.",
744
+ body: "Décaler {{count}} tâche(s) plus tard pour respecter les liens de dépendance ?",
745
+ skipped: "{{count}} tâche(s) verrouillée(s) violent aussi les liens et ont été ignorées.",
655
746
  confirm: "Appliquer",
656
747
  cancel: "Annuler",
657
748
  none: "Toutes les dépendances sont respectées — rien à replanifier.",
@@ -688,6 +779,7 @@ const fr = {
688
779
  exportPng: "Exporter en PNG",
689
780
  exportPdf: "Exporter en PDF",
690
781
  saveLayout: "Enregistrer la disposition",
782
+ refresh: "Actualiser",
691
783
  undo: "Annuler",
692
784
  redo: "Rétablir",
693
785
  prevPeriod: "Période précédente",
@@ -728,11 +820,11 @@ const fr = {
728
820
  defaultBadge: "par défaut",
729
821
  tabActionsFor: "Actions de vue pour {{name}}",
730
822
  readonlyAriaLabel: "Vue en lecture seule",
731
- readonlyTooltip: "Vue système — dupliquer pour personnaliser.",
823
+ readonlyTooltip: "Vue système — définie dans le code, en lecture seule.",
732
824
  },
733
825
  designer: {
734
- undo: 'Undo',
735
- redo: 'Redo',
826
+ undo: "Annuler",
827
+ redo: "Rétablir",
736
828
  },
737
829
  detail: {
738
830
  editInlineHint: "Double-cliquez pour modifier",
@@ -774,13 +866,15 @@ const fr = {
774
866
  relatedRecords: "{{count}} enregistrements",
775
867
  relatedRecordOne: "{{count}} enregistrement",
776
868
  noRelatedRecords: "Aucun enregistrement associé trouvé",
777
- loading: "Chargement...",
869
+ loading: "Chargement…",
778
870
  copyToClipboard: "Copier dans le presse-papiers",
779
871
  copied: "Copié !",
780
872
  deleteConfirmation: "Êtes-vous sûr de vouloir supprimer cet enregistrement ?",
873
+ deleted: "Enregistrement supprimé",
781
874
  editRecord: "Modifier l'enregistrement",
782
875
  viewAll: "Tout afficher",
783
876
  new: "Nouveau",
877
+ add: "Ajouter",
784
878
  emptyValue: "—",
785
879
  comments: "Commentaires",
786
880
  searchComments: "Rechercher des commentaires…",
@@ -810,6 +904,10 @@ const fr = {
810
904
  attachmentDownloadDenied: "Vous n'avez pas accès pour télécharger cette pièce jointe.",
811
905
  attachmentAuthRequired: "Veuillez vous connecter pour télécharger cette pièce jointe.",
812
906
  attachmentPermissionDenied: "Vous n'avez pas la permission de faire cela.",
907
+ attachmentsAccessDenied: "Vous n'avez pas accès à ces pièces jointes.",
908
+ attachmentsLoadFailed: "Impossible de charger les pièces jointes de cet enregistrement.",
909
+ attachmentsApiUnavailable: "La liste des pièces jointes n'est pas disponible sur cet objet.",
910
+ retryLoadAttachments: "Réessayer",
813
911
  unifiedDiff: "Vue unifiée",
814
912
  sideBySideDiff: "Vue côte à côte",
815
913
  noChanges: "Aucune modification",
@@ -845,6 +943,7 @@ const fr = {
845
943
  loadMore: "Charger plus",
846
944
  edited: "(modifié)",
847
945
  via: "via {{source}}",
946
+ viewSource: "Voir la source",
848
947
  replyCount: "{{count}} réponse",
849
948
  replyCountPlural: "{{count}} réponses",
850
949
  replyPlaceholder: "Répondre…",
@@ -860,6 +959,8 @@ const fr = {
860
959
  writeStrippedTitle: "Enregistré — mais certains champs n'ont pas été appliqués",
861
960
  writeStrippedReadonly: "En lecture seule, donc non appliqué : {{fields}}",
862
961
  writeStrippedByState: "Non modifiable dans l'état actuel de cet enregistrement, donc non appliqué : {{fields}}",
962
+ writeStrippedPrimaryKey: "L'identifiant de l'enregistrement ne peut pas être modifié lors d'un enregistrement, donc non appliqué : {{fields}}",
963
+ writeStrippedUnknownReason: "Non appliqué par le serveur : {{fields}}",
863
964
  approvalPendingEditable: "En approbation · modifiable",
864
965
  approvalPendingTooltip: "Cet enregistrement a une demande d'approbation en attente ; cette étape autorise encore la modification",
865
966
  approvalProgress: "Approbations — {{got}} sur {{need}}",
@@ -872,6 +973,13 @@ const fr = {
872
973
  cancelApprovalTooltipUnlocked: "Annuler la demande d'approbation en attente",
873
974
  cancelApprovalFailed: "Échec de l'annulation de l'approbation",
874
975
  cancelApprovalUnavailable: "L'annulation des approbations n'est pas prise en charge par cette source de données",
976
+ pathLabel: "Parcours de l'enregistrement",
977
+ pathStageCompleted: '{{stage}}, terminée',
978
+ pathStageCurrent: '{{stage}}, étape actuelle',
979
+ pathStageUpcoming: '{{stage}}, à venir',
980
+ pathStageLostCurrent: '{{stage}}, perdue, étape actuelle',
981
+ pathStageLostUpcoming: '{{stage}}, perdue, non atteinte',
982
+ pathStageWonUpcoming: '{{stage}}, étape objectif, non atteinte',
875
983
  linkCopied: "Lien copié dans le presse-papiers",
876
984
  linkCopyFailed: "Impossible de copier le lien",
877
985
  cancel: "Annuler",
@@ -886,9 +994,11 @@ const fr = {
886
994
  concurrentUpdateReload: "Charger la version actuelle",
887
995
  concurrentUpdateOverwrite: "Écraser quand même",
888
996
  concurrentUpdateCancel: "Annuler",
997
+ concurrentUpdateRecordLabel: "cet enregistrement",
889
998
  openInNewTab: "Ouvrir dans un nouvel onglet",
890
999
  activity: "Activité",
891
1000
  history: "Historique",
1001
+ historyEmpty: "Aucun historique pour le moment",
892
1002
  editRow: "Modifier",
893
1003
  deleteRow: "Supprimer",
894
1004
  deleteRowConfirmation: "Supprimer cet enregistrement ?",
@@ -898,10 +1008,15 @@ const fr = {
898
1008
  nextPage: "Suivant",
899
1009
  pageOf: "Page {{current}} sur {{total}}",
900
1010
  sortBy: "Trier par",
901
- filterPlaceholder: "Filtrer...",
1011
+ filterPlaceholder: "Filtrer…",
902
1012
  highlightFields: "Champs clés",
903
1013
  createdBy: "Créé par",
904
1014
  updatedBy: "Mis à jour par",
1015
+ // objectui#3863 — base key. fr has a third category, `many`, which CLDR uses from
1016
+ // a million up; the plural form is correct there, so the base repeats `_other`
1017
+ // rather than restructuring (unlike ru/ar, whose unenumerated categories cover
1018
+ // everyday counts).
1019
+ showEmptyRelated: "+ {{count}} vides",
905
1020
  showEmptyRelated_one: "+ {{count}} vide",
906
1021
  showEmptyRelated_other: "+ {{count}} vides",
907
1022
  copyEmail: "Copier l'e-mail",
@@ -913,7 +1028,8 @@ const fr = {
913
1028
  },
914
1029
  chart: {
915
1030
  noData: "Aucune donnée de graphique disponible",
916
- loading: "Chargement du graphique...",
1031
+ loading: "Chargement du graphique…",
1032
+ nullCategory: "(Non défini)",
917
1033
  },
918
1034
  map: {
919
1035
  searchLocations: "Rechercher des lieux…",
@@ -922,68 +1038,9 @@ const fr = {
922
1038
  invalidCoordinates: "{{count}} enregistrement avec des coordonnées manquantes ou invalides exclu de la carte.",
923
1039
  invalidCoordinatesPlural: "{{count}} enregistrements avec des coordonnées manquantes ou invalides exclus de la carte.",
924
1040
  },
925
- workflow: {
926
- draft: "Brouillon",
927
- active: "Actif",
928
- paused: "En pause",
929
- completed: "Terminé",
930
- cancelled: "Annulé",
931
- save: "Enregistrer",
932
- publish: "Publier",
933
- addNode: "Ajouter un nœud",
934
- workflowFlow: "Flux de travail",
935
- properties: "Propriétés",
936
- connections: "Connexions",
937
- quickConnect: "Connexion rapide",
938
- fromPlaceholder: "De...",
939
- toPlaceholder: "Vers...",
940
- connect: "Connecter",
941
- label: "Libellé",
942
- type: "Type",
943
- description: "Description",
944
- assignee: "Responsable",
945
- assigneeType: "Type de responsable",
946
- user: "Utilisateur",
947
- role: "Rôle",
948
- group: "Groupe",
949
- expression: "Expression",
950
- timeoutMinutes: "Délai (minutes)",
951
- selectNodeToEdit: "Sélectionnez un nœud pour modifier ses propriétés",
952
- workflowTitle: "Titre du workflow",
953
- newWorkflow: "Nouveau workflow",
954
- outConnections: "{{count}} sortie(s)",
955
- start: "Début",
956
- end: "Fin",
957
- task: "Tâche",
958
- userTask: "Tâche utilisateur",
959
- serviceTask: "Tâche service",
960
- scriptTask: "Tâche script",
961
- approval: "Approbation",
962
- condition: "Condition",
963
- parallelGateway: "Passerelle parallèle",
964
- joinGateway: "Passerelle de jonction",
965
- boundaryEvent: "Événement limite",
966
- delay: "Délai",
967
- notification: "Notification",
968
- webhook: "Webhook",
969
- allowConcurrency: "Autoriser (exécution simultanée)",
970
- forbidConcurrency: "Interdire (ignorer les nouveaux)",
971
- replaceConcurrency: "Remplacer (annuler les existants)",
972
- queueConcurrency: "File d'attente (exécuter après)",
973
- conditionEvent: "Condition",
974
- manualEvent: "Manuel",
975
- webhookEvent: "Webhook",
976
- timerEvent: "Minuterie",
977
- signalEvent: "Signal",
978
- versionHistory: "Historique des versions",
979
- importBpmn: "Importer BPMN",
980
- exportBpmn: "Exporter BPMN",
981
- undo: "Annuler",
982
- redo: "Rétablir",
983
- resetZoom: "Réinitialiser le zoom",
984
- },
985
1041
  dashboard: {
986
1042
  noRows: "Aucune ligne",
1043
+ loading: "Chargement…",
987
1044
  pickMeasures: "Choisissez des mesures (valeurs) pour ce widget de dataset.",
988
1045
  datasetUnsupported: "Cette source de données ne prend pas en charge les requêtes de dataset.",
989
1046
  details: "Détails",
@@ -1020,6 +1077,105 @@ const fr = {
1020
1077
  total: "Total",
1021
1078
  noDataAvailable: "Aucune donnée disponible",
1022
1079
  noDataSourceFor: "Aucune source de données pour",
1080
+ config: {
1081
+ breadcrumb: {
1082
+ dashboard: "Tableau de bord",
1083
+ configuration: "Configuration",
1084
+ widget: "Widget",
1085
+ chart: "Graphique",
1086
+ table: "Tableau",
1087
+ pivotTable: "Tableau croisé",
1088
+ },
1089
+ section: {
1090
+ general: "Général",
1091
+ layout: "Disposition",
1092
+ data: "Données",
1093
+ dataBinding: "Liaison de données",
1094
+ appearance: "Apparence",
1095
+ },
1096
+ field: {
1097
+ title: "Titre",
1098
+ description: "Description",
1099
+ columns: "Colonnes",
1100
+ gap: "Espacement",
1101
+ rowHeight: "Hauteur de ligne (px)",
1102
+ autoRefresh: "Actualisation automatique",
1103
+ showDescription: "Afficher la description",
1104
+ theme: "Thème",
1105
+ widgetType: "Type de widget",
1106
+ colorVariant: "Variante de couleur",
1107
+ dataset: "Jeu de données",
1108
+ dimensions: "Dimensions",
1109
+ values: "Valeurs",
1110
+ width: "Largeur (colonnes)",
1111
+ height: "Hauteur (lignes)",
1112
+ },
1113
+ placeholder: {
1114
+ dashboardTitle: "Titre du tableau de bord",
1115
+ dashboardDescription: "Résumé court affiché sous le titre",
1116
+ widgetTitle: "Titre du widget",
1117
+ widgetDescription: "Description du widget",
1118
+ datasetName: "Nom du jeu de données",
1119
+ selectDataset: "Sélectionner un jeu de données…",
1120
+ searchDatasets: "Rechercher des jeux de données…",
1121
+ addDimension: "Ajouter une dimension…",
1122
+ addMeasure: "Ajouter une mesure…",
1123
+ searchMembers: "Rechercher…",
1124
+ },
1125
+ empty: {
1126
+ datasets: "Aucun jeu de données trouvé.",
1127
+ dimensions: "Aucune dimension sélectionnée.",
1128
+ measures: "Aucune mesure sélectionnée.",
1129
+ nothingToAdd: "Plus rien à ajouter.",
1130
+ },
1131
+ help: {
1132
+ dataset: "Le jeu de données de la couche sémantique auquel ce widget est lié (ADR-0021).",
1133
+ dimensions: "Grouper/diviser les valeurs selon ces dimensions du jeu de données.",
1134
+ dimensionsPivot: "Champs de groupement/division. La dernière dimension se déploie en colonnes.",
1135
+ values: "Mesures du jeu de données à afficher (au moins une).",
1136
+ },
1137
+ action: {
1138
+ add: "Ajouter",
1139
+ remove: "Supprimer {{name}}",
1140
+ },
1141
+ refresh: {
1142
+ off: "Désactivé",
1143
+ every30s: "Toutes les 30 s",
1144
+ every1m: "Toutes les minutes",
1145
+ every5m: "Toutes les 5 min",
1146
+ every15m: "Toutes les 15 min",
1147
+ every30m: "Toutes les 30 min",
1148
+ every1h: "Toutes les heures",
1149
+ },
1150
+ themeOption: {
1151
+ light: "Clair",
1152
+ dark: "Sombre",
1153
+ auto: "Automatique",
1154
+ },
1155
+ widgetType: {
1156
+ metric: "Indicateur",
1157
+ bar: "Graphique à barres",
1158
+ horizontalBar: "Barres horizontales",
1159
+ line: "Graphique en courbes",
1160
+ pie: "Graphique circulaire",
1161
+ donut: "Graphique en anneau",
1162
+ area: "Graphique en aires",
1163
+ scatter: "Nuage de points",
1164
+ funnel: "Entonnoir",
1165
+ table: "Tableau",
1166
+ pivot: "Tableau croisé",
1167
+ },
1168
+ color: {
1169
+ default: "Par défaut",
1170
+ blue: "Bleu",
1171
+ teal: "Sarcelle",
1172
+ orange: "Orange",
1173
+ purple: "Violet",
1174
+ success: "Succès",
1175
+ warning: "Avertissement",
1176
+ danger: "Danger",
1177
+ },
1178
+ },
1023
1179
  trend: {
1024
1180
  vsLastQuarter: "vs. trimestre dernier",
1025
1181
  vsLastMonth: "vs. mois dernier",
@@ -1029,24 +1185,6 @@ const fr = {
1029
1185
  vsPreviousPeriod: "vs. période précédente",
1030
1186
  },
1031
1187
  },
1032
- configPanel: {
1033
- save: "Enregistrer",
1034
- discard: "Annuler",
1035
- close: "Fermer",
1036
- layout: "Disposition",
1037
- columns: "Colonnes",
1038
- gap: "Espacement",
1039
- rowHeight: "Hauteur de ligne",
1040
- data: "Données",
1041
- refreshInterval: "Intervalle de rafraîchissement",
1042
- appearance: "Apparence",
1043
- title: "Titre",
1044
- showDescription: "Afficher la description",
1045
- theme: "Thème",
1046
- configuration: "Configuration",
1047
- general: "Général",
1048
- advanced: "Avancé",
1049
- },
1050
1188
  appDesigner: {
1051
1189
  createApp: "Créer une application",
1052
1190
  editApp: "Modifier l'application",
@@ -1097,8 +1235,6 @@ const fr = {
1097
1235
  showSort: "Afficher le tri",
1098
1236
  appearance: "Apparence",
1099
1237
  rowHeight: "Hauteur de ligne",
1100
- stripedRows: "Lignes alternées",
1101
- bordered: "Avec bordure",
1102
1238
  livePreview: "Aperçu en direct",
1103
1239
  stepBasicDesc: "Nom, titre et mise en page",
1104
1240
  stepObjectsDesc: "Sélectionner les objets métier",
@@ -1212,7 +1348,6 @@ const fr = {
1212
1348
  unique: "Unique",
1213
1349
  readOnly: "Lecture seule",
1214
1350
  hidden: "Masqué",
1215
- indexed: "Indexé",
1216
1351
  externalId: "ID externe",
1217
1352
  trackHistory: "Suivre l'historique",
1218
1353
  defaultValue: "Valeur par défaut",
@@ -1241,6 +1376,7 @@ const fr = {
1241
1376
  },
1242
1377
  },
1243
1378
  console: {
1379
+ saveAdvisoryTitle: "Enregistré — le contrôle de création a signalé {{count}} recommandation(s)",
1244
1380
  settingsHub: {
1245
1381
  title: "Paramètres",
1246
1382
  subtitle: "Configurez votre espace de travail, vos intégrations et vos indicateurs de fonctionnalité.",
@@ -1285,6 +1421,13 @@ const fr = {
1285
1421
  passwordsDownload: "Télécharger le CSV",
1286
1422
  },
1287
1423
  ai: {
1424
+ pendingDrafts: {
1425
+ count: "{{count}} modification(s) ne sont pas encore publiée(s) — les utilisateurs ne peuvent pas les voir.",
1426
+ publish: "Publier",
1427
+ published: "Toutes les modifications en attente sont actives.",
1428
+ failed: "Échec de la publication.",
1429
+ publishedWithFindings: "Publié, mais les contrôles d'exécution ont signalé des problèmes : {{detail}}",
1430
+ },
1288
1431
  usage: {
1289
1432
  title: "Utilisation de l'IA",
1290
1433
  meterBuild: "Créer",
@@ -1307,7 +1450,7 @@ const fr = {
1307
1450
  shareTitle: "Partager cette conversation",
1308
1451
  shareDisabledTitle: "Commencez à discuter pour activer le partage",
1309
1452
  newChat: "Nouveau",
1310
- searchChats: "Rechercher des discussions...",
1453
+ searchChats: "Rechercher des discussions…",
1311
1454
  noChatsYet: "Aucune discussion pour l'instant",
1312
1455
  noChatsDescription: "Démarrez une nouvelle conversation pour la voir ici.",
1313
1456
  noMatchingChats: "Aucune discussion correspondante.",
@@ -1316,18 +1459,18 @@ const fr = {
1316
1459
  deleteConversation: "Supprimer la conversation",
1317
1460
  saveRename: "Enregistrer le nom",
1318
1461
  cancelRename: "Annuler le changement de nom",
1319
- loadingHistory: "Chargement de l'historique de la conversation...",
1462
+ loadingHistory: "Chargement de l'historique de la conversation…",
1320
1463
  conversationReady: "Conversation prête",
1321
1464
  preparingConversation: "Préparation d'une nouvelle conversation",
1322
1465
  offlineDemoMode: "Mode démo hors ligne — liste des agents indisponible",
1323
1466
  sendFailedRateLimited: "Vous envoyez des messages trop rapidement. Votre message est conservé ci-dessous — patientez un instant puis réessayez.",
1324
1467
  sendFailedGeneric: "Impossible d'envoyer votre message. Il est conservé ci-dessous — veuillez réessayer.",
1325
- askAgent: "Demander à {{agent}}...",
1468
+ askAgent: "Demander à {{agent}}…",
1326
1469
  assistant: "Assistant",
1327
1470
  liveCanvas: "Aperçu en direct — {{app}} (brouillon)",
1328
1471
  liveCanvasUnlisted: "Application en direct — {{app}} (non répertoriée jusqu'à publication)",
1329
- loadingAgents: "Chargement des agents...",
1330
- askAnything: "Posez n'importe quelle question...",
1472
+ loadingAgents: "Chargement des agents…",
1473
+ askAnything: "Posez n'importe quelle question…",
1331
1474
  emptyTitle: "Démarrer une conversation",
1332
1475
  emptyDescription: "Posez n'importe quelle question — l'assistant a accès au contexte de votre application actuelle.",
1333
1476
  switchAssistant: "Changer d'assistant",
@@ -1420,6 +1563,11 @@ const fr = {
1420
1563
  changesConfirmed: "Confirmé",
1421
1564
  changesConfirm: "Confirmer",
1422
1565
  changesConfirmHint: "Répondez pour confirmer ou ajuster cette modification.",
1566
+ changesApplying: "Application…",
1567
+ changesApplied: "Appliqué",
1568
+ changesDrafted: "Enregistré comme brouillon",
1569
+ changesFailed: "Non appliqué",
1570
+ discussing: "Sujet : {{target}}",
1423
1571
  changeVerb: {
1424
1572
  createObject: "Créer un objet",
1425
1573
  addField: "Ajouter un champ",
@@ -1430,9 +1578,60 @@ const fr = {
1430
1578
  createSeed: "Générer des données d'exemple",
1431
1579
  createPackage: "Créer un package d'application",
1432
1580
  },
1581
+ // objectui#3546 slice four — the AI console surfaces: the /ai chat page's app switcher,
1582
+ // connection banner and plan/publish cards, the ChatDock chrome, and the
1583
+ // conversation-list date buckets. `group.*` is the template-key family
1584
+ // `console.ai.group.${key}` (ConversationsSidebar), enumerated from the
1585
+ // ConversationGroupKey union — all five members, no wildcard.
1586
+ collapseToDock: "Réduire dans le panneau latéral",
1587
+ switchApp: "Changer d'application",
1588
+ switchAppLabel: "Conversations de création par application",
1589
+ newApp: "Nouvelle application",
1590
+ connectionWaiting: "En attente du serveur…",
1591
+ connectionStalled: "Toujours en cours…",
1592
+ connectionOffline: "Connexion perdue — reconnexion…",
1593
+ designingPlan: "Conception de votre application…",
1594
+ designingPlanHint: {
1595
+ data: "Cartographie des données que vous allez suivre…",
1596
+ objects: "Définition des objets et de leurs champs…",
1597
+ relations: "Connexion des enregistrements liés…",
1598
+ lookups: "Configuration des relations et des champs de recherche…",
1599
+ views: "Planification des écrans et des vues…",
1600
+ forms: "Mise en page des formulaires et des listes…",
1601
+ defaults: "Ajout de valeurs par défaut et de validations pertinentes…",
1602
+ dashboard: "Esquisse d'un tableau de bord pour le suivi…",
1603
+ review: "Vérification de la cohérence de la structure…",
1604
+ finalize: "Assemblage du plan…",
1605
+ },
1606
+ planBuilding: "Création…",
1607
+ planBuilt: "Créé",
1608
+ planDeferred: "Pas encore créé",
1609
+ planReady: "Le plan est prêt. Créez-le maintenant, ou dites-moi ce qu'il faut ajuster.",
1610
+ published: "Publié",
1611
+ publishFailed: "Échec de la publication",
1612
+ unavailableTitle: "Assistant IA non disponible",
1613
+ unavailableDescription: "Cette instance n'a pas d'assistant IA activé. Tout le reste fonctionne normalement.",
1614
+ unavailableError: "Impossible de joindre le service IA. Il est peut-être temporairement hors ligne — réessayez, ou retournez à l'accueil.",
1615
+ unavailableRetry: "Réessayer",
1616
+ unavailableHome: "Retour à l'accueil",
1617
+ dock: {
1618
+ title: "Assistant",
1619
+ description: "Discussion avec l'assistant IA",
1620
+ resize: "Redimensionner la discussion",
1621
+ collapse: "Réduire la discussion",
1622
+ maximize: "Ouvrir en pleine page",
1623
+ open: "Ouvrir l'assistant",
1624
+ },
1625
+ group: {
1626
+ today: "Aujourd'hui",
1627
+ yesterday: "Hier",
1628
+ previous7Days: "7 jours précédents",
1629
+ previous30Days: "30 jours précédents",
1630
+ older: "Plus anciennes",
1631
+ },
1433
1632
  },
1434
1633
  title: "Console ObjectStack",
1435
- initializing: "Initialisation de l'application...",
1634
+ initializing: "Initialisation de l'application…",
1436
1635
  loadingHint: "La configuration d'un nouvel environnement peut prendre quelques instants.",
1437
1636
  breadcrumb: {
1438
1637
  dashboards: "Tableaux de bord",
@@ -1440,6 +1639,31 @@ const fr = {
1440
1639
  reports: "Rapports",
1441
1640
  system: "Système",
1442
1641
  },
1642
+ // objectui#4024 — the single-namespace settings screen. Its sibling
1643
+ // `settingsHub` above already resolved through this pack; the view was the
1644
+ // one file still carrying English literals.
1645
+ settingsView: {
1646
+ backToHub: "Tous les paramètres",
1647
+ back: "Retour",
1648
+ noNamespace: "Aucun espace de noms sélectionné.",
1649
+ loadError: "Échec du chargement des paramètres",
1650
+ saved: "Paramètres enregistrés",
1651
+ saveFailed: "Échec de l'enregistrement",
1652
+ lockedByEnv: "Verrouillé par l'environnement : {{key}}",
1653
+ lockedByEnvNoKey: "Verrouillé par l'environnement",
1654
+ actionSucceeded: "Action réussie",
1655
+ actionFailed: "Échec de l'action",
1656
+ discard: "Abandonner",
1657
+ saveChanges: "Enregistrer les modifications",
1658
+ unsavedCount: "{{count}} modifications non enregistrées",
1659
+ unsavedCount_one: "{{count}} modification non enregistrée",
1660
+ unsavedCount_other: "{{count}} modifications non enregistrées",
1661
+ cryptoRefusalTitle: "Ce déploiement ne peut pas chiffrer les secrets",
1662
+ cryptoRefusalSubjectSuffix: "est déclaré chiffré, aucune écriture n'a donc eu lieu.",
1663
+ cryptoRefusalNoSubject: "La valeur déclarée chiffrée a été refusée, aucune écriture n'a donc eu lieu.",
1664
+ cryptoRefusalToast: "Impossible de chiffrer les secrets : {{subject}}",
1665
+ cryptoRefusalToastNoSubject: "Impossible de chiffrer les secrets",
1666
+ },
1443
1667
  loadingSteps: {
1444
1668
  connecting: "Connexion à la source de données",
1445
1669
  loadingConfig: "Chargement de la configuration",
@@ -1469,6 +1693,7 @@ const fr = {
1469
1693
  general: "Général",
1470
1694
  navigation: "Navigation",
1471
1695
  dataViews: "Vues de données",
1696
+ aiChat: "Assistant IA",
1472
1697
  preferences: "Préférences",
1473
1698
  },
1474
1699
  openCommandPalette: "Ouvrir la palette de commandes",
@@ -1479,11 +1704,13 @@ const fr = {
1479
1704
  createRecord: "Créer un nouvel enregistrement",
1480
1705
  refreshData: "Actualiser les données",
1481
1706
  editRecord: "Modifier l'enregistrement sélectionné",
1707
+ newChat: "Nouvelle discussion",
1708
+ toggleChatsList: "Basculer la liste des discussions",
1482
1709
  toggleDarkMode: "Basculer le mode sombre",
1483
1710
  },
1484
1711
  commandPalette: {
1485
1712
  title: "Palette de commandes",
1486
- placeholder: "Tapez une commande ou recherchez...",
1713
+ placeholder: "Tapez une commande ou recherchez…",
1487
1714
  noResults: "Aucun résultat trouvé.",
1488
1715
  objects: "Objets",
1489
1716
  dashboards: "Tableaux de bord",
@@ -1509,6 +1736,12 @@ const fr = {
1509
1736
  goHome: "Retour à l'accueil",
1510
1737
  errorDetails: "Détails de l'erreur (développement uniquement)",
1511
1738
  },
1739
+ // objectui#3546 slice four — the console's catch-all route (AppContent `RouteNotFound`).
1740
+ notFound: {
1741
+ title: "Page introuvable",
1742
+ description: "L'URL que vous avez suivie ne correspond à aucune vue de cette application.",
1743
+ back: "Retour",
1744
+ },
1512
1745
  theme: {
1513
1746
  toggle: "Changer de thème",
1514
1747
  light: "Clair",
@@ -1524,109 +1757,41 @@ const fr = {
1524
1757
  viewNameHelp: "Clé technique (snake_case). Remplie automatiquement à partir du titre — modifiable si vous le souhaitez.",
1525
1758
  viewNameRequired: "Saisissez une clé (minuscules, chiffres, tiret bas). Non remplie automatiquement pour les titres non latins.",
1526
1759
  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',
1760
+ systemViewReadonly: "Vue système définie dans le code — en lecture seule.",
1761
+ cannotEditMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être modifiée.",
1762
+ cannotDeleteMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être supprimée.",
1763
+ expandToPage: "Ouvrir en pleine page",
1529
1764
  objectNotFound: "Objet introuvable",
1530
1765
  objectNotFoundDescription: "L'objet « {{objectName}} » n'existe pas dans la configuration actuelle.",
1531
1766
  objectNotFoundHint: "Vérifiez les paramètres de navigation de votre application ou sélectionnez un autre objet dans la barre latérale.",
1532
1767
  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.",
1533
1768
  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.",
1534
1769
  allRecords: "Tous les enregistrements",
1535
- exitDesignMode: "Quitter le mode conception",
1536
- enterDesignMode: "Entrer en mode conception",
1537
- metadataInspector: "Inspecteur de métadonnées",
1538
- editView: "Modifier la vue",
1539
- addView: "Ajouter une vue",
1540
- designTools: "Outils de conception",
1541
1770
  new: "Nouveau",
1542
1771
  configureView: "Configurer la vue",
1543
- closePanel: "Fermer le panneau",
1544
- page: "Page",
1545
- pageConfigHint: "Barre d'outils, navigation et paramètres du shell de vue",
1546
- listConfigHint: "Rendu des données, colonnes et apparence pour ce type de liste",
1547
- general: "Général",
1548
- generalHint: "Titre, description et type de la vue",
1549
1772
  toolbar: "Barre d'outils",
1550
- toolbarHint: "Recherche, filtre, tri, regroupement et bascule de densité",
1551
1773
  toolbarEnabledCount: "{{count}} sur {{total}} activés",
1552
- navigationSection: "Navigation",
1553
- navigationHint: "Comportement au clic sur la ligne et paramètres de la vue détaillée",
1554
- records: "Enregistrements",
1555
- recordsHint: "Mode de sélection, ajout d'enregistrement et édition en ligne",
1556
- exportPrint: "Export et impression",
1557
- exportPrintHint: "Formats d'export, impression et affichage du nombre d'enregistrements",
1558
- showAllFields: "Tout afficher",
1559
- hideAllFields: "Tout masquer",
1560
- searchFields: "Rechercher des champs...",
1774
+ searchFields: "Rechercher des champs…",
1561
1775
  title: "Titre",
1562
- description: "Description",
1563
- data: "Données",
1564
- source: "Source",
1565
- columns: "Colonnes",
1566
- filterBy: "Filtrer par",
1567
- sortBy: "Trier par",
1568
- appearance: "Apparence",
1569
- showDescription: "Afficher la description",
1570
1776
  viewType: "Type de vue",
1571
- userFilters: "Filtres utilisateur",
1572
- enableSearch: "Activer la recherche",
1573
- enableFilter: "Activer le filtre",
1574
- enableSort: "Activer le tri",
1575
- enableHideFields: "Activer masquer les champs",
1576
- enableGroup: "Activer le regroupement",
1577
- enableColor: "Activer la couleur",
1578
- enableDensity: "Activer la densité",
1579
- userActions: "Actions utilisateur",
1580
- addRecordViaForm: "Ajouter des enregistrements via un formulaire",
1581
- advanced: "Avancé",
1582
- allowExport: "Autoriser l'exportation",
1583
1777
  recordCount: "{{count}} enregistrements",
1584
- noDescription: "Aucune description",
1585
- none: "Aucun",
1586
- columnsConfigured: "{{count}} colonnes",
1587
1778
  save: "Enregistrer",
1588
1779
  discard: "Annuler",
1589
1780
  createView: "Créer une vue",
1590
1781
  newView: "Nouvelle vue",
1591
- typeOptions: "Options de type",
1592
1782
  groupByField: "Champ de regroupement",
1593
1783
  startDateField: "Champ de date de début",
1594
1784
  titleField: "Champ de titre",
1595
1785
  latitudeField: "Champ de latitude",
1596
1786
  longitudeField: "Champ de longitude",
1597
1787
  imageField: "Champ d'image",
1598
- dateField: "Champ de date",
1599
- selectField: "Sélectionner un champ...",
1600
- gridOptionsHint: "La vue grille utilise les colonnes configurées ci-dessus.",
1788
+ selectField: "Sélectionner un champ…",
1601
1789
  groupBy: "Regrouper par",
1602
- prefixField: "Champ de préfixe",
1603
- fields: "Champs",
1604
- fieldsVisible: "{{count}} visibles",
1605
- sortsCount: "{{count}} tris",
1606
- filtersCount: "{{count}} filtres",
1607
1790
  endDateField: "Champ de date de fin",
1608
- color: "Couleur",
1609
- fieldTextColor: "Couleur du texte du champ",
1610
- rowHeight: "Hauteur de ligne",
1611
- wrapHeaders: "Retour à la ligne des en-têtes",
1612
- showFieldDescriptions: "Afficher les descriptions des champs",
1613
- collapseAllByDefault: "Tout réduire par défaut",
1614
- striped: "Lignes rayées",
1615
- bordered: "Cellules bordées",
1616
- inlineEdit: "Modifier les enregistrements en ligne",
1617
- addDeleteRecordsInline: "Ajouter/supprimer des enregistrements en ligne",
1618
- clickIntoRecordDetails: "Cliquer pour les détails de l'enregistrement",
1619
- navigationMode: "Mode de navigation",
1620
- navigationWidth: "Largeur de navigation",
1621
- navigationWidthHint: "Disponible pour les modes de navigation tiroir, modale et partagée",
1622
- openNewTab: "Ouvrir dans un nouvel onglet",
1623
- openNewTabHint: "Disponible pour les modes de navigation page et nouvelle fenêtre",
1624
1791
  import: "Importer",
1625
1792
  importTitle: "Importer depuis CSV",
1626
1793
  importedToast: "{{count}} ligne(s) importée(s).",
1627
1794
  importedWithSkipped: "{{ok}} ligne(s) importée(s) ; {{skipped}} ignorée(s).",
1628
- showAdvancedSettings: "Afficher les paramètres avancés",
1629
- showFewerSettings: "Afficher moins de paramètres",
1630
1795
  createViewDesc: "Choisissez un type de vue et donnez-lui un nom. Tous les paramètres peuvent être modifiés ensuite.",
1631
1796
  cancel: "Annuler",
1632
1797
  create: "Créer",
@@ -1659,7 +1824,7 @@ const fr = {
1659
1824
  latitudeFieldHelp: "Champ contenant la latitude (champs géo uniquement).",
1660
1825
  longitudeFieldHelp: "Champ contenant la longitude (champs géo uniquement).",
1661
1826
  imageFieldHelp: "La couverture de la galerie provient de ce champ image ou pièce jointe.",
1662
- selectOption: "Sélectionner...",
1827
+ selectOption: "Sélectionner…",
1663
1828
  noEligibleFieldForType: "Aucun champ éligible de ce type. Ajoutez-en un à l'objet d'abord.",
1664
1829
  viewTypeUnavailable: "Cet objet n'a pas de champ pouvant servir de \"{{field}}\".",
1665
1830
  viewTypeUnavailableShort: "Non pris en charge par cet objet.",
@@ -1674,58 +1839,9 @@ const fr = {
1674
1839
  xAxisFieldHelp: "La dimension catégorielle ou temporelle.",
1675
1840
  yAxisField: "Champ axe Y",
1676
1841
  yAxisFieldHelp: "Le champ numérique à agréger.",
1677
- selectionMode: "Mode de sélection",
1678
- selectionNone: "Aucun",
1679
- selectionSingle: "Unique",
1680
- selectionMultiple: "Multiple",
1681
- pageSize: "Taille de page",
1682
- pageSizeOptions: "Options de taille de page",
1683
- exportFormats: "Formats d'exportation",
1684
- exportMaxRecords: "Enregistrements max",
1685
- exportIncludeHeaders: "Inclure les en-têtes",
1686
- exportFileNamePrefix: "Préfixe du nom de fichier",
1687
- searchableFields: "Champs recherchables",
1688
- filterableFields: "Champs filtrables",
1689
- resizableColumns: "Colonnes redimensionnables",
1690
- densityCompact: "Compact",
1691
- densityComfortable: "Normal",
1692
- densitySpacious: "Spacieux",
1693
- densityMode: "Mode de densité",
1694
- hiddenFields: "Champs masqués",
1695
- rowActions: "Actions de ligne",
1696
- bulkActions: "Actions en masse",
1697
- sharing: "Partage",
1698
- sharingEnabled: "Partage activé",
1699
- sharingVisibility: "Visibilité",
1700
- addRecordEnabled: "Ajout d'enregistrement activé",
1701
- addRecordPosition: "Position",
1702
- addRecordMode: "Mode",
1703
- addRecordFormView: "Vue formulaire",
1704
- conditionalFormatting: "Mise en forme conditionnelle",
1705
- addRule: "Ajouter une règle",
1706
- quickFilters: "Filtres rapides",
1707
- addQuickFilter: "Ajouter un filtre rapide",
1708
- ufElements: "Éléments",
1709
- ufDropdown: "Liste déroulante",
1710
1842
  ufTabs: "Onglets",
1711
- ufToggle: "Bascule",
1712
- ufAddField: "+ Ajouter un champ de filtre...",
1713
- ufNoFields: "Aucun champ disponible",
1714
- ufAddTab: "+ Ajouter un onglet",
1715
- ufTabLabel: "Étiquette",
1843
+ ufAddField: "+ Ajouter un champ de filtre…",
1716
1844
  ufShowAllRecords: "Afficher l'onglet \"Tous les enregistrements\"",
1717
- ufAllowAddTab: "Autoriser l'ajout d'onglets",
1718
- showRecordCount: "Afficher le nombre d'enregistrements",
1719
- allowPrinting: "Autoriser l'impression",
1720
- virtualScroll: "Défilement virtuel",
1721
- emptyStateTitle: "Titre de l'état vide",
1722
- emptyStateMessage: "Message de l'état vide",
1723
- emptyStateIcon: "Icône de l'état vide",
1724
- ariaLabel: "Étiquette ARIA",
1725
- ariaDescribedBy: "Décrit par ARIA",
1726
- ariaLive: "ARIA en direct",
1727
- accessibility: "Accessibilité",
1728
- viewTabs: "Onglets de vue",
1729
1845
  },
1730
1846
  localeSwitcher: {
1731
1847
  label: "Langue",
@@ -1769,7 +1885,7 @@ const fr = {
1769
1885
  passwordPlaceholder: "Entrez votre mot de passe",
1770
1886
  forgotPasswordText: "Mot de passe oublié ?",
1771
1887
  submitButton: "Se connecter",
1772
- submittingButton: "Connexion en cours...",
1888
+ submittingButton: "Connexion en cours…",
1773
1889
  noAccountText: "Vous n'avez pas de compte ?",
1774
1890
  signUpText: "S'inscrire",
1775
1891
  errors: {
@@ -1777,6 +1893,18 @@ const fr = {
1777
1893
  invalidCredentials: "E-mail ou mot de passe invalide. Veuillez réessayer.",
1778
1894
  emailNotVerified: "Veuillez vérifier votre adresse e-mail avant de vous connecter.",
1779
1895
  },
1896
+ // objectui#3546 slice three — phone/OTP sign-in. `{seconds}` is LoginForm's own
1897
+ // literal `.replace()` hole, not i18next interpolation: keep the single braces.
1898
+ emailOrPhoneLabel: "E-mail ou numéro de téléphone",
1899
+ emailOrPhonePlaceholder: "name@example.com ou +1 555 000 0000",
1900
+ phoneLabel: "Numéro de téléphone",
1901
+ phonePlaceholder: "+1 555 000 0000",
1902
+ otpCodeLabel: "Code de vérification",
1903
+ otpCodePlaceholder: "Code à 6 chiffres",
1904
+ sendOtpButton: "Obtenir un code",
1905
+ resendOtpCountdownText: "Renvoyer dans {seconds} s",
1906
+ usePhoneOtpText: "Se connecter avec un code de vérification",
1907
+ usePasswordSignInText: "Se connecter avec un mot de passe à la place",
1780
1908
  },
1781
1909
  register: {
1782
1910
  title: "Créer un compte",
@@ -1792,7 +1920,7 @@ const fr = {
1792
1920
  passwordMismatchError: "Les mots de passe ne correspondent pas",
1793
1921
  passwordTooShortError: "Le mot de passe doit contenir au moins 8 caractères",
1794
1922
  submitButton: "Créer un compte",
1795
- submittingButton: "Création du compte...",
1923
+ submittingButton: "Création du compte…",
1796
1924
  hasAccountText: "Vous avez déjà un compte ?",
1797
1925
  signInText: "Se connecter",
1798
1926
  errors: {
@@ -1813,12 +1941,26 @@ const fr = {
1813
1941
  emailLabel: "E-mail",
1814
1942
  emailPlaceholder: "name@example.com",
1815
1943
  submitButton: "Envoyer le lien de réinitialisation",
1816
- submittingButton: "Envoi en cours...",
1944
+ submittingButton: "Envoi en cours…",
1817
1945
  successTitle: "Vérifiez vos e-mails",
1818
- successDescription: "Nous avons envoyé un lien de réinitialisation du mot de passe à {{email}}. Veuillez vérifier votre boîte de réception.",
1946
+ successDescription: "Nous avons envoyé un lien de réinitialisation du mot de passe à {email}. Veuillez vérifier votre boîte de réception.",
1819
1947
  backToSignInText: "Retour à la connexion",
1820
1948
  rememberPasswordText: "Vous vous souvenez de votre mot de passe ?",
1821
1949
  signInText: "Se connecter",
1950
+ // objectui#3546 slice three — the SMS reset branch of the same form.
1951
+ phoneLabel: "Numéro de téléphone",
1952
+ phonePlaceholder: "+1 555 000 0000",
1953
+ otpCodeLabel: "Code de vérification",
1954
+ otpCodePlaceholder: "Code à 6 chiffres",
1955
+ sendOtpButton: "Obtenir un code",
1956
+ resendOtpCountdownText: "Renvoyer dans {seconds} s",
1957
+ newPasswordLabel: "Nouveau mot de passe",
1958
+ newPasswordPlaceholder: "Entrez un nouveau mot de passe",
1959
+ resetButton: "Réinitialiser le mot de passe",
1960
+ usePhoneResetText: "Réinitialiser par code SMS",
1961
+ useEmailResetText: "Réinitialiser par e-mail à la place",
1962
+ phoneSuccessTitle: "Mot de passe réinitialisé",
1963
+ phoneSuccessDescription: "Votre mot de passe a été réinitialisé. Vous pouvez maintenant vous connecter avec votre nouveau mot de passe.",
1822
1964
  },
1823
1965
  resetPassword: {
1824
1966
  title: "Définir un nouveau mot de passe",
@@ -1857,6 +1999,8 @@ const fr = {
1857
1999
  backToLogin: "Retour à la connexion",
1858
2000
  checkSpam: "E-mail non reçu ? Vérifiez votre dossier spam ou contactez le support.",
1859
2001
  or: "Ou",
2002
+ // objectui#3546 slice three.
2003
+ resendUnavailable: "L'envoi d'e-mails n'est peut-être pas configuré pour cet environnement. Contactez le support si le problème persiste.",
1860
2004
  },
1861
2005
  setup: {
1862
2006
  welcomeTitle: "Bienvenue sur ObjectStack",
@@ -1895,6 +2039,9 @@ const fr = {
1895
2039
  invalidDescription: "Aucun code d'appareil n'a été fourni dans l'URL.",
1896
2040
  loading: "Chargement…",
1897
2041
  cancel: "Annuler",
2042
+ // objectui#3546 slice three — device-authorization plugin switched off.
2043
+ disabledTitle: "Autorisation d'appareil non activée",
2044
+ disabledDescription: "L'autorisation d'appareil n'est pas activée sur ce déploiement, cet appareil ne peut donc pas être approuvé ici.",
1898
2045
  },
1899
2046
  shell: {
1900
2047
  tenantHostHint: "Vous vous connectez à cet espace de travail",
@@ -1934,6 +2081,29 @@ const fr = {
1934
2081
  },
1935
2082
  },
1936
2083
  },
2084
+ // objectui#3546 slice three — the /oauth/consent screen.
2085
+ oauth: {
2086
+ consent: {
2087
+ title: "{{appName}} souhaite accéder à votre compte",
2088
+ request: "{{appName}} demande une autorisation{{suffix}}.",
2089
+ unknownApp: "une application",
2090
+ willAllow: "Cette application pourra :",
2091
+ scope: {
2092
+ openid: "Confirmer votre identité",
2093
+ profile: "Lire votre profil de base (nom, photo)",
2094
+ email: "Lire votre adresse e-mail",
2095
+ offlineAccess: "Rester connecté (renouveler l'accès)",
2096
+ },
2097
+ deny: "Refuser",
2098
+ authorize: "Autoriser",
2099
+ submitting: "Autorisation…",
2100
+ granted: "Accès accordé",
2101
+ denied: "Accès refusé",
2102
+ noRedirect: "Le serveur n'a renvoyé aucune URL de redirection.",
2103
+ failed: "Échec du consentement",
2104
+ footer: "Vous pouvez révoquer cet accès à tout moment dans les paramètres de votre compte.",
2105
+ },
2106
+ },
1937
2107
  profile: {
1938
2108
  title: "Profil",
1939
2109
  subtitle: "Gérez les paramètres de votre compte",
@@ -1995,6 +2165,8 @@ const fr = {
1995
2165
  invite: "Inviter un membre",
1996
2166
  members: "Membres",
1997
2167
  settings: "Paramètres de l'espace de travail",
2168
+ multiOrgDisabled: "La création de nouvelles organisations est désactivée sur cette instance.",
2169
+ createFailed: "Échec de la création de l'espace de travail",
1998
2170
  },
1999
2171
  help: {
2000
2172
  onThisPage: "Sur cette page",
@@ -2005,7 +2177,7 @@ const fr = {
2005
2177
  },
2006
2178
  sidebar: {
2007
2179
  packageManagement: "Gestion des packages",
2008
- searchNavigation: "Rechercher dans la navigation...",
2180
+ searchNavigation: "Rechercher dans la navigation…",
2009
2181
  settings: "Paramètres",
2010
2182
  help: "Aide",
2011
2183
  helpTooltip: "Aide et documentation",
@@ -2029,8 +2201,8 @@ const fr = {
2029
2201
  switchObject: "Changer d'objet",
2030
2202
  connection: {
2031
2203
  connected: "Connecté",
2032
- connecting: "Connexion...",
2033
- reconnecting: "Reconnexion...",
2204
+ connecting: "Connexion…",
2205
+ reconnecting: "Reconnexion…",
2034
2206
  disconnected: "Déconnecté",
2035
2207
  error: "Erreur de connexion",
2036
2208
  },
@@ -2046,10 +2218,12 @@ const fr = {
2046
2218
  build: {
2047
2219
  title: "Créer une application",
2048
2220
  subtitle: "Partir de zéro — concevez les objets, formulaires, automatisations et interfaces.",
2221
+ noCapability: "La création d'applications n'est pas disponible dans cet espace de travail : elle requiert l'autorisation « Gérer les métadonnées », que votre compte ne possède pas.",
2049
2222
  },
2050
2223
  template: {
2051
2224
  title: "Partir d'un modèle",
2052
2225
  subtitle: "Installez une application modèle depuis la place de marché et personnalisez-la.",
2226
+ marketplaceDisabled: "Aucune place de marché d'applications n'est configurée pour ce runtime : il n'y a donc aucun modèle à installer ici.",
2053
2227
  },
2054
2228
  welcomeAdminDescription: "Décrivez votre activité en une phrase — l'IA génère les objets, les écrans, les API et les outils d'agent. Ou configurez tout vous-même depuis le menu de gauche.",
2055
2229
  welcomeAdminDescriptionNoBuild: "Configurez votre première application depuis le menu Administration à gauche. Une fois les données en place, l'assistant IA pourra vous aider à les explorer.",
@@ -2069,6 +2243,14 @@ const fr = {
2069
2243
  publishing: "Publication…",
2070
2244
  published: "Publié ! Vos modifications sont actives.",
2071
2245
  publishFailed: "Échec de la publication",
2246
+ // objectui#3546 slice six — seedWarn reprend mot pour mot la traduction de
2247
+ // console.ai.seedWarn (même phrase anglaise). Marqueur "(s)" comme
2248
+ // home.pendingDrafts.message dans cette même famille.
2249
+ nothing: "Rien à publier.",
2250
+ probeWarn: "Publié, mais la vérification a détecté des problèmes.",
2251
+ seedWarn: "Publié, mais certaines données d'exemple n'ont pas pu être chargées.",
2252
+ publishedVerified: "Publié et vérifié — {{count}} ligne(s) d'exemple active(s).",
2253
+ capabilityWarn: "Contrôle de conception : {{count}} référence(s) de capacité ne mènent à rien.",
2072
2254
  },
2073
2255
  title: "Accueil",
2074
2256
  subtitle: "Tableau de bord de votre espace de travail",
@@ -2082,7 +2264,7 @@ const fr = {
2082
2264
  title: "Nécessite votre attention",
2083
2265
  empty: "Vous êtes à jour",
2084
2266
  },
2085
- loading: "Chargement de l'espace de travail...",
2267
+ loading: "Chargement de l'espace de travail…",
2086
2268
  recent: "Récent",
2087
2269
  starred: "Favoris",
2088
2270
  welcome: "Bienvenue dans ObjectUI",
@@ -2143,6 +2325,9 @@ const fr = {
2143
2325
  roles: "Rôles",
2144
2326
  configuration: "Configuration",
2145
2327
  createApp: "Créer une application",
2328
+ administration: "Administration",
2329
+ datasources: "Sources de données",
2330
+ documentation: "Documentation",
2146
2331
  },
2147
2332
  appSwitcher: {
2148
2333
  switchApplication: "Changer d'application",
@@ -2182,7 +2367,7 @@ const fr = {
2182
2367
  search: {
2183
2368
  title: "Rechercher",
2184
2369
  back: "Retour",
2185
- placeholder: "Rechercher des objets, tableaux de bord, pages, rapports...",
2370
+ placeholder: "Rechercher des objets, tableaux de bord, pages, rapports…",
2186
2371
  inputAriaLabel: "Rechercher des objets, tableaux de bord, pages, rapports",
2187
2372
  resultsCount: "{{count}} résultat pour \"{{query}}\"",
2188
2373
  resultsCountPlural: "{{count}} résultats pour \"{{query}}\"",
@@ -2201,6 +2386,7 @@ const fr = {
2201
2386
  empty: {
2202
2387
  objectNotFound: "Objet introuvable",
2203
2388
  objectNotFoundDescription: "La définition de l'objet \"{{name}}\" est manquante. Vérifiez votre configuration ou revenez en arrière.",
2389
+ interfacePageSourceMissing: "Cette page d'interface référence \"{{name}}\", qui n'est pas disponible.",
2204
2390
  pageNotFound: "Page introuvable",
2205
2391
  pageNotFoundDescription: "La page \"{{name}}\" est introuvable. Elle a peut-être été supprimée ou renommée.",
2206
2392
  dashboardNotFound: "Tableau de bord introuvable",
@@ -2209,27 +2395,17 @@ const fr = {
2209
2395
  reportNotFoundDescription: "Le rapport \"{{name}}\" est introuvable. Il a peut-être été supprimé ou renommé.",
2210
2396
  noAppsConfigured: "Aucune application configurée",
2211
2397
  noAppsConfiguredDescription: "Aucune application n'est enregistrée. Créez votre première application ou visitez les paramètres système.",
2398
+ appNotAvailable: "Application non disponible",
2399
+ appNotAvailableDescription: "Cette application n'est pas encore disponible — sa publication est peut-être en cours. Réessayez dans un instant.",
2400
+ appAccessDenied: "Vous n'avez pas accès à cette application",
2401
+ appAccessDeniedDescription: "Cette application existe, mais votre compte n'est pas autorisé à l'ouvrir. Demandez l'accès à un administrateur.",
2402
+ appAccessDeniedHome: "Retour à l'accueil",
2212
2403
  createFirstApp: "Créer la première application",
2213
2404
  systemSettings: "Paramètres système",
2214
2405
  back: "Retour",
2215
2406
  recordNotFound: "Enregistrement introuvable",
2216
2407
  recordNotFoundDescription: "L'enregistrement que vous recherchez n'existe pas ou a peut-être été supprimé.",
2217
2408
  },
2218
- renderer: {
2219
- noPageSchema: "Aucun schéma de page fourni",
2220
- noFormSchema: "Aucun schéma de formulaire fourni",
2221
- noDashboardSchema: "Aucun schéma de tableau de bord fourni",
2222
- pageRendering: "Rendu de la page : {{name}}",
2223
- dashboardRendering: "Rendu du tableau de bord : {{name}}",
2224
- formRenderingMode: "Formulaire rendu en mode {{mode}}",
2225
- formRenderingFor: "pour l'enregistrement {{id}}",
2226
- createRecord: "Créer un enregistrement",
2227
- editRecord: "Modifier l'enregistrement",
2228
- page: "Page",
2229
- dashboard: "Tableau de bord",
2230
- save: "Enregistrer",
2231
- cancel: "Annuler",
2232
- },
2233
2409
  actionDialog: {
2234
2410
  title: "Paramètres d'action",
2235
2411
  description: "Veuillez saisir les informations requises pour continuer.",
@@ -2280,7 +2456,7 @@ const fr = {
2280
2456
  deleteFailed: "Impossible de supprimer la vue",
2281
2457
  },
2282
2458
  dashboardActions: {
2283
- pdfPreparing: "Préparation de l'export PDF…",
2459
+ printDialogOpening: "Ouverture de la boîte de dialogue d'impression de votre navigateur (ce n'est pas un export PDF)",
2284
2460
  exportFailed: "Échec de l'export : {{message}}",
2285
2461
  forecastSoon: "La vue de prévision arrive bientôt",
2286
2462
  },
@@ -2324,126 +2500,159 @@ const fr = {
2324
2500
  first: "Premier",
2325
2501
  },
2326
2502
  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}",
2503
+ panelTitle: "Modifier le rapport",
2432
2504
  },
2433
2505
  },
2434
2506
  organizations: {
2435
2507
  create: "Créer un espace de travail",
2436
- mine: "Mes organisations",
2437
- title: "Organisations",
2438
- heading: "Vos organisations",
2439
- subtitle: "Sélectionnez une organisation pour continuer ou créez-en une nouvelle.",
2440
- searchPlaceholder: "Rechercher une organisation",
2441
- new: "Nouvelle organisation",
2442
- current: "Organisation actuelle",
2508
+ mine: "Mes espaces de travail",
2509
+ title: "Espaces de travail",
2510
+ heading: "Vos espaces de travail",
2511
+ subtitle: "Sélectionnez un espace de travail pour continuer ou créez-en un nouveau.",
2512
+ searchPlaceholder: "Rechercher un espace de travail",
2513
+ new: "Nouvel espace de travail",
2514
+ current: "Espace de travail actuel",
2443
2515
  manage: "Gérer",
2444
- emptyTitle: "Aucune organisation pour le moment",
2445
- emptyDescription: "Créez votre première organisation pour commencer.",
2446
- noMatches: "Aucune organisation ne correspond à votre recherche.",
2516
+ emptyTitle: "Aucun espace de travail pour le moment",
2517
+ emptyDescription: "Créez votre premier espace de travail pour commencer.",
2518
+ noMatches: "Aucun espace de travail ne correspond à votre recherche.",
2519
+ },
2520
+ organization: {
2521
+ roles: {
2522
+ owner: 'Propriétaire',
2523
+ admin: 'Administrateur',
2524
+ delegatedAdmin: 'Administrateur délégué',
2525
+ member: 'Membre',
2526
+ },
2527
+ errors: {
2528
+ notAllowedToInvite: "Vous n'êtes pas autorisé à inviter des utilisateurs dans cette organisation.",
2529
+ notAllowedToInviteWithRole: "Vous n'êtes pas autorisé à inviter un utilisateur avec ce rôle.",
2530
+ alreadyInvited: 'Cet utilisateur a déjà été invité dans cette organisation.',
2531
+ organizationExists: 'Cette organisation existe déjà.',
2532
+ slugTaken: 'Ce slug est déjà utilisé.',
2533
+ notAllowedToCreate: "Vous n'êtes pas autorisé à créer une nouvelle organisation.",
2534
+ notTheRecipient: "Vous n'êtes pas le destinataire de cette invitation.",
2535
+ invitationNotFound: "Cette invitation n'existe plus ou a expiré.",
2536
+ unknown: 'Une erreur est survenue. Veuillez réessayer.',
2537
+ },
2538
+ backToList: "Retour aux organisations",
2539
+ notFound: "Organisation introuvable",
2540
+ notFoundDescription: "Cette organisation n'existe pas ou vous n'y avez pas accès.",
2541
+ tabs: {
2542
+ members: "Membres",
2543
+ invitations: "Invitations",
2544
+ settings: "Paramètres",
2545
+ },
2546
+ members: {
2547
+ title: "Membres",
2548
+ inviteMember: "Inviter un membre",
2549
+ inviteRestrictedNote: "Seuls les administrateurs de l'organisation peuvent inviter des membres.",
2550
+ removeMember: "Retirer le membre",
2551
+ removeConfirmTitle: "Retirer ce membre ?",
2552
+ removeConfirmDescription: "{{name}} sera retiré de l'organisation et perdra immédiatement son accès.",
2553
+ removeConfirmAction: "Retirer",
2554
+ memberRemoved: "Membre retiré",
2555
+ removeFailed: "Impossible de retirer le membre",
2556
+ roleUpdated: "Rôle mis à jour",
2557
+ roleUpdateFailed: "Impossible de mettre à jour le rôle",
2558
+ memberActions: 'Actions du membre',
2559
+ loadFailed: 'Échec du chargement des membres',
2560
+ },
2561
+ invitations: {
2562
+ title: "Invitations",
2563
+ empty: "Aucune invitation.",
2564
+ expiresAt: "Expire le",
2565
+ linkCopied: "Lien d'invitation copié",
2566
+ copyFailed: "Impossible de copier le lien",
2567
+ canceled: "Invitation annulée",
2568
+ cancelFailed: "Impossible d'annuler l'invitation",
2569
+ cancelTitle: "Annuler l'invitation ?",
2570
+ cancelDescription: "L'invitation de {{email}} sera révoquée.",
2571
+ cancelAction: "Annuler l'invitation",
2572
+ inviteTitle: "Inviter un membre",
2573
+ inviteDescription: "La personne recevra une invitation à rejoindre cette organisation.",
2574
+ emailLabel: "E-mail",
2575
+ roleLabel: "Rôle",
2576
+ placementLabel: "Affectation (facultatif)",
2577
+ 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.",
2578
+ businessUnitLabel: "Unité opérationnelle",
2579
+ businessUnitPlaceholder: "Aucune affectation",
2580
+ positionsLabel: "Postes",
2581
+ sendInvite: "Envoyer l'invitation",
2582
+ sentTitle: "Invitation créée",
2583
+ sentDescription: "Partagez le lien ci-dessous avec la personne invitée. Elle devra se connecter pour accepter.",
2584
+ linkLabel: "Lien d'acceptation",
2585
+ invitedAs: "{{email}} invité en tant que {{role}}",
2586
+ copyLinkLabel: "Copier le lien d'invitation",
2587
+ loadFailed: 'Échec du chargement des invitations',
2588
+ inviteFailed: "Échec de l'invitation du membre",
2589
+ status: {
2590
+ all: "Toutes",
2591
+ pending: "En attente",
2592
+ accepted: "Acceptée",
2593
+ rejected: "Refusée",
2594
+ canceled: "Annulée",
2595
+ },
2596
+ },
2597
+ settings: {
2598
+ generalTitle: "Général",
2599
+ generalDescription: "Mettez à jour les informations de votre organisation.",
2600
+ readOnlyNote: "Seuls les propriétaires peuvent modifier les paramètres.",
2601
+ nameLabel: "Nom de l'organisation",
2602
+ slugLabel: "Slug",
2603
+ logoLabel: "Logo",
2604
+ logoUpload: "Téléverser",
2605
+ logoReplace: "Remplacer",
2606
+ logoClear: "Retirer",
2607
+ logoUploaded: "Logo téléversé — enregistrez pour appliquer",
2608
+ logoUploadFailed: "Impossible de téléverser le logo",
2609
+ save: "Enregistrer les modifications",
2610
+ saved: "Paramètres enregistrés",
2611
+ saveFailed: "Impossible d'enregistrer les paramètres",
2612
+ leaveTitle: "Quitter l'organisation",
2613
+ leaveDescription: "Vous perdrez l'accès à cette organisation.",
2614
+ leaveAction: "Quitter",
2615
+ leaveConfirmTitle: "Quitter l'organisation ?",
2616
+ leaveConfirmDescription: "Voulez-vous vraiment quitter {{name}} ? Vous perdrez immédiatement votre accès.",
2617
+ leaveConfirmAction: "Quitter",
2618
+ leftOrg: "Vous avez quitté l'organisation",
2619
+ leaveFailed: "Impossible de quitter l'organisation",
2620
+ dangerZone: "Zone de danger",
2621
+ deleteTitle: "Supprimer l'organisation",
2622
+ deleteDescription: "Supprimez définitivement cette organisation et toutes ses données.",
2623
+ deleteAction: "Supprimer",
2624
+ deleteConfirmTitle: "Supprimer l'organisation ?",
2625
+ deleteConfirmDescription: "Cette action est irréversible. Toutes les données seront définitivement supprimées. Saisissez le slug de l'organisation pour confirmer.",
2626
+ deleteConfirmSlugLabel: "Saisissez « {{slug}} » pour confirmer",
2627
+ deleteConfirmAction: "Supprimer l'organisation",
2628
+ deleted: "Organisation supprimée",
2629
+ deleteFailed: "Impossible de supprimer l'organisation",
2630
+ },
2631
+ accept: {
2632
+ title: "Vous avez été invité",
2633
+ description: "Vous avez été invité à rejoindre {{orgName}} en tant que {{role}}.",
2634
+ errorTitle: "Invitation indisponible",
2635
+ goToOrgs: "Aller aux organisations",
2636
+ loading: "Chargement de l'invitation…",
2637
+ organization: "Organisation",
2638
+ role: "Rôle",
2639
+ expiresAt: "Expire le",
2640
+ accept: "Accepter l'invitation",
2641
+ accepted: "Invitation acceptée",
2642
+ acceptFailed: "Impossible d'accepter l'invitation",
2643
+ decline: "Refuser",
2644
+ declined: "Invitation refusée",
2645
+ declineFailed: "Impossible de refuser l'invitation",
2646
+ },
2647
+ current: {
2648
+ label: "Organisation actuelle",
2649
+ },
2650
+ switcher: {
2651
+ label: "Changer d'organisation",
2652
+ groupLabel: "Organisation de travail",
2653
+ groupHint: "Les nouveaux enregistrements sont créés ici. Les vues affichent les données de toutes vos organisations.",
2654
+ manageMembers: "Gérer les membres",
2655
+ },
2447
2656
  },
2448
2657
  notifications: {
2449
2658
  regionLabel: "Notifications",
@@ -2458,6 +2667,9 @@ const fr = {
2458
2667
  viewApprovals: "Voir les approbations",
2459
2668
  noPendingApprovals: "Aucune approbation en attente",
2460
2669
  openApprovalsInbox: "Ouvrir la boîte d'approbations",
2670
+ badgeTotal: "{{total}} au total",
2671
+ badgeNotifications: "{{unread}} notifications",
2672
+ badgeApprovals: "{{approvals}} approbations en attente",
2461
2673
  emptyUnread: "Tout est lu",
2462
2674
  filterUnread: "Non lus",
2463
2675
  filterAll: "Tous",
@@ -2482,52 +2694,6 @@ const fr = {
2482
2694
  consentRequired: "Veuillez accepter la politique de confidentialité pour continuer.",
2483
2695
  rateLimited: "Prenez un moment pour vérifier vos réponses avant d'envoyer.",
2484
2696
  redirectBlocked: "Soumission acceptée, mais l'URL de redirection a été bloquée pour des raisons de sécurité.",
2485
- demo: {
2486
- contactTitle: "Nous contacter",
2487
- contactDescription: "Parlez-nous de votre projet et un représentant commercial vous contactera dans un jour ouvrable.",
2488
- supportTitle: "Soumettre une demande d'assistance",
2489
- supportDescription: "Décrivez-nous le problème — notre équipe répondra dans un jour ouvrable.",
2490
- thankYouSalesTitle: "Merci — nous avons reçu votre message !",
2491
- thankYouSalesMessage: "Un représentant commercial vous contactera dans un jour ouvrable.",
2492
- thankYouSupportTitle: "C'est bon — votre demande est en file d'attente.",
2493
- thankYouSupportMessage: "Un ingénieur d'assistance vous fera un suivi bientôt. Sauvegardez cette page si vous avez des captures d'écran supplémentaires.",
2494
- field: {
2495
- firstName: "Prénom",
2496
- lastName: "Nom",
2497
- email: "E-mail professionnel",
2498
- phone: "Téléphone",
2499
- jobTitle: "Titre du poste",
2500
- company: "Entreprise",
2501
- website: "Site web",
2502
- industry: "Secteur",
2503
- companySize: "Taille de l'entreprise",
2504
- howCanWeHelp: "Comment pouvons-nous vous aider ?",
2505
- subject: "Sujet",
2506
- description: "Description",
2507
- issueType: "Type de problème",
2508
- priority: "Priorité",
2509
- },
2510
- industry: {
2511
- technology: "Technologie",
2512
- software: "Logiciel / SaaS",
2513
- finance: "Finance",
2514
- healthcare: "Santé",
2515
- retail: "Commerce de détail",
2516
- other: "Autre",
2517
- },
2518
- issueType: {
2519
- question: "Question",
2520
- problem: "Problème",
2521
- bug: "Bug",
2522
- feature_request: "Demande de fonctionnalité",
2523
- },
2524
- priority: {
2525
- low: "Faible",
2526
- medium: "Moyen",
2527
- high: "Élevé",
2528
- critical: "Critique",
2529
- },
2530
- },
2531
2697
  },
2532
2698
  connectAgent: {
2533
2699
  disabled: {
@@ -2640,6 +2806,7 @@ const fr = {
2640
2806
  retry: "Réessayer",
2641
2807
  errors: {
2642
2808
  expired: "La demande a expiré avant d'être approuvée. Recommencez.",
2809
+ accessDenied: "La demande de connexion a été refusée. Recommencez.",
2643
2810
  bindFailed: "Échec de la liaison.",
2644
2811
  deviceCodeFailed: "Échec de la demande de code d'appareil.",
2645
2812
  },
@@ -2705,10 +2872,16 @@ const fr = {
2705
2872
  installedBadge: "Installé v{{version}}",
2706
2873
  load: {
2707
2874
  failed: "Impossible de charger le marketplace",
2708
- failedHint: "Par défaut, ce runtime pointe vers le cloud public ObjectStack. Assurez-vous que le runtime est en ligne.",
2875
+ failedHintConfigured: "Ce runtime accède à la place de marché via le plan de contrôle situé à {{url}}. Vérifiez qu'il est en ligne et joignable depuis ici.",
2876
+ failedHintSameOrigin: "Ce runtime sert lui-même le catalogue de la place de marché. Vérifiez qu'il est en ligne.",
2709
2877
  packageFailed: "Impossible de charger le paquet",
2710
2878
  notFound: "Introuvable.",
2711
2879
  },
2880
+ disabled: {
2881
+ title: "La place de marché des applications est désactivée",
2882
+ description: "Aucune place de marché n'est configurée pour ce runtime : il n'y a donc rien à parcourir ni à installer ici.",
2883
+ hint: "C'est l'état attendu lorsque le runtime démarre avec <code>OS_CLOUD_URL=off</code> (ou <code>none</code>, <code>local</code>, <code>disabled</code>). Pour activer la place de marché, faites pointer <code>OS_CLOUD_URL</code> vers un plan de contrôle puis redémarrez le runtime.",
2884
+ },
2712
2885
  detail: {
2713
2886
  homepage: "Page d'accueil",
2714
2887
  installedV: "Installé · v{{version}}",
@@ -2744,6 +2917,7 @@ const fr = {
2744
2917
  dismiss: "Fermer",
2745
2918
  openOnCloud: "Ouvrir dans le cloud",
2746
2919
  backHome: "Retour à l'accueil",
2920
+ updateTo: "Mettre à jour",
2747
2921
  },
2748
2922
  install: {
2749
2923
  dialogTitle: "Installer {{name}}",
@@ -2760,6 +2934,37 @@ const fr = {
2760
2934
  localManifestConflict: "{{message}}\nRemarque : Une application locale possède déjà ce manifest_id. Supprimez-la d'abord de objectstack.config.ts.",
2761
2935
  localUnauthorized: "Connectez-vous d'abord à ce runtime.",
2762
2936
  localMarketplaceUnavailable: "Ce runtime n'a pas de OS_CLOUD_URL configuré.",
2937
+ updateTo: "Mettre à jour → v{{version}}",
2938
+ installedVersion: "Installé v{{version}}",
2939
+ },
2940
+ // objectui#3546 — the MarketplacePage "Your organization" strip.
2941
+ org: {
2942
+ heading: "Votre organisation",
2943
+ install: "Installer",
2944
+ installed: "{{name}} installé",
2945
+ installedBadge: "Installé",
2946
+ installing: "Installation…",
2947
+ },
2948
+ // ADR-0025 PD4 §3.5/§3.11 — the pre-install consent panel
2949
+ // (PluginDisclosure.tsx). `runtime` is a CLOSED enum: spec
2950
+ // PluginRuntimeSchema = z.enum(['node', 'sandbox', 'worker']).
2951
+ disclosure: {
2952
+ containsCode: "Ce paquet contient du code",
2953
+ reviewed: "Examiné et approuvé",
2954
+ unreviewed: "Pas encore examiné",
2955
+ signed: "Signé",
2956
+ grantsIntro: "À l'installation, ce paquet obtiendra :",
2957
+ services: "Services de la plateforme",
2958
+ hooks: "Hooks de cycle de vie",
2959
+ network: "Accès réseau",
2960
+ fs: "Accès au système de fichiers",
2961
+ noPermissions: "Ne demande aucune autorisation particulière.",
2962
+ acknowledge: "Je comprends que ce paquet exécute du code et obtient les autorisations ci-dessus.",
2963
+ runtime: {
2964
+ node: "Dans le processus · confiance totale",
2965
+ sandbox: "Bac à sable",
2966
+ worker: "Hors processus",
2967
+ },
2763
2968
  },
2764
2969
  uninstall: {
2765
2970
  confirm: "Désinstaller {{manifestId}} v{{version}} de ce runtime ?\n\nLe manifeste en cache sera supprimé.",
@@ -2916,12 +3121,19 @@ const fr = {
2916
3121
  submittedAgo: 'Soumise {{when}}',
2917
3122
  completedAt: 'Terminée {{when}}',
2918
3123
  waitingOn: 'En attente de',
3124
+ approverNameSeparator: ', ',
3125
+ approverUnstaffed: '{{seat}} (poste actuellement vacant)',
2919
3126
  history: 'Activité',
2920
3127
  noActions: 'Aucune action pour le moment.',
2921
3128
  actSubmit: 'Soumise',
2922
3129
  actApprove: 'Approuvée',
2923
3130
  actReject: 'Rejetée',
2924
3131
  actRecall: 'Retirée',
3132
+ overrideActionLabel: '{{action}} (dérogation)',
3133
+ overrideNotice: "Vous n'occupez aucun poste d'approbateur à cette étape. En continuant, votre dérogation d'administrateur sera utilisée : l'étape est finalisée immédiatement et tout approbateur n'ayant pas encore statué est contourné. La décision est enregistrée comme une dérogation d'administrateur.",
3134
+ overrideNoticeWho: "Vous n'occupez aucun poste d'approbateur à cette étape. En continuant, votre dérogation d'administrateur sera utilisée : l'étape est finalisée immédiatement et les approbateurs n'ayant pas encore statué sont contournés — {{who}}. La décision est enregistrée comme une dérogation d'administrateur.",
3135
+ viaOverrideChip: 'Dérogation administrateur',
3136
+ viaOverrideHint: "L'auteur n'occupait aucun poste d'approbateur à cette étape — admis par la voie de dérogation administrateur.",
2925
3137
  rawData: 'Données brutes (JSON)',
2926
3138
  copy: 'Copier',
2927
3139
  copied: 'Copié',
@@ -3008,6 +3220,39 @@ const fr = {
3008
3220
  detailChangedKeys: 'Également modifié :',
3009
3221
  confirmNote: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
3010
3222
  publishConfirm: 'Tout publier',
3223
+ // [objectui#5418] Pre-publish security-posture findings, shown next to
3224
+ // the confirm button so a refusal the door would issue is read BEFORE
3225
+ // the click rather than as a toast after the batch rolled back.
3226
+ securityBlockTitle: 'La publication sera refusée — {{count}} élément(s) nécessitent d’abord une décision',
3227
+ securityBlockWhere: 'Corrigez-le sur l’objet dans Paramètres → Partage d’enregistrements, puis publiez à nouveau.',
3228
+ },
3229
+ // ADR-0045 — the materialized-but-unlisted app banner
3230
+ // (UnpublishedAppBar.tsx), sibling of draftBar above.
3231
+ unpublishedBar: {
3232
+ message: 'Application non publiée — entièrement fonctionnelle, mais visible seulement par les créateurs. Publiez-la pour la rendre visible à vos utilisateurs.',
3233
+ publish: 'Publier',
3234
+ publishing: 'Publication…',
3235
+ published: 'Publié ! L\'application est maintenant visible par vos utilisateurs.',
3236
+ publishFailed: 'Échec de la publication',
3237
+ },
3238
+ // ADR-0067 — the append-only build/revert timeline (CommitTimeline.tsx);
3239
+ // `button` is the banner's entry point into it.
3240
+ history: {
3241
+ button: 'Historique',
3242
+ title: 'Historique des générations',
3243
+ 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.',
3244
+ loadFailed: 'Impossible de charger l\'historique :',
3245
+ loadFailedUnavailable: 'Magasin de commits temporairement injoignable — cette lecture n\'a pas eu lieu, aucun historique n\'est donc affiché. Réessayez dans un instant.',
3246
+ loading: 'Chargement de l\'historique…',
3247
+ empty: 'Aucun historique pour cette application.',
3248
+ revertLabel: 'Modification annulée',
3249
+ applyLabel: 'Modification de génération',
3250
+ revert: 'annulation',
3251
+ items: 'éléments',
3252
+ revertAction: 'Annuler',
3253
+ reverted: 'Annulé — la modification a été retirée.',
3254
+ revertFailed: 'Échec de l\'annulation',
3255
+ 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.',
3011
3256
  },
3012
3257
  },
3013
3258
  filterBuilder: {
@@ -3026,10 +3271,15 @@ const fr = {
3026
3271
  noResults: "Aucun résultat",
3027
3272
  searchField: "Rechercher {{label}}…",
3028
3273
  enterId: "Saisir l'ID {{label}}",
3274
+ addValue: "Saisir une valeur, puis Entrée",
3275
+ removeValue: "Supprimer {{value}}",
3276
+ rangeStart: "De",
3277
+ rangeEnd: "À",
3029
3278
  operators: {
3030
3279
  equals: "Égal à",
3031
3280
  notEquals: "Différent de",
3032
3281
  contains: "Contient",
3282
+ containsCaseInsensitive: "Contient (ignorer la casse)",
3033
3283
  notContains: "Ne contient pas",
3034
3284
  isEmpty: "Est vide",
3035
3285
  isNotEmpty: "N'est pas vide",
@@ -3042,6 +3292,12 @@ const fr = {
3042
3292
  between: "Entre",
3043
3293
  in: "Dans",
3044
3294
  notIn: "Pas dans",
3295
+ startsWith: "Commence par",
3296
+ endsWith: "Se termine par",
3297
+ isNull: "Est null",
3298
+ isNotNull: "N'est pas null",
3299
+ exists: "Est défini",
3300
+ notExists: "N'est pas défini",
3045
3301
  },
3046
3302
  },
3047
3303
  sortBuilder: {
@@ -3087,5 +3343,64 @@ const fr = {
3087
3343
  statusIdle: "inactif",
3088
3344
  statusAway: "absent",
3089
3345
  },
3346
+ wizard: {
3347
+ missingRequired: "Veuillez renseigner les champs obligatoires : {{fields}}",
3348
+ },
3349
+ flowRunner: {
3350
+ title: 'Saisie',
3351
+ submitting: 'Envoi…',
3352
+ saveAndContinue: 'Enregistrer et continuer',
3353
+ nextStep: 'Enregistré — étape suivante',
3354
+ completed: 'Flux « {{flow}} » terminé',
3355
+ },
3356
+ appManagement: {
3357
+ title: "Applications",
3358
+ subtitle: "Gérer toutes les applications configurées",
3359
+ newApp: "Nouvelle application",
3360
+ searchLabel: "Rechercher des applications",
3361
+ searchPlaceholder: "Rechercher des applications…",
3362
+ selectedCount: "{{n}} sélectionnées",
3363
+ bulkEnable: "Activer",
3364
+ bulkDisable: "Désactiver",
3365
+ selectAll: "Tout sélectionner ({{n}})",
3366
+ empty: "Aucune application trouvée.",
3367
+ defaultBadge: "Par défaut",
3368
+ active: "Active",
3369
+ inactive: "Inactive",
3370
+ selectApp: "Sélectionner {{name}}",
3371
+ openApp: "Ouvrir l'application",
3372
+ openAppNamed: "Ouvrir {{name}}",
3373
+ editApp: "Modifier l'application",
3374
+ editAppNamed: "Modifier {{name}}",
3375
+ editWithAi: "Modifier avec l'IA",
3376
+ editWithAiNamed: "Modifier {{name}} avec l'IA",
3377
+ enableApp: "Activer l'application",
3378
+ disableApp: "Désactiver l'application",
3379
+ enableAppNamed: "Activer {{name}}",
3380
+ disableAppNamed: "Désactiver {{name}}",
3381
+ setDefault: "Définir par défaut",
3382
+ setDefaultNamed: "Définir {{name}} par défaut",
3383
+ deleteApp: "Supprimer l'application",
3384
+ deleteAppNamed: "Supprimer {{name}}",
3385
+ confirmDelete: "Cliquez à nouveau pour confirmer la suppression",
3386
+ confirmDeleteNamed: "Confirmer la suppression de {{name}}",
3387
+ toast: {
3388
+ noClient: "Impossible de joindre le service de métadonnées",
3389
+ unknownError: "erreur inconnue",
3390
+ appEnabled: "{{name}} activée",
3391
+ appDisabled: "{{name}} désactivée",
3392
+ toggleFailed: "Échec du changement d'état de l'application : {{reason}}",
3393
+ setDefaultDone: "{{name}} définie par défaut",
3394
+ setDefaultFailed: "Échec de la définition de l'application par défaut : {{reason}}",
3395
+ appDeleted: "{{name}} supprimée",
3396
+ deleteFailed: "Échec de la suppression de l'application : {{reason}}",
3397
+ bulkEnabled: "{{n}} applications activées",
3398
+ bulkDisabled: "{{n}} applications désactivées",
3399
+ bulkFailed: "Échec pour {{n}} : {{details}}",
3400
+ bulkFailureEntry: "{{name}} ({{reason}})",
3401
+ bulkFailureJoiner: " ; ",
3402
+ bulkOperationFailed: "Échec de l'opération groupée : {{reason}}",
3403
+ },
3404
+ },
3090
3405
  };
3091
3406
  export default fr;