@object-ui/i18n 17.6.0 → 17.7.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 (56) hide show
  1. package/CHANGELOG.md +4320 -0
  2. package/README.md +192 -13
  3. package/dist/builtinAggregateLabels.d.ts +40 -0
  4. package/dist/builtinAggregateLabels.js +23 -0
  5. package/dist/currency.d.ts +27 -3
  6. package/dist/currency.js +28 -4
  7. package/dist/fallbackInterpolation.d.ts +79 -0
  8. package/dist/fallbackInterpolation.js +124 -0
  9. package/dist/i18n.d.ts +27 -1
  10. package/dist/i18n.js +99 -16
  11. package/dist/index.d.ts +7 -13
  12. package/dist/index.js +41 -17
  13. package/dist/locales/ar.d.ts +946 -113
  14. package/dist/locales/ar.js +1095 -161
  15. package/dist/locales/de.d.ts +618 -113
  16. package/dist/locales/de.js +715 -134
  17. package/dist/locales/en.d.ts +632 -127
  18. package/dist/locales/en.js +1044 -162
  19. package/dist/locales/es.d.ts +700 -113
  20. package/dist/locales/es.js +794 -130
  21. package/dist/locales/fr.d.ts +700 -113
  22. package/dist/locales/fr.js +795 -132
  23. package/dist/locales/index.d.ts +6990 -1169
  24. package/dist/locales/index.js +48 -9
  25. package/dist/locales/ja.d.ts +618 -113
  26. package/dist/locales/ja.js +708 -128
  27. package/dist/locales/ko.d.ts +618 -113
  28. package/dist/locales/ko.js +712 -132
  29. package/dist/locales/pt.d.ts +700 -113
  30. package/dist/locales/pt.js +794 -130
  31. package/dist/locales/registry.d.ts +102 -0
  32. package/dist/locales/registry.js +220 -0
  33. package/dist/locales/rtl.d.ts +24 -0
  34. package/dist/locales/rtl.js +26 -0
  35. package/dist/locales/ru.d.ts +782 -113
  36. package/dist/locales/ru.js +910 -152
  37. package/dist/locales/zh.d.ts +635 -130
  38. package/dist/locales/zh.js +725 -131
  39. package/dist/pickLocalized.d.ts +30 -0
  40. package/dist/pickLocalized.js +39 -0
  41. package/dist/provider.d.ts +101 -12
  42. package/dist/provider.js +335 -50
  43. package/dist/translateFn.d.ts +29 -0
  44. package/dist/translateFn.js +8 -0
  45. package/dist/useDisplayLocale.d.ts +11 -0
  46. package/dist/useDisplayLocale.js +11 -0
  47. package/dist/useObjectLabel.d.ts +40 -18
  48. package/dist/useObjectLabel.js +46 -14
  49. package/dist/useSafeTranslation.js +40 -42
  50. package/dist/utils/formatting.d.ts +16 -0
  51. package/dist/utils/formatting.js +23 -3
  52. package/dist/utils/spec-formatters.d.ts +13 -23
  53. package/dist/utils/spec-formatters.js +41 -2
  54. package/dist/utils/spec-translations.d.ts +16 -3
  55. package/dist/utils/spec-translations.js +52 -13
  56. package/package.json +12 -6
@@ -19,10 +19,12 @@ const fr = {
19
19
  manage_users: "Gérer les utilisateurs",
20
20
  manage_org_users: "Gérer les utilisateurs de l'organisation",
21
21
  manage_metadata: "Gérer les métadonnées",
22
+ manage_org_presentation: "Gérer la présentation de l'organisation",
22
23
  manage_platform_settings: "Gérer les paramètres de la plateforme",
23
24
  setup_access: "Accès à la configuration",
24
25
  setup_write: "Écriture des paramètres",
25
26
  studio_access: "Accès à Studio",
27
+ manage_sharing: "Gérer le partage",
26
28
  },
27
29
  group: {
28
30
  platform: 'Plateforme',
@@ -39,12 +41,20 @@ const fr = {
39
41
  more: "+{{count}} de plus",
40
42
  objects: "{{count}} objets",
41
43
  objects_one: "{{count}} objet",
44
+ objects_many: "{{count}} d'objets",
45
+ objects_other: "{{count}} objets",
42
46
  fields: "{{count}} règles de champ",
43
47
  fields_one: "{{count}} règle de champ",
48
+ fields_many: "{{count}} de règles de champ",
49
+ fields_other: "{{count}} règles de champ",
44
50
  rls: "{{count}} politiques RLS",
45
51
  rls_one: "{{count}} politique RLS",
52
+ rls_many: "{{count}} de politiques RLS",
53
+ rls_other: "{{count}} politiques RLS",
46
54
  tabs: "{{count}} règles d'onglet",
47
55
  tabs_one: "{{count}} règle d'onglet",
56
+ tabs_many: "{{count}} de règles d'onglet",
57
+ tabs_other: "{{count}} règles d'onglet",
48
58
  adminScope: "Administration déléguée configurée",
49
59
  designInStudio: "Concevoir dans Studio →",
50
60
  designInStudioHint: "Concevoir dans Studio",
@@ -63,7 +73,9 @@ const fr = {
63
73
  selectFirst: 'Sélectionnez d’abord {{fields}}',
64
74
  selectRecord: 'Sélectionner un enregistrement',
65
75
  recordCount: '{{count}} enregistrements',
66
- recordCountOne: '1 enregistrement',
76
+ recordCount_one: '{{count}} enregistrement',
77
+ recordCount_many: "{{count}} d'enregistrements",
78
+ recordCount_other: '{{count}} enregistrements',
67
79
  pageOf: 'Page {{current}} sur {{total}}',
68
80
  filters: 'Filtres',
69
81
  clear: 'Effacer',
@@ -116,7 +128,9 @@ const fr = {
116
128
  closePanel: "Fermer le panneau",
117
129
  resizeDrawer: "Redimensionner le panneau",
118
130
  itemCount: "{{count}} éléments",
119
- itemCountOne: "{{count}} élément",
131
+ itemCount_one: "{{count}} élément",
132
+ itemCount_many: "{{count}} d'éléments",
133
+ itemCount_other: "{{count}} éléments",
120
134
  toggleSidebar: "Basculer la barre latérale",
121
135
  package: "Package",
122
136
  done: "Terminé",
@@ -124,6 +138,16 @@ const fr = {
124
138
  record: "Enregistrement",
125
139
  retry: "Réessayer",
126
140
  printDialogHint: "Ouvre la boîte de dialogue d'impression de votre navigateur (ce n'est pas un export PDF)",
141
+ // The non-grid row ceiling's footnote (objectui#7210). Two keys because
142
+ // there are two conditions: a reported `total` states the fact with BOTH
143
+ // numbers, a missing one cannot name how many. Kept terse deliberately —
144
+ // this copy is eagerly loaded, and since objectui#7399 these bytes are
145
+ // budgeted by the `i18n-locales` chunk, not `framework`. ⛔ That ceiling's
146
+ // headroom is deliberately NOT restated here — it moves on every
147
+ // re-baseline, and the figure that was here went stale.
148
+ // `pnpm check:eager-closure` prints it.
149
+ rowCeilingNote: "Affichage des {{shown}} premiers enregistrements sur {{total}}. Affinez le filtre.",
150
+ rowCeilingNoteUnknownTotal: "Affichage des {{shown}} premiers enregistrements. Affinez le filtre.",
127
151
  },
128
152
  actions: {
129
153
  decisionOutput: {
@@ -135,6 +159,14 @@ const fr = {
135
159
  acknowledge: 'Je l\'ai enregistrée',
136
160
  copyAll: 'Tout copier',
137
161
  },
162
+ notAvailableHere: '« {{action}} » n\'est pas disponible sur la page actuelle.',
163
+ completedSuccessfully: 'Action effectuée avec succès',
164
+ failed: "Échec de l'action",
165
+ parallelFailed: 'Une ou plusieurs actions parallèles ont échoué',
166
+ undo: 'Annuler',
167
+ undone: 'Modification annulée',
168
+ undoneOperation: 'Annuler : {{description}}',
169
+ redoneOperation: 'Rétablir : {{description}}',
138
170
  },
139
171
  validation: {
140
172
  required: "{{field}} est obligatoire",
@@ -152,19 +184,45 @@ const fr = {
152
184
  },
153
185
  form: {
154
186
  noPermissionToSave: "Vous n'avez pas l'autorisation d'enregistrer cet enregistrement.",
187
+ noPermissionToCreate: "Vous n'avez pas l'autorisation de créer des enregistrements {{object}}. Les champs sont en lecture seule.",
188
+ noPermissionToEdit: "Vous n'avez pas l'autorisation de modifier les enregistrements {{object}}. Les champs sont en lecture seule.",
155
189
  submitFailed: "Échec de l'enregistrement. Veuillez réessayer.",
190
+ uploadInFlight: "Attendez la fin du téléversement avant de sauvegarder.",
191
+ clearedOnHide: "Ce qui ne s'applique plus aux valeurs actuelles a été effacé : {{fields}}",
192
+ visibleWhenFaulted: "Envoi impossible : la règle visibleWhen de {{fields}} n'a pas pu être évaluée. La règle doit être corrigée avant que ce formulaire puisse être envoyé.",
156
193
  discardTitle: "Abandonner les modifications ?",
157
194
  discardMessage: "Vous avez des modifications non enregistrées. Si vous fermez ce formulaire maintenant, vos modifications seront perdues.",
158
195
  // objectui#4024 — the create/edit dialog's `sr-only` accessible
159
196
  // description, used when the form declares no `description` of its own.
160
197
  dialogDescriptionFallback: "Remplissez les champs du formulaire, puis envoyez ou annulez.",
198
+ deniedDescription: "Vous n'avez pas l'autorisation de modifier ce champ.",
199
+ masterDetail: {
200
+ loadingColumns: "Chargement des colonnes…",
201
+ subtotal: "Sous-total",
202
+ tax: "Taxe ({{rate}} %)",
203
+ total: "Total",
204
+ lineItem: "Ligne",
205
+ rowTitle: "{{title}} — ligne {{row}}",
206
+ applyRow: "Appliquer",
207
+ editorDescription: "Saisissez l'enregistrement et ses lignes, puis enregistrez.",
208
+ noChildObject: "Aucun objet enfant n'est configuré pour cette collection : définissez {{property}} sur l'objet dont elle liste les lignes.",
209
+ schemaUnavailable: "Impossible de charger le schéma de {{object}} : cette collection n'a donc aucune colonne à afficher. Vérifiez que l'objet existe et est lisible, puis rechargez.",
210
+ noRelationshipField: "Impossible de déterminer comment {{object}} est lié à {{parent}} : aucun champ lookup ou master_detail de cet objet ne référence le parent. Définissez {{property}} sur cette collection avec le champ qui contient l'enregistrement parent.",
211
+ },
212
+ lineItems: {
213
+ title: "Lignes",
214
+ saveRecordFirst: "Enregistrez d'abord l'enregistrement pour ajouter des lignes.",
215
+ notLoaded: "Les lignes de cet enregistrement n'ont pas été chargées.",
216
+ loadFailed: "Échec du chargement des lignes",
217
+ saveFailed: "Échec de l'enregistrement des lignes",
218
+ noChildObject: "Aucun objet enfant n'est configuré pour ce panneau : définissez {{property}} sur l'objet dont il liste les lignes.",
219
+ },
161
220
  keepEditing: "Continuer l'édition",
162
221
  discard: "Abandonner",
163
222
  conflictTitle: "Conflit d'enregistrement",
164
223
  conflictMessage: "Cet enregistrement a été modifié par quelqu'un d'autre pendant votre édition. L'écrasement remplacera ses modifications par les vôtres.",
165
224
  conflictLatestVersion: "Son enregistrement : {{time}}",
166
225
  conflictOverwrite: "Écraser",
167
- addItem: "Ajouter un élément",
168
226
  removeItem: "Supprimer un élément",
169
227
  fieldRequired: "Ce champ est obligatoire",
170
228
  invalidFormat: "Format invalide",
@@ -182,6 +240,12 @@ const fr = {
182
240
  createSuccess: "{{object}} créé",
183
241
  updateSuccess: "{{object}} mis à jour",
184
242
  deleteSuccess: "{{object}} supprimé",
243
+ created: "Créé",
244
+ saved: "Enregistré",
245
+ savedNamed: "{{title}} enregistré",
246
+ submitted: "Envoyé",
247
+ errorLoading: "Erreur de chargement du formulaire",
248
+ navigateRefused: "La destination `navigateOnSuccess` déclarée pour ce formulaire a été refusée, la navigation n’a donc pas eu lieu.",
185
249
  fullscreen: {
186
250
  title: "Modifier le texte",
187
251
  description: "Modifiez la valeur texte complète, puis enregistrez ou annulez vos modifications.",
@@ -206,6 +270,9 @@ const fr = {
206
270
  },
207
271
  relativeDate: {
208
272
  overdue: "En retard de {{count}} j",
273
+ overdue_one: "En retard de {{count}} j",
274
+ overdue_many: "En retard de {{count}} j",
275
+ overdue_other: "En retard de {{count}} j",
209
276
  },
210
277
  file: {
211
278
  dragDropHere: 'Glissez-déposez des fichiers ici',
@@ -222,6 +289,7 @@ const fr = {
222
289
  remove: 'Supprimer {{name}}',
223
290
  exceedsMaxSize: '« {{name}} » dépasse la taille maximale ({{max}} Mo)',
224
291
  uploadFailed: 'Échec du téléversement de « {{name}} » : {{error}}',
292
+ uploadIncomplete: 'Le téléversement de « {{name}} » n’a pas abouti : aucun identifiant de fichier n’a été renvoyé, rien n’a été enregistré',
225
293
  },
226
294
  richText: {
227
295
  format: "Format : {{format}}",
@@ -249,6 +317,9 @@ const fr = {
249
317
  selectBusinessUnit: "Sélectionner une unité opérationnelle",
250
318
  selectPosition: "Sélectionner un poste",
251
319
  selectUnitAndSubordinates: "Sélectionner une unité opérationnelle",
320
+ selectField: "Sélectionner un champ utilisateur",
321
+ noUserFields: "Cet objet n'a aucun champ utilisateur",
322
+ fieldNotUserTyped: "{{name}} — pas un champ utilisateur",
252
323
  },
253
324
  filterCondition: {
254
325
  selectObjectFirst: "Sélectionnez d'abord un objet.",
@@ -259,6 +330,26 @@ const fr = {
259
330
  editAsJson: "Modifier en JSON",
260
331
  useVisualBuilder: "Utiliser le constructeur visuel",
261
332
  },
333
+ object: {
334
+ invalidJson: "JSON invalide",
335
+ },
336
+ location: {
337
+ refusedFormat: "Non enregistré : saisissez une paire latitude, longitude (exemple : 30.2741, 120.1551).",
338
+ refusedRange: "Non enregistré : {{detail}}",
339
+ latitude: "latitude",
340
+ longitude: "longitude",
341
+ refusedResidueOne: "Non enregistré : {{name}} « {{text}} » n'est pas un nombre. Saisissez des décimales simples (exemple : 30.2741, 120.1551).",
342
+ refusedResidue: "Non enregistré : {{name}} « {{text}} » et {{otherName}} « {{otherText}} » ne sont pas des nombres. Saisissez des décimales simples (exemple : 30.2741, 120.1551).",
343
+ },
344
+ date: {
345
+ impossibleDay: "La valeur enregistrée « {{value}} » n’est pas une date réelle. Choisissez une date pour la remplacer.",
346
+ },
347
+ dateTime: {
348
+ impossibleDay: "La valeur enregistrée « {{value}} » n’est pas une date réelle. Choisissez une date et une heure pour la remplacer.",
349
+ },
350
+ number: {
351
+ badInput: "Non enregistré : le texte de ce champ n'est pas un nombre. Saisissez une décimale simple (exemple : {{example}}).",
352
+ },
262
353
  tags: {
263
354
  placeholder: "Saisissez puis appuyez sur Entrée pour ajouter…",
264
355
  },
@@ -274,6 +365,16 @@ const fr = {
274
365
  characterCount: "Nombre de caractères : {{count}} sur {{max}}",
275
366
  charactersRemaining: "Caractères restants : {{count}}",
276
367
  },
368
+ grid: {
369
+ addLine: "Ajouter une ligne",
370
+ noItems: "Aucun élément",
371
+ noItemsAddHint: "Aucun élément pour l'instant — cliquez sur « {{label}} » pour commencer.",
372
+ optionalColumns: "Colonnes facultatives",
373
+ computed: "Calculé",
374
+ openRow: "Ouvrir la ligne",
375
+ duplicateRow: "Dupliquer la ligne",
376
+ removeRow: "Supprimer la ligne",
377
+ },
277
378
  },
278
379
  table: {
279
380
  rowsPerPage: "Lignes par page",
@@ -302,23 +403,41 @@ const fr = {
302
403
  open: "Ouvrir",
303
404
  search: "Rechercher…",
304
405
  modified: "{{count}} ligne(s) modifiée(s)",
406
+ modified_one: "{{count}} ligne modifiée",
407
+ modified_many: "{{count}} de lignes modifiées",
408
+ modified_other: "{{count}} lignes modifiées",
305
409
  saveFailed: 'Échec de l’enregistrement',
306
410
  selected: "{{count}} sélectionné(s)",
411
+ selected_one: "{{count}} sélectionné",
412
+ selected_many: "{{count}} sélectionnés",
413
+ selected_other: "{{count}} sélectionnés",
307
414
  edit: "Modifier",
308
415
  delete: "Supprimer",
309
416
  },
310
417
  grid: {
311
418
  bulkSelected: "{{count}} sélectionné(s)",
419
+ bulkSelected_one: "{{count}} sélectionné",
420
+ bulkSelected_many: "{{count}} sélectionnés",
421
+ bulkSelected_other: "{{count}} sélectionnés",
312
422
  bulkSelectedAllMatches: "{{count}} sélectionné(s) (tous les résultats)",
313
423
  bulkClear: "Effacer",
314
424
  bulkAllOnPage: "Les {{count}} éléments de cette page sont sélectionnés.",
425
+ bulkAllOnPage_one: "{{count}} enregistrement de cette page est sélectionné.",
426
+ bulkAllOnPage_many: "Les {{count}} éléments de cette page sont sélectionnés.",
427
+ bulkAllOnPage_other: "Les {{count}} éléments de cette page sont sélectionnés.",
315
428
  bulkSelectAllMatching: "Sélectionner les {{count}} correspondances",
316
429
  bulkAllMatchingSelected: "Les {{count}} enregistrements correspondants sont tous sélectionnés.",
317
430
  bulk: {
318
431
  confirmDefault: "Ceci s'appliquera à {{count}} enregistrement(s).",
432
+ confirmDefault_one: "Ceci s'appliquera à {{count}} enregistrement.",
433
+ confirmDefault_many: "Ceci s'appliquera à {{count}} d'enregistrements.",
434
+ confirmDefault_other: "Ceci s'appliquera à {{count}} enregistrements.",
319
435
  overLimit: "La sélection ({{count}}) dépasse la limite de l'action ({{limit}}). Réduisez la sélection pour continuer.",
320
436
  affectedRecords: "Enregistrements concernés ({{count}}) :",
321
437
  skippedIneligible: '{{count}} des enregistrements sélectionnés ne sont pas éligibles à cette action et seront ignorés.',
438
+ skippedIneligible_one: "{{count}} des enregistrements sélectionnés n'est pas éligible à cette action et sera ignoré.",
439
+ skippedIneligible_many: '{{count}} des enregistrements sélectionnés ne sont pas éligibles à cette action et seront ignorés.',
440
+ skippedIneligible_other: '{{count}} des enregistrements sélectionnés ne sont pas éligibles à cette action et seront ignorés.',
322
441
  rowFallback: "Ligne {{index}}",
323
442
  andMore: "… et {{count}} de plus",
324
443
  processed: "{{count}} / {{total}} traités",
@@ -336,7 +455,6 @@ const fr = {
336
455
  undo: "Annuler",
337
456
  undoing: "Annulation…",
338
457
  done: "Terminé",
339
- selectPlaceholder: "Sélectionner…",
340
458
  loading: "Chargement…",
341
459
  },
342
460
  actions: "Actions",
@@ -355,6 +473,14 @@ const fr = {
355
473
  yes: "Oui",
356
474
  no: "Non",
357
475
  systemFields: "Système",
476
+ // objectui#10881 — the grouped grid's two refusals: over a data source
477
+ // that cannot answer the group header query, and over rows a host
478
+ // handed in while declaring them one page of more. `queryGroupHeaders`
479
+ // is the member's name and stays untranslated.
480
+ grouping: {
481
+ needsHeaderQuery: "Cette vue est groupée, mais sa source de données n'implémente pas queryGroupHeaders : les groupes ne peuvent donc pas être comptés. Supprimez le regroupement pour afficher les enregistrements.",
482
+ needsWholeRows: "Le regroupement a besoin de tous les enregistrements, mais cette grille n'en a reçu qu'une page : les groupes ne peuvent donc pas être comptés. Fournissez tous les enregistrements, ou laissez la grille les charger depuis une source de données qui implémente queryGroupHeaders.",
483
+ },
358
484
  // objectui#4024 — column-footer aggregate prefixes, keyed by the spec's
359
485
  // `ColumnSummary` vocabulary. `pattern` owns the label/value join so this
360
486
  // pack controls its own separator and word order.
@@ -381,10 +507,15 @@ const fr = {
381
507
  },
382
508
  import: {
383
509
  downloadTemplate: "Télécharger le modèle",
384
- downloadTemplateHint: "Obtenez un CSV avec les bonnes colonnes (les champs obligatoires sont marqués d'un *).",
510
+ downloadTemplateHint: "Obtenez un fichier Excel des colonnes importables (les champs obligatoires sont marqués d'un *), avec des instructions de saisie.",
385
511
  templateFileName: "{{object}}-import-template",
512
+ templateDownloadFailed: "Impossible de télécharger le modèle. Veuillez réessayer.",
513
+ templateNotPermitted: "Vous n'êtes pas autorisé à créer des enregistrements de cet objet, son modèle d'import n'est donc pas disponible.",
386
514
  autoMatched: "Associé automatiquement",
387
515
  autoMatchedSummary: "{{count}} colonne(s) associée(s) automatiquement — vérifiez et ajustez ci-dessous.",
516
+ autoMatchedSummary_one: "{{count}} colonne associée automatiquement — vérifiez et ajustez ci-dessous.",
517
+ autoMatchedSummary_many: "{{count}} de colonnes associées automatiquement — vérifiez et ajustez ci-dessous.",
518
+ autoMatchedSummary_other: "{{count}} colonnes associées automatiquement — vérifiez et ajustez ci-dessous.",
388
519
  confidence: {
389
520
  high: "Confiance élevée",
390
521
  medium: "Confiance moyenne",
@@ -397,8 +528,17 @@ const fr = {
397
528
  cancelImport: "Annuler l'import",
398
529
  importCancelled: "Import annulé",
399
530
  resultsTruncated: "Affichage des {{count}} premiers résultats de lignes (sur {{total}}).",
531
+ resultsTruncated_one: "Affichage du premier résultat de ligne ({{count}} sur {{total}}).",
532
+ resultsTruncated_many: "Affichage des {{count}} premiers résultats de lignes (sur {{total}}).",
533
+ resultsTruncated_other: "Affichage des {{count}} premiers résultats de lignes (sur {{total}}).",
400
534
  createdCount: "{{count}} créé(s)",
535
+ createdCount_one: "{{count}} créé",
536
+ createdCount_many: "{{count}} créés",
537
+ createdCount_other: "{{count}} créés",
401
538
  updatedCount: "{{count}} mis à jour",
539
+ updatedCount_one: "{{count}} mis à jour",
540
+ updatedCount_many: "{{count}} mis à jour",
541
+ updatedCount_other: "{{count}} mis à jour",
402
542
  downloadFailed: "Télécharger les lignes en échec",
403
543
  options: "Options d'import",
404
544
  writeMode: "Lorsqu'une ligne correspond à un enregistrement existant",
@@ -446,6 +586,9 @@ const fr = {
446
586
  historyColResult: "Résultat",
447
587
  historyColTime: "Quand",
448
588
  errorCount: "{{count}} erreurs",
589
+ errorCount_one: "{{count}} erreur",
590
+ errorCount_many: "{{count}} d'erreurs",
591
+ errorCount_other: "{{count}} erreurs",
449
592
  undoImport: "Annuler l'import",
450
593
  undoing: "Annulation…",
451
594
  undoConfirm: "Annuler cet import ? Les enregistrements créés seront supprimés et les enregistrements mis à jour seront rétablis à leurs valeurs précédentes.",
@@ -506,7 +649,13 @@ const fr = {
506
649
  mapped: "Mappé",
507
650
  skipped: "Ignoré",
508
651
  rowsWithErrors: "{{count}} ligne(s) avec des erreurs",
652
+ rowsWithErrors_one: "{{count}} ligne avec des erreurs",
653
+ rowsWithErrors_many: "{{count}} de lignes avec des erreurs",
654
+ rowsWithErrors_other: "{{count}} lignes avec des erreurs",
509
655
  rowsCorrected: "{{count}} ligne(s) corrigée(s)",
656
+ rowsCorrected_one: "{{count}} ligne corrigée",
657
+ rowsCorrected_many: "{{count}} de lignes corrigées",
658
+ rowsCorrected_other: "{{count}} lignes corrigées",
510
659
  clickToFix: "— cliquez sur une cellule mise en surbrillance pour modifier en ligne.",
511
660
  showingRows: "Affichage de {{shown}} sur {{total}} lignes",
512
661
  importing: "Importation… {{progress}}%",
@@ -514,11 +663,17 @@ const fr = {
514
663
  imported: "{{count}} importé(s)",
515
664
  skippedCount: "{{count}} ignoré(s)",
516
665
  moreErrors: "…et {{count}} erreur(s) de plus",
666
+ moreErrors_one: "…et {{count}} erreur de plus",
667
+ moreErrors_many: "…et {{count}} d'erreurs de plus",
668
+ moreErrors_other: "…et {{count}} erreurs de plus",
517
669
  cancel: "Annuler",
518
670
  back: "Retour",
519
671
  next: "Suivant",
520
672
  close: "Fermer",
521
673
  importNRows: "Importer {{count}} lignes",
674
+ importNRows_one: "Importer {{count}} ligne",
675
+ importNRows_many: "Importer {{count}} de lignes",
676
+ importNRows_other: "Importer {{count}} lignes",
522
677
  importingProgress: "Importation…",
523
678
  requiredMark: "*",
524
679
  required: "Obligatoire",
@@ -530,11 +685,38 @@ const fr = {
530
685
  month: "Mois",
531
686
  week: "Semaine",
532
687
  day: "Jour",
533
- agenda: "Agenda",
534
688
  allDay: "Toute la journée",
535
- noEvents: "Aucun événement",
536
689
  newEvent: "Nouvel événement",
537
690
  moreEvents: "+{{count}} de plus",
691
+ unscheduled: "Non planifié ({{count}})",
692
+ loading: "Chargement du calendrier…",
693
+ loadError: "Erreur : {{message}}",
694
+ configRequired: "Configuration du calendrier requise. Veuillez indiquer startDateField, la seule clé obligatoire du calendrier ; le titre de l'événement se résout sans titleField.",
695
+ configRequiredHint: "Elle appartient au bloc calendar de la vue. Une page d'interface n'a pas d'emplacement de calendrier propre : pointez son sourceView vers une vue qui en déclare un.",
696
+ eventDetails: "Détails de l'événement",
697
+ pullToRefresh: "Tirer pour actualiser",
698
+ refreshing: "Actualisation…",
699
+ onDate: "Le {{date}}",
700
+ eventTitle: "Titre",
701
+ eventTitlePlaceholder: "De quoi s'agit-il ?",
702
+ creating: "Création…",
703
+ titleRequired: "Le titre est obligatoire",
704
+ a11y: {
705
+ region: "Calendrier",
706
+ grid: "Grille du calendrier",
707
+ goToToday: "Aller à aujourd'hui",
708
+ previousPeriod: "Période précédente",
709
+ nextPeriod: "Période suivante",
710
+ currentDate: "Date actuelle : {{date}}",
711
+ dayCell: "{{date}}, {{count}} événements",
712
+ dayCell_one: "{{date}}, {{count}} événement",
713
+ dayCell_many: "{{date}}, {{count}} d'événements",
714
+ dayCell_other: "{{date}}, {{count}} événements",
715
+ resizeEventEnd: "Modifier la fin de l'événement",
716
+ resizeEventEndHint: "Faites glisser pour modifier la date de fin",
717
+ resizeStart: "Modifier le début",
718
+ resizeEnd: "Modifier la fin",
719
+ },
538
720
  },
539
721
  list: {
540
722
  firstRunTitle: "Rien pour l'instant",
@@ -577,7 +759,9 @@ const fr = {
577
759
  refresh: "Actualiser",
578
760
  loading: "Chargement des enregistrements…",
579
761
  recordCount: "{{count}} enregistrements",
580
- recordCountOne: "{{count}} enregistrement",
762
+ recordCount_one: "{{count}} enregistrement",
763
+ recordCount_many: "{{count}} d'enregistrements",
764
+ recordCount_other: "{{count}} enregistrements",
581
765
  addRecord: "Ajouter un enregistrement",
582
766
  tabs: "Onglets",
583
767
  allRecords: "Tous les enregistrements",
@@ -609,7 +793,7 @@ const fr = {
609
793
  hideFieldsTitle: "Masquer les champs",
610
794
  dataLimitReached: "Les {{limit}} premiers enregistrements sont affichés. Il peut y avoir plus de données disponibles.",
611
795
  viewSettings: "Paramètres de vue",
612
- viewSettingsHint: "Regroupement, couleur, densité et champs visibles.",
796
+ viewSettingsHint: "Regroupement, couleur, densité et champs visibles. S’applique à tous les utilisateurs de cette vue.",
613
797
  addGroup: "Ajouter un champ de groupe",
614
798
  collapsedByDefault: "Réduit par défaut",
615
799
  removeGroup: "Supprimer",
@@ -674,6 +858,17 @@ const fr = {
674
858
  },
675
859
  gantt: {
676
860
  rowLabel: "Éléments",
861
+ unusableRange: {
862
+ malformedDate: "Plage de dates du gantt inutilisable — {{path}} vaut {{value}}, ce qui n'est pas une date valide. Toutes les dates du gantt doivent être analysables : startDate et endDate de chaque élément de ligne, ainsi que tout minDate / maxDate fixé sur le schéma.",
863
+ malformedRow: "Lignes du gantt inutilisables — {{path}} vaut {{value}}, ce qui n'est pas la forme d'une ligne. Un gantt lit items comme une liste de lignes, chaque ligne comme un objet avec un label et ses propres items, et les items de chaque ligne comme une liste de barres ; un null, un nombre, une chaîne ou un objet simple à l'un de ces emplacements ne peut pas être dessiné.",
864
+ inverted: "Plage de dates du gantt inutilisable — minDate {{minDate}} est postérieur à maxDate {{maxDate}}. Un minDate / maxDate fixé l'emporte sur la plage calculée à partir des lignes ; cet axe n'a donc aucune colonne et aucune barre ne peut y être placée. Intervertissez les deux valeurs.",
865
+ },
866
+ },
867
+ unsupported: {
868
+ objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
869
+ },
870
+ unconfigured: {
871
+ noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
677
872
  },
678
873
  },
679
874
  gantt: {
@@ -691,6 +886,7 @@ const fr = {
691
886
  },
692
887
  aria: {
693
888
  taskList: "Liste des tâches",
889
+ refreshing: "Actualisation…",
694
890
  },
695
891
  tooltip: {
696
892
  days: "j",
@@ -736,13 +932,22 @@ const fr = {
736
932
  conflict: {
737
933
  title: "Conflit de planning",
738
934
  body: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche(s) concernée(s) ?",
935
+ body_one: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche concernée ?",
936
+ body_many: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} de tâches concernées ?",
937
+ body_other: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâches concernées ?",
739
938
  confirm: "Replanifier automatiquement",
740
939
  cancel: "Laisser tel quel",
741
940
  },
742
941
  autoScheduleDlg: {
743
942
  title: "Planification automatique",
744
943
  body: "Décaler {{count}} tâche(s) plus tard pour respecter les liens de dépendance ?",
944
+ body_one: "Décaler {{count}} tâche plus tard pour respecter les liens de dépendance ?",
945
+ body_many: "Décaler {{count}} de tâches plus tard pour respecter les liens de dépendance ?",
946
+ body_other: "Décaler {{count}} tâches plus tard pour respecter les liens de dépendance ?",
745
947
  skipped: "{{count}} tâche(s) verrouillée(s) violent aussi les liens et ont été ignorées.",
948
+ skipped_one: "{{count}} tâche verrouillée viole aussi les liens et a été ignorée.",
949
+ skipped_many: "{{count}} de tâches verrouillées violent aussi les liens et ont été ignorées.",
950
+ skipped_other: "{{count}} tâches verrouillées violent aussi les liens et ont été ignorées.",
746
951
  confirm: "Appliquer",
747
952
  cancel: "Annuler",
748
953
  none: "Toutes les dépendances sont respectées — rien à replanifier.",
@@ -821,6 +1026,7 @@ const fr = {
821
1026
  tabActionsFor: "Actions de vue pour {{name}}",
822
1027
  readonlyAriaLabel: "Vue en lecture seule",
823
1028
  readonlyTooltip: "Vue système — définie dans le code, en lecture seule.",
1029
+ malformedFilter: "Le filtre de cette vue est incorrect, aucun enregistrement n’est donc affiché : la condition {{subject}} ne peut pas être appliquée.",
824
1030
  },
825
1031
  designer: {
826
1032
  undo: "Annuler",
@@ -848,7 +1054,9 @@ const fr = {
848
1054
  pageHeaderActions: "Actions de l'en-tête de page",
849
1055
  emojiPicker: "Sélecteur d'émojis",
850
1056
  reactionCount: "{{emoji}} {{count}} réactions",
851
- reactionCountOne: "{{emoji}} {{count}} réaction",
1057
+ reactionCount_one: "{{emoji}} {{count}} réaction",
1058
+ reactionCount_many: "{{emoji}} {{count}} de réactions",
1059
+ reactionCount_other: "{{emoji}} {{count}} réactions",
852
1060
  recordDetail: "Détail de l'enregistrement",
853
1061
  recordDetailWithLabel: "Détail — {{label}}",
854
1062
  openAsFullPage: "Ouvrir en pleine page",
@@ -875,7 +1083,6 @@ const fr = {
875
1083
  viewAll: "Tout afficher",
876
1084
  new: "Nouveau",
877
1085
  add: "Ajouter",
878
- emptyValue: "—",
879
1086
  comments: "Commentaires",
880
1087
  searchComments: "Rechercher des commentaires…",
881
1088
  addCommentPlaceholder: "Ajouter un commentaire… (Ctrl+Entrée pour envoyer)",
@@ -886,11 +1093,22 @@ const fr = {
886
1093
  unpin: "Désépingler",
887
1094
  justNow: "à l'instant",
888
1095
  minutesAgo: "il y a {{count}} min",
1096
+ minutesAgo_one: "il y a {{count}} min",
1097
+ minutesAgo_many: "il y a {{count}} min",
1098
+ minutesAgo_other: "il y a {{count}} min",
889
1099
  hoursAgo: "il y a {{count}} h",
1100
+ hoursAgo_one: "il y a {{count}} h",
1101
+ hoursAgo_many: "il y a {{count}} h",
1102
+ hoursAgo_other: "il y a {{count}} h",
890
1103
  daysAgo: "il y a {{count}} j",
1104
+ daysAgo_one: "il y a {{count}} j",
1105
+ daysAgo_many: "il y a {{count}} j",
1106
+ daysAgo_other: "il y a {{count}} j",
891
1107
  dropFilesToUpload: "Déposez les fichiers ici ou cliquez pour télécharger",
892
1108
  attachmentCount: "{{count}} pièce jointe",
893
- attachmentCountPlural: "{{count}} pièces jointes",
1109
+ attachmentCount_one: "{{count}} pièce jointe",
1110
+ attachmentCount_many: "{{count}} de pièces jointes",
1111
+ attachmentCount_other: "{{count}} pièces jointes",
894
1112
  removeAttachment: "Supprimer la pièce jointe",
895
1113
  // Record Attachments panel (enable.files, objectstack#4358)
896
1114
  attachments: "Pièces jointes",
@@ -908,11 +1126,6 @@ const fr = {
908
1126
  attachmentsLoadFailed: "Impossible de charger les pièces jointes de cet enregistrement.",
909
1127
  attachmentsApiUnavailable: "La liste des pièces jointes n'est pas disponible sur cet objet.",
910
1128
  retryLoadAttachments: "Réessayer",
911
- unifiedDiff: "Vue unifiée",
912
- sideBySideDiff: "Vue côte à côte",
913
- noChanges: "Aucune modification",
914
- previousVersion: "Précédent",
915
- currentVersion: "Actuel",
916
1129
  discussion: "Discussion",
917
1130
  showDiscussion: "Afficher la discussion ({{count}})",
918
1131
  hideDiscussion: "Masquer la discussion",
@@ -927,25 +1140,36 @@ const fr = {
927
1140
  writeComment: "Écrire un commentaire…",
928
1141
  subscribedTooltip: "Abonné — cliquez pour vous désabonner",
929
1142
  unsubscribedTooltip: "S'abonner aux notifications",
930
- firstRecord: "Premier enregistrement (Début)",
931
- previousRecordKey: "Enregistrement précédent (←)",
932
- nextRecordKey: "Enregistrement suivant (→)",
933
- lastRecord: "Dernier enregistrement (Fin)",
934
1143
  noRecords: "Aucun enregistrement",
935
- searchWhileNavigating: "Rechercher pendant la navigation",
936
- searchRecords: "Rechercher des enregistrements…",
937
1144
  allActivity: "Toute l'activité",
938
1145
  commentsOnly: "Commentaires uniquement",
939
1146
  fieldChangesFilter: "Modifications de champs",
940
1147
  tasksOnly: "Tâches uniquement",
941
1148
  leaveCommentPlaceholder: "Laisser un commentaire… (Ctrl+Entrée pour envoyer)",
942
1149
  noActivity: "Aucune activité enregistrée",
1150
+ activityAccessDenied: "Vous n'avez pas l'autorisation de consulter l'activité de cet enregistrement.",
1151
+ commentsAccessDenied: "Vous n'avez pas l'autorisation de consulter les commentaires de cet enregistrement.",
1152
+ // objectui#7149 — the rest of `ActivityTimeline`. The four chip labels the
1153
+ // `detail.*` pack did not already name, and the `formatFieldChange`
1154
+ // sentences, which are assembled in code and so need interpolation holes.
1155
+ allFilter: 'Tout',
1156
+ createsFilter: 'Créations',
1157
+ deletesFilter: 'Suppressions',
1158
+ statusChangesFilter: 'Changements de statut',
1159
+ activityEmptyValue: '(vide)',
1160
+ activityFieldChanged: '{{field}} modifié de « {{old}} » à « {{new}} »',
1161
+ activityCreated: 'A créé cet enregistrement',
1162
+ activityDeleted: 'A supprimé cet enregistrement',
1163
+ activityStatusChanged: 'A changé le statut en « {{value}} »',
1164
+ activityUpdated: 'A mis à jour l\'enregistrement',
943
1165
  loadMore: "Charger plus",
944
1166
  edited: "(modifié)",
945
1167
  via: "via {{source}}",
946
1168
  viewSource: "Voir la source",
947
1169
  replyCount: "{{count}} réponse",
948
- replyCountPlural: "{{count}} réponses",
1170
+ replyCount_one: "{{count}} réponse",
1171
+ replyCount_many: "{{count}} de réponses",
1172
+ replyCount_other: "{{count}} réponses",
949
1173
  replyPlaceholder: "Répondre…",
950
1174
  filterActivity: "Filtrer l'activité",
951
1175
  openDiscussion: "Ouvrir le panneau de discussion",
@@ -960,6 +1184,7 @@ const fr = {
960
1184
  writeStrippedReadonly: "En lecture seule, donc non appliqué : {{fields}}",
961
1185
  writeStrippedByState: "Non modifiable dans l'état actuel de cet enregistrement, donc non appliqué : {{fields}}",
962
1186
  writeStrippedPrimaryKey: "L'identifiant de l'enregistrement ne peut pas être modifié lors d'un enregistrement, donc non appliqué : {{fields}}",
1187
+ writeStrippedComputed: "Calculé par le serveur à partir d'une formule, donc la valeur envoyée n'a pas été appliquée : {{fields}}",
963
1188
  writeStrippedUnknownReason: "Non appliqué par le serveur : {{fields}}",
964
1189
  approvalPendingEditable: "En approbation · modifiable",
965
1190
  approvalPendingTooltip: "Cet enregistrement a une demande d'approbation en attente ; cette étape autorise encore la modification",
@@ -981,6 +1206,8 @@ const fr = {
981
1206
  pathStageLostUpcoming: '{{stage}}, perdue, non atteinte',
982
1207
  pathStageWonUpcoming: '{{stage}}, étape objectif, non atteinte',
983
1208
  linkCopied: "Lien copié dans le presse-papiers",
1209
+ commentFailed: "Votre commentaire n'a pas été publié. Rien n'a été enregistré — veuillez réessayer.",
1210
+ reactionFailed: "Votre réaction n'a pas été enregistrée. Veuillez réessayer.",
984
1211
  linkCopyFailed: "Impossible de copier le lien",
985
1212
  cancel: "Annuler",
986
1213
  cancelEdit: "Abandonner les modifications",
@@ -1010,39 +1237,68 @@ const fr = {
1010
1237
  sortBy: "Trier par",
1011
1238
  filterPlaceholder: "Filtrer…",
1012
1239
  highlightFields: "Champs clés",
1240
+ highlightsLabel: "Champs clés de l'enregistrement",
1013
1241
  createdBy: "Créé par",
1014
1242
  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).
1243
+ // objectui#3863 — base key, answering only a call made without a count. fr's
1244
+ // third category, `many` (exact millions), has its own slot since objectui#11432;
1245
+ // here it repeats `_other` because the count governs no noun ("de" goes before a
1246
+ // noun complement, and this label has none).
1019
1247
  showEmptyRelated: "+ {{count}} vides",
1020
1248
  showEmptyRelated_one: "+ {{count}} vide",
1249
+ showEmptyRelated_many: "+ {{count}} vides",
1021
1250
  showEmptyRelated_other: "+ {{count}} vides",
1022
1251
  copyEmail: "Copier l'e-mail",
1023
1252
  copyPhone: "Copier le téléphone",
1024
1253
  copyRecordId: "Copier l'ID",
1025
1254
  showEmptyFields: "Afficher {{count}} champs vides",
1255
+ showEmptyFields_one: "Afficher {{count}} champ vide",
1256
+ showEmptyFields_many: "Afficher {{count}} de champs vides",
1257
+ showEmptyFields_other: "Afficher {{count}} champs vides",
1026
1258
  hideEmptyFields: "Masquer les champs vides",
1027
1259
  noValue: "Aucune valeur",
1260
+ unresolvedReference: "Référence non résolue : {{value}} n'a pas été résolue en utilisateur",
1261
+ unresolvedLookupReference: "Référence non résolue : {{value}} n'a pas été résolue en enregistrement sur cet écran",
1262
+ repeaterItemCount: "{{count}} éléments",
1263
+ repeaterItemCount_one: "{{count}} élément",
1264
+ repeaterItemCount_many: "{{count}} d'éléments",
1265
+ repeaterItemCount_other: "{{count}} éléments",
1266
+ fileCount: "{{count}} fichiers",
1267
+ fileCount_one: "{{count}} fichier",
1268
+ fileCount_many: "{{count}} de fichiers",
1269
+ fileCount_other: "{{count}} fichiers",
1028
1270
  },
1029
1271
  chart: {
1030
- noData: "Aucune donnée de graphique disponible",
1031
1272
  loading: "Chargement du graphique…",
1273
+ refreshing: "Actualisation…",
1032
1274
  nullCategory: "(Non défini)",
1033
- },
1034
- map: {
1035
- searchLocations: "Rechercher des lieux…",
1036
- locationDetails: "Détails du lieu",
1037
- markersCount: "{{count}} marqueurs",
1038
- invalidCoordinates: "{{count}} enregistrement avec des coordonnées manquantes ou invalides exclu de la carte.",
1039
- invalidCoordinatesPlural: "{{count}} enregistrements avec des coordonnées manquantes ou invalides exclus de la carte.",
1275
+ scatterOneMeasure: "Un nuage de points trace une seule mesure. Ne conservez qu’une série :",
1276
+ unconfigured: {
1277
+ noCategoryAxis: "Axe de catégories requis — un graphique lié à un objet n’en invente pas. Déclarez l’un des suivants :",
1278
+ },
1040
1279
  },
1041
1280
  dashboard: {
1042
- noRows: "Aucune ligne",
1281
+ // objectui#7063 — the DEFAULT empty state every dashboard widget renders
1282
+ // when its query SUCCEEDED and returned nothing. It replaced the terse
1283
+ // per-widget `noRows` / `noDataAvailable` fragments at the render site;
1284
+ // objectui#7125 deleted those two keys from all ten packs once nothing
1285
+ // read them. The copy here has to read as a state rather than a failure,
1286
+ // which is why it says the widget loaded. `sourceLabel` carries its own
1287
+ // punctuation so the call site concatenates no separator (see
1288
+ // `WidgetEmptyState`).
1289
+ empty: {
1290
+ title: "Pas encore de données",
1291
+ message: "Ce widget s'est chargé correctement, mais la requête n'a encore renvoyé aucun enregistrement.",
1292
+ sourceLabel: "Source de données :",
1293
+ },
1043
1294
  loading: "Chargement…",
1295
+ refreshing: "Actualisation…",
1296
+ refreshAll: "Tout actualiser",
1297
+ refreshDashboard: "Actualiser le tableau de bord",
1044
1298
  pickMeasures: "Choisissez des mesures (valeurs) pour ce widget de dataset.",
1045
1299
  datasetUnsupported: "Cette source de données ne prend pas en charge les requêtes de dataset.",
1300
+ widgetForbiddenTitle: "Accès refusé",
1301
+ widgetForbiddenMessage: "Vous n’avez pas l’autorisation de voir les données de ce widget.",
1046
1302
  details: "Détails",
1047
1303
  exportCsv: "Exporter en CSV",
1048
1304
  openInList: "Ouvrir dans la liste",
@@ -1070,12 +1326,10 @@ const fr = {
1070
1326
  },
1071
1327
  },
1072
1328
  addWidget: "Ajouter un widget",
1073
- removeWidget: "Supprimer un widget",
1074
1329
  editLayout: "Modifier la mise en page",
1075
1330
  saveLayout: "Enregistrer la mise en page",
1076
1331
  resetLayout: "Réinitialiser la mise en page",
1077
1332
  total: "Total",
1078
- noDataAvailable: "Aucune donnée disponible",
1079
1333
  noDataSourceFor: "Aucune source de données pour",
1080
1334
  config: {
1081
1335
  breadcrumb: {
@@ -1197,10 +1451,6 @@ const fr = {
1197
1451
  appDescription: "Description",
1198
1452
  appIcon: "Icône",
1199
1453
  template: "Modèle",
1200
- layout: "Disposition",
1201
- layoutSidebar: "Barre latérale",
1202
- layoutHeader: "En-tête",
1203
- layoutEmpty: "Vide",
1204
1454
  selectObjects: "Sélectionner des objets",
1205
1455
  searchObjects: "Rechercher des objets…",
1206
1456
  selectAll: "Tout sélectionner",
@@ -1209,7 +1459,6 @@ const fr = {
1209
1459
  addGroup: "Ajouter un groupe",
1210
1460
  addUrl: "Ajouter une URL",
1211
1461
  addSeparator: "Ajouter un séparateur",
1212
- noNavItems: "Aucun élément de navigation pour l'instant.",
1213
1462
  logoUrl: "URL du logo",
1214
1463
  primaryColor: "Couleur principale",
1215
1464
  faviconUrl: "URL du favicon",
@@ -1236,13 +1485,12 @@ const fr = {
1236
1485
  appearance: "Apparence",
1237
1486
  rowHeight: "Hauteur de ligne",
1238
1487
  livePreview: "Aperçu en direct",
1239
- stepBasicDesc: "Nom, titre et mise en page",
1488
+ stepBasicDesc: "Nom, titre et icône",
1240
1489
  stepObjectsDesc: "Sélectionner les objets métier",
1241
1490
  stepNavigationDesc: "Construire l'arbre de navigation",
1242
1491
  stepBrandingDesc: "Logo, couleurs et favicon",
1243
1492
  noObjectsFound: "Aucun objet trouvé.",
1244
1493
  noNavItemsHint: "Pas encore d'éléments de navigation. Sélectionnez des objets à l'étape précédente ou ajoutez-en manuellement.",
1245
- separator: "Séparateur",
1246
1494
  separatorLabel: "— Séparateur —",
1247
1495
  newGroup: "Nouveau groupe",
1248
1496
  newLink: "Nouveau lien",
@@ -1276,6 +1524,7 @@ const fr = {
1276
1524
  navTypeSeparator: "Séparateur",
1277
1525
  navTypeAction: "Action",
1278
1526
  navTypeComponent: "Composant",
1527
+ navTypeDoc: "Document",
1279
1528
  navEditIcon: "Modifier l'icône",
1280
1529
  navToggleVisible: "Basculer la visibilité",
1281
1530
  navHidden: "Masqué",
@@ -1353,11 +1602,8 @@ const fr = {
1353
1602
  defaultValue: "Valeur par défaut",
1354
1603
  placeholder: "Espace réservé",
1355
1604
  referenceTo: "Référence à",
1356
- formula: "Formule",
1357
1605
  options: "Options",
1358
1606
  addOption: "Ajouter une option",
1359
- validationRules: "Règles de validation",
1360
- addRule: "Ajouter une règle",
1361
1607
  systemBadge: "Système",
1362
1608
  ungrouped: "Général",
1363
1609
  deleteConfirmTitle: "Supprimer le champ ?",
@@ -1376,7 +1622,23 @@ const fr = {
1376
1622
  },
1377
1623
  },
1378
1624
  console: {
1625
+ studio: {
1626
+ backToHome: "Retour à l'accueil",
1627
+ },
1379
1628
  saveAdvisoryTitle: "Enregistré — le contrôle de création a signalé {{count}} recommandation(s)",
1629
+ saveAdvisoryTitle_one: "Enregistré — le contrôle de création a signalé {{count}} recommandation",
1630
+ saveAdvisoryTitle_many: "Enregistré — le contrôle de création a signalé {{count}} de recommandations",
1631
+ saveAdvisoryTitle_other: "Enregistré — le contrôle de création a signalé {{count}} recommandations",
1632
+ publishAdvisoryTitle: "Publié — le contrôle de création a signalé {{count}} recommandation(s)",
1633
+ publishAdvisoryTitle_one: "Publié — le contrôle de création a signalé {{count}} recommandation",
1634
+ publishAdvisoryTitle_many: "Publié — le contrôle de création a signalé {{count}} de recommandations",
1635
+ publishAdvisoryTitle_other: "Publié — le contrôle de création a signalé {{count}} recommandations",
1636
+ importMappingsUnavailable: "Impossible de charger les mappages d’import enregistrés pour {{object}}",
1637
+ importMappingsRefused: "Le serveur a refusé cette requête : cette liste est donc vide parce qu’elle n’a pas pu être lue, et non parce que rien n’est enregistré. Reconnectez-vous ou demandez un accès à un administrateur.",
1638
+ importMappingsUnreadable: "Cette liste est vide parce qu’elle n’a pas pu être lue, et non parce que rien n’est enregistré. Réessayez, et signalez le problème s’il persiste.",
1639
+ savedViewsUnavailable: "Impossible de charger les vues enregistrées pour {{object}}",
1640
+ savedViewsRefused: "Le serveur a refusé cette requête : cette liste est donc vide parce qu’elle n’a pas pu être lue, et non parce que cet objet n’aurait aucune vue enregistrée. Reconnectez-vous ou demandez un accès à un administrateur.",
1641
+ savedViewsUnreadable: "Cette liste est vide parce qu’elle n’a pas pu être lue, et non parce que cet objet n’aurait aucune vue enregistrée. Réessayez, et signalez le problème s’il persiste.",
1380
1642
  settingsHub: {
1381
1643
  title: "Paramètres",
1382
1644
  subtitle: "Configurez votre espace de travail, vos intégrations et vos indicateurs de fonctionnalité.",
@@ -1437,9 +1699,18 @@ const fr = {
1437
1699
  statusFull: "Limite atteinte",
1438
1700
  resetsDaily: "Réinitialisation ce soir",
1439
1701
  resetsMonthly: "Réinitialisation au prochain cycle",
1702
+ resetsWeeklyDays: "Réinitialisation dans {{count}} jours",
1703
+ resetsWeeklyDays_one: "Réinitialisation dans {{count}} jour",
1704
+ resetsWeeklyDays_many: "Réinitialisation dans {{count}} de jours",
1705
+ resetsWeeklyDays_other: "Réinitialisation dans {{count}} jours",
1706
+ resetsWeeklyHours: "Réinitialisation dans {{count}} heures",
1707
+ resetsWeeklyHours_one: "Réinitialisation dans {{count}} heure",
1708
+ resetsWeeklyHours_many: "Réinitialisation dans {{count}} d'heures",
1709
+ resetsWeeklyHours_other: "Réinitialisation dans {{count}} heures",
1440
1710
  ctaUpgrade: "Passer à l'offre supérieure pour continuer",
1441
1711
  ctaTopUp: "Ajouter des crédits pour continuer",
1442
1712
  ariaLabel: "Utilisation de l'IA : {{status}}",
1713
+ breakdownTitle: "Utilisé jusqu'à présent",
1443
1714
  },
1444
1715
  workspaceTitle: "Espace de travail IA",
1445
1716
  workspaceSubtitle: "Posez des questions, inspectez et reprenez vos conversations",
@@ -1449,6 +1720,31 @@ const fr = {
1449
1720
  share: "Partager",
1450
1721
  shareTitle: "Partager cette conversation",
1451
1722
  shareDisabledTitle: "Commencez à discuter pour activer le partage",
1723
+ buildDoctor: "Diagnostic de build",
1724
+ buildDoctorTitle: "Diagnostic de build — qu'est-ce qui a réellement été appliqué ?",
1725
+ buildDoctorDisabledTitle: "Envoyez d'abord un message",
1726
+ buildDoctorDrawer: {
1727
+ description: "Ce que l'agent a annoncé face à ce qui est réellement en ligne. Diagnostic en lecture seule.",
1728
+ reconciling: 'Rapprochement…',
1729
+ notAvailable: "Non disponible — la conversation est introuvable ou vous n'êtes pas autorisé.",
1730
+ untitled: '(sans titre)',
1731
+ summary: '{{turns}} tour(s) · {{messages}} msg · {{tokens}} jetons · {{seconds}} s LLM',
1732
+ allLive: "Les {{count}} modification(s) tentée(s) sont en ligne — rien ne s'est perdu.",
1733
+ discrepancies: '{{count}} écart(s) — ce que le chat a annoncé ne correspond pas à ce qui est en ligne.',
1734
+ orphanedTitle: 'Proposé mais jamais appliqué',
1735
+ orphanedHint: "Une carte de confirmation proposée par l'agent qu'aucun tour ultérieur n'a appliquée — la modification s'est perdue silencieusement.",
1736
+ missingTitle: 'Annoncé mais absent',
1737
+ missingHint: "Un résultat d'outil indiquait une application, mais l'artefact n'est pas en ligne dans sys_metadata.",
1738
+ toolErrorsTitle: "Erreurs d'outils",
1739
+ toolErrorsHint: "Appels d'outils ayant renvoyé une erreur pendant le build.",
1740
+ verifyTitle: 'Vérification du build (verify_build)',
1741
+ yourApp: 'Votre application :',
1742
+ noIssues: '0 problème',
1743
+ issueCount: '{{count}} problème(s)',
1744
+ platformNoise: '{{count}} constat(s) sys_* de la plateforme masqué(s)',
1745
+ pendingActions: 'Actions en attente',
1746
+ timeline: 'Chronologie ({{count}})',
1747
+ },
1452
1748
  newChat: "Nouveau",
1453
1749
  searchChats: "Rechercher des discussions…",
1454
1750
  noChatsYet: "Aucune discussion pour l'instant",
@@ -1478,7 +1774,7 @@ const fr = {
1478
1774
  empty: {
1479
1775
  build: {
1480
1776
  title: "Créer avec l'IA",
1481
- description: "Décrivez une application ou un flux de travail en langage courant — je rédige les objets, les écrans et les automatisations, puis vous vérifiez et publiez.",
1777
+ description: "Décrivez une application en langage courant — je rédige les objets, les écrans et les données d'exemple, puis vous vérifiez et publiez.",
1482
1778
  },
1483
1779
  ask: {
1484
1780
  title: "Interroger vos données",
@@ -1487,7 +1783,7 @@ const fr = {
1487
1783
  editApp: {
1488
1784
  title: "Modification de « {{app}} »",
1489
1785
  titleGeneric: "Modifier cette application",
1490
- description: "Que souhaitez-vous changer ? Je modifie cette application sur place — ajouter un champ, un objet, une vue ou une automatisation, ou ajuster l'existant.",
1786
+ description: "Que souhaitez-vous changer ? Je modifie cette application sur place — ajouter un champ, un objet, une vue ou un tableau de bord, ou ajuster l'existant.",
1491
1787
  },
1492
1788
  },
1493
1789
  clearConversation: "Effacer",
@@ -1540,23 +1836,41 @@ const fr = {
1540
1836
  recentRecords: "Liste les 5 enregistrements créés le plus récemment.",
1541
1837
  recordCounts: "Compte les enregistrements pour chaque objet.",
1542
1838
  },
1839
+ // cloud#1984 — these five chips are the maker's own recommendations, so
1840
+ // they may only ask for what ADR-0112 v1 BUILDS: objects, fields, views
1841
+ // (grid/kanban/calendar/gallery), pages, dashboards and sample data. No
1842
+ // wording that promises autonomous behaviour (alert / remind / notify /
1843
+ // automate / status workflow) — v1 has no flows, actions or schedules, and
1844
+ // the model silently degrades such a request into a board or a filtered
1845
+ // view, so the chip would promise an alert and deliver a page. REVERT to
1846
+ // the automation wording when ADR-0112 v2 re-adds flows and actions.
1543
1847
  metadataAssistant: {
1544
- buildCrm: "Crée un CRM commercial — clients, contacts et un pipeline d'affaires que je peux totaliser par étape.",
1545
- buildApp: "Crée un suivi de projets — projets, tâches avec responsables et échéances, et un tableau par statut.",
1546
- buildFlow: "Conçois un service d'assistance — tickets avec priorité, un flux de statuts et des liens vers les clients.",
1547
- buildInventory: "Crée une application de stock — produits, niveaux de stock, fournisseurs et visibilité des stocks faibles.",
1548
- buildRecruiting: "Crée un suivi de candidatures — candidats, postes ouverts, étapes d'entretien et notes.",
1848
+ buildCrm: "Crée un CRM commercial — clients, contacts et affaires avec un champ étape, plus un tableau de bord qui totalise le montant par étape.",
1849
+ buildApp: "Crée un suivi de projets — projets, tâches avec responsables et échéances, un tableau par statut et un calendrier des échéances.",
1850
+ buildFlow: "Conçois un service d'assistance — tickets avec des champs priorité et statut, un tableau par statut et des liens vers les clients.",
1851
+ buildInventory: "Crée une application de stock — produits, niveaux de stock, fournisseurs et une vue qui filtre les articles sous leur seuil de réapprovisionnement.",
1852
+ buildRecruiting: "Crée un suivi de candidatures — candidats, postes ouverts, un champ étape d'entretien et un tableau par étape.",
1549
1853
  },
1550
1854
  generic: {
1551
1855
  help: "En quoi peux-tu m'aider ?",
1552
1856
  availableObjects: "Liste les objets de données disponibles.",
1553
1857
  recentActivity: "Résume mon activité récente.",
1554
1858
  },
1859
+ // objectui#7709 — the edit-mode starters, shown when the maker is bound
1860
+ // to an EXISTING app (`?package=`). Same rule as the five above: they
1861
+ // may only ask for what ADR-0112 v1 BUILDS. The fourth chip used to be
1862
+ // `addAutomation` ("an approval, a status flow, or a notification") and
1863
+ // every capability it named is refused by v1 (cloud#1956 / PR #1970), so
1864
+ // it now asks for sample data — `seed` IS on v1's whitelist, and having
1865
+ // no data is what an existing app most often lacks. REVERT: when
1866
+ // ADR-0112 v2 re-adds flows and actions, THIS chip's automation wording
1867
+ // comes back as `addAutomation`; the retired string is pinned for every
1868
+ // pack in `packages/i18n/src/__tests__/makerEditChips-v1-scope-7709.test.ts`.
1555
1869
  editApp: {
1556
1870
  addField: "Ajoute un champ à l'un des objets.",
1557
1871
  addObject: "Ajoute un nouvel objet et relie-le à un objet existant.",
1558
1872
  addDashboard: "Ajoute un tableau de bord pour les indicateurs clés.",
1559
- addAutomation: "Ajoute une automatisation — une approbation, un flux de statuts ou une notification.",
1873
+ addSampleData: "Remplis les objets existants avec des données d'exemple réalistes pour que je puisse présenter l'application.",
1560
1874
  },
1561
1875
  },
1562
1876
  changesTitle: "Confirmer les modifications",
@@ -1638,6 +1952,13 @@ const fr = {
1638
1952
  pages: "Pages",
1639
1953
  reports: "Rapports",
1640
1954
  system: "Système",
1955
+ marketplace: "Marketplace",
1956
+ settings: 'Paramètres',
1957
+ apps: 'Applications',
1958
+ profile: 'Profil',
1959
+ approvals: 'Approbations',
1960
+ aiApprovals: 'Approbations IA',
1961
+ auditLog: "Journal d'audit",
1641
1962
  },
1642
1963
  // objectui#4024 — the single-namespace settings screen. Its sibling
1643
1964
  // `settingsHub` above already resolved through this pack; the view was the
@@ -1657,6 +1978,7 @@ const fr = {
1657
1978
  saveChanges: "Enregistrer les modifications",
1658
1979
  unsavedCount: "{{count}} modifications non enregistrées",
1659
1980
  unsavedCount_one: "{{count}} modification non enregistrée",
1981
+ unsavedCount_many: "{{count}} de modifications non enregistrées",
1660
1982
  unsavedCount_other: "{{count}} modifications non enregistrées",
1661
1983
  cryptoRefusalTitle: "Ce déploiement ne peut pas chiffrer les secrets",
1662
1984
  cryptoRefusalSubjectSuffix: "est déclaré chiffré, aucune écriture n'a donc eu lieu.",
@@ -1729,6 +2051,21 @@ const fr = {
1729
2051
  records: "Enregistrements",
1730
2052
  recentRecords: "Récemment consultés",
1731
2053
  },
2054
+ // objectui#9954 — see the `en` pack for what raises each case.
2055
+ readRate: {
2056
+ ratioTitle: 'Volume de lecture inhabituel dans cet environnement',
2057
+ ratio: '{{ratio}} lignes sont lues pour chaque ligne écrite. La plateforme signale tout ce qui dépasse {{threshold}}. Rien n’est limité ni bloqué ; il s’agit d’un rapport permettant d’examiner le schéma de lecture.',
2058
+ noWritesTitle: 'Lectures sans aucune écriture dans cet environnement',
2059
+ noWrites: 'Des lignes sont lues alors qu’aucune n’est écrite, de sorte que le taux de lecture n’a aucune limite supérieure. C’est la mesure la plus grave. La plateforme signale tout ce qui dépasse {{threshold}}. Rien n’est limité ni bloqué ; il s’agit d’un rapport permettant d’examiner le schéma de lecture.',
2060
+ },
2061
+ // objectui#10439 — see the `en` pack for what raises each case.
2062
+ storageUsage: {
2063
+ warningTitle: 'Le stockage est presque plein',
2064
+ warning: '{{used}} Mo sur {{limit}} Mo utilisés. Les envois et les importations sont suspendus dès que le stockage est plein.',
2065
+ blockedTitle: 'Stockage plein : les envois et les importations sont suspendus',
2066
+ blocked: "{{used}} Mo sur {{limit}} Mo utilisés. Les données existantes ne sont pas modifiées, et la lecture, l'export et la modification d'enregistrements individuels fonctionnent toujours.",
2067
+ upgrade: "Passer à l'offre supérieure pour continuer",
2068
+ },
1732
2069
  errors: {
1733
2070
  somethingWentWrong: "Quelque chose s'est mal passé",
1734
2071
  unexpectedError: "Une erreur inattendue est survenue lors du rendu de cette vue.",
@@ -1759,6 +2096,7 @@ const fr = {
1759
2096
  viewNameInvalid: "Utilisez des minuscules, des chiffres et des tirets bas ; commencez par une lettre ou un tiret bas.",
1760
2097
  systemViewReadonly: "Vue système définie dans le code — en lecture seule.",
1761
2098
  cannotEditMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être modifiée.",
2099
+ viewConfigPermissionDenied: "Les paramètres de vue s’appliquent à tous les utilisateurs de cette vue ; les modifier requiert donc l’autorisation « Gérer les métadonnées ». Demandez à un administrateur d’effectuer ce changement.",
1762
2100
  cannotDeleteMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être supprimée.",
1763
2101
  expandToPage: "Ouvrir en pleine page",
1764
2102
  objectNotFound: "Objet introuvable",
@@ -1769,12 +2107,14 @@ const fr = {
1769
2107
  allRecords: "Tous les enregistrements",
1770
2108
  new: "Nouveau",
1771
2109
  configureView: "Configurer la vue",
1772
- toolbar: "Barre d'outils",
1773
2110
  toolbarEnabledCount: "{{count}} sur {{total}} activés",
1774
2111
  searchFields: "Rechercher des champs…",
1775
2112
  title: "Titre",
1776
2113
  viewType: "Type de vue",
1777
2114
  recordCount: "{{count}} enregistrements",
2115
+ recordCount_one: "{{count}} enregistrement",
2116
+ recordCount_many: "{{count}} d'enregistrements",
2117
+ recordCount_other: "{{count}} enregistrements",
1778
2118
  save: "Enregistrer",
1779
2119
  discard: "Annuler",
1780
2120
  createView: "Créer une vue",
@@ -1786,11 +2126,13 @@ const fr = {
1786
2126
  longitudeField: "Champ de longitude",
1787
2127
  imageField: "Champ d'image",
1788
2128
  selectField: "Sélectionner un champ…",
1789
- groupBy: "Regrouper par",
1790
2129
  endDateField: "Champ de date de fin",
1791
2130
  import: "Importer",
1792
2131
  importTitle: "Importer depuis CSV",
1793
2132
  importedToast: "{{count}} ligne(s) importée(s).",
2133
+ importedToast_one: "{{count}} ligne importée.",
2134
+ importedToast_many: "{{count}} de lignes importées.",
2135
+ importedToast_other: "{{count}} lignes importées.",
1794
2136
  importedWithSkipped: "{{ok}} ligne(s) importée(s) ; {{skipped}} ignorée(s).",
1795
2137
  createViewDesc: "Choisissez un type de vue et donnez-lui un nom. Tous les paramètres peuvent être modifiés ensuite.",
1796
2138
  cancel: "Annuler",
@@ -1799,6 +2141,9 @@ const fr = {
1799
2141
  deleteViewTitle: "Supprimer la vue",
1800
2142
  deleteViewConfirm: "Supprimer la vue \"{{name}}\" ? Ceci est irréversible.",
1801
2143
  bulkDeleteConfirm: "Supprimer {{count}} enregistrements sélectionnés ? Ceci est irréversible.",
2144
+ bulkDeleteConfirm_one: "Supprimer {{count}} enregistrement sélectionné ? Ceci est irréversible.",
2145
+ bulkDeleteConfirm_many: "Supprimer {{count}} d'enregistrements sélectionnés ? Ceci est irréversible.",
2146
+ bulkDeleteConfirm_other: "Supprimer {{count}} enregistrements sélectionnés ? Ceci est irréversible.",
1802
2147
  duplicateViewName: "Une vue avec ce nom existe déjà.",
1803
2148
  viewTypeGrid: "Grille",
1804
2149
  viewTypeGridDesc: "Tableau de type tableur d'enregistrements.",
@@ -1835,10 +2180,14 @@ const fr = {
1835
2180
  chartTypePie: "Graphique circulaire",
1836
2181
  chartTypeArea: "Graphique en aires",
1837
2182
  chartTypeScatter: "Nuage de points",
1838
- xAxisField: "Champ axe X",
1839
- xAxisFieldHelp: "La dimension catégorielle ou temporelle.",
1840
- yAxisField: "Champ axe Y",
1841
- yAxisFieldHelp: "Le champ numérique à agréger.",
2183
+ dataset: "Jeu de données",
2184
+ datasetHelp: "Le graphique lit ses valeurs dans ce jeu de données de l’objet.",
2185
+ chartMeasure: "Mesure",
2186
+ chartMeasureHelp: "La mesure du jeu de données tracée sur l’axe des valeurs.",
2187
+ chartDimension: "Dimension",
2188
+ chartDimensionHelp: "La dimension du jeu de données selon laquelle les valeurs sont regroupées (facultatif).",
2189
+ viewTypeUnavailableDataset: "Cet objet n’expose aucun jeu de données à représenter.",
2190
+ noDatasetMeasure: "Ce jeu de données ne déclare aucune mesure à représenter.",
1842
2191
  ufTabs: "Onglets",
1843
2192
  ufAddField: "+ Ajouter un champ de filtre…",
1844
2193
  ufShowAllRecords: "Afficher l'onglet \"Tous les enregistrements\"",
@@ -1852,6 +2201,9 @@ const fr = {
1852
2201
  unpinItem: "Désépingler {{name}}",
1853
2202
  dragToReorder: "Glisser pour réorganiser",
1854
2203
  favorites: "Favoris",
2204
+ launcherLabel: "Lanceur d'applications",
2205
+ menuLabel: "Navigation de l'application",
2206
+ menuEmpty: "Cette application n'a aucune entrée de navigation que vous pouvez ouvrir.",
1855
2207
  },
1856
2208
  },
1857
2209
  auth: {
@@ -1905,6 +2257,8 @@ const fr = {
1905
2257
  resendOtpCountdownText: "Renvoyer dans {seconds} s",
1906
2258
  usePhoneOtpText: "Se connecter avec un code de vérification",
1907
2259
  usePasswordSignInText: "Se connecter avec un mot de passe à la place",
2260
+ socialButton: "Continuer avec {provider}",
2261
+ orText: "ou continuer avec l'e-mail",
1908
2262
  },
1909
2263
  register: {
1910
2264
  title: "Créer un compte",
@@ -1923,8 +2277,12 @@ const fr = {
1923
2277
  submittingButton: "Création du compte…",
1924
2278
  hasAccountText: "Vous avez déjà un compte ?",
1925
2279
  signInText: "Se connecter",
2280
+ socialButton: "S'inscrire avec {provider}",
2281
+ orText: "ou continuer avec l'e-mail",
1926
2282
  errors: {
1927
2283
  userExists: "Un compte avec cet e-mail existe déjà. Essayez de vous connecter.",
2284
+ selfRegistrationClosed: "L'inscription libre n'est pas ouverte dans cet environnement. Demandez une invitation à un administrateur.",
2285
+ emailDomainNotAllowed: "Le domaine de cet e-mail n'est pas autorisé à s'inscrire ici. Utilisez l'e-mail de votre organisation ou demandez une invitation à un administrateur.",
1928
2286
  },
1929
2287
  verifyInbox: {
1930
2288
  title: "Vérifiez votre boîte de réception",
@@ -2123,6 +2481,15 @@ const fr = {
2123
2481
  role: "Rôle",
2124
2482
  save: "Enregistrer les modifications",
2125
2483
  },
2484
+ language: {
2485
+ title: "Langue",
2486
+ description: "La langue utilisée pour les notifications et les messages qui vous sont envoyés. La langue de l'interface se choisit séparément, dans le menu du globe.",
2487
+ label: "Langue préférée",
2488
+ systemDefault: "Utiliser la valeur par défaut du déploiement",
2489
+ save: "Enregistrer",
2490
+ saved: "Préférence de langue mise à jour.",
2491
+ readOnly: "La langue de votre compte est gérée par votre administrateur.",
2492
+ },
2126
2493
  password: {
2127
2494
  changeTitle: "Changer le mot de passe",
2128
2495
  setTitle: "Définir un mot de passe local",
@@ -2154,7 +2521,6 @@ const fr = {
2154
2521
  label: "Espaces de travail",
2155
2522
  default: "Mon espace de travail",
2156
2523
  switch: "Changer d'espace de travail",
2157
- create: "Créer un espace de travail",
2158
2524
  createTitle: "Créer un espace de travail",
2159
2525
  createDescription: "Un espace de travail est un lieu partagé pour la collaboration de votre équipe.",
2160
2526
  createButton: "Créer un espace de travail",
@@ -2179,7 +2545,6 @@ const fr = {
2179
2545
  packageManagement: "Gestion des packages",
2180
2546
  searchNavigation: "Rechercher dans la navigation…",
2181
2547
  settings: "Paramètres",
2182
- help: "Aide",
2183
2548
  helpTooltip: "Aide et documentation",
2184
2549
  activityFeed: "Flux d'activité",
2185
2550
  notifications: "Notifications",
@@ -2239,6 +2604,9 @@ const fr = {
2239
2604
  },
2240
2605
  pendingDrafts: {
2241
2606
  message: "Vous avez {{count}} modification(s) non publiée(s) — publiez-les pour les activer.",
2607
+ message_one: "Vous avez {{count}} modification non publiée — publiez-la pour l'activer.",
2608
+ message_many: "Vous avez {{count}} de modifications non publiées — publiez-les pour les activer.",
2609
+ message_other: "Vous avez {{count}} modifications non publiées — publiez-les pour les activer.",
2242
2610
  cta: "Publier",
2243
2611
  publishing: "Publication…",
2244
2612
  published: "Publié ! Vos modifications sont actives.",
@@ -2253,7 +2621,6 @@ const fr = {
2253
2621
  capabilityWarn: "Contrôle de conception : {{count}} référence(s) de capacité ne mènent à rien.",
2254
2622
  },
2255
2623
  title: "Accueil",
2256
- subtitle: "Tableau de bord de votre espace de travail",
2257
2624
  nav: "Accueil",
2258
2625
  allApps: "Toutes les applications",
2259
2626
  yourApps: "Vos applications",
@@ -2265,8 +2632,6 @@ const fr = {
2265
2632
  empty: "Vous êtes à jour",
2266
2633
  },
2267
2634
  loading: "Chargement de l'espace de travail…",
2268
- recent: "Récent",
2269
- starred: "Favoris",
2270
2635
  welcome: "Bienvenue dans ObjectUI",
2271
2636
  welcomeDescription: "Commencez par créer votre première application ou configurer les paramètres système.",
2272
2637
  createFirstApp: "Créez votre première app",
@@ -2274,8 +2639,6 @@ const fr = {
2274
2639
  browseMarketplace: "Parcourir la marketplace d'apps",
2275
2640
  quickActions: {
2276
2641
  title: "Actions rapides",
2277
- createApp: "Créer une app",
2278
- createAppDesc: "Commencez avec une nouvelle application",
2279
2642
  manageObjects: "Gérer les objets",
2280
2643
  manageObjectsDesc: "Configurer les modèles de données",
2281
2644
  systemSettings: "Paramètres système",
@@ -2291,18 +2654,15 @@ const fr = {
2291
2654
  greetingNight: "Travail de nuit",
2292
2655
  heroTagline: "Reprenez là où vous vous êtes arrêté ou découvrez quelque chose de nouveau.",
2293
2656
  open: "Ouvrir",
2294
- stats: {
2295
- apps: "Applications",
2296
- starred: "Étoilés",
2297
- recent: "Récents",
2298
- },
2299
2657
  recentApps: {
2300
2658
  title: "Récemment ouverts",
2301
2659
  itemType: {
2302
2660
  object: "Objet",
2303
2661
  dashboard: "Tableau de bord",
2304
2662
  page: "Page",
2663
+ report: "Rapport",
2305
2664
  record: "Enregistrement",
2665
+ metadata: "Métadonnées",
2306
2666
  },
2307
2667
  },
2308
2668
  starredApps: {
@@ -2324,7 +2684,6 @@ const fr = {
2324
2684
  organizations: "Organisations",
2325
2685
  roles: "Rôles",
2326
2686
  configuration: "Configuration",
2327
- createApp: "Créer une application",
2328
2687
  administration: "Administration",
2329
2688
  datasources: "Sources de données",
2330
2689
  documentation: "Documentation",
@@ -2349,6 +2708,7 @@ const fr = {
2349
2708
  typeUpdate: "Mettre à jour",
2350
2709
  typeDelete: "Supprimer",
2351
2710
  typeComment: "Commentaire",
2711
+ typeSystem: "Système",
2352
2712
  relativeJustNow: "à l'instant",
2353
2713
  relativeSecondsAgo: "il y a {{count}}s",
2354
2714
  relativeMinutesAgo: "il y a {{count}}m",
@@ -2370,8 +2730,13 @@ const fr = {
2370
2730
  placeholder: "Rechercher des objets, tableaux de bord, pages, rapports…",
2371
2731
  inputAriaLabel: "Rechercher des objets, tableaux de bord, pages, rapports",
2372
2732
  resultsCount: "{{count}} résultat pour \"{{query}}\"",
2373
- resultsCountPlural: "{{count}} résultats pour \"{{query}}\"",
2733
+ resultsCount_one: "{{count}} résultat pour \"{{query}}\"",
2734
+ resultsCount_many: "{{count}} de résultats pour \"{{query}}\"",
2735
+ resultsCount_other: "{{count}} résultats pour \"{{query}}\"",
2374
2736
  itemsAvailable: "{{count}} éléments disponibles",
2737
+ itemsAvailable_one: "{{count}} élément disponible",
2738
+ itemsAvailable_many: "{{count}} d'éléments disponibles",
2739
+ itemsAvailable_other: "{{count}} éléments disponibles",
2375
2740
  noResults: "Aucun résultat trouvé",
2376
2741
  noResultsHint: "Essayez d'ajuster vos termes de recherche",
2377
2742
  typeObjects: "Objets",
@@ -2396,7 +2761,11 @@ const fr = {
2396
2761
  noAppsConfigured: "Aucune application configurée",
2397
2762
  noAppsConfiguredDescription: "Aucune application n'est enregistrée. Créez votre première application ou visitez les paramètres système.",
2398
2763
  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.",
2764
+ appNotAvailableDescription: "Cette application n'est pas disponible — réessayez dans un instant.",
2765
+ appNotFound: "Impossible d'ouvrir cette application",
2766
+ appNotFoundDescription: "Le serveur n'a pas renvoyé cette application pour votre compte.",
2767
+ appUnreachable: "Impossible de joindre le serveur",
2768
+ appUnreachableDescription: "Cette application n'a pas pu être vérifiée. Réessayez dans un instant.",
2400
2769
  appAccessDenied: "Vous n'avez pas accès à cette application",
2401
2770
  appAccessDeniedDescription: "Cette application existe, mais votre compte n'est pas autorisé à l'ouvrir. Demandez l'accès à un administrateur.",
2402
2771
  appAccessDeniedHome: "Retour à l'accueil",
@@ -2411,11 +2780,11 @@ const fr = {
2411
2780
  description: "Veuillez saisir les informations requises pour continuer.",
2412
2781
  selectPlaceholder: "Sélectionner {{label}}",
2413
2782
  requiredError: "{{label}} est obligatoire",
2783
+ unresolvedParam: 'Ce paramètre ne peut pas être affiché : le champ dont il dépend est absent des métadonnées de l’objet, le contrôle nécessaire ne peut donc pas être construit. Demandez à un administrateur de corriger la définition de l’action.',
2784
+ carryOverHint: 'Repris tel quel (lecture seule)',
2414
2785
  cancel: "Annuler",
2415
2786
  confirm: "Confirmer",
2416
2787
  uploading: "Téléversement…",
2417
- defaultActionTitle: "Action",
2418
- ok: "OK",
2419
2788
  lookupPlaceholder: "ID d'enregistrement pour {{label}}",
2420
2789
  lookupHelpText: "Aucun objet de référence n'est configuré pour ce paramètre, le sélecteur d'enregistrement est donc indisponible. Saisissez un ID d'enregistrement ou demandez à un administrateur de corriger le paramètre d'action.",
2421
2790
  },
@@ -2424,11 +2793,6 @@ const fr = {
2424
2793
  confirm: "Continuer",
2425
2794
  cancel: "Annuler",
2426
2795
  },
2427
- rowAction: {
2428
- openMenu: "Ouvrir le menu",
2429
- edit: "Modifier",
2430
- delete: "Supprimer",
2431
- },
2432
2796
  navigationSync: {
2433
2797
  addedPage: "Navigation mise à jour : page \"{{name}}\" ajoutée",
2434
2798
  addedDashboard: "Navigation mise à jour : tableau de bord \"{{name}}\" ajouté",
@@ -2449,6 +2813,9 @@ const fr = {
2449
2813
  noRecordId: "Aucun ID d'enregistrement fourni",
2450
2814
  deleteConfirm: "Supprimer cet enregistrement ?",
2451
2815
  bulkDeleteSuccess: "{{count}} enregistrement(s) {{label}} supprimé(s)",
2816
+ bulkDeleteSuccess_one: "{{count}} enregistrement {{label}} supprimé",
2817
+ bulkDeleteSuccess_many: "{{count}} d'enregistrements {{label}} supprimés",
2818
+ bulkDeleteSuccess_other: "{{count}} enregistrements {{label}} supprimés",
2452
2819
  bulkDeletePartial: "{{succeeded}} supprimé(s), {{failed}} échoué(s)",
2453
2820
  },
2454
2821
  objectViewActions: {
@@ -2460,15 +2827,6 @@ const fr = {
2460
2827
  exportFailed: "Échec de l'export : {{message}}",
2461
2828
  forecastSoon: "La vue de prévision arrive bientôt",
2462
2829
  },
2463
- recordDetail: {
2464
- viewersTooltip: "Utilisateurs consultant cet enregistrement en ce moment",
2465
- },
2466
- cellRender: {
2467
- empty: "Vide",
2468
- yes: "Oui",
2469
- no: "Non",
2470
- systemFields: "Système",
2471
- },
2472
2830
  user: {
2473
2831
  profile: "Profil",
2474
2832
  settings: "Paramètres",
@@ -2658,18 +3016,37 @@ const fr = {
2658
3016
  regionLabel: "Notifications",
2659
3017
  groupCount: "{{count}} notifications",
2660
3018
  groupUnread: "{{count}} non lues",
3019
+ groupUnread_one: "{{count}} non lue",
3020
+ groupUnread_many: "{{count}} non lues",
3021
+ groupUnread_other: "{{count}} non lues",
2661
3022
  groupMarkRead: "Marquer comme lu",
2662
3023
  groupMarkReadTitle: "Tout marquer comme lu pour ce type",
2663
3024
  empty: "Aucune notification",
2664
3025
  markAllRead: "Tout marquer comme lu",
2665
3026
  viewAll: "Voir toutes les notifications",
2666
3027
  approvalsPending: "{{count}} approbations en attente",
3028
+ approvalsPending_one: "{{count}} approbation en attente",
3029
+ approvalsPending_many: "{{count}} d'approbations en attente",
3030
+ approvalsPending_other: "{{count}} approbations en attente",
2667
3031
  viewApprovals: "Voir les approbations",
2668
3032
  noPendingApprovals: "Aucune approbation en attente",
2669
3033
  openApprovalsInbox: "Ouvrir la boîte d'approbations",
2670
3034
  badgeTotal: "{{total}} au total",
2671
3035
  badgeNotifications: "{{unread}} notifications",
2672
3036
  badgeApprovals: "{{approvals}} approbations en attente",
3037
+ arrivalMany: "{{count}} nouveaux messages",
3038
+ arrivalMany_one: "{{count}} nouveau message",
3039
+ arrivalMany_many: "{{count}} de nouveaux messages",
3040
+ arrivalMany_other: "{{count}} nouveaux messages",
3041
+ arrivalRepeats: "{{count}} nouveaux messages sur ce sujet",
3042
+ arrivalRepeats_one: "{{count}} nouveau message sur ce sujet",
3043
+ arrivalRepeats_many: "{{count}} de nouveaux messages sur ce sujet",
3044
+ arrivalRepeats_other: "{{count}} nouveaux messages sur ce sujet",
3045
+ arrivalOpen: "Afficher",
3046
+ toastEnabled: "Alertes dans l'application",
3047
+ desktopEnabled: "Notifications du bureau",
3048
+ desktopBlocked: "Bloqué. Autorisez les notifications pour ce site dans les paramètres du navigateur.",
3049
+ desktopUnsupported: "Ce navigateur ne prend pas en charge les notifications du bureau.",
2673
3050
  emptyUnread: "Tout est lu",
2674
3051
  filterUnread: "Non lus",
2675
3052
  filterAll: "Tous",
@@ -2683,12 +3060,14 @@ const fr = {
2683
3060
  thankYouTitle: "Merci !",
2684
3061
  thankYouMessage: "Votre soumission a été reçue avec succès.",
2685
3062
  redirecting: "Redirection dans {{seconds}} seconde(s)…",
3063
+ redirectPending: "Redirection…",
2686
3064
  unavailableTitle: "Formulaire non disponible",
2687
3065
  unavailableDescription: "Aucun formulaire public n'est disponible à cette URL. Assurez-vous que la vue sous-jacente a le partage anonyme activé.",
2688
3066
  tryDemo: "Essayer la démo",
2689
3067
  retry: "Réessayer",
2690
3068
  loading: "Chargement du formulaire…",
2691
3069
  requiredHint: "* Champ obligatoire",
3070
+ requiredFields: "Champs obligatoires : {{fields}}",
2692
3071
  consentLabelDefault: "J'accepte la politique de confidentialité et consens au traitement de mes données pour cette demande.",
2693
3072
  consentLink: "Politique de confidentialité",
2694
3073
  consentRequired: "Veuillez accepter la politique de confidentialité pour continuer.",
@@ -2739,6 +3118,9 @@ const fr = {
2739
3118
  noImportableFields: "Cet objet n'a aucun champ importable.",
2740
3119
  schemaReadFailed: "Impossible de lire le schéma de l'objet.",
2741
3120
  imported: "{{count}} ligne(s) importée(s) dans {{object}}.",
3121
+ imported_one: "{{count}} ligne importée dans {{object}}.",
3122
+ imported_many: "{{count}} de lignes importées dans {{object}}.",
3123
+ imported_other: "{{count}} lignes importées dans {{object}}.",
2742
3124
  importFrom: "Importer les lignes réelles depuis",
2743
3125
  into: "vers",
2744
3126
  opening: "Ouverture…",
@@ -2752,6 +3134,78 @@ const fr = {
2752
3134
  openProduction: "Ouvrir la production",
2753
3135
  manageEnvironments: "Gérer les environnements",
2754
3136
  },
3137
+ cloudPlanStatus: {
3138
+ current: "Offre actuelle",
3139
+ },
3140
+ ai: {
3141
+ nlQuery: {
3142
+ placeholder: "Posez une question sur vos données…",
3143
+ ask: "Demander",
3144
+ results: "Résultats",
3145
+ match: "Correspondance : {{percent}}",
3146
+ simulatedSummary: "Résultats pour : {{query}}",
3147
+ noResults: "Aucun enregistrement correspondant",
3148
+ recentQueries: "Requêtes récentes",
3149
+ },
3150
+ formAssist: {
3151
+ title: "Suggestions de l’IA",
3152
+ suggestionCount: "{{count}} suggestions",
3153
+ suggestionCount_one: "{{count}} suggestion",
3154
+ suggestionCount_many: "{{count}} de suggestions",
3155
+ suggestionCount_other: "{{count}} suggestions",
3156
+ applyAll: "Tout appliquer",
3157
+ confidence: "Confiance : {{percent}}",
3158
+ appliedCount: "{{count}} suggestions appliquées",
3159
+ appliedCount_one: "{{count}} suggestion appliquée",
3160
+ appliedCount_many: "{{count}} de suggestions appliquées",
3161
+ appliedCount_other: "{{count}} suggestions appliquées",
3162
+ },
3163
+ recommendations: {
3164
+ title: "Recommandations",
3165
+ generating: "Génération des recommandations…",
3166
+ empty: "Aucune recommandation disponible",
3167
+ },
3168
+ },
3169
+ aiApprovals: {
3170
+ title: "Approbations IA",
3171
+ description: "Actions proposées par un agent IA qui nécessitent une validation humaine avant exécution.",
3172
+ tabPending: "En attente",
3173
+ tabDecided: "Traitées",
3174
+ tabAll: "Toutes",
3175
+ statusPending: "En attente",
3176
+ statusApproved: "Approuvée",
3177
+ statusExecuted: "Exécutée",
3178
+ statusFailed: "Échouée",
3179
+ statusRejected: "Rejetée",
3180
+ colTool: "Outil",
3181
+ colAction: "Action",
3182
+ colObject: "Objet",
3183
+ colStatus: "Statut",
3184
+ colProposed: "Proposée",
3185
+ colDecision: "Décision",
3186
+ emptyTitle: "Aucune action en attente",
3187
+ emptyDescription: "Lorsque l'IA propose une action sensible, elle apparaît ici pour validation.",
3188
+ view: "Voir",
3189
+ approve: "Approuver",
3190
+ reject: "Rejeter",
3191
+ working: "En cours…",
3192
+ approveAndExecute: "Approuver et exécuter",
3193
+ outcomeApprove: "Approbation de {{id}} : {{message}}",
3194
+ outcomeReject: "Rejet de {{id}} : {{message}}",
3195
+ outcomeExecuteFailed: "L'action a échoué pendant son exécution",
3196
+ drawerFallbackTitle: "Action en attente",
3197
+ drawerSubtitle: "Outil {{tool}} sur {{object}}",
3198
+ fieldProposedBy: "Proposée par",
3199
+ fieldDecidedBy: "Décidée par",
3200
+ fieldConversation: "Conversation",
3201
+ fieldToolInput: "Entrée de l'outil",
3202
+ fieldResult: "Résultat",
3203
+ fieldError: "Erreur",
3204
+ fieldRejectionReason: "Motif du rejet",
3205
+ rejectTitle: "Rejeter cette action ?",
3206
+ rejectBody: "Le motif est renvoyé à l'IA pour qu'elle ajuste sa prochaine réponse.",
3207
+ rejectPlaceholder: "Motif facultatif (par ex. « Identifiant d'enregistrement erroné — merci de confirmer d'abord avec l'utilisateur. »)",
3208
+ },
2755
3209
  aiModelStatus: {
2756
3210
  summary: "Créer / Demander utilise {{conversational}} ({{conversationalSource}}) ; structuré utilise {{structured}} ({{structuredSource}}).",
2757
3211
  summaryRouting: "Politique de routage : offres gratuites → {{free}}, offres payantes → {{paid}}.",
@@ -2769,6 +3223,114 @@ const fr = {
2769
3223
  sourceInherits: "identique à build/ask",
2770
3224
  sourcePinned: "figé par {{source}}",
2771
3225
  },
3226
+ // objectui#7254 — the AI copilot's tool cards. Three families, all of them
3227
+ // English-only until this landed while every other string on the same screen
3228
+ // was translated:
3229
+ //
3230
+ // `tool.*` — one entry per PLATFORM-PROVIDED tool name
3231
+ // (@objectstack/spec `PLATFORM_TOOLS_BY_PACKAGE`, the
3232
+ // closed registry those runtimes are conformance-tested
3233
+ // against). `humanizeToolName` looks each up as
3234
+ // `chatbot.tool.<tool_name>` and falls back to its English
3235
+ // title-caser for a custom / third-party tool, so a name
3236
+ // missing here is degraded, never broken. The `en` values
3237
+ // are deliberately EQUAL to what that title-caser produces:
3238
+ // adding the key must not silently reword the English UI.
3239
+ // `toolState.*` — the card-header badge + activity-chip vocabulary. ONE
3240
+ // set for both surfaces (they used to carry separate
3241
+ // tables and disagreed on casing).
3242
+ // `plan.*` — the "N objects · N views · N dashboards" strip. Plural
3243
+ // FAMILIES: one slot per CLDR category the pack's language
3244
+ // selects (objectui#11432), plus the base key for a call
3245
+ // made without a count. `all-locales-key-parity.test.ts`
3246
+ // derives the required slots from `Intl.PluralRules`.
3247
+ //
3248
+ // objectui#7481 — five `tool.*` entries are NEWER than the registry above:
3249
+ // `get_authoring_rules` (cloud#1837), `load_tools`, `open_record`, `test_flow`
3250
+ // and `toggle_flow` are registered by cloud `service-ai-studio` but the pinned
3251
+ // `@objectstack/spec` snapshot does not list them yet. They are kept here on
3252
+ // purpose: a step label the user reads must not wait on a pin bump. When the
3253
+ // pin advances, `chatbotToolLabels-locale-parity-7481` starts checking them
3254
+ // against the registry instead of against its own hand-held list.
3255
+ chatbot: {
3256
+ tool: {
3257
+ aggregate_data: "Agréger les données",
3258
+ get_record: "Lire un enregistrement",
3259
+ query_data: "Interroger les données",
3260
+ query_records: "Interroger les enregistrements",
3261
+ search_knowledge: "Rechercher dans la base de connaissances",
3262
+ visualize_data: "Créer un graphique",
3263
+ add_field: "Ajouter un champ",
3264
+ apply_blueprint: "Construire l’application",
3265
+ apply_edit: "Appliquer les modifications",
3266
+ create_metadata: "Créer des métadonnées",
3267
+ create_object: "Créer un objet",
3268
+ create_package: "Créer un paquet",
3269
+ create_seed: "Générer des données d’exemple",
3270
+ delete_field: "Supprimer un champ",
3271
+ describe_metadata: "Consulter les métadonnées",
3272
+ describe_object: "Consulter la structure de l’objet",
3273
+ get_active_package: "Lire le paquet actif",
3274
+ get_authoring_rules: "Lire les règles d'écriture",
3275
+ get_metadata_schema: "Lire le schéma des métadonnées",
3276
+ get_package: "Lire le paquet",
3277
+ list_metadata: "Lister les métadonnées",
3278
+ list_objects: "Lister les objets",
3279
+ list_packages: "Lister les paquets",
3280
+ load_tools: "Charger les outils",
3281
+ modify_field: "Modifier un champ",
3282
+ open_record: "Ouvrir la fiche",
3283
+ propose_blueprint: "Concevoir le plan de l’application",
3284
+ set_active_package: "Changer le paquet actif",
3285
+ suggest_builder: "Proposer une méthode de construction",
3286
+ test_flow: "Tester le flux",
3287
+ todo_write: "Noter les tâches",
3288
+ toggle_flow: "Activer ou désactiver le flux",
3289
+ update_metadata: "Mettre à jour les métadonnées",
3290
+ validate_expression: "Valider l’expression",
3291
+ verify_build: "Vérifier la construction",
3292
+ },
3293
+ toolState: {
3294
+ agentActivity: "Activité de l’agent",
3295
+ pending: "En attente",
3296
+ running: "En cours",
3297
+ awaitingApproval: "En attente d’approbation",
3298
+ responded: "Répondu",
3299
+ completed: "Terminé",
3300
+ error: "Erreur",
3301
+ denied: "Refusé",
3302
+ failed: "Échec",
3303
+ },
3304
+ plan: {
3305
+ countObjects: "{{count}} objets",
3306
+ countObjects_one: "{{count}} objet",
3307
+ countObjects_many: "{{count}} d'objets",
3308
+ countObjects_other: "{{count}} objets",
3309
+ countViews: "{{count}} vues",
3310
+ countViews_one: "{{count}} vue",
3311
+ countViews_many: "{{count}} de vues",
3312
+ countViews_other: "{{count}} vues",
3313
+ countDashboards: "{{count}} tableaux de bord",
3314
+ countDashboards_one: "{{count}} tableau de bord",
3315
+ countDashboards_many: "{{count}} de tableaux de bord",
3316
+ countDashboards_other: "{{count}} tableaux de bord",
3317
+ countSeedData: "données d’exemple",
3318
+ },
3319
+ build: {
3320
+ building: "Création de {{app}}…",
3321
+ built: "Création de {{app}} terminée",
3322
+ appFallback: "votre application",
3323
+ addingSampleData: "ajout de données d’exemple",
3324
+ group: {
3325
+ object: "Objets",
3326
+ view: "Vues",
3327
+ dashboard: "Tableaux de bord",
3328
+ app: "Application",
3329
+ seed: "Données d’exemple",
3330
+ },
3331
+ moreArtifacts: "+{{n}} autres",
3332
+ },
3333
+ },
2772
3334
  chatbotError: {
2773
3335
  title: "Échec de la réponse",
2774
3336
  fallbackDetail: "Une erreur s'est produite. Veuillez réessayer.",
@@ -2849,7 +3411,7 @@ const fr = {
2849
3411
  },
2850
3412
  title: "Marketplace d'applications",
2851
3413
  subtitle: "Parcourez les applications approuvées publiées dans le catalogue ObjectStack. Cliquez sur une application pour voir les détails et l'installer dans l'un de vos environnements.",
2852
- searchPlaceholder: "Rechercher des applications par nom ou ID de manifeste…",
3414
+ searchPlaceholder: "Rechercher des applications par nom ou ID d'application…",
2853
3415
  searchAria: "Rechercher des applications du marketplace",
2854
3416
  installed: "Installé",
2855
3417
  installedCount: "Installées ({{count}})",
@@ -2897,10 +3459,17 @@ const fr = {
2897
3459
  purgeSampleData: 'Supprimer les données d\'exemple',
2898
3460
  purgeConfirm: 'Supprimer tous les enregistrements d\'exemple créés par ce paquet ? Les enregistrements ajoutés par l\'utilisateur ne seront PAS touchés.',
2899
3461
  purgeSuccess: '{{count}} enregistrement(s) d\'exemple supprimé(s).',
3462
+ purgeSuccess_one: "{{count}} enregistrement d'exemple supprimé.",
3463
+ purgeSuccess_many: "{{count}} d'enregistrements d'exemple supprimés.",
3464
+ purgeSuccess_other: "{{count}} enregistrements d'exemple supprimés.",
2900
3465
  purgeNoData: 'Aucun enregistrement d\'exemple à supprimer.',
2901
3466
  reseedQueued: 'Les données d\'exemple seront rechargées au prochain accès à l\'environnement.',
2902
3467
  reseedLocalSuccess: 'Données d\'exemple rechargées : {{inserted}} ajoutés, {{updated}} mis à jour.',
2903
3468
  reseedPartialErrors: '({{count}} enregistrement(s) n\'ont pas pu être écrits)',
3469
+ reseedPartialErrors_one: "({{count}} enregistrement n'a pas pu être écrit)",
3470
+ reseedPartialErrors_many: "({{count}} d'enregistrements n'ont pas pu être écrits)",
3471
+ reseedPartialErrors_other: "({{count}} enregistrements n'ont pas pu être écrits)",
3472
+ sampleDataKernelUnavailable: 'Ce plan de contrôle n\'a pas de noyau d\'environnement : les données d\'exemple ne peuvent donc être ni rechargées ni supprimées ici. Faites-le depuis le runtime propre à l\'environnement.',
2904
3473
  updateAvailable: 'Mise à jour disponible',
2905
3474
  },
2906
3475
  action: {
@@ -2953,7 +3522,8 @@ const fr = {
2953
3522
  reviewed: "Examiné et approuvé",
2954
3523
  unreviewed: "Pas encore examiné",
2955
3524
  signed: "Signé",
2956
- grantsIntro: "À l'installation, ce paquet obtiendra :",
3525
+ grantsIntro: "Ce paquet demande :",
3526
+ notEnforced: "Cette liste est enregistrée à l'installation et reconfirmée si une version ultérieure en demande davantage, mais l'exécution ne restreint pas encore le paquet à cette liste.",
2957
3527
  services: "Services de la plateforme",
2958
3528
  hooks: "Hooks de cycle de vie",
2959
3529
  network: "Accès réseau",
@@ -2992,30 +3562,21 @@ const fr = {
2992
3562
  storage: "Stockage",
2993
3563
  other: "Autre",
2994
3564
  },
2995
- pricing: {
2996
- free: "Gratuit",
2997
- freemium: "Freemium",
2998
- paid: "Payant",
2999
- subscription: "Abonnement",
3000
- "usage-based": "À l'utilisation",
3001
- "contact-sales": "Contacter les ventes",
3002
- },
3003
3565
  relativeTime: {
3004
3566
  today: "aujourd'hui",
3005
3567
  daysAgo: "il y a {{count}}j",
3006
3568
  monthsAgo: "il y a {{count}} mois",
3569
+ monthsAgo_one: "il y a {{count}} mois",
3570
+ monthsAgo_many: "il y a {{count}} mois",
3571
+ monthsAgo_other: "il y a {{count}} mois",
3007
3572
  yearsAgo: "il y a {{count}} ans",
3573
+ yearsAgo_one: "il y a {{count}} an",
3574
+ yearsAgo_many: "il y a {{count}} ans",
3575
+ yearsAgo_other: "il y a {{count}} ans",
3008
3576
  },
3009
3577
  },
3010
- approvals: {
3011
- approve: 'Approuver',
3012
- reject: 'Rejeter',
3013
- comment: 'Commentaire (facultatif)',
3014
- approveSuccess: 'Approuvé',
3015
- rejectSuccess: 'Rejeté',
3016
- rejectConfirm: 'Rejeter cette demande d’approbation ?',
3017
- },
3018
3578
  approvalsInbox: {
3579
+ recordUnresolvable: 'Cet enregistrement ne peut pas être ouvert',
3019
3580
  loadMore: 'Charger plus',
3020
3581
  loadingMore: 'Chargement…',
3021
3582
  loadedOf: '{{loaded}} sur {{total}} chargées',
@@ -3034,6 +3595,9 @@ const fr = {
3034
3595
  requestInfoSent: 'Renvoyée au demandeur pour complément',
3035
3596
  remindBtn: 'Relancer',
3036
3597
  remindSuccess: 'Relance envoyée à {{count}} approbateur(s)',
3598
+ remindSuccess_one: 'Relance envoyée à {{count}} approbateur',
3599
+ remindSuccess_many: "Relance envoyée à {{count}} d'approbateurs",
3600
+ remindSuccess_other: 'Relance envoyée à {{count}} approbateurs',
3037
3601
  remindThrottled: 'Une relance a déjà été envoyée récemment — réessayez plus tard.',
3038
3602
  replyPlaceholder: 'Répondre sur cette demande…',
3039
3603
  slaRemaining: 'SLA : {{dur}} restants',
@@ -3050,6 +3614,9 @@ const fr = {
3050
3614
  progressApprovals: 'Approbations — {{got}} sur {{need}}',
3051
3615
  progressGroups: 'Avancement des visas — {{got}} sur {{need}} groupes',
3052
3616
  progressEligible: '{{count}} approbateur(s) éligible(s)',
3617
+ progressEligible_one: '{{count}} approbateur éligible',
3618
+ progressEligible_many: "{{count}} d'approbateurs éligibles",
3619
+ progressEligible_other: '{{count}} approbateurs éligibles',
3053
3620
  progressBar: 'Avancement de la décision',
3054
3621
  declaredActions: 'Actions',
3055
3622
  attachmentChip: 'Pièce jointe',
@@ -3081,6 +3648,9 @@ const fr = {
3081
3648
  filterCount: '{{shown}} sur {{total}}',
3082
3649
  selected: 'sélectionnées',
3083
3650
  actionableCount: '({{count}} actionnables)',
3651
+ actionableCount_one: '({{count}} actionnable)',
3652
+ actionableCount_many: '({{count}} actionnables)',
3653
+ actionableCount_other: '({{count}} actionnables)',
3084
3654
  selectAll: 'Tout sélectionner',
3085
3655
  selectRow: 'Sélectionner la demande',
3086
3656
  colRequest: 'Demande',
@@ -3154,11 +3724,23 @@ const fr = {
3154
3724
  approveN: 'Approuver {{count}}',
3155
3725
  rejectN: 'Rejeter {{count}}',
3156
3726
  bulkApproveTitle: 'Approuver {{count}} demandes ?',
3727
+ bulkApproveTitle_one: 'Approuver {{count}} demande ?',
3728
+ bulkApproveTitle_many: 'Approuver {{count}} de demandes ?',
3729
+ bulkApproveTitle_other: 'Approuver {{count}} demandes ?',
3157
3730
  bulkApproveBody: 'Chaque demande est approuvée avec votre identité et son flux continue sur la branche d\'approbation.',
3158
3731
  bulkRejectTitle: 'Rejeter {{count}} demandes ?',
3732
+ bulkRejectTitle_one: 'Rejeter {{count}} demande ?',
3733
+ bulkRejectTitle_many: 'Rejeter {{count}} de demandes ?',
3734
+ bulkRejectTitle_other: 'Rejeter {{count}} demandes ?',
3159
3735
  bulkRejectBody: 'Les demandes sélectionnées seront rejetées et leurs demandeurs notifiés.',
3160
3736
  bulkApproved: '{{count}} demandes approuvées',
3737
+ bulkApproved_one: '{{count}} demande approuvée',
3738
+ bulkApproved_many: '{{count}} de demandes approuvées',
3739
+ bulkApproved_other: '{{count}} demandes approuvées',
3161
3740
  bulkRejected: '{{count}} demandes rejetées',
3741
+ bulkRejected_one: '{{count}} demande rejetée',
3742
+ bulkRejected_many: '{{count}} de demandes rejetées',
3743
+ bulkRejected_other: '{{count}} demandes rejetées',
3162
3744
  bulkPartial: '{{ok}} réussies, {{fail}} échouées : {{which}}',
3163
3745
  rejectOneTitle: 'Rejeter « {{title}} » ?',
3164
3746
  rejectOneBody: 'La demande sera rejetée et le demandeur notifié.',
@@ -3183,8 +3765,17 @@ const fr = {
3183
3765
  alreadyDecided: 'Cette demande a déjà été traitée. Actualisez la liste.',
3184
3766
  justNow: 'à l\'instant',
3185
3767
  minutesAgo: 'il y a {{count}} min',
3768
+ minutesAgo_one: 'il y a {{count}} min',
3769
+ minutesAgo_many: 'il y a {{count}} min',
3770
+ minutesAgo_other: 'il y a {{count}} min',
3186
3771
  hoursAgo: 'il y a {{count}} h',
3772
+ hoursAgo_one: 'il y a {{count}} h',
3773
+ hoursAgo_many: 'il y a {{count}} h',
3774
+ hoursAgo_other: 'il y a {{count}} h',
3187
3775
  daysAgo: 'il y a {{count}} jours',
3776
+ daysAgo_one: 'il y a {{count}} jour',
3777
+ daysAgo_many: 'il y a {{count}} jours',
3778
+ daysAgo_other: 'il y a {{count}} jours',
3188
3779
  },
3189
3780
  preview: {
3190
3781
  empty: {
@@ -3219,11 +3810,17 @@ const fr = {
3219
3810
  detailNone: 'Aucune différence détectée — le brouillon correspond à la version publiée.',
3220
3811
  detailChangedKeys: 'Également modifié :',
3221
3812
  confirmNote: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
3813
+ confirmNote_one: 'La publication libère atomiquement {{count}} brouillon en attente de ce paquet.',
3814
+ confirmNote_many: 'La publication libère atomiquement les {{count}} de brouillons en attente de ce paquet.',
3815
+ confirmNote_other: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
3222
3816
  publishConfirm: 'Tout publier',
3223
- // [objectui#5418] Pre-publish security-posture findings, shown next to
3817
+ // [`7a90afdf9`] Pre-publish security-posture findings, shown next to
3224
3818
  // the confirm button so a refusal the door would issue is read BEFORE
3225
3819
  // the click rather than as a toast after the batch rolled back.
3226
3820
  securityBlockTitle: 'La publication sera refusée — {{count}} élément(s) nécessitent d’abord une décision',
3821
+ securityBlockTitle_one: 'La publication sera refusée — {{count}} élément nécessite d’abord une décision',
3822
+ securityBlockTitle_many: 'La publication sera refusée — {{count}} d’éléments nécessitent d’abord une décision',
3823
+ securityBlockTitle_other: 'La publication sera refusée — {{count}} éléments nécessitent d’abord une décision',
3227
3824
  securityBlockWhere: 'Corrigez-le sur l’objet dans Paramètres → Partage d’enregistrements, puis publiez à nouveau.',
3228
3825
  },
3229
3826
  // ADR-0045 — the materialized-but-unlisted app banner
@@ -3248,7 +3845,7 @@ const fr = {
3248
3845
  revertLabel: 'Modification annulée',
3249
3846
  applyLabel: 'Modification de génération',
3250
3847
  revert: 'annulation',
3251
- items: 'éléments',
3848
+ items: 'Éléments : {{count}}',
3252
3849
  revertAction: 'Annuler',
3253
3850
  reverted: 'Annulé — la modification a été retirée.',
3254
3851
  revertFailed: 'Échec de l\'annulation',
@@ -3277,25 +3874,25 @@ const fr = {
3277
3874
  rangeEnd: "À",
3278
3875
  operators: {
3279
3876
  equals: "Égal à",
3280
- notEquals: "Différent de",
3877
+ not_equals: "Différent de",
3281
3878
  contains: "Contient",
3282
- containsCaseInsensitive: "Contient (ignorer la casse)",
3283
- notContains: "Ne contient pas",
3284
- isEmpty: "Est vide",
3285
- isNotEmpty: "N'est pas vide",
3286
- greaterThan: "Supérieur à",
3287
- lessThan: "Inférieur à",
3288
- greaterOrEqual: "Supérieur ou égal",
3289
- lessOrEqual: "Inférieur ou égal",
3879
+ icontains: "Contient (ignorer la casse)",
3880
+ not_contains: "Ne contient pas",
3881
+ is_empty: "Est vide",
3882
+ is_not_empty: "N'est pas vide",
3883
+ greater_than: "Supérieur à",
3884
+ less_than: "Inférieur à",
3885
+ greater_than_or_equal: "Supérieur ou égal",
3886
+ less_than_or_equal: "Inférieur ou égal",
3290
3887
  before: "Avant",
3291
3888
  after: "Après",
3292
3889
  between: "Entre",
3293
3890
  in: "Dans",
3294
- notIn: "Pas dans",
3295
- startsWith: "Commence par",
3296
- endsWith: "Se termine par",
3297
- isNull: "Est null",
3298
- isNotNull: "N'est pas null",
3891
+ not_in: "Pas dans",
3892
+ starts_with: "Commence par",
3893
+ ends_with: "Se termine par",
3894
+ is_null: "Est null",
3895
+ is_not_null: "N'est pas null",
3299
3896
  exists: "Est défini",
3300
3897
  notExists: "N'est pas défini",
3301
3898
  },
@@ -3311,7 +3908,9 @@ const fr = {
3311
3908
  },
3312
3909
  collaboration: {
3313
3910
  commentCount: "{{count}} commentaires",
3314
- commentCountOne: "{{count}} commentaire",
3911
+ commentCount_one: "{{count}} commentaire",
3912
+ commentCount_many: "{{count}} de commentaires",
3913
+ commentCount_other: "{{count}} commentaires",
3315
3914
  resolvedSuffix: " · Résolu",
3316
3915
  sortComments: "Trier les commentaires",
3317
3916
  sortOldest: "Plus anciens",
@@ -3320,11 +3919,22 @@ const fr = {
3320
3919
  reopen: "Rouvrir",
3321
3920
  justNow: "à l'instant",
3322
3921
  minutesAgo: "il y a {{count}} min",
3922
+ minutesAgo_one: "il y a {{count}} min",
3923
+ minutesAgo_many: "il y a {{count}} min",
3924
+ minutesAgo_other: "il y a {{count}} min",
3323
3925
  hoursAgo: "il y a {{count}} h",
3926
+ hoursAgo_one: "il y a {{count}} h",
3927
+ hoursAgo_many: "il y a {{count}} h",
3928
+ hoursAgo_other: "il y a {{count}} h",
3324
3929
  daysAgo: "il y a {{count}} j",
3930
+ daysAgo_one: "il y a {{count}} j",
3931
+ daysAgo_many: "il y a {{count}} j",
3932
+ daysAgo_other: "il y a {{count}} j",
3325
3933
  edited: "(modifié)",
3326
3934
  reactionCount: "{{count}} réactions",
3327
- reactionCountOne: "{{count}} réaction",
3935
+ reactionCount_one: "{{count}} réaction",
3936
+ reactionCount_many: "{{count}} de réactions",
3937
+ reactionCount_other: "{{count}} réactions",
3328
3938
  addThumbsUp: "Ajouter un pouce levé",
3329
3939
  reply: "Répondre",
3330
3940
  reactThumbsUp: "Réagir avec un pouce levé",
@@ -3335,9 +3945,13 @@ const fr = {
3335
3945
  commentPlaceholder: "Ajouter un commentaire… (utilisez @ pour mentionner)",
3336
3946
  send: "Envoyer",
3337
3947
  presentUserCount: "{{count}} utilisateurs présents",
3338
- presentUserCountOne: "{{count}} utilisateur présent",
3948
+ presentUserCount_one: "{{count}} utilisateur présent",
3949
+ presentUserCount_many: "{{count}} d'utilisateurs présents",
3950
+ presentUserCount_other: "{{count}} utilisateurs présents",
3339
3951
  moreUserCount: "{{count}} autres utilisateurs",
3340
- moreUserCountOne: "{{count}} autre utilisateur",
3952
+ moreUserCount_one: "{{count}} autre utilisateur",
3953
+ moreUserCount_many: "{{count}} d'autres utilisateurs",
3954
+ moreUserCount_other: "{{count}} autres utilisateurs",
3341
3955
  userStatusTitle: "{{name}} ({{status}})",
3342
3956
  statusActive: "actif",
3343
3957
  statusIdle: "inactif",
@@ -3345,6 +3959,11 @@ const fr = {
3345
3959
  },
3346
3960
  wizard: {
3347
3961
  missingRequired: "Veuillez renseigner les champs obligatoires : {{fields}}",
3962
+ back: "Retour",
3963
+ submitting: "Envoi…",
3964
+ stepFallback: "Étape {{n}}",
3965
+ progressLabel: "Progression",
3966
+ emptyStep: "Aucun champ configuré pour cette étape",
3348
3967
  },
3349
3968
  flowRunner: {
3350
3969
  title: 'Saisie',
@@ -3402,5 +4021,49 @@ const fr = {
3402
4021
  bulkOperationFailed: "Échec de l'opération groupée : {{reason}}",
3403
4022
  },
3404
4023
  },
4024
+ // objectui#6301 — Configuration › Automatisation des packages (ADR-0126
4025
+ // §7.4). Terminologie du pack : `common.package` = Package,
4026
+ // `flowRunner.completed` = Flux, guillemets « … ». ⛔ Aucune formulation
4027
+ // d'ascendance ou de dérive dans ce groupe (§9).
4028
+ packagedAutomation: {
4029
+ title: "Automatisation des packages",
4030
+ subtitle: "Flux et actions fournis par les packages installés. Désactivez-en un pour ce déploiement, ou clonez un flux sous un nouveau nom pour le personnaliser. La modification se fait dans Studio.",
4031
+ refresh: "Actualiser",
4032
+ flowsHeading: "Flux des packages",
4033
+ actionsHeading: "Actions des packages",
4034
+ colFlow: "Flux",
4035
+ colActivation: "Activation",
4036
+ colActions: "Actions",
4037
+ toggleLabel: "Activation de {{label}}",
4038
+ on: "Activé",
4039
+ off: "Désactivé",
4040
+ clone: "Cloner",
4041
+ cloneTitle: "Cloner le flux du package",
4042
+ cloneBody: "La copie reprend toute la définition et exige un nouveau nom machine et un nouveau libellé. Modifiez la copie dans Studio.",
4043
+ cloneName: "Nouveau nom machine",
4044
+ cloneLabel: "Nouveau libellé",
4045
+ cancel: "Annuler",
4046
+ cloneConfirm: "Créer le clone",
4047
+ cloneCreated: "Flux « {{name}} » créé.",
4048
+ emptyTitle: "Aucun flux de package",
4049
+ emptyBody: "Aucun package installé ne fournit de flux d'automatisation sur ce déploiement. Les flux que vous créez vous-même se trouvent dans Studio.",
4050
+ loadFailed: "Impossible de charger l'automatisation des packages.",
4051
+ toggleFailedHttp: "Impossible de modifier l'activation (HTTP {{status}}).",
4052
+ toggleFailed: "Impossible de modifier l'activation.",
4053
+ cloneFailedHttp: "Impossible de cloner ce flux (HTTP {{status}}).",
4054
+ cloneFailed: "Impossible de cloner ce flux.",
4055
+ actionsSubtitle: "Actions fournies par les packages installés. Désactivez-en une pour ce déploiement et elle cesse de s'exécuter partout où elle est proposée. Vous pouvez toujours créer votre propre action à côté, dans Studio.",
4056
+ colAction: "Action",
4057
+ colObject: "Objet",
4058
+ actionToggleLabel: "Activation de {{label}} sur {{object}}",
4059
+ actionsEmptyTitle: "Aucune action de package",
4060
+ actionsEmptyBody: "Aucun package installé ne déclare d'action sur ce déploiement. Les actions que vous créez vous-même se trouvent dans Studio.",
4061
+ actionsLoadFailed: "Impossible de charger les actions des packages.",
4062
+ },
4063
+ element: {
4064
+ number: {
4065
+ noObject: "Aucun objet indiqué : définissez object ou dataSource.object.",
4066
+ },
4067
+ },
3405
4068
  };
3406
4069
  export default fr;