@object-ui/i18n 16.0.0 → 17.1.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.
@@ -1,6 +1,15 @@
1
1
  const fr = {
2
2
  // objectui#2600 B5 — capability picker scope group headers (labels come from the sys_capability registry).
3
3
  capability: {
4
+ label: {
5
+ manage_users: "Gérer les utilisateurs",
6
+ manage_org_users: "Gérer les utilisateurs de l'organisation",
7
+ manage_metadata: "Gérer les métadonnées",
8
+ manage_platform_settings: "Gérer les paramètres de la plateforme",
9
+ setup_access: "Accès à la configuration",
10
+ setup_write: "Écriture des paramètres",
11
+ studio_access: "Accès à Studio",
12
+ },
4
13
  group: {
5
14
  platform: 'Plateforme',
6
15
  org: 'Organisation',
@@ -74,9 +83,14 @@ const fr = {
74
83
  package: "Package",
75
84
  },
76
85
  actions: {
86
+ decisionOutput: {
87
+ help: 'Transmis au flux comme sortie de décision.',
88
+ helpMultiValue: 'Transmis au flux comme sortie de décision. Séparez les valeurs multiples par des virgules.',
89
+ },
77
90
  resultDialog: {
78
- defaultTitle: 'Save this value now',
79
- acknowledge: 'I have saved this',
91
+ defaultTitle: 'Enregistrez cette valeur maintenant',
92
+ acknowledge: 'Je l\'ai enregistrée',
93
+ copyAll: 'Tout copier',
80
94
  },
81
95
  },
82
96
  validation: {
@@ -93,6 +107,16 @@ const fr = {
93
107
  type: "{{field}} doit être un {{type}} valide",
94
108
  },
95
109
  form: {
110
+ noPermissionToSave: "Vous n'avez pas l'autorisation d'enregistrer cet enregistrement.",
111
+ submitFailed: "Échec de l'enregistrement. Veuillez réessayer.",
112
+ discardTitle: "Abandonner les modifications ?",
113
+ discardMessage: "Vous avez des modifications non enregistrées. Si vous fermez ce formulaire maintenant, vos modifications seront perdues.",
114
+ keepEditing: "Continuer l'édition",
115
+ discard: "Abandonner",
116
+ conflictTitle: "Conflit d'enregistrement",
117
+ conflictMessage: "Cet enregistrement a été modifié par quelqu'un d'autre pendant votre édition. L'écrasement remplacera ses modifications par les vôtres.",
118
+ conflictLatestVersion: "Son enregistrement : {{time}}",
119
+ conflictOverwrite: "Écraser",
96
120
  addItem: "Ajouter un élément",
97
121
  removeItem: "Supprimer un élément",
98
122
  fieldRequired: "Ce champ est obligatoire",
@@ -103,8 +127,6 @@ const fr = {
103
127
  stepOf: "Étape {{current}} sur {{total}}",
104
128
  createTitle: "Créer {{object}}",
105
129
  editTitle: "Modifier {{object}}",
106
- createDescription: "Ajouter un nouveau {{object}} à votre base de données.",
107
- editDescription: "Mettre à jour les détails de {{object}}",
108
130
  saveRecord: "Enregistrer",
109
131
  create: "Créer",
110
132
  update: "Mettre à jour",
@@ -113,14 +135,70 @@ const fr = {
113
135
  deleteSuccess: "{{object}} supprimé",
114
136
  },
115
137
  fields: {
138
+ image: {
139
+ upload: "Téléverser une image",
140
+ addMore: "Ajouter d'autres images",
141
+ uploading: "Téléversement…",
142
+ imageAlt: "Image {{index}}",
143
+ crop: "Recadrer l'image {{index}}",
144
+ remove: "Supprimer l'image {{index}}",
145
+ enlarge: "Agrandir {{name}}",
146
+ preview: "Aperçu de l'image",
147
+ previous: "Image précédente",
148
+ next: "Image suivante",
149
+ counter: "{{current}} / {{total}}",
150
+ },
116
151
  relativeDate: {
117
152
  overdue: "En retard de {{count}} j",
118
153
  },
154
+ file: {
155
+ dragDropHere: 'Glissez-déposez des fichiers ici',
156
+ dropFilesHere: 'Déposez les fichiers ici',
157
+ browseHint: 'ou cliquez pour parcourir',
158
+ browseHintCamera: 'ou cliquez pour parcourir • utilisez le bouton appareil photo ci-dessous',
159
+ takePhoto: 'Prendre une photo',
160
+ takeSelfie: 'Prendre un selfie',
161
+ cameraCapture: 'Capture photo',
162
+ uploading: 'Téléversement…',
163
+ uploadingPct: 'Téléversement… ({{pct}} %)',
164
+ fileFallback: 'Fichier',
165
+ upload: 'Téléverser',
166
+ remove: 'Supprimer {{name}}',
167
+ exceedsMaxSize: '« {{name}} » dépasse la taille maximale ({{max}} Mo)',
168
+ uploadFailed: 'Échec du téléversement de « {{name}} » : {{error}}',
169
+ },
119
170
  richText: {
120
171
  format: "Format : {{format}}",
121
172
  basicEditorHint: "Éditeur de texte enrichi (basique)",
122
173
  placeholder: "Écrivez quelque chose...",
123
174
  },
175
+ objectRef: {
176
+ loading: "Chargement des objets…",
177
+ placeholder: "Sélectionner un objet",
178
+ search: "Rechercher des objets…",
179
+ empty: "Aucun objet trouvé",
180
+ },
181
+ recipient: {
182
+ selectTypeFirst: "Sélectionnez d'abord un type de destinataire.",
183
+ loading: "Chargement…",
184
+ search: "Rechercher…",
185
+ empty: "Aucune correspondance",
186
+ select: "Sélectionner un destinataire",
187
+ selectUser: "Sélectionner un utilisateur",
188
+ selectTeam: "Sélectionner une équipe",
189
+ selectBusinessUnit: "Sélectionner une unité opérationnelle",
190
+ selectPosition: "Sélectionner un poste",
191
+ selectUnitAndSubordinates: "Sélectionner une unité opérationnelle",
192
+ },
193
+ filterCondition: {
194
+ selectObjectFirst: "Sélectionnez d'abord un objet.",
195
+ noCriteria: "Aucun critère — cette règle ne partage rien",
196
+ criteriaRequired: "Ajoutez au moins une condition. Une règle sans critères partagerait tous les enregistrements ; elle ne peut donc pas être enregistrée.",
197
+ invalidJson: "JSON invalide — la règle ne correspondra à aucun enregistrement tant qu'elle n'est pas corrigée.",
198
+ jsonOnly: "Ce critère ne peut être modifié qu'en JSON",
199
+ editAsJson: "Modifier en JSON",
200
+ useVisualBuilder: "Utiliser le constructeur visuel",
201
+ },
124
202
  },
125
203
  table: {
126
204
  rowsPerPage: "Lignes par page",
@@ -155,6 +233,37 @@ const fr = {
155
233
  delete: "Supprimer",
156
234
  },
157
235
  grid: {
236
+ bulkSelected: "{{count}} sélectionné(s)",
237
+ bulkSelectedAllMatches: "{{count}} sélectionné(s) (tous les résultats)",
238
+ bulkClear: "Effacer",
239
+ bulkAllOnPage: "Les {{count}} éléments de cette page sont sélectionnés.",
240
+ bulkSelectAllMatching: "Sélectionner les {{count}} correspondances",
241
+ bulkAllMatchingSelected: "Les {{count}} enregistrements correspondants sont tous sélectionnés.",
242
+ bulk: {
243
+ confirmDefault: "Ceci s'appliquera à {{count}} enregistrement(s).",
244
+ overLimit: "La sélection ({{count}}) dépasse la limite de l'action ({{limit}}). Réduisez la sélection pour continuer.",
245
+ affectedRecords: "Enregistrements concernés ({{count}}) :",
246
+ skippedIneligible: '{{count}} des enregistrements sélectionnés ne sont pas éligibles à cette action et seront ignorés.',
247
+ rowFallback: "Ligne {{index}}",
248
+ andMore: "… et {{count}} de plus",
249
+ processed: "{{count}} / {{total}} traités",
250
+ processedFailed: " · {{count}} en échec",
251
+ undonePrefix: "Annulé — ",
252
+ succeeded: "Réussis {{count}} / {{total}}",
253
+ resultFailed: " · Échecs {{count}}",
254
+ retry: "Réessayer",
255
+ downloadErrorCsv: "Télécharger le CSV d'erreurs",
256
+ cancel: "Annuler",
257
+ back: "Retour",
258
+ next: "Suivant",
259
+ run: "Exécuter",
260
+ running: "Exécution…",
261
+ undo: "Annuler",
262
+ undoing: "Annulation…",
263
+ done: "Terminé",
264
+ selectPlaceholder: "Sélectionner…",
265
+ loading: "Chargement…",
266
+ },
158
267
  actions: "Actions",
159
268
  edit: "Modifier",
160
269
  delete: "Supprimer",
@@ -180,7 +289,88 @@ const fr = {
180
289
  densityCycleShortHint: "Cliquer pour changer",
181
290
  },
182
291
  import: {
292
+ downloadTemplate: "Télécharger le modèle",
293
+ downloadTemplateHint: "Obtenez un CSV avec les bonnes colonnes (les champs obligatoires sont marqués d'un *).",
294
+ templateFileName: "{{object}}-import-template",
295
+ autoMatched: "Associé automatiquement",
296
+ autoMatchedSummary: "{{count}} colonne(s) associée(s) automatiquement — vérifiez et ajustez ci-dessous.",
297
+ confidence: {
298
+ high: "Confiance élevée",
299
+ medium: "Confiance moyenne",
300
+ low: "Confiance faible",
301
+ },
302
+ asyncQueued: "En file d'attente — préparation de l'import…",
303
+ asyncProcessing: "Import de {{processed}} lignes sur {{total}}… {{progress}} %",
304
+ asyncLargeHint: "Ce fichier est volumineux, il sera donc importé en arrière-plan.",
305
+ largeSampleNotice: "Aperçu des {{shown}} premières lignes sur {{total}}.",
306
+ cancelImport: "Annuler l'import",
307
+ importCancelled: "Import annulé",
308
+ resultsTruncated: "Affichage des {{count}} premiers résultats de lignes (sur {{total}}).",
309
+ createdCount: "{{count}} créé(s)",
310
+ updatedCount: "{{count}} mis à jour",
311
+ downloadFailed: "Télécharger les lignes en échec",
312
+ options: "Options d'import",
313
+ writeMode: "Lorsqu'une ligne correspond à un enregistrement existant",
314
+ writeModeOpt: {
315
+ insert: "Toujours créer",
316
+ update: "Mettre à jour l'existant (ignorer sans correspondance)",
317
+ upsert: "Mettre à jour si correspondance, sinon créer",
318
+ },
319
+ matchFields: "Correspondance sur",
320
+ matchFieldsPlaceholder: "Choisir le ou les champs de correspondance…",
321
+ matchFieldsHint: "Les lignes sont rapprochées des enregistrements existants via ces champs.",
322
+ needMatchFields: "Sélectionnez au moins un champ de correspondance.",
323
+ matchOnlyField: "(correspondance seule)",
324
+ optCreateOptions: "Conserver les valeurs d'option inconnues",
325
+ optRunAutomations: "Exécuter les automatisations et déclencheurs",
326
+ optTreatHistorical: "Importer comme données historiques",
327
+ optTreatHistoricalHint: "(importer les enregistrements terminés tels quels — ignorer les contrôles de la machine à états et conserver leurs horodatages et auteurs d'origine au lieu d'horodater maintenant)",
328
+ optSkipBlankKey: "Ignorer les lignes dont la valeur de correspondance est vide",
329
+ optBackground: "Importer en arrière-plan",
330
+ optBackgroundHint: "(s'exécute comme une tâche annulable)",
331
+ validate: "Valider les données",
332
+ validating: "Validation…",
333
+ validateHint: "Vérifier chaque ligne auprès du serveur avant l'import.",
334
+ validatePassed: "Les {{ok}} lignes sont toutes valides.",
335
+ validateFailed: "{{ok}} valides, {{errors}} en erreur.",
336
+ errorRowPrefix: "Ligne {{row}} : ",
337
+ referenceNotFound: "Aucun enregistrement correspondant à « {{value}} »",
338
+ referenceAmbiguous: "« {{value}} » correspond à plusieurs enregistrements — utilisez une valeur unique ou l'identifiant de l'enregistrement",
339
+ invalidBoolean: "« {{value}} » n'est pas une valeur vrai/faux valide",
340
+ invalidNumber: "« {{value}} » n'est pas un nombre valide",
341
+ invalidDate: "« {{value}} » n'est pas une date valide",
342
+ invalidOption: "« {{value}} » ne fait pas partie des options autorisées",
343
+ requiredValue: "Ce champ est obligatoire",
344
+ matchAmbiguous: "Correspond à plusieurs enregistrements existants — utilisez une valeur unique ou l'identifiant de l'enregistrement",
345
+ history: "Historique",
346
+ historyBack: "Retour à l'import",
347
+ historyDescription: "Imports récents pour cet objet.",
348
+ historyHint: "Tâches d'import en arrière-plan, les plus récentes d'abord.",
349
+ historyRefresh: "Actualiser",
350
+ historyLoading: "Chargement…",
351
+ historyEmpty: "Aucun import pour l'instant.",
352
+ historyUnsupported: "L'historique des imports n'est pas disponible pour cette source de données.",
353
+ historyColStatus: "Statut",
354
+ historyColRows: "Lignes",
355
+ historyColResult: "Résultat",
356
+ historyColTime: "Quand",
357
+ errorCount: "{{count}} erreurs",
358
+ undoImport: "Annuler l'import",
359
+ undoing: "Annulation…",
360
+ undoConfirm: "Annuler cet import ? Les enregistrements créés seront supprimés et les enregistrements mis à jour seront rétablis à leurs valeurs précédentes.",
361
+ reverted: "Annulé",
362
+ jobStatus: {
363
+ pending: "En attente",
364
+ running: "En cours",
365
+ succeeded: "Réussi",
366
+ failed: "Échec",
367
+ cancelled: "Annulé",
368
+ },
369
+ legacyReferenceBlocked: "Import bloqué : {{fields}} sont des champs de relation qui nécessitent la route d'import côté serveur pour convertir les noms en identifiants d'enregistrement, et cette connexion ne la prend pas en charge. Les importer en texte brut corromprait les données. Mettez à jour le backend/client, ou retirez l'association de ces colonnes et importez-les séparément.",
370
+ missingRequiredHint: "Impossible de continuer — champs obligatoires non associés : {{fields}}. Ajoutez une colonne correspondante à votre fichier, ou revenez en arrière et téléversez-en un qui la contient.",
371
+ legacyFallbackNotice: "Importé via un mode de compatibilité : cette connexion ne prend pas en charge la route d'import côté serveur, les valeurs ont donc été enregistrées comme texte sans conversion de type côté serveur. Mettez à jour le backend/client pour un import complet (conversion de type et résolution des relations).",
183
372
  title: "Importer {{object}}",
373
+ notAllowed: "Cet objet n'est pas ouvert à l'import.",
184
374
  stepUpload: "Télécharger",
185
375
  stepMapping: "Correspondance",
186
376
  stepPreview: "Aperçu",
@@ -256,6 +446,42 @@ const fr = {
256
446
  moreEvents: "+{{count}} de plus",
257
447
  },
258
448
  list: {
449
+ firstRunTitle: "Rien pour l'instant",
450
+ firstRunMessage: "Créez votre premier enregistrement pour commencer.",
451
+ noMatches: "Aucun enregistrement correspondant",
452
+ noMatchesMessage: "Aucun enregistrement ne correspond à vos filtres ou à votre recherche. Essayez de les ajuster ou de les effacer.",
453
+ loadErrorTitle: "Impossible de charger les enregistrements",
454
+ loadErrorMessage: "Une erreur s'est produite lors du chargement de ces données. Vérifiez votre connexion et réessayez.",
455
+ loadErrorForbiddenTitle: "Accès refusé",
456
+ loadErrorForbiddenMessage: "Vous n'avez pas la permission de consulter ces enregistrements. Contactez votre administrateur si vous pensez devoir y accéder.",
457
+ loadErrorUnauthorizedTitle: "Connexion requise",
458
+ loadErrorUnauthorizedMessage: "Votre session a expiré ou vous êtes déconnecté. Reconnectez-vous pour consulter ces enregistrements.",
459
+ loadErrorRejectedTitle: "La requête de cette vue a été rejetée",
460
+ loadErrorRejectedMessage: "Le serveur n’a pas pu traiter le filtre ou les options de requête de cette vue. Effacer les filtres suffit généralement ; si la vue est enregistrée ainsi, un administrateur doit la corriger.",
461
+ retry: "Réessayer",
462
+ managedBy: {
463
+ system: {
464
+ title: "Rien pour l'instant",
465
+ message: "Les entrées apparaissent automatiquement lorsque leur action source s'exécute (par ex. Soumettre pour approbation, Partager, Inviter). Déclenchez l'une d'elles sur un enregistrement source pour créer une ligne.",
466
+ },
467
+ appendOnly: {
468
+ title: "Aucun événement enregistré",
469
+ message: "Ceci est un journal d'audit immuable. Les lignes sont écrites par la plateforme lorsque des événements surviennent — vous pouvez exporter l'historique mais pas créer d'entrées ici.",
470
+ },
471
+ betterAuth: {
472
+ title: "Aucun enregistrement d'identité",
473
+ message: "Ces enregistrements sont créés par le fournisseur d'authentification — via la connexion, le provisionnement et les flux de sécurité — et non ajoutés à la main ici.",
474
+ },
475
+ betterAuthUser: {
476
+ title: "Aucun utilisateur pour l'instant",
477
+ message: "Les comptes utilisateur sont provisionnés par le fournisseur d'authentification et ne sont pas créés ici. Invitez vos collègues dans votre organisation : ils apparaissent automatiquement à leur première connexion (provisionnement SSO à la volée). Les utilisateurs finaux arrivent lorsqu'ils s'inscrivent via votre application.",
478
+ },
479
+ betterAuthTeam: {
480
+ title: "Aucune équipe pour l'instant",
481
+ message: "Les équipes regroupent les membres au sein d'une organisation. Créez-en une avec « Créer une équipe », ou elles arrivent via les flux de provisionnement d'organisation et SSO de votre fournisseur d'authentification.",
482
+ },
483
+ },
484
+ refresh: "Actualiser",
259
485
  loading: 'Loading records...',
260
486
  recordCount: "{{count}} enregistrements",
261
487
  recordCountOne: "{{count}} enregistrement",
@@ -267,6 +493,8 @@ const fr = {
267
493
  filterRecords: "Filtrer les enregistrements",
268
494
  sort: "Trier",
269
495
  sortRecords: "Trier les enregistrements",
496
+ sortByIdSuffix: "(par ID)",
497
+ sortRelationalHint: "Les colonnes qui pointent vers un autre enregistrement ne sont pas listées : elles ne peuvent être triées que par l'ID stocké, et non par le nom affiché dans la cellule. Pour trier par ce nom, ajoutez un champ de formule qui le contient.",
270
498
  group: "Grouper",
271
499
  groupBy: "Grouper par",
272
500
  export: "Exporter",
@@ -296,6 +524,11 @@ const fr = {
296
524
  recordEditingTitle: "Modification des enregistrements",
297
525
  },
298
526
  managedByBadge: {
527
+ systemWritable: {
528
+ short: "Schéma de la plateforme",
529
+ title: "Défini par la plateforme, modifiable par l'administrateur",
530
+ body: "Le schéma de cet objet est défini par la plateforme, mais ses lignes vous appartiennent : vous pouvez les créer et les modifier ici. Qui peut écrire est déterminé par l'administration déléguée et la sécurité au niveau des enregistrements, pas par ce badge.",
531
+ },
299
532
  config: {
300
533
  short: "Config admin",
301
534
  title: "Configuration administrateur",
@@ -318,6 +551,7 @@ const fr = {
318
551
  },
319
552
  },
320
553
  kanban: {
554
+ uncategorized: "Non catégorisé",
321
555
  addCard: "Ajouter une carte",
322
556
  addColumn: "Ajouter une colonne",
323
557
  moveCard: "Déplacer la carte",
@@ -339,12 +573,92 @@ const fr = {
339
573
  },
340
574
  },
341
575
  gantt: {
576
+ viewMode: {
577
+ day: "Jour",
578
+ week: "Semaine",
579
+ month: "Mois",
580
+ quarter: "Trimestre",
581
+ year: "Année",
582
+ },
583
+ row: {
584
+ expand: "Développer",
585
+ collapse: "Réduire",
586
+ open: "Ouvrir les détails",
587
+ },
588
+ aria: {
589
+ taskList: "Liste des tâches",
590
+ },
591
+ tooltip: {
592
+ days: "j",
593
+ },
594
+ menu: {
595
+ view: "Afficher les détails",
596
+ edit: "Modifier en ligne",
597
+ delete: "Supprimer",
598
+ addPredecessor: "Ajouter un prédécesseur…",
599
+ addSuccessor: "Ajouter un successeur…",
600
+ removeDependency: "Supprimer la dépendance",
601
+ noCandidates: "Aucune tâche disponible",
602
+ searchTasks: "Rechercher des tâches…",
603
+ },
604
+ delete: {
605
+ title: "Supprimer cette tâche ?",
606
+ body: "« {{title}} » sera définitivement supprimée. Cette action est irréversible.",
607
+ cancel: "Annuler",
608
+ confirm: "Supprimer",
609
+ deleting: "Suppression…",
610
+ },
611
+ drawer: {
612
+ fallbackTitle: "Détails de la tâche",
613
+ },
614
+ linkType: {
615
+ fs: "Fin → Début",
616
+ ss: "Début → Début",
617
+ ff: "Fin → Fin",
618
+ sf: "Début → Fin",
619
+ },
620
+ conflict: {
621
+ title: "Conflit de planning",
622
+ body: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche(s) concernée(s) ?",
623
+ confirm: "Replanifier automatiquement",
624
+ cancel: "Laisser tel quel",
625
+ },
626
+ autoScheduleDlg: {
627
+ title: "Planification automatique",
628
+ body: "Décaler {count} tâche(s) plus tard pour respecter les liens de dépendance ?",
629
+ skipped: "{count} tâche(s) verrouillée(s) violent aussi les liens et ont été ignorées.",
630
+ confirm: "Appliquer",
631
+ cancel: "Annuler",
632
+ none: "Toutes les dépendances sont respectées — rien à replanifier.",
633
+ },
634
+ resource: {
635
+ header: "Ressource",
636
+ peak: "Pic",
637
+ over: "surchargée",
638
+ empty: "Aucune tâche à affecter.",
639
+ },
640
+ readOnly: "Lecture seule",
641
+ readOnlyHint: "L'édition est désactivée pour cette vue.",
642
+ lockedHint: "Aucune autorisation de modification",
643
+ writeFailed: "Échec de l'enregistrement — la modification a été annulée",
342
644
  column: {
343
645
  taskName: "Nom de la tâche",
344
646
  start: "Début",
345
647
  end: "Fin",
346
648
  },
347
649
  toolbar: {
650
+ thisWeek: "Cette semaine",
651
+ thisMonth: "Ce mois-ci",
652
+ viewMode: "Granularité de la chronologie",
653
+ enterFullscreen: "Passer en plein écran",
654
+ exitFullscreen: "Quitter le plein écran",
655
+ criticalPath: "Mettre en évidence le chemin critique",
656
+ autoSchedule: "Planifier automatiquement les dépendances",
657
+ exportPng: "Exporter en PNG",
658
+ exportPdf: "Exporter en PDF",
659
+ saveLayout: "Enregistrer la disposition",
660
+ undo: "Annuler",
661
+ redo: "Rétablir",
348
662
  prevPeriod: "Période précédente",
349
663
  nextPeriod: "Période suivante",
350
664
  zoomIn: "Zoom avant",
@@ -390,6 +704,11 @@ const fr = {
390
704
  redo: 'Redo',
391
705
  },
392
706
  detail: {
707
+ editInlineHint: "Double-cliquez pour modifier",
708
+ systemActor: "Système",
709
+ unknownUser: "Inconnu",
710
+ created: "Créé",
711
+ updated: "Mis à jour",
393
712
  back: "Retour",
394
713
  edit: "Modifier",
395
714
  editInline: "Modifier",
@@ -439,6 +758,18 @@ const fr = {
439
758
  attachmentCount: "{{count}} pièce jointe",
440
759
  attachmentCountPlural: "{{count}} pièces jointes",
441
760
  removeAttachment: "Supprimer la pièce jointe",
761
+ // Record Attachments panel (enable.files, objectstack#4358)
762
+ attachments: "Pièces jointes",
763
+ uploadAttachment: "Téléverser",
764
+ loadingAttachments: "Chargement des pièces jointes…",
765
+ noAttachments: "Aucune pièce jointe pour le moment. Téléversez un fichier pour commencer.",
766
+ downloadAttachment: "Télécharger",
767
+ deleteAttachment: "Supprimer la pièce jointe",
768
+ attachmentDeleteDenied: "Seule la personne qui l'a téléversée ou une personne pouvant modifier cet enregistrement peut supprimer cette pièce jointe.",
769
+ attachmentParentAccessDenied: "Vous n'avez pas accès pour joindre des fichiers à cet enregistrement.",
770
+ attachmentDownloadDenied: "Vous n'avez pas accès pour télécharger cette pièce jointe.",
771
+ attachmentAuthRequired: "Veuillez vous connecter pour télécharger cette pièce jointe.",
772
+ attachmentPermissionDenied: "Vous n'avez pas la permission de faire cela.",
442
773
  unifiedDiff: "Vue unifiée",
443
774
  sideBySideDiff: "Vue côte à côte",
444
775
  noChanges: "Aucune modification",
@@ -486,9 +817,15 @@ const fr = {
486
817
  saving: "Enregistrement…",
487
818
  lockedByApproval: "Verrouillé pour approbation",
488
819
  lockedTooltip: "Cet enregistrement a une demande d'approbation en attente ; la modification est verrouillée",
820
+ writeStrippedTitle: "Certains champs n'ont pas été enregistrés",
821
+ writeStrippedReadonly: "En lecture seule, donc non enregistré : {{fields}}",
822
+ writeStrippedByState: "Non modifiable dans l'état actuel de cet enregistrement, donc non enregistré : {{fields}}",
823
+ approvalPendingEditable: "En approbation · modifiable",
824
+ approvalPendingTooltip: "Cet enregistrement a une demande d'approbation en attente ; cette étape autorise encore la modification",
489
825
  cancelApproval: "Annuler l'approbation",
490
826
  cancelApprovalInFlight: "Annulation…",
491
827
  cancelApprovalTooltip: "Annuler la demande d'approbation en attente pour déverrouiller l'enregistrement",
828
+ cancelApprovalTooltipUnlocked: "Annuler la demande d'approbation en attente",
492
829
  cancelApprovalFailed: "Échec de l'annulation de l'approbation",
493
830
  cancelApprovalUnavailable: "L'annulation des approbations n'est pas prise en charge par cette source de données",
494
831
  linkCopied: "Lien copié dans le presse-papiers",
@@ -602,6 +939,35 @@ const fr = {
602
939
  resetZoom: "Réinitialiser le zoom",
603
940
  },
604
941
  dashboard: {
942
+ noRows: "Aucune ligne",
943
+ pickMeasures: "Choisissez des mesures (valeurs) pour ce widget de dataset.",
944
+ datasetUnsupported: "Cette source de données ne prend pas en charge les requêtes de dataset.",
945
+ details: "Détails",
946
+ exportCsv: "Exporter en CSV",
947
+ openInList: "Ouvrir dans la liste",
948
+ filters: {
949
+ label: "Filtres du tableau de bord",
950
+ dateRange: "Plage de dates",
951
+ allTime: "Depuis toujours",
952
+ custom: "Personnalisé…",
953
+ all: "Tout",
954
+ reset: "Réinitialiser",
955
+ range: {
956
+ today: "Aujourd'hui",
957
+ yesterday: "Hier",
958
+ this_week: "Cette semaine",
959
+ last_week: "La semaine dernière",
960
+ this_month: "Ce mois-ci",
961
+ last_month: "Le mois dernier",
962
+ this_quarter: "Ce trimestre",
963
+ last_quarter: "Le trimestre dernier",
964
+ this_year: "Cette année",
965
+ last_year: "L'année dernière",
966
+ last_7_days: "7 derniers jours",
967
+ last_30_days: "30 derniers jours",
968
+ last_90_days: "90 derniers jours",
969
+ },
970
+ },
605
971
  addWidget: "Ajouter un widget",
606
972
  removeWidget: "Supprimer un widget",
607
973
  editLayout: "Modifier la mise en page",
@@ -729,6 +1095,7 @@ const fr = {
729
1095
  navTypeGroup: "Groupe",
730
1096
  navTypeSeparator: "Séparateur",
731
1097
  navTypeAction: "Action",
1098
+ navTypeComponent: "Composant",
732
1099
  navEditIcon: "Modifier l'icône",
733
1100
  navToggleVisible: "Basculer la visibilité",
734
1101
  navHidden: "Masqué",
@@ -830,8 +1197,199 @@ const fr = {
830
1197
  },
831
1198
  },
832
1199
  console: {
1200
+ settingsHub: {
1201
+ title: "Paramètres",
1202
+ subtitle: "Configurez votre espace de travail, vos intégrations et vos indicateurs de fonctionnalité.",
1203
+ loadError: "Échec du chargement des paramètres",
1204
+ empty: "Aucun paramètre enregistré. Les plugins peuvent enregistrer des manifestes de paramètres via le SettingsService.",
1205
+ settingsCount: "{{n}} paramètres",
1206
+ beta: "Bêta",
1207
+ categories: {
1208
+ Workspace: "Espace de travail",
1209
+ Communication: "Communication",
1210
+ Security: "Sécurité",
1211
+ Infrastructure: "Infrastructure",
1212
+ Beta: "Bêta",
1213
+ Other: "Autre",
1214
+ },
1215
+ },
1216
+ objectData: {
1217
+ badge: "Données",
1218
+ description: "Extrait de données défini par l'URL — non lié à une vue enregistrée.",
1219
+ filteredBy: "Filtré par",
1220
+ removeFilter: "Supprimer le filtre {{field}}",
1221
+ saveAsView: "Enregistrer comme vue",
1222
+ noAccessTitle: "Accès refusé",
1223
+ noAccess: "Vous n'avez pas l'autorisation de consulter ces données.",
1224
+ },
1225
+ identityImport: {
1226
+ policyTitle: "Configuration de connexion pour les utilisateurs importés",
1227
+ policy: {
1228
+ auto: "Automatique (recommandé)",
1229
+ invite: "Envoyer des invitations",
1230
+ temporary: "Mots de passe temporaires",
1231
+ none: "Aucun mot de passe (identité seulement)",
1232
+ },
1233
+ policyHint: {
1234
+ auto: "Les utilisateurs joignables reçoivent une invitation (e-mail ou SMS) ; ceux que nous ne pouvons pas joindre reçoivent un mot de passe à usage unique, affiché UNE SEULE FOIS sur l'écran de résultat. Fonctionne avec ou sans service e-mail/SMS.",
1235
+ invite: "Chaque utilisateur créé reçoit un e-mail de définition de mot de passe (ou un SMS d'invitation pour les lignes avec téléphone uniquement). Nécessite un service e-mail/SMS configuré — les lignes injoignables échouent.",
1236
+ temporary: "Pour les déploiements sans e-mail/SMS : chaque utilisateur créé reçoit un mot de passe à usage unique, affiché UNE SEULE FOIS sur l'écran de résultat. La première connexion impose un changement.",
1237
+ none: "Les utilisateurs se connectent d'abord avec un code OTP par téléphone, un lien magique ou un lien de réinitialisation, puis définissent leur propre mot de passe.",
1238
+ },
1239
+ passwordsNote: "Mots de passe temporaires — affichés une seule fois, jamais stockés. Enregistrez-les maintenant ; chaque utilisateur doit changer le sien à la première connexion.",
1240
+ passwordsMore: "Autres entrées omises — utilisez le téléchargement.",
1241
+ passwordsDownload: "Télécharger le CSV",
1242
+ },
1243
+ ai: {
1244
+ usage: {
1245
+ title: "Utilisation de l'IA",
1246
+ meterBuild: "Créer",
1247
+ meterAsk: "Demander",
1248
+ statusOk: "Il en reste beaucoup",
1249
+ statusLow: "Bientôt épuisé",
1250
+ statusFull: "Limite atteinte",
1251
+ resetsDaily: "Réinitialisation ce soir",
1252
+ resetsMonthly: "Réinitialisation au prochain cycle",
1253
+ ctaUpgrade: "Passer à l'offre supérieure pour continuer",
1254
+ ctaTopUp: "Ajouter des crédits pour continuer",
1255
+ ariaLabel: "Utilisation de l'IA : {{status}}",
1256
+ },
1257
+ workspaceTitle: "Espace de travail IA",
1258
+ workspaceSubtitle: "Posez des questions, inspectez et reprenez vos conversations",
1259
+ openChats: "Ouvrir les discussions",
1260
+ chats: "Discussions",
1261
+ chatsDescription: "Parcourez et gérez les conversations avec l'IA.",
1262
+ share: "Partager",
1263
+ shareTitle: "Partager cette conversation",
1264
+ shareDisabledTitle: "Commencez à discuter pour activer le partage",
1265
+ newChat: "Nouveau",
1266
+ searchChats: "Rechercher des discussions...",
1267
+ noChatsYet: "Aucune discussion pour l'instant",
1268
+ noChatsDescription: "Démarrez une nouvelle conversation pour la voir ici.",
1269
+ noMatchingChats: "Aucune discussion correspondante.",
1270
+ newConversation: "Nouvelle conversation",
1271
+ renameConversation: "Renommer la conversation",
1272
+ deleteConversation: "Supprimer la conversation",
1273
+ saveRename: "Enregistrer le nom",
1274
+ cancelRename: "Annuler le changement de nom",
1275
+ loadingHistory: "Chargement de l'historique de la conversation...",
1276
+ conversationReady: "Conversation prête",
1277
+ preparingConversation: "Préparation d'une nouvelle conversation",
1278
+ offlineDemoMode: "Mode démo hors ligne — liste des agents indisponible",
1279
+ sendFailedRateLimited: "Vous envoyez des messages trop rapidement. Votre message est conservé ci-dessous — patientez un instant puis réessayez.",
1280
+ sendFailedGeneric: "Impossible d'envoyer votre message. Il est conservé ci-dessous — veuillez réessayer.",
1281
+ askAgent: "Demander à {{agent}}...",
1282
+ assistant: "Assistant",
1283
+ liveCanvas: "Aperçu en direct — {{app}} (brouillon)",
1284
+ liveCanvasUnlisted: "Application en direct — {{app}} (non répertoriée jusqu'à publication)",
1285
+ loadingAgents: "Chargement des agents...",
1286
+ askAnything: "Posez n'importe quelle question...",
1287
+ emptyTitle: "Démarrer une conversation",
1288
+ emptyDescription: "Posez n'importe quelle question — l'assistant a accès au contexte de votre application actuelle.",
1289
+ switchAssistant: "Changer d'assistant",
1290
+ chooseAgent: "Choisir un assistant…",
1291
+ empty: {
1292
+ build: {
1293
+ title: "Créer avec l'IA",
1294
+ 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.",
1295
+ },
1296
+ ask: {
1297
+ title: "Interroger vos données",
1298
+ description: "Posez des questions sur vos enregistrements — comptages, listes et synthèses sur les données auxquelles vous avez accès.",
1299
+ },
1300
+ editApp: {
1301
+ title: "Modification de « {{app}} »",
1302
+ titleGeneric: "Modifier cette application",
1303
+ 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.",
1304
+ },
1305
+ },
1306
+ clearConversation: "Effacer",
1307
+ sendHint: "pour envoyer",
1308
+ agentActivity: "Activité de l'agent",
1309
+ toolCompleted: "Terminé",
1310
+ toolRunning: "En cours",
1311
+ toolAwaitingApproval: "En attente d'approbation",
1312
+ toolFailed: "Échec",
1313
+ toolDetailsHidden: "Les entrées des outils et les résultats bruts sont masqués dans cette vue.",
1314
+ copy: "Copier",
1315
+ copied: "Copié",
1316
+ regenerate: "Régénérer",
1317
+ model: "Modèle",
1318
+ submit: "Envoyer",
1319
+ uploadFiles: "Téléverser des fichiers",
1320
+ stopResponse: "Arrêter la réponse",
1321
+ trace: "trace",
1322
+ viewTrace: "Afficher la trace",
1323
+ nextSteps: "Et ensuite",
1324
+ publishDrafts: "Publier",
1325
+ publishOk: "Publié — les objets sont maintenant actifs.",
1326
+ seedWarn: "Publié, mais certaines données d'exemple n'ont pas pu être chargées.",
1327
+ openBuiltApp: "Ouvrir l'application",
1328
+ designBuiltApp: "Concevoir dans Studio",
1329
+ previewDraft: "Aperçu",
1330
+ previewApp: "Aperçu de l'application",
1331
+ resizeSplit: "Redimensionner la discussion et l'aperçu",
1332
+ hideChats: "Masquer les discussions",
1333
+ showChats: "Afficher les discussions",
1334
+ planTitle: "Plan proposé",
1335
+ planQuestions: "Confirmer avant de créer",
1336
+ planAssumptions: "Hypothèses",
1337
+ planApproveHint: "Répondez pour approuver ou ajuster ce plan.",
1338
+ planApprove: "Créer",
1339
+ planAdjust: "Ajuster",
1340
+ justNow: "à l'instant",
1341
+ minutesAgo: "il y a {{count}} min",
1342
+ hoursAgo: "il y a {{count}} h",
1343
+ daysAgo: "il y a {{count}} j",
1344
+ agentLabels: {
1345
+ ask: "Demander",
1346
+ build: "Créer",
1347
+ dataChat: "Assistant",
1348
+ metadataAssistant: "Assistant de métadonnées",
1349
+ },
1350
+ suggestions: {
1351
+ dataChat: {
1352
+ userCount: "Combien d'utilisateurs y a-t-il dans le système ? Liste leurs adresses e-mail.",
1353
+ recentRecords: "Liste les 5 enregistrements créés le plus récemment.",
1354
+ recordCounts: "Compte les enregistrements pour chaque objet.",
1355
+ },
1356
+ metadataAssistant: {
1357
+ buildCrm: "Crée un CRM commercial — clients, contacts et un pipeline d'affaires que je peux totaliser par étape.",
1358
+ buildApp: "Crée un suivi de projets — projets, tâches avec responsables et échéances, et un tableau par statut.",
1359
+ buildFlow: "Conçois un service d'assistance — tickets avec priorité, un flux de statuts et des liens vers les clients.",
1360
+ buildInventory: "Crée une application de stock — produits, niveaux de stock, fournisseurs et visibilité des stocks faibles.",
1361
+ buildRecruiting: "Crée un suivi de candidatures — candidats, postes ouverts, étapes d'entretien et notes.",
1362
+ },
1363
+ generic: {
1364
+ help: "En quoi peux-tu m'aider ?",
1365
+ availableObjects: "Liste les objets de données disponibles.",
1366
+ recentActivity: "Résume mon activité récente.",
1367
+ },
1368
+ editApp: {
1369
+ addField: "Ajoute un champ à l'un des objets.",
1370
+ addObject: "Ajoute un nouvel objet et relie-le à un objet existant.",
1371
+ addDashboard: "Ajoute un tableau de bord pour les indicateurs clés.",
1372
+ addAutomation: "Ajoute une automatisation — une approbation, un flux de statuts ou une notification.",
1373
+ },
1374
+ },
1375
+ changesTitle: "Confirmer les modifications",
1376
+ changesConfirmed: "Confirmé",
1377
+ changesConfirm: "Confirmer",
1378
+ changesConfirmHint: "Répondez pour confirmer ou ajuster cette modification.",
1379
+ changeVerb: {
1380
+ createObject: "Créer un objet",
1381
+ addField: "Ajouter un champ",
1382
+ modifyField: "Modifier un champ",
1383
+ deleteField: "Supprimer un champ",
1384
+ createMetadata: "Créer",
1385
+ updateMetadata: "Modifier",
1386
+ createSeed: "Générer des données d'exemple",
1387
+ createPackage: "Créer un package d'application",
1388
+ },
1389
+ },
833
1390
  title: "Console ObjectStack",
834
1391
  initializing: "Initialisation de l'application...",
1392
+ loadingHint: "La configuration d'un nouvel environnement peut prendre quelques instants.",
835
1393
  breadcrumb: {
836
1394
  dashboards: "Tableaux de bord",
837
1395
  pages: "Pages",
@@ -873,6 +1431,7 @@ const fr = {
873
1431
  toggleDarkMode: "Basculer le mode sombre",
874
1432
  },
875
1433
  commandPalette: {
1434
+ title: "Palette de commandes",
876
1435
  placeholder: "Tapez une commande ou recherchez...",
877
1436
  noResults: "Aucun résultat trouvé.",
878
1437
  objects: "Objets",
@@ -906,6 +1465,14 @@ const fr = {
906
1465
  system: "Système",
907
1466
  },
908
1467
  objectView: {
1468
+ viewTypeTree: "Arborescence",
1469
+ viewTypeTreeDesc: "Imbriquer les enregistrements auto-référencés en hiérarchie via un champ parent.",
1470
+ parentField: "Champ parent",
1471
+ parentFieldHelp: "Le champ pointant vers l'enregistrement parent (même objet) qui définit la hiérarchie. Seuls les champs auto-référencés conviennent.",
1472
+ viewName: "Nom",
1473
+ viewNameHelp: "Clé technique (snake_case). Remplie automatiquement à partir du titre — modifiable si vous le souhaitez.",
1474
+ viewNameRequired: "Saisissez une clé (minuscules, chiffres, tiret bas). Non remplie automatiquement pour les titres non latins.",
1475
+ viewNameInvalid: "Utilisez des minuscules, des chiffres et des tirets bas ; commencez par une lettre ou un tiret bas.",
909
1476
  systemViewReadonly: 'System view defined in code - duplicate to customize.',
910
1477
  expandToPage: 'Open as full page',
911
1478
  objectNotFound: "Objet introuvable",
@@ -1119,7 +1686,28 @@ const fr = {
1119
1686
  },
1120
1687
  },
1121
1688
  auth: {
1689
+ setPassword: {
1690
+ title: "Définir un mot de passe de secours",
1691
+ description: "Vous vous êtes connecté via l'authentification unique. Définissez un mot de passe local afin de pouvoir toujours vous connecter directement à cet environnement si le SSO devenait indisponible.",
1692
+ email: "E-mail",
1693
+ newPassword: "Nouveau mot de passe",
1694
+ confirmPassword: "Confirmer le mot de passe",
1695
+ submit: "Définir le mot de passe",
1696
+ submitting: "Enregistrement…",
1697
+ success: "Mot de passe local défini",
1698
+ failed: "Impossible de définir le mot de passe",
1699
+ passwordsMismatch: "Les mots de passe ne correspondent pas",
1700
+ noSession: "Votre session a expiré.",
1701
+ backToSignIn: "Se reconnecter",
1702
+ },
1122
1703
  login: {
1704
+ signingIn: "Connexion en cours…",
1705
+ ssoHandoff: "Continuer vers {{target}}",
1706
+ devAdminHint: {
1707
+ title: "Instance de développement",
1708
+ body: "Connectez-vous avec l'administrateur de développement prédéfini :",
1709
+ dismiss: "Ignorer",
1710
+ },
1123
1711
  title: "Connectez-vous à votre compte",
1124
1712
  description: "Entrez votre e-mail et votre mot de passe pour continuer",
1125
1713
  emailLabel: "E-mail",
@@ -1132,6 +1720,7 @@ const fr = {
1132
1720
  noAccountText: "Vous n'avez pas de compte ?",
1133
1721
  signUpText: "S'inscrire",
1134
1722
  errors: {
1723
+ oauthCallbackFailed: "L'authentification unique n'a pas pu aboutir — le lien de connexion a expiré ou a déjà été utilisé. Veuillez réessayer.",
1135
1724
  invalidCredentials: "E-mail ou mot de passe invalide. Veuillez réessayer.",
1136
1725
  emailNotVerified: "Veuillez vérifier votre adresse e-mail avant de vous connecter.",
1137
1726
  },
@@ -1257,6 +1846,40 @@ const fr = {
1257
1846
  shell: {
1258
1847
  tenantHostHint: "Vous vous connectez à cet espace de travail",
1259
1848
  },
1849
+ layout: {
1850
+ headline: "Créez des applications métier puissantes, plus vite.",
1851
+ subhead: "La plateforme universelle pour la gestion des données, les workflows et l'analytique en entreprise.",
1852
+ },
1853
+ remediation: {
1854
+ signOut: "Se déconnecter à la place",
1855
+ password: {
1856
+ title: "Votre mot de passe a expiré",
1857
+ fallbackMessage: "Veuillez définir un nouveau mot de passe pour continuer.",
1858
+ current: "Mot de passe actuel",
1859
+ next: "Nouveau mot de passe",
1860
+ confirm: "Confirmer le nouveau mot de passe",
1861
+ submit: "Changer le mot de passe et continuer",
1862
+ submitting: "Mise à jour…",
1863
+ mismatch: "Les nouveaux mots de passe ne correspondent pas.",
1864
+ failed: "Impossible de changer le mot de passe.",
1865
+ },
1866
+ mfa: {
1867
+ title: "Configurer l'authentification à deux facteurs",
1868
+ fallbackMessage: "Votre organisation exige une application d'authentification pour continuer.",
1869
+ confirmPassword: "Confirmez votre mot de passe",
1870
+ continue: "Continuer",
1871
+ preparing: "Préparation…",
1872
+ enrollFailed: "Impossible de démarrer l'enrôlement.",
1873
+ scanTitle: "Scannez avec votre application d'authentification",
1874
+ scanBody: "Scannez ce QR code avec Google Authenticator, 1Password, Authy, etc., puis saisissez le code à 6 chiffres.",
1875
+ backupTitle: "Enregistrez vos codes de secours",
1876
+ backupBody: "Conservez-les en lieu sûr — chacun peut être utilisé une fois si vous perdez votre appareil.",
1877
+ codeLabel: "Code à 6 chiffres",
1878
+ verify: "Vérifier et continuer",
1879
+ verifying: "Vérification…",
1880
+ invalidCode: "Code invalide. Veuillez réessayer.",
1881
+ },
1882
+ },
1260
1883
  },
1261
1884
  profile: {
1262
1885
  title: "Profil",
@@ -1321,11 +1944,15 @@ const fr = {
1321
1944
  settings: "Paramètres de l'espace de travail",
1322
1945
  },
1323
1946
  help: {
1947
+ onThisPage: "Sur cette page",
1948
+ keyboardShortcuts: "Raccourcis clavier",
1324
1949
  appDocs: 'Documentation de cette app',
1325
1950
  allDocs: 'Toute la documentation',
1326
1951
  onlineDocs: 'Documentation en ligne',
1327
1952
  },
1328
1953
  sidebar: {
1954
+ packageManagement: "Gestion des packages",
1955
+ searchNavigation: "Rechercher dans la navigation...",
1329
1956
  settings: "Paramètres",
1330
1957
  help: "Aide",
1331
1958
  helpTooltip: "Aide et documentation",
@@ -1342,14 +1969,66 @@ const fr = {
1342
1969
  removeFromFavorites: "Retirer {{name}} des favoris",
1343
1970
  },
1344
1971
  topbar: {
1972
+ openAssistant: "Ouvrir l'assistant {{name}}",
1973
+ offline: "Hors ligne",
1974
+ usersOnline: "Utilisateurs actuellement en ligne",
1975
+ switchView: "Changer de vue",
1976
+ switchObject: "Changer d'objet",
1977
+ connection: {
1978
+ connected: "Connecté",
1979
+ connecting: "Connexion...",
1980
+ reconnecting: "Reconnexion...",
1981
+ disconnected: "Déconnecté",
1982
+ error: "Erreur de connexion",
1983
+ },
1984
+ stage: {
1985
+ preview: "Aperçu",
1986
+ beta: "Bêta",
1987
+ tooltip: "Cette plateforme est en avant-première — les fonctionnalités peuvent changer.",
1988
+ },
1345
1989
  aiAssistant: "Assistant IA",
1346
1990
  designInStudio: "Concevoir dans Studio",
1347
1991
  },
1348
1992
  home: {
1993
+ build: {
1994
+ title: "Créer une application",
1995
+ subtitle: "Partir de zéro — concevez les objets, formulaires, automatisations et interfaces.",
1996
+ },
1997
+ template: {
1998
+ title: "Partir d'un modèle",
1999
+ subtitle: "Installez une application modèle depuis la place de marché et personnalisez-la.",
2000
+ },
2001
+ welcomeAdminDescription: "Décrivez votre activité en une phrase — l'IA génère les objets, les écrans, les API et les outils d'agent. Ou configurez tout vous-même depuis le menu de gauche.",
2002
+ welcomeAdminDescriptionNoBuild: "Configurez votre première application depuis le menu Administration à gauche. Une fois les données en place, l'assistant IA pourra vous aider à les explorer.",
2003
+ welcomeAdminDescriptionNoAi: "Configurez votre première application depuis le menu Administration à gauche.",
2004
+ noAppsTitle: "Aucune application pour l'instant",
2005
+ noAppsDescription: "Votre espace de travail est en cours de configuration — les applications partagées par votre administrateur apparaîtront ici.",
2006
+ buildWithAI: "Créer avec l'IA",
2007
+ askAI: "Demander à l'IA",
2008
+ recoveryReminder: {
2009
+ message: "Définissez un mot de passe de secours afin de pouvoir vous connecter même si l'authentification unique est indisponible.",
2010
+ cta: "Définir le mot de passe",
2011
+ dismiss: "Ignorer",
2012
+ },
2013
+ pendingDrafts: {
2014
+ message: "Vous avez {{count}} modification(s) non publiée(s) — publiez-les pour les activer.",
2015
+ cta: "Publier",
2016
+ publishing: "Publication…",
2017
+ published: "Publié ! Vos modifications sont actives.",
2018
+ publishFailed: "Échec de la publication",
2019
+ },
1349
2020
  title: "Accueil",
1350
2021
  subtitle: "Tableau de bord de votre espace de travail",
1351
2022
  nav: "Accueil",
1352
2023
  allApps: "Toutes les applications",
2024
+ yourApps: "Vos applications",
2025
+ showMoreApps: "Plus",
2026
+ showLess: "Afficher moins",
2027
+ continueEmpty: "Les éléments que vous ouvrez apparaîtront ici.",
2028
+ actionCenter: {
2029
+ title: "Nécessite votre attention",
2030
+ empty: "Vous êtes à jour",
2031
+ },
1353
2032
  loading: "Chargement de l'espace de travail...",
1354
2033
  recent: "Récent",
1355
2034
  starred: "Favoris",
@@ -1401,7 +2080,21 @@ const fr = {
1401
2080
  },
1402
2081
  },
1403
2082
  layout: {
2083
+ systemNav: {
2084
+ systemSettings: "Paramètres système",
2085
+ applications: "Applications",
2086
+ appMarketplace: "Place de marché d'applications",
2087
+ objectManager: "Gestionnaire d'objets",
2088
+ users: "Utilisateurs",
2089
+ organizations: "Organisations",
2090
+ roles: "Rôles",
2091
+ configuration: "Configuration",
2092
+ createApp: "Créer une application",
2093
+ },
1404
2094
  appSwitcher: {
2095
+ switchApplication: "Changer d'application",
2096
+ appsAvailable: "{{count}} applications disponibles",
2097
+ editNavigation: "Modifier la navigation",
1405
2098
  home: "Accueil",
1406
2099
  addApp: "Ajouter une application",
1407
2100
  editApp: "Modifier l'application",
@@ -1491,10 +2184,11 @@ const fr = {
1491
2184
  requiredError: "{{label}} est obligatoire",
1492
2185
  cancel: "Annuler",
1493
2186
  confirm: "Confirmer",
2187
+ uploading: "Téléversement…",
1494
2188
  defaultActionTitle: "Action",
1495
2189
  ok: "OK",
1496
- lookupPlaceholder: "Coller l'ID d'enregistrement (UUID) pour {{label}}",
1497
- lookupHelpText: "Entrez l'ID de l'enregistrement de l'objet référencé. Un sélecteur sera bientôt ajouté.",
2190
+ lookupPlaceholder: "ID d'enregistrement pour {{label}}",
2191
+ 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.",
1498
2192
  },
1499
2193
  actionConfirm: {
1500
2194
  title: "Confirmer l’action",
@@ -1519,6 +2213,8 @@ const fr = {
1519
2213
  updateFailed: "Impossible de mettre à jour la navigation",
1520
2214
  },
1521
2215
  objectActions: {
2216
+ resetPackageSetConfirm: "Ce jeu d'autorisations est fourni avec un package installé et ne peut pas être supprimé. La suppression le réinitialise à la version livrée et abandonne vos personnalisations dans cet environnement. Continuer ?",
2217
+ resetPackageSetSuccess: "Jeu d'autorisations réinitialisé à la version livrée",
1522
2218
  deleteSuccess: "{{label}} supprimé avec succès",
1523
2219
  deleteFailed: "Impossible de supprimer {{label}}",
1524
2220
  noRecordId: "Aucun ID d'enregistrement fourni",
@@ -1683,6 +2379,7 @@ const fr = {
1683
2379
  },
1684
2380
  },
1685
2381
  organizations: {
2382
+ create: "Créer un espace de travail",
1686
2383
  mine: "Mes organisations",
1687
2384
  title: "Organisations",
1688
2385
  heading: "Vos organisations",
@@ -1696,6 +2393,11 @@ const fr = {
1696
2393
  noMatches: "Aucune organisation ne correspond à votre recherche.",
1697
2394
  },
1698
2395
  notifications: {
2396
+ regionLabel: "Notifications",
2397
+ groupCount: "{{count}} notifications",
2398
+ groupUnread: "{{count}} non lues",
2399
+ groupMarkRead: "Marquer comme lu",
2400
+ groupMarkReadTitle: "Tout marquer comme lu pour ce type",
1699
2401
  empty: "Aucune notification",
1700
2402
  markAllRead: "Tout marquer comme lu",
1701
2403
  viewAll: "Voir toutes les notifications",
@@ -1814,7 +2516,103 @@ const fr = {
1814
2516
  done: 'Terminé — masquer',
1815
2517
  },
1816
2518
  },
2519
+ excelImport: {
2520
+ noImportableFields: "Cet objet n'a aucun champ importable.",
2521
+ schemaReadFailed: "Impossible de lire le schéma de l'objet.",
2522
+ imported: "{{count}} ligne(s) importée(s) dans {{object}}.",
2523
+ importFrom: "Importer les lignes réelles depuis",
2524
+ into: "vers",
2525
+ opening: "Ouverture…",
2526
+ importAction: "Importer",
2527
+ dismiss: "Ignorer",
2528
+ },
2529
+ cloudOnboarding: {
2530
+ hintCreate: "Créez votre premier environnement — un espace de travail privé avec sa propre URL, sa base de données et son offre. C'est là que se fait la création.",
2531
+ hintReady: "Votre environnement de production est prêt. Ouvrez-le pour créer et exécuter vos applications — tout se passe à l'intérieur.",
2532
+ createEnvironment: "Créer votre environnement",
2533
+ openProduction: "Ouvrir la production",
2534
+ manageEnvironments: "Gérer les environnements",
2535
+ },
2536
+ aiModelStatus: {
2537
+ summary: "Créer / Demander utilise {{conversational}} ({{conversationalSource}}) ; structuré utilise {{structured}} ({{structuredSource}}).",
2538
+ summaryRouting: "Politique de routage : offres gratuites → {{free}}, offres payantes → {{paid}}.",
2539
+ modelUnknown: "inconnu",
2540
+ sourceUnknown: "non communiqué par l'adaptateur",
2541
+ rowConversational: "Modèle Build / Ask",
2542
+ rowStructured: "Structuré (blueprint / seed)",
2543
+ rowReasoning: "Effort de raisonnement",
2544
+ readFailed: "Impossible de lire le modèle d'IA effectif. Cet environnement n'exécute peut-être pas de service d'IA, ou vous n'avez pas la permission ai:read.",
2545
+ readFailedWithStatus: "Impossible de lire le modèle d'IA effectif (HTTP {{status}}). Cet environnement n'exécute peut-être pas de service d'IA, ou vous n'avez pas la permission ai:read.",
2546
+ overridesInEffect: "Surcharges actives : ",
2547
+ noOverrides: "aucune — les valeurs par défaut du code déployé s'appliquent.",
2548
+ adapter: "Adaptateur : ",
2549
+ sourceCodeDefault: "valeur par défaut du code (aucune surcharge env)",
2550
+ sourceInherits: "identique à build/ask",
2551
+ sourcePinned: "figé par {{source}}",
2552
+ },
2553
+ chatbotError: {
2554
+ title: "Échec de la réponse",
2555
+ fallbackDetail: "Une erreur s'est produite. Veuillez réessayer.",
2556
+ details: "Détails",
2557
+ hide: "Masquer",
2558
+ retry: "Réessayer",
2559
+ },
2560
+ chatbotQuota: {
2561
+ title: "Mise à niveau requise",
2562
+ fallbackMessage: "Vous avez atteint votre quota d'IA.",
2563
+ buyCredits: "Acheter un pack de crédits",
2564
+ upgradePlan: "Changer d'offre",
2565
+ },
2566
+ environment: {
2567
+ addEnvironment: "Ajouter un environnement",
2568
+ setUpProduction: "Configurer votre environnement de production",
2569
+ addDevelopment: "Ajouter un environnement de développement",
2570
+ },
2571
+ cloudConnection: {
2572
+ checking: "Vérification de la connexion…",
2573
+ retry: "Réessayer",
2574
+ errors: {
2575
+ expired: "La demande a expiré avant d'être approuvée. Recommencez.",
2576
+ bindFailed: "Échec de la liaison.",
2577
+ deviceCodeFailed: "Échec de la demande de code d'appareil.",
2578
+ },
2579
+ waiting: {
2580
+ popupOpened: "Approuvez la connexion dans la fenêtre qui vient de s'ouvrir — cette page se met à jour toute seule.",
2581
+ polling: "En attente d'approbation dans la console cloud…",
2582
+ openApproval: "Ouvrir la page d'approbation",
2583
+ copy: "Copier",
2584
+ copied: "Copié",
2585
+ codePrefilled: "Le code est pré-rempli sur la page d'approbation.",
2586
+ openItHere: "La fenêtre ne s'est pas affichée ? Ouvrez-la ici",
2587
+ cancel: "Annuler",
2588
+ },
2589
+ bound: {
2590
+ title: "Connecté à ObjectStack Cloud",
2591
+ runtime: "Runtime",
2592
+ organization: "Organisation",
2593
+ approvedBy: "Approuvé par",
2594
+ runtimeId: "ID du runtime",
2595
+ environment: "Environnement",
2596
+ since: "Depuis",
2597
+ privatePackages: "Les paquets privés de votre organisation apparaissent désormais dans la Marketplace sous « Votre organisation ».",
2598
+ disconnect: "Déconnecter",
2599
+ },
2600
+ unbound: {
2601
+ title: "Non connecté",
2602
+ body: "Connectez ce runtime à un plan de contrôle ObjectStack pour parcourir les paquets privés de votre organisation et les installer ici. L'approbation se fait en un seul clic dans votre compte cloud — aucun identifiant ni justificatif n'est saisi sur cette page.",
2603
+ connect: "Connecter",
2604
+ },
2605
+ },
1817
2606
  marketplace: {
2607
+ suggestedBindings: {
2608
+ promptEveryone: "Cette application suggère d'accorder « {{set}} » à tous les utilisateurs connectés (position Everyone).",
2609
+ promptGuest: "Cette application suggère d'accorder « {{set}} » aux visiteurs non authentifiés (position Guest).",
2610
+ confirm: "Accorder",
2611
+ confirming: "Attribution…",
2612
+ dismiss: "Ignorer",
2613
+ confirmedToast: "« {{set}} » est désormais accordé à {{anchor}}.",
2614
+ dismissedToast: "Suggestion pour « {{set}} » ignorée.",
2615
+ },
1818
2616
  title: "Marketplace d'applications",
1819
2617
  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.",
1820
2618
  searchPlaceholder: "Rechercher des applications par nom ou ID de manifeste…",
@@ -1866,6 +2664,7 @@ const fr = {
1866
2664
  updateAvailable: 'Mise à jour disponible',
1867
2665
  },
1868
2666
  action: {
2667
+ installed: "Installé",
1869
2668
  install: "Installer",
1870
2669
  reinstall: "Réinstaller",
1871
2670
  working: "Traitement…",
@@ -1936,6 +2735,14 @@ const fr = {
1936
2735
  yearsAgo: "il y a {{count}} ans",
1937
2736
  },
1938
2737
  },
2738
+ approvals: {
2739
+ approve: 'Approuver',
2740
+ reject: 'Rejeter',
2741
+ comment: 'Commentaire (facultatif)',
2742
+ approveSuccess: 'Approuvé',
2743
+ rejectSuccess: 'Rejeté',
2744
+ rejectConfirm: 'Rejeter cette demande d’approbation ?',
2745
+ },
1939
2746
  approvalsInbox: {
1940
2747
  loadMore: 'Charger plus',
1941
2748
  loadingMore: 'Chargement…',
@@ -1960,13 +2767,28 @@ const fr = {
1960
2767
  slaRemaining: 'SLA : {{dur}} restants',
1961
2768
  slaOverdue: 'SLA dépassé de {{dur}}',
1962
2769
  actReassign: 'Réattribuée',
2770
+ reassignFromTo: 'de {{from}} à {{to}}',
1963
2771
  actRemind: 'Relance',
1964
2772
  actRequestInfo: 'Infos demandées',
1965
2773
  actComment: 'Commentaire',
1966
2774
  stepProgress: 'Étapes d\'approbation',
1967
2775
  prevRequest: 'Précédente',
1968
2776
  nextRequest: 'Suivante',
1969
- positionOf: '{{index}} sur {{total}}',
2777
+ positionOf: 'Demande {{index}} sur {{total}}',
2778
+ progressApprovals: 'Approbations — {{got}} sur {{need}}',
2779
+ progressGroups: 'Avancement des visas — {{got}} sur {{need}} groupes',
2780
+ progressEligible: '{{count}} approbateur(s) éligible(s)',
2781
+ progressBar: 'Avancement de la décision',
2782
+ declaredActions: 'Actions',
2783
+ attachmentChip: 'Pièce jointe',
2784
+ attachmentOpenFailed: "Impossible d'ouvrir la pièce jointe — veuillez réessayer",
2785
+ approveOneTitle: 'Approuver « {{title}} » ?',
2786
+ approveOneBody: 'Cette action approuve la demande en votre nom. Pour ajouter un commentaire ou une pièce jointe, ouvrez la demande.',
2787
+ flowOrigin: 'Initiée par un flux',
2788
+ sortBy: 'Trier',
2789
+ sortRecent: 'Plus récentes d’abord',
2790
+ sortOldest: 'Plus anciennes d’abord',
2791
+ sortAmount: 'Montant (décroissant)',
1970
2792
  quickPhrase1: 'Approuvée — conforme aux exigences.',
1971
2793
  quickPhrase2: 'Approuvée sous conditions — surveillez l\'exécution.',
1972
2794
  quickPhrase3: 'Veuillez compléter le dossier et soumettre à nouveau.',
@@ -2095,6 +2917,10 @@ const fr = {
2095
2917
  retry: 'Réessayer',
2096
2918
  },
2097
2919
  draftBar: {
2920
+ messageClean: "Aperçu du brouillon — aucune modification non publiée ; tout ce qui figure ici est déjà en ligne.",
2921
+ sampleDataTitle: "Les données d'exemple apparaissent après publication",
2922
+ sampleDataBody: "Vous prévisualisez la structure de votre application. Publiez-la pour charger des enregistrements d'exemple et la mettre en ligne.",
2923
+ publishCta: "Publier pour voir en ligne",
2098
2924
  message: "Aperçu du brouillon — vous voyez des modifications non publiées. Rien n'est en ligne avant publication.",
2099
2925
  publish: 'Publier',
2100
2926
  publishing: 'Publication…',