@object-ui/i18n 17.2.0 → 17.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +1817 -1
  2. package/README.md +26 -13
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +14 -1
  5. package/dist/locales/ar.d.ts +550 -107
  6. package/dist/locales/ar.js +646 -156
  7. package/dist/locales/de.d.ts +550 -107
  8. package/dist/locales/de.js +661 -178
  9. package/dist/locales/en.d.ts +586 -143
  10. package/dist/locales/en.js +851 -143
  11. package/dist/locales/es.d.ts +550 -107
  12. package/dist/locales/es.js +647 -160
  13. package/dist/locales/fr.d.ts +550 -107
  14. package/dist/locales/fr.js +640 -155
  15. package/dist/locales/index.d.ts +5587 -1157
  16. package/dist/locales/ja.d.ts +550 -107
  17. package/dist/locales/ja.js +632 -149
  18. package/dist/locales/ko.d.ts +550 -107
  19. package/dist/locales/ko.js +638 -156
  20. package/dist/locales/pt.d.ts +550 -107
  21. package/dist/locales/pt.js +639 -157
  22. package/dist/locales/ru.d.ts +550 -107
  23. package/dist/locales/ru.js +650 -156
  24. package/dist/locales/zh.d.ts +588 -145
  25. package/dist/locales/zh.js +629 -145
  26. package/dist/pickLocalized.d.ts +21 -0
  27. package/dist/pickLocalized.js +40 -7
  28. package/dist/provider.d.ts +125 -1
  29. package/dist/provider.js +380 -4
  30. package/dist/useDisplayLocale.d.ts +49 -0
  31. package/dist/useDisplayLocale.js +55 -0
  32. package/dist/useObjectLabel.d.ts +8 -2
  33. package/dist/useObjectLabel.js +28 -8
  34. package/dist/useSafeTranslation.js +67 -3
  35. package/dist/utils/index.d.ts +1 -0
  36. package/dist/utils/index.js +1 -0
  37. package/dist/utils/number-display.d.ts +32 -0
  38. package/dist/utils/number-display.js +32 -0
  39. package/dist/utils/spec-formatters.d.ts +39 -13
  40. package/dist/utils/spec-formatters.js +3 -3
  41. package/package.json +5 -4
@@ -1,4 +1,18 @@
1
1
  const es = {
2
+ // objectui#4467 — the impersonation banner (app-shell ImpersonationBanner).
3
+ // Raised by `session.impersonatedBy`, so it survives SPA reboots; it names
4
+ // BOTH parties because the audit trail attributes the work to the impersonated
5
+ // user, and the exit states its own failure rather than appearing to succeed.
6
+ impersonation: {
7
+ banner: {
8
+ message: 'Está suplantando a {{user}}: todas las acciones se registran a su nombre.',
9
+ startedBy: 'Iniciado por el administrador {{admin}}.',
10
+ stop: 'Dejar de suplantar',
11
+ stopping: 'Finalizando…',
12
+ stopFailed: 'No se pudo dejar de suplantar: {{reason}}',
13
+ notRestored: 'El servidor aceptó la solicitud pero no restauró su sesión de administrador: sigue suplantando a {{user}}. Cierre sesión y vuelva a iniciarla para terminar.',
14
+ },
15
+ },
2
16
  // objectui#2600 B5 — capability picker scope group headers (labels come from the sys_capability registry).
3
17
  capability: {
4
18
  label: {
@@ -16,6 +30,25 @@ const es = {
16
30
  other: 'Otro',
17
31
  },
18
32
  },
33
+ // objectui#3546 slice six — el resumen de solo lectura de las facetas de
34
+ // autorización de PermissionFacetLink. "pestaña" como en list.tabs.
35
+ perm: {
36
+ facet: {
37
+ none: "Ninguno",
38
+ more: "+{{count}} más",
39
+ objects: "{{count}} objetos",
40
+ objects_one: "{{count}} objeto",
41
+ fields: "{{count}} reglas de campo",
42
+ fields_one: "{{count}} regla de campo",
43
+ rls: "{{count}} políticas RLS",
44
+ rls_one: "{{count}} política RLS",
45
+ tabs: "{{count}} reglas de pestaña",
46
+ tabs_one: "{{count}} regla de pestaña",
47
+ adminScope: "Administración delegada configurada",
48
+ designInStudio: "Diseñar en Studio →",
49
+ designInStudioHint: "Diseñar en Studio",
50
+ },
51
+ },
19
52
  lookup: {
20
53
  recentlyUsed: 'Usados recientemente',
21
54
  allResults: 'Todos los resultados',
@@ -46,13 +79,12 @@ const es = {
46
79
  common: {
47
80
  addToFavorites: "Añadir a favoritos",
48
81
  removeFromFavorites: "Quitar de favoritos",
49
- loading: "Cargando...",
82
+ loading: "Cargando…",
50
83
  save: "Guardar",
51
84
  cancel: "Cancelar",
52
85
  delete: "Eliminar",
53
86
  edit: "Editar",
54
87
  create: "Crear",
55
- search: "Buscar",
56
88
  filter: "Filtrar",
57
89
  reset: "Restablecer",
58
90
  confirm: "Confirmar",
@@ -76,11 +108,20 @@ const es = {
76
108
  required: "Obligatorio",
77
109
  optional: "Opcional",
78
110
  selectOption: "Seleccionar una opción",
79
- select: "Seleccionar...",
111
+ select: "Seleccionar…",
80
112
  openChat: "Abrir chat",
81
113
  closeChat: "Cerrar chat",
114
+ closePanel: "Cerrar panel",
115
+ resizeDrawer: "Ajustar el ancho del panel",
116
+ itemCount: "{{count}} elementos",
117
+ itemCountOne: "{{count}} elemento",
82
118
  toggleSidebar: "Alternar barra lateral",
83
119
  package: "Paquete",
120
+ done: "Listo",
121
+ editInStudio: "Editar en Studio",
122
+ record: "Registro",
123
+ retry: "Reintentar",
124
+ printDialogHint: "Abre el cuadro de diálogo de impresión de tu navegador (no es una exportación a PDF)",
84
125
  },
85
126
  actions: {
86
127
  decisionOutput: {
@@ -94,7 +135,12 @@ const es = {
94
135
  },
95
136
  },
96
137
  validation: {
97
- required: "{{field}} es obligatorio",
138
+ // "{{field}} es obligatorio" only agreed with masculine field labels —
139
+ // "Cuenta es obligatorio" is wrong (objectstack#5407). Spanish adjectives
140
+ // agree with the head noun, which a runtime label cannot declare, so the
141
+ // template supplies its own masculine head ("el campo") and the adjective
142
+ // agrees with THAT for every label.
143
+ required: "El campo {{field}} es obligatorio",
98
144
  minLength: "{{field}} debe tener al menos {{min}} caracteres",
99
145
  maxLength: "{{field}} debe tener como máximo {{max}} caracteres",
100
146
  min: "{{field}} debe ser al menos {{min}}",
@@ -103,7 +149,8 @@ const es = {
103
149
  url: "Por favor, introduzca una URL válida",
104
150
  pattern: "El formato de {{field}} no es válido",
105
151
  formInvalid: "Por favor, revise los campos resaltados: {{fields}}",
106
- unique: "{{field}} debe ser único",
152
+ formInvalidJoiner: ", ",
153
+ unique: "El campo {{field}} debe ser único",
107
154
  type: "{{field}} debe ser un {{type}} válido",
108
155
  },
109
156
  form: {
@@ -111,6 +158,9 @@ const es = {
111
158
  submitFailed: "No se pudo guardar. Inténtalo de nuevo.",
112
159
  discardTitle: "¿Descartar los cambios?",
113
160
  discardMessage: "Tiene cambios sin guardar. Si cierra este formulario ahora, sus ediciones se perderán.",
161
+ // objectui#4024 — the create/edit dialog's `sr-only` accessible
162
+ // description, used when the form declares no `description` of its own.
163
+ dialogDescriptionFallback: "Complete los campos del formulario y luego envíe o cancele.",
114
164
  keepEditing: "Seguir editando",
115
165
  discard: "Descartar",
116
166
  conflictTitle: "Conflicto al guardar",
@@ -127,12 +177,21 @@ const es = {
127
177
  stepOf: "Paso {{current}} de {{total}}",
128
178
  createTitle: "Crear {{object}}",
129
179
  editTitle: "Editar {{object}}",
180
+ viewTitle: "Ver {{object}}",
181
+ createTargetOrg: "Se crea en {{org}}",
130
182
  saveRecord: "Guardar registro",
131
183
  create: "Crear",
132
184
  update: "Actualizar",
133
185
  createSuccess: "{{object}} creado",
134
186
  updateSuccess: "{{object}} actualizado",
135
187
  deleteSuccess: "{{object}} eliminado",
188
+ fullscreen: {
189
+ title: "Editar texto",
190
+ description: "Edita el valor de texto completo y luego guarda o cancela los cambios.",
191
+ done: "Listo",
192
+ toggle: "Editar {{label}} en pantalla completa",
193
+ textFallback: "texto",
194
+ },
136
195
  },
137
196
  fields: {
138
197
  image: {
@@ -170,7 +229,11 @@ const es = {
170
229
  richText: {
171
230
  format: "Formato: {{format}}",
172
231
  basicEditorHint: "Editor de texto enriquecido (básico)",
173
- placeholder: "Escribe algo...",
232
+ placeholder: "Escribe algo…",
233
+ },
234
+ options: {
235
+ empty: "No hay opciones disponibles",
236
+ selectFirst: "Seleccione primero {{fields}}",
174
237
  },
175
238
  objectRef: {
176
239
  loading: "Cargando objetos…",
@@ -199,6 +262,13 @@ const es = {
199
262
  editAsJson: "Editar como JSON",
200
263
  useVisualBuilder: "Usar el constructor visual",
201
264
  },
265
+ tags: {
266
+ placeholder: "Escriba y pulse Intro para añadir…",
267
+ },
268
+ textarea: {
269
+ characterCount: "Recuento de caracteres: {{count}} de {{max}}",
270
+ charactersRemaining: "Caracteres restantes: {{count}}",
271
+ },
202
272
  },
203
273
  table: {
204
274
  rowsPerPage: "Filas por página",
@@ -225,7 +295,7 @@ const es = {
225
295
  saveAll: "Guardar todo ({{count}})",
226
296
  addRecord: "Agregar registro",
227
297
  open: "Abrir",
228
- search: "Buscar...",
298
+ search: "Buscar…",
229
299
  modified: "{{count}} filas modificadas",
230
300
  saveFailed: 'Error al guardar',
231
301
  selected: "{{count}} seleccionados",
@@ -269,7 +339,7 @@ const es = {
269
339
  delete: "Eliminar",
270
340
  export: "Exportar",
271
341
  exportAs: "Exportar como {{format}}",
272
- loading: "Cargando cuadrícula...",
342
+ loading: "Cargando cuadrícula…",
273
343
  errorLoading: "Error al cargar la cuadrícula",
274
344
  pullToRefresh: "Desliza para actualizar",
275
345
  refreshing: "Actualizando…",
@@ -280,6 +350,22 @@ const es = {
280
350
  yes: "Sí",
281
351
  no: "No",
282
352
  systemFields: "Sistema",
353
+ // objectui#4024 — column-footer aggregate prefixes, keyed by the spec's
354
+ // `ColumnSummary` vocabulary. `pattern` owns the label/value join so this
355
+ // pack controls its own separator and word order.
356
+ summary: {
357
+ pattern: "{{label}}: {{value}}",
358
+ count: "Recuento",
359
+ countEmpty: "Vacíos",
360
+ countFilled: "Rellenos",
361
+ countUnique: "Únicos",
362
+ percentEmpty: "Vacíos",
363
+ percentFilled: "Rellenos",
364
+ sum: "Suma",
365
+ avg: "Promedio",
366
+ min: "Mín.",
367
+ max: "Máx.",
368
+ },
283
369
  toolbar: {
284
370
  densityMode: "Densidad",
285
371
  densityCompact: "Compacto",
@@ -393,12 +479,12 @@ const es = {
393
479
  templateName: "Nombre de la plantilla",
394
480
  save: "Guardar",
395
481
  deleteTemplate: "Eliminar plantilla",
396
- savedMapping: 'Saved mapping:',
397
- chooseSavedMapping: 'Choose a saved mapping…',
398
- manualMapping: '— Map columns manually —',
399
- transform: 'Transform',
400
- savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
401
- savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
482
+ savedMapping: 'Asignación guardada:',
483
+ chooseSavedMapping: 'Elegir una asignación guardada…',
484
+ manualMapping: '— Asignar columnas manualmente —',
485
+ transform: 'Transformación',
486
+ savedMappingHint: 'La asignación "{{name}}" aplica el cambio de nombre + las transformaciones + la conversión de tipos en el servidor. La asignación de columnas es de solo lectura.',
487
+ savedMappingPreviewNote: 'La vista previa muestra sus columnas de origen; al importar, la asignación "{{name}}" aplica el cambio de nombre, las transformaciones y la conversión de tipos en el servidor.',
402
488
  csvColumn: "Columna",
403
489
  mapsTo: "Se asigna a",
404
490
  typeMismatch: "Parece {{type}}",
@@ -458,6 +544,8 @@ const es = {
458
544
  loadErrorUnauthorizedMessage: "Su sesión ha expirado o ha cerrado sesión. Inicie sesión de nuevo para ver estos registros.",
459
545
  loadErrorRejectedTitle: "La consulta de esta vista fue rechazada",
460
546
  loadErrorRejectedMessage: "El servidor no pudo procesar el filtro ni las opciones de consulta de esta vista. Borrar los filtros suele resolverlo; si la vista está guardada así, un administrador debe corregirla.",
547
+ loadErrorApiDisabledTitle: "Este objeto no está disponible a través de la API",
548
+ loadErrorApiDisabledMessage: "Esta página no puede cargar sus registros porque el objeto no está expuesto a través de la API. Es un ajuste del propio objeto, no un permiso: un administrador debe habilitar el acceso por API para que esta página funcione.",
461
549
  retry: "Reintentar",
462
550
  managedBy: {
463
551
  system: {
@@ -482,7 +570,7 @@ const es = {
482
570
  },
483
571
  },
484
572
  refresh: "Actualizar",
485
- loading: 'Loading records...',
573
+ loading: "Cargando registros…",
486
574
  recordCount: "{{count}} registros",
487
575
  recordCountOne: "{{count}} registro",
488
576
  addRecord: "Agregar registro",
@@ -494,7 +582,8 @@ const es = {
494
582
  sort: "Ordenar",
495
583
  sortRecords: "Ordenar registros",
496
584
  sortByIdSuffix: "(por ID)",
497
- sortRelationalHint: "Las columnas que apuntan a otro registro no aparecen aquí: solo pueden ordenarse por el ID almacenado, no por el nombre que se muestra en la celda. Para ordenar por ese nombre, añada un campo de fórmula que lo contenga.",
585
+ sortRelationalHint: "Las columnas que apuntan a otro registro no aparecen aquí: solo pueden ordenarse por el ID almacenado, no por el nombre que se muestra en la celda. Para ordenar por ese nombre, desnormalícelo en este objeto como un campo almacenado, que se escribe cuando cambia el origen, y ordene por él. No un campo de fórmula: es virtual, no se almacena ninguna columna para él y el servidor rechaza ordenar por él.",
586
+ resetSortToDefault: "Restablecer al valor predeterminado de la vista",
498
587
  group: "Agrupar",
499
588
  groupBy: "Agrupar por",
500
589
  export: "Exportar",
@@ -552,13 +641,16 @@ const es = {
552
641
  },
553
642
  kanban: {
554
643
  uncategorized: "Sin categoría",
644
+ columns: "columnas",
555
645
  addCard: "Añadir tarjeta",
556
646
  addColumn: "Añadir columna",
557
647
  moveCard: "Mover tarjeta",
558
648
  deleteCard: "Eliminar tarjeta",
559
649
  deleteColumn: "Eliminar columna",
560
650
  noCards: "Sin tarjetas",
561
- cardTitlePlaceholder: "Escriba el título de la tarjeta...",
651
+ cardTitlePlaceholder: "Escriba el título de la tarjeta…",
652
+ requiredFieldsTitle: "Complete los campos obligatorios",
653
+ requiredFieldsDescription: "Este movimiento hace que los campos siguientes sean obligatorios. Complételos para continuar.",
562
654
  },
563
655
  timeline: {
564
656
  bucket: {
@@ -571,6 +663,13 @@ const es = {
571
663
  noDate: "Sin fecha",
572
664
  unassigned: "Sin asignar",
573
665
  },
666
+ scale: {
667
+ week: "Semana {{n}}",
668
+ quarter: "T{{quarter}} {{year}}",
669
+ },
670
+ gantt: {
671
+ rowLabel: "Elementos",
672
+ },
574
673
  },
575
674
  gantt: {
576
675
  viewMode: {
@@ -617,6 +716,18 @@ const es = {
617
716
  ff: "Fin → Fin",
618
717
  sf: "Inicio → Fin",
619
718
  },
719
+ linkEnd: {
720
+ start: "Inicio",
721
+ end: "Fin",
722
+ },
723
+ link: {
724
+ rejected: {
725
+ self: "Una tarea no puede depender de sí misma.",
726
+ locked: "Esta fila está bloqueada y no puede recibir una nueva dependencia.",
727
+ group: "Una fila de resumen no puede recibir dependencias: vincule una de sus tareas.",
728
+ cycle: "Ese vínculo crearía una dependencia circular.",
729
+ },
730
+ },
620
731
  conflict: {
621
732
  title: "Conflicto de programación",
622
733
  body: "Este movimiento entra en conflicto con las restricciones de dependencia. ¿Reprogramar automáticamente {{count}} tarea(s) afectada(s)?",
@@ -625,8 +736,8 @@ const es = {
625
736
  },
626
737
  autoScheduleDlg: {
627
738
  title: "Programación automática",
628
- body: "¿Retrasar {count} tarea(s) para respetar los vínculos de dependencia?",
629
- skipped: "{count} tarea(s) bloqueada(s) también incumplen los vínculos y se han omitido.",
739
+ body: "¿Retrasar {{count}} tarea(s) para respetar los vínculos de dependencia?",
740
+ skipped: "{{count}} tarea(s) bloqueada(s) también incumplen los vínculos y se han omitido.",
630
741
  confirm: "Aplicar",
631
742
  cancel: "Cancelar",
632
743
  none: "Todas las dependencias se cumplen: no hay nada que reprogramar.",
@@ -637,6 +748,12 @@ const es = {
637
748
  over: "sobrecargado",
638
749
  empty: "No hay tareas que asignar.",
639
750
  },
751
+ quickFilter: {
752
+ all: "Todos",
753
+ clear: "Borrar filtros",
754
+ empty: "Sin opciones",
755
+ resultSummary: "Mostrando {shown} / {total} tareas",
756
+ },
640
757
  readOnly: "Solo lectura",
641
758
  readOnlyHint: "La edición está deshabilitada en esta vista.",
642
759
  lockedHint: "Sin permiso de edición",
@@ -657,6 +774,7 @@ const es = {
657
774
  exportPng: "Exportar como PNG",
658
775
  exportPdf: "Exportar PDF",
659
776
  saveLayout: "Guardar la disposición",
777
+ refresh: "Actualizar",
660
778
  undo: "Deshacer",
661
779
  redo: "Rehacer",
662
780
  prevPeriod: "Período anterior",
@@ -697,11 +815,11 @@ const es = {
697
815
  defaultBadge: "predeterminada",
698
816
  tabActionsFor: "Acciones de vista para {{name}}",
699
817
  readonlyAriaLabel: "Vista de solo lectura",
700
- readonlyTooltip: "Vista del sistema — duplique para personalizar.",
818
+ readonlyTooltip: "Vista del sistema — definida en el código, solo lectura.",
701
819
  },
702
820
  designer: {
703
- undo: 'Undo',
704
- redo: 'Redo',
821
+ undo: "Deshacer",
822
+ redo: "Rehacer",
705
823
  },
706
824
  detail: {
707
825
  editInlineHint: "Haga doble clic para editar",
@@ -719,6 +837,15 @@ const es = {
719
837
  viewHistory: "Ver historial",
720
838
  delete: "Eliminar",
721
839
  moreActions: "Más acciones",
840
+ addReaction: "Añadir reacción",
841
+ pageHeaderActions: "Acciones del encabezado de página",
842
+ emojiPicker: "Selector de emojis",
843
+ reactionCount: "{{emoji}} {{count}} reacciones",
844
+ reactionCountOne: "{{emoji}} {{count}} reacción",
845
+ recordDetail: "Detalle del registro",
846
+ recordDetailWithLabel: "Detalle de {{label}}",
847
+ openAsFullPage: "Abrir como página completa",
848
+ recordDetailOverlay: "Capa de detalle del registro para {{title}}.",
722
849
  addToFavorites: "Añadir a favoritos",
723
850
  removeFromFavorites: "Quitar de favoritos",
724
851
  previousRecord: "Registro anterior",
@@ -732,13 +859,15 @@ const es = {
732
859
  relatedRecords: "{{count}} registros",
733
860
  relatedRecordOne: "{{count}} registro",
734
861
  noRelatedRecords: "No se encontraron registros relacionados",
735
- loading: "Cargando...",
862
+ loading: "Cargando…",
736
863
  copyToClipboard: "Copiar al portapapeles",
737
864
  copied: "¡Copiado!",
738
865
  deleteConfirmation: "¿Está seguro de que desea eliminar este registro?",
866
+ deleted: "Registro eliminado",
739
867
  editRecord: "Editar registro",
740
868
  viewAll: "Ver todo",
741
869
  new: "Nuevo",
870
+ add: "Agregar",
742
871
  emptyValue: "—",
743
872
  comments: "Comentarios",
744
873
  searchComments: "Buscar comentarios…",
@@ -803,6 +932,7 @@ const es = {
803
932
  loadMore: "Cargar más",
804
933
  edited: "(editado)",
805
934
  via: "vía {{source}}",
935
+ viewSource: "Ver origen",
806
936
  replyCount: "{{count}} respuesta",
807
937
  replyCountPlural: "{{count}} respuestas",
808
938
  replyPlaceholder: "Responder…",
@@ -815,14 +945,15 @@ const es = {
815
945
  saving: "Guardando…",
816
946
  lockedByApproval: "Bloqueado para aprobación",
817
947
  lockedTooltip: "Este registro tiene una solicitud de aprobación pendiente; la edición está bloqueada",
818
- writeStrippedTitle: "Algunos campos no se guardaron",
819
- writeStrippedReadonly: "De solo lectura, por lo que no se guardó: {{fields}}",
820
- writeStrippedByState: "No editable en el estado actual de este registro, por lo que no se guardó: {{fields}}",
948
+ writeStrippedTitle: "Guardado, pero algunos campos no se aplicaron",
949
+ writeStrippedReadonly: "De solo lectura, por lo que no se aplicó: {{fields}}",
950
+ writeStrippedByState: "No editable en el estado actual de este registro, por lo que no se aplicó: {{fields}}",
821
951
  approvalPendingEditable: "En aprobación · editable",
822
952
  approvalPendingTooltip: "Este registro tiene una solicitud de aprobación pendiente; este paso todavía permite la edición",
823
953
  approvalProgress: "Aprobaciones — {{got}} de {{need}}",
824
954
  approvalProgressGroups: "Firmas — {{got}} de {{need}} grupos",
825
955
  approvalProgressLabel: "Progreso de la aprobación",
956
+ approvalsPanelTitle: "Aprobaciones",
826
957
  cancelApproval: "Cancelar aprobación",
827
958
  cancelApprovalInFlight: "Cancelando…",
828
959
  cancelApprovalTooltip: "Cancelar la solicitud de aprobación pendiente para desbloquear el registro",
@@ -843,9 +974,11 @@ const es = {
843
974
  concurrentUpdateReload: "Cargar versión actual",
844
975
  concurrentUpdateOverwrite: "Sobrescribir de todos modos",
845
976
  concurrentUpdateCancel: "Cancelar",
977
+ concurrentUpdateRecordLabel: "este registro",
846
978
  openInNewTab: "Abrir en nueva pestaña",
847
979
  activity: "Actividad",
848
980
  history: "Historial",
981
+ historyEmpty: "Aún no hay historial",
849
982
  editRow: "Editar",
850
983
  deleteRow: "Eliminar",
851
984
  deleteRowConfirmation: "¿Eliminar este registro?",
@@ -855,12 +988,15 @@ const es = {
855
988
  nextPage: "Siguiente",
856
989
  pageOf: "Página {{current}} de {{total}}",
857
990
  sortBy: "Ordenar por",
858
- filterPlaceholder: "Filtrar...",
991
+ filterPlaceholder: "Filtrar…",
859
992
  highlightFields: "Campos clave",
860
993
  createdBy: "Creado por",
861
994
  updatedBy: "Actualizado por",
862
995
  created: "Creado",
863
996
  updated: "Actualizado",
997
+ // objectui#3863 — base key. es's third category `many` starts at a million, where
998
+ // the plural form is correct, so the base repeats `_other`.
999
+ showEmptyRelated: "+ {{count}} vacíos",
864
1000
  showEmptyRelated_one: "+ {{count}} vacío",
865
1001
  showEmptyRelated_other: "+ {{count}} vacíos",
866
1002
  copyEmail: "Copiar correo",
@@ -872,7 +1008,8 @@ const es = {
872
1008
  },
873
1009
  chart: {
874
1010
  noData: "No hay datos de gráfico disponibles",
875
- loading: "Cargando gráfico...",
1011
+ loading: "Cargando gráfico…",
1012
+ nullCategory: "(Sin especificar)",
876
1013
  },
877
1014
  map: {
878
1015
  searchLocations: "Buscar ubicaciones…",
@@ -894,8 +1031,8 @@ const es = {
894
1031
  properties: "Propiedades",
895
1032
  connections: "Conexiones",
896
1033
  quickConnect: "Conexión rápida",
897
- fromPlaceholder: "Desde...",
898
- toPlaceholder: "Hasta...",
1034
+ fromPlaceholder: "Desde…",
1035
+ toPlaceholder: "Hasta…",
899
1036
  connect: "Conectar",
900
1037
  label: "Etiqueta",
901
1038
  type: "Tipo",
@@ -943,6 +1080,7 @@ const es = {
943
1080
  },
944
1081
  dashboard: {
945
1082
  noRows: "Sin filas",
1083
+ loading: "Cargando…",
946
1084
  pickMeasures: "Elija medidas (valores) para este widget de dataset.",
947
1085
  datasetUnsupported: "Esta fuente de datos no admite consultas de dataset.",
948
1086
  details: "Detalles",
@@ -1200,6 +1338,7 @@ const es = {
1200
1338
  },
1201
1339
  },
1202
1340
  console: {
1341
+ saveAdvisoryTitle: "Guardado: la comprobación de creación generó {{count}} recomendación(es)",
1203
1342
  settingsHub: {
1204
1343
  title: "Configuración",
1205
1344
  subtitle: "Configure su espacio de trabajo, las integraciones y los indicadores de funciones.",
@@ -1266,7 +1405,7 @@ const es = {
1266
1405
  shareTitle: "Compartir esta conversación",
1267
1406
  shareDisabledTitle: "Empiece a chatear para habilitar el uso compartido",
1268
1407
  newChat: "Nuevo",
1269
- searchChats: "Buscar chats...",
1408
+ searchChats: "Buscar chats…",
1270
1409
  noChatsYet: "Todavía no hay chats",
1271
1410
  noChatsDescription: "Inicie una conversación nueva para verla aquí.",
1272
1411
  noMatchingChats: "No hay chats coincidentes.",
@@ -1275,18 +1414,18 @@ const es = {
1275
1414
  deleteConversation: "Eliminar conversación",
1276
1415
  saveRename: "Guardar el nombre",
1277
1416
  cancelRename: "Cancelar el cambio de nombre",
1278
- loadingHistory: "Cargando el historial de la conversación...",
1417
+ loadingHistory: "Cargando el historial de la conversación…",
1279
1418
  conversationReady: "Conversación lista",
1280
1419
  preparingConversation: "Preparando una nueva conversación",
1281
1420
  offlineDemoMode: "Modo de demostración sin conexión — lista de agentes no disponible",
1282
1421
  sendFailedRateLimited: "Está enviando mensajes demasiado rápido. Su mensaje se conserva abajo — espere un momento y vuelva a intentarlo.",
1283
1422
  sendFailedGeneric: "No se pudo enviar su mensaje. Se conserva abajo — inténtelo de nuevo.",
1284
- askAgent: "Pregunte a {{agent}}...",
1423
+ askAgent: "Pregunte a {{agent}}…",
1285
1424
  assistant: "Asistente",
1286
1425
  liveCanvas: "Vista previa en vivo — {{app}} (borrador)",
1287
1426
  liveCanvasUnlisted: "Aplicación en vivo — {{app}} (no listada hasta su publicación)",
1288
- loadingAgents: "Cargando agentes...",
1289
- askAnything: "Pregunte lo que quiera...",
1427
+ loadingAgents: "Cargando agentes…",
1428
+ askAnything: "Pregunte lo que quiera…",
1290
1429
  emptyTitle: "Iniciar una conversación",
1291
1430
  emptyDescription: "Pregunte lo que quiera — el asistente tiene acceso al contexto de su aplicación actual.",
1292
1431
  switchAssistant: "Cambiar de asistente",
@@ -1389,9 +1528,60 @@ const es = {
1389
1528
  createSeed: "Generar datos de ejemplo",
1390
1529
  createPackage: "Crear paquete de aplicación",
1391
1530
  },
1531
+ // objectui#3546 slice four — the AI console surfaces: the /ai chat page's app switcher,
1532
+ // connection banner and plan/publish cards, the ChatDock chrome, and the
1533
+ // conversation-list date buckets. `group.*` is the template-key family
1534
+ // `console.ai.group.${key}` (ConversationsSidebar), enumerated from the
1535
+ // ConversationGroupKey union — all five members, no wildcard.
1536
+ collapseToDock: "Contraer al panel lateral",
1537
+ switchApp: "Cambiar de aplicación",
1538
+ switchAppLabel: "Conversaciones de creación por aplicación",
1539
+ newApp: "Nueva aplicación",
1540
+ connectionWaiting: "Esperando al servidor…",
1541
+ connectionStalled: "Sigue en proceso…",
1542
+ connectionOffline: "Conexión perdida — reconectando…",
1543
+ designingPlan: "Diseñando su aplicación…",
1544
+ designingPlanHint: {
1545
+ data: "Trazando los datos que va a registrar…",
1546
+ objects: "Dando forma a los objetos y sus campos…",
1547
+ relations: "Conectando los registros relacionados…",
1548
+ lookups: "Configurando las relaciones y los campos de búsqueda…",
1549
+ views: "Planificando las pantallas y las vistas…",
1550
+ forms: "Organizando los formularios y las listas…",
1551
+ defaults: "Agregando valores predeterminados y validaciones razonables…",
1552
+ dashboard: "Bosquejando un panel para el seguimiento…",
1553
+ review: "Comprobando que la estructura encaje…",
1554
+ finalize: "Reuniendo el plan…",
1555
+ },
1556
+ planBuilding: "Creando…",
1557
+ planBuilt: "Creado",
1558
+ planDeferred: "Aún no creado",
1559
+ planReady: "El plan está listo. Créelo ahora o dígame qué ajustar.",
1560
+ published: "Publicado",
1561
+ publishFailed: "Error al publicar",
1562
+ unavailableTitle: "Asistente de IA no disponible",
1563
+ unavailableDescription: "Esta implementación no tiene habilitado un asistente de IA. Todo lo demás funciona con normalidad.",
1564
+ unavailableError: "No se pudo contactar con el servicio de IA. Puede estar temporalmente sin conexión — reinténtelo o vuelva al inicio.",
1565
+ unavailableRetry: "Reintentar",
1566
+ unavailableHome: "Volver al inicio",
1567
+ dock: {
1568
+ title: "Asistente",
1569
+ description: "Chat con el asistente de IA",
1570
+ resize: "Redimensionar el chat",
1571
+ collapse: "Contraer el chat",
1572
+ maximize: "Abrir como página completa",
1573
+ open: "Abrir el asistente",
1574
+ },
1575
+ group: {
1576
+ today: "Hoy",
1577
+ yesterday: "Ayer",
1578
+ previous7Days: "7 días anteriores",
1579
+ previous30Days: "30 días anteriores",
1580
+ older: "Anteriores",
1581
+ },
1392
1582
  },
1393
1583
  title: "Consola ObjectStack",
1394
- initializing: "Inicializando aplicación...",
1584
+ initializing: "Inicializando aplicación…",
1395
1585
  loadingHint: "Configurar un entorno nuevo puede tardar unos momentos.",
1396
1586
  breadcrumb: {
1397
1587
  dashboards: "Paneles",
@@ -1399,6 +1589,31 @@ const es = {
1399
1589
  reports: "Informes",
1400
1590
  system: "Sistema",
1401
1591
  },
1592
+ // objectui#4024 — the single-namespace settings screen. Its sibling
1593
+ // `settingsHub` above already resolved through this pack; the view was the
1594
+ // one file still carrying English literals.
1595
+ settingsView: {
1596
+ backToHub: "Toda la configuración",
1597
+ back: "Atrás",
1598
+ noNamespace: "No hay ningún espacio de nombres seleccionado.",
1599
+ loadError: "No se pudo cargar la configuración",
1600
+ saved: "Configuración guardada",
1601
+ saveFailed: "Error al guardar",
1602
+ lockedByEnv: "Bloqueado por el entorno: {{key}}",
1603
+ lockedByEnvNoKey: "Bloqueado por el entorno",
1604
+ actionSucceeded: "La acción se completó correctamente",
1605
+ actionFailed: "La acción falló",
1606
+ discard: "Descartar",
1607
+ saveChanges: "Guardar cambios",
1608
+ unsavedCount: "{{count}} cambios sin guardar",
1609
+ unsavedCount_one: "{{count}} cambio sin guardar",
1610
+ unsavedCount_other: "{{count}} cambios sin guardar",
1611
+ cryptoRefusalTitle: "Esta instalación no puede cifrar secretos",
1612
+ cryptoRefusalSubjectSuffix: "está declarado como cifrado, por lo que no se escribió nada.",
1613
+ cryptoRefusalNoSubject: "El valor declarado como cifrado fue rechazado, por lo que no se escribió nada.",
1614
+ cryptoRefusalToast: "No se pueden cifrar los secretos: {{subject}}",
1615
+ cryptoRefusalToastNoSubject: "No se pueden cifrar los secretos",
1616
+ },
1402
1617
  loadingSteps: {
1403
1618
  connecting: "Conectando a la fuente de datos",
1404
1619
  loadingConfig: "Cargando configuración",
@@ -1414,6 +1629,13 @@ const es = {
1414
1629
  retry: "Reintentar",
1415
1630
  retrying: "Reintentando…",
1416
1631
  },
1632
+ serverAction: {
1633
+ openingTitle: "Abriendo…",
1634
+ openingBody: "Abriendo… esto puede tardar un momento.",
1635
+ popupBlockedTitle: "Ventana emergente bloqueada",
1636
+ popupBlockedDescription: "El navegador bloqueó la apertura de la nueva pestaña.",
1637
+ popupBlockedAction: "Abrir en una pestaña nueva",
1638
+ },
1417
1639
  shortcuts: {
1418
1640
  title: "Atajos de teclado",
1419
1641
  description: "Referencia rápida de todos los atajos de teclado disponibles.",
@@ -1421,6 +1643,7 @@ const es = {
1421
1643
  general: "General",
1422
1644
  navigation: "Navegación",
1423
1645
  dataViews: "Vistas de datos",
1646
+ aiChat: "Asistente de IA",
1424
1647
  preferences: "Preferencias",
1425
1648
  },
1426
1649
  openCommandPalette: "Abrir paleta de comandos",
@@ -1431,11 +1654,13 @@ const es = {
1431
1654
  createRecord: "Crear nuevo registro",
1432
1655
  refreshData: "Actualizar datos",
1433
1656
  editRecord: "Editar registro seleccionado",
1657
+ newChat: "Nuevo chat",
1658
+ toggleChatsList: "Alternar lista de chats",
1434
1659
  toggleDarkMode: "Alternar modo oscuro",
1435
1660
  },
1436
1661
  commandPalette: {
1437
1662
  title: "Paleta de comandos",
1438
- placeholder: "Escriba un comando o busque...",
1663
+ placeholder: "Escriba un comando o busque…",
1439
1664
  noResults: "No se encontraron resultados.",
1440
1665
  objects: "Objetos",
1441
1666
  dashboards: "Paneles",
@@ -1461,6 +1686,12 @@ const es = {
1461
1686
  goHome: "Ir al inicio",
1462
1687
  errorDetails: "Detalles del error (solo desarrollo)",
1463
1688
  },
1689
+ // objectui#3546 slice four — the console's catch-all route (AppContent `RouteNotFound`).
1690
+ notFound: {
1691
+ title: "Página no encontrada",
1692
+ description: "La URL que siguió no coincide con ninguna vista de esta aplicación.",
1693
+ back: "Volver",
1694
+ },
1464
1695
  theme: {
1465
1696
  toggle: "Cambiar tema",
1466
1697
  light: "Claro",
@@ -1476,11 +1707,15 @@ const es = {
1476
1707
  viewNameHelp: "Clave técnica (snake_case). Se rellena automáticamente a partir del título — edítela si lo desea.",
1477
1708
  viewNameRequired: "Introduzca una clave (minúsculas, números, guion bajo). No se rellena automáticamente con títulos no latinos.",
1478
1709
  viewNameInvalid: "Use minúsculas, números y guiones bajos; empiece por una letra o un guion bajo.",
1479
- systemViewReadonly: 'System view defined in code - duplicate to customize.',
1480
- expandToPage: 'Open as full page',
1710
+ systemViewReadonly: "Vista del sistema definida en el código: solo lectura.",
1711
+ cannotEditMetaView: "Esta vista está integrada y definida en el código: no se puede modificar.",
1712
+ cannotDeleteMetaView: "Esta vista está integrada y definida en el código: no se puede eliminar.",
1713
+ expandToPage: "Abrir como página completa",
1481
1714
  objectNotFound: "Objeto no encontrado",
1482
1715
  objectNotFoundDescription: "El objeto \"{{objectName}}\" no existe en la configuración actual.",
1483
1716
  objectNotFoundHint: "Verifique la configuración de navegación de su aplicación o seleccione un objeto diferente en la barra lateral.",
1717
+ filterOrNotSavable: "Este filtro une las condiciones con O, algo que una vista guardada aún no puede almacenar. Se sigue aplicando a esta lista: quite la agrupación O para guardarlo en la vista.",
1718
+ filterNestedNotSavable: "Este filtro usa grupos de condiciones anidados, que una vista guardada no puede almacenar. Conviértalo en una única lista de condiciones para guardarlo en la vista.",
1484
1719
  allRecords: "Todos los registros",
1485
1720
  exitDesignMode: "Salir del modo de diseño",
1486
1721
  enterDesignMode: "Entrar en modo de diseño",
@@ -1507,7 +1742,7 @@ const es = {
1507
1742
  exportPrintHint: "Formatos de exportación, impresión y visualización del recuento de registros",
1508
1743
  showAllFields: "Mostrar todo",
1509
1744
  hideAllFields: "Ocultar todo",
1510
- searchFields: "Buscar campos...",
1745
+ searchFields: "Buscar campos…",
1511
1746
  title: "Título",
1512
1747
  description: "Descripción",
1513
1748
  data: "Datos",
@@ -1546,7 +1781,7 @@ const es = {
1546
1781
  longitudeField: "Campo de longitud",
1547
1782
  imageField: "Campo de imagen",
1548
1783
  dateField: "Campo de fecha",
1549
- selectField: "Seleccionar campo...",
1784
+ selectField: "Seleccionar campo…",
1550
1785
  gridOptionsHint: "La vista de cuadrícula usa las columnas configuradas arriba.",
1551
1786
  groupBy: "Agrupar por",
1552
1787
  prefixField: "Campo de prefijo",
@@ -1609,7 +1844,7 @@ const es = {
1609
1844
  latitudeFieldHelp: "Campo que contiene la latitud (solo campos geográficos).",
1610
1845
  longitudeFieldHelp: "Campo que contiene la longitud (solo campos geográficos).",
1611
1846
  imageFieldHelp: "La portada de la galería proviene de este campo de imagen o adjunto.",
1612
- selectOption: "Seleccionar...",
1847
+ selectOption: "Seleccionar…",
1613
1848
  noEligibleFieldForType: "Ningún campo elegible de ese tipo. Agregue uno al objeto primero.",
1614
1849
  viewTypeUnavailable: "Este objeto no tiene un campo que sirva como \"{{field}}\".",
1615
1850
  viewTypeUnavailableShort: "No compatible con este objeto.",
@@ -1659,7 +1894,7 @@ const es = {
1659
1894
  ufDropdown: "Desplegable",
1660
1895
  ufTabs: "Pestañas",
1661
1896
  ufToggle: "Alternar",
1662
- ufAddField: "+ Agregar campo de filtro...",
1897
+ ufAddField: "+ Agregar campo de filtro…",
1663
1898
  ufNoFields: "Sin campos disponibles",
1664
1899
  ufAddTab: "+ Agregar pestaña",
1665
1900
  ufTabLabel: "Etiqueta",
@@ -1719,7 +1954,7 @@ const es = {
1719
1954
  passwordPlaceholder: "Ingresa tu contraseña",
1720
1955
  forgotPasswordText: "¿Olvidaste tu contraseña?",
1721
1956
  submitButton: "Iniciar sesión",
1722
- submittingButton: "Iniciando sesión...",
1957
+ submittingButton: "Iniciando sesión…",
1723
1958
  noAccountText: "¿No tienes una cuenta?",
1724
1959
  signUpText: "Regístrate",
1725
1960
  errors: {
@@ -1727,6 +1962,18 @@ const es = {
1727
1962
  invalidCredentials: "Correo o contraseña inválidos. Inténtelo de nuevo.",
1728
1963
  emailNotVerified: "Verifique su correo electrónico antes de iniciar sesión.",
1729
1964
  },
1965
+ // objectui#3546 slice three — phone/OTP sign-in. `{seconds}` is LoginForm's own
1966
+ // literal `.replace()` hole, not i18next interpolation: keep the single braces.
1967
+ emailOrPhoneLabel: "Correo electrónico o número de teléfono",
1968
+ emailOrPhonePlaceholder: "name@example.com o +1 555 000 0000",
1969
+ phoneLabel: "Número de teléfono",
1970
+ phonePlaceholder: "+1 555 000 0000",
1971
+ otpCodeLabel: "Código de verificación",
1972
+ otpCodePlaceholder: "Código de 6 dígitos",
1973
+ sendOtpButton: "Obtener código",
1974
+ resendOtpCountdownText: "Reenviar en {seconds} s",
1975
+ usePhoneOtpText: "Iniciar sesión con código de verificación",
1976
+ usePasswordSignInText: "Iniciar sesión con contraseña en su lugar",
1730
1977
  },
1731
1978
  register: {
1732
1979
  title: "Crear una cuenta",
@@ -1742,7 +1989,7 @@ const es = {
1742
1989
  passwordMismatchError: "Las contraseñas no coinciden",
1743
1990
  passwordTooShortError: "La contraseña debe tener al menos 8 caracteres",
1744
1991
  submitButton: "Crear cuenta",
1745
- submittingButton: "Creando cuenta...",
1992
+ submittingButton: "Creando cuenta…",
1746
1993
  hasAccountText: "¿Ya tienes una cuenta?",
1747
1994
  signInText: "Iniciar sesión",
1748
1995
  errors: {
@@ -1763,12 +2010,26 @@ const es = {
1763
2010
  emailLabel: "Correo electrónico",
1764
2011
  emailPlaceholder: "name@example.com",
1765
2012
  submitButton: "Enviar enlace de restablecimiento",
1766
- submittingButton: "Enviando...",
2013
+ submittingButton: "Enviando…",
1767
2014
  successTitle: "Revisa tu correo electrónico",
1768
2015
  successDescription: "Hemos enviado un enlace para restablecer la contraseña a {{email}}. Por favor revisa tu bandeja de entrada.",
1769
2016
  backToSignInText: "Volver a iniciar sesión",
1770
2017
  rememberPasswordText: "¿Recuerdas tu contraseña?",
1771
2018
  signInText: "Iniciar sesión",
2019
+ // objectui#3546 slice three — the SMS reset branch of the same form.
2020
+ phoneLabel: "Número de teléfono",
2021
+ phonePlaceholder: "+1 555 000 0000",
2022
+ otpCodeLabel: "Código de verificación",
2023
+ otpCodePlaceholder: "Código de 6 dígitos",
2024
+ sendOtpButton: "Obtener código",
2025
+ resendOtpCountdownText: "Reenviar en {seconds} s",
2026
+ newPasswordLabel: "Nueva contraseña",
2027
+ newPasswordPlaceholder: "Ingresa una nueva contraseña",
2028
+ resetButton: "Restablecer contraseña",
2029
+ usePhoneResetText: "Restablecer con código SMS",
2030
+ useEmailResetText: "Restablecer por correo electrónico en su lugar",
2031
+ phoneSuccessTitle: "Contraseña restablecida",
2032
+ phoneSuccessDescription: "Tu contraseña ha sido restablecida. Ahora puedes iniciar sesión con tu nueva contraseña.",
1772
2033
  },
1773
2034
  resetPassword: {
1774
2035
  title: "Establecer nueva contraseña",
@@ -1807,6 +2068,8 @@ const es = {
1807
2068
  backToLogin: "Volver al inicio de sesión",
1808
2069
  checkSpam: "¿No recibió el correo? Revise su carpeta de spam o contacte soporte.",
1809
2070
  or: "O",
2071
+ // objectui#3546 slice three.
2072
+ resendUnavailable: "Puede que el envío de correos no esté configurado en este entorno. Contacte soporte si el problema persiste.",
1810
2073
  },
1811
2074
  setup: {
1812
2075
  welcomeTitle: "Bienvenido a ObjectStack",
@@ -1845,6 +2108,9 @@ const es = {
1845
2108
  invalidDescription: "No se proporcionó código de dispositivo en la URL.",
1846
2109
  loading: "Cargando…",
1847
2110
  cancel: "Cancelar",
2111
+ // objectui#3546 slice three — device-authorization plugin switched off.
2112
+ disabledTitle: "La autorización de dispositivos no está habilitada",
2113
+ disabledDescription: "Esta implementación no tiene habilitada la autorización de dispositivos, por lo que este dispositivo no puede aprobarse aquí.",
1848
2114
  },
1849
2115
  shell: {
1850
2116
  tenantHostHint: "Está iniciando sesión en este espacio de trabajo",
@@ -1884,6 +2150,29 @@ const es = {
1884
2150
  },
1885
2151
  },
1886
2152
  },
2153
+ // objectui#3546 slice three — the /oauth/consent screen.
2154
+ oauth: {
2155
+ consent: {
2156
+ title: "{{appName}} quiere acceder a su cuenta",
2157
+ request: "{{appName}} solicita permiso{{suffix}}.",
2158
+ unknownApp: "una aplicación",
2159
+ willAllow: "Esta aplicación podrá:",
2160
+ scope: {
2161
+ openid: "Confirmar su identidad",
2162
+ profile: "Leer su perfil básico (nombre, foto)",
2163
+ email: "Leer su dirección de correo electrónico",
2164
+ offlineAccess: "Mantener la sesión abierta (renovar el acceso)",
2165
+ },
2166
+ deny: "Denegar",
2167
+ authorize: "Autorizar",
2168
+ submitting: "Autorizando…",
2169
+ granted: "Acceso concedido",
2170
+ denied: "Acceso denegado",
2171
+ noRedirect: "El servidor no devolvió ninguna URL de redirección.",
2172
+ failed: "Error en el consentimiento",
2173
+ footer: "Puede revocar el acceso en cualquier momento desde la configuración de su cuenta.",
2174
+ },
2175
+ },
1887
2176
  profile: {
1888
2177
  title: "Perfil",
1889
2178
  subtitle: "Gestione la configuración de su cuenta",
@@ -1945,6 +2234,8 @@ const es = {
1945
2234
  invite: "Invitar miembro",
1946
2235
  members: "Miembros",
1947
2236
  settings: "Configuración del espacio de trabajo",
2237
+ multiOrgDisabled: "La creación de nuevas organizaciones está deshabilitada en esta instancia.",
2238
+ createFailed: 'No se pudo crear el espacio de trabajo',
1948
2239
  },
1949
2240
  help: {
1950
2241
  onThisPage: "En esta página",
@@ -1955,7 +2246,7 @@ const es = {
1955
2246
  },
1956
2247
  sidebar: {
1957
2248
  packageManagement: "Gestión de paquetes",
1958
- searchNavigation: "Buscar en la navegación...",
2249
+ searchNavigation: "Buscar en la navegación…",
1959
2250
  settings: "Configuración",
1960
2251
  help: "Ayuda",
1961
2252
  helpTooltip: "Ayuda y documentación",
@@ -1979,8 +2270,8 @@ const es = {
1979
2270
  switchObject: "Cambiar de objeto",
1980
2271
  connection: {
1981
2272
  connected: "Conectado",
1982
- connecting: "Conectando...",
1983
- reconnecting: "Reconectando...",
2273
+ connecting: "Conectando…",
2274
+ reconnecting: "Reconectando…",
1984
2275
  disconnected: "Desconectado",
1985
2276
  error: "Error de conexión",
1986
2277
  },
@@ -2019,6 +2310,14 @@ const es = {
2019
2310
  publishing: "Publicando…",
2020
2311
  published: "¡Publicado! Sus cambios están activos.",
2021
2312
  publishFailed: "Error al publicar",
2313
+ // objectui#3546 slice six — seedWarn reutiliza la traducción de
2314
+ // console.ai.seedWarn (misma frase en inglés). Marcador "(s)" como en
2315
+ // home.pendingDrafts.message, de esta misma familia.
2316
+ nothing: "Nada que publicar.",
2317
+ probeWarn: "Publicado, pero la verificación encontró problemas.",
2318
+ seedWarn: "Publicado, pero no se pudieron cargar algunos datos de ejemplo.",
2319
+ publishedVerified: "Publicado y verificado — {{count}} fila(s) de ejemplo activa(s).",
2320
+ capabilityWarn: "Comprobación de autoría: {{count}} referencia(s) de capacidad no apuntan a nada.",
2022
2321
  },
2023
2322
  title: "Inicio",
2024
2323
  subtitle: "Panel de tu espacio de trabajo",
@@ -2032,7 +2331,7 @@ const es = {
2032
2331
  title: "Requiere tu atención",
2033
2332
  empty: "Estás al día",
2034
2333
  },
2035
- loading: "Cargando espacio de trabajo...",
2334
+ loading: "Cargando espacio de trabajo…",
2036
2335
  recent: "Recientes",
2037
2336
  starred: "Destacados",
2038
2337
  welcome: "Bienvenido a ObjectUI",
@@ -2093,6 +2392,9 @@ const es = {
2093
2392
  roles: "Roles",
2094
2393
  configuration: "Configuración",
2095
2394
  createApp: "Crear aplicación",
2395
+ administration: "Administración",
2396
+ datasources: "Fuentes de datos",
2397
+ documentation: "Documentación",
2096
2398
  },
2097
2399
  appSwitcher: {
2098
2400
  switchApplication: "Cambiar de aplicación",
@@ -2132,7 +2434,7 @@ const es = {
2132
2434
  search: {
2133
2435
  title: "Buscar",
2134
2436
  back: "Atrás",
2135
- placeholder: "Buscar objetos, paneles, páginas, informes...",
2437
+ placeholder: "Buscar objetos, paneles, páginas, informes…",
2136
2438
  inputAriaLabel: "Buscar objetos, paneles, páginas, informes",
2137
2439
  resultsCount: "{{count}} resultado para \"{{query}}\"",
2138
2440
  resultsCountPlural: "{{count}} resultados para \"{{query}}\"",
@@ -2151,6 +2453,7 @@ const es = {
2151
2453
  empty: {
2152
2454
  objectNotFound: "Objeto no encontrado",
2153
2455
  objectNotFoundDescription: "Falta la definición del objeto \"{{name}}\". Verifique su configuración o navegue hacia atrás.",
2456
+ interfacePageSourceMissing: "Esta página de interfaz hace referencia a \"{{name}}\", que no está disponible.",
2154
2457
  pageNotFound: "Página no encontrada",
2155
2458
  pageNotFoundDescription: "La página \"{{name}}\" no fue encontrada. Puede haber sido eliminada o renombrada.",
2156
2459
  dashboardNotFound: "Panel no encontrado",
@@ -2159,6 +2462,11 @@ const es = {
2159
2462
  reportNotFoundDescription: "El informe \"{{name}}\" no fue encontrado. Puede haber sido eliminado o renombrado.",
2160
2463
  noAppsConfigured: "Sin aplicaciones configuradas",
2161
2464
  noAppsConfiguredDescription: "No hay aplicaciones registradas. Cree su primera aplicación o visite la configuración del sistema.",
2465
+ appNotAvailable: "Aplicación no disponible",
2466
+ appNotAvailableDescription: "Esta aplicación aún no está disponible — puede que todavía se esté publicando. Vuelva a intentarlo en un momento.",
2467
+ appAccessDenied: "No tiene acceso a esta aplicación",
2468
+ appAccessDeniedDescription: "Esta aplicación existe, pero su cuenta no está autorizada para abrirla. Solicite acceso a un administrador.",
2469
+ appAccessDeniedHome: "Volver al inicio",
2162
2470
  createFirstApp: "Crear primera aplicación",
2163
2471
  systemSettings: "Configuración del sistema",
2164
2472
  back: "Atrás",
@@ -2230,7 +2538,7 @@ const es = {
2230
2538
  deleteFailed: "No se pudo eliminar la vista",
2231
2539
  },
2232
2540
  dashboardActions: {
2233
- pdfPreparing: "Preparando exportación PDF…",
2541
+ printDialogOpening: "Abriendo el cuadro de diálogo de impresión de tu navegador (no es una exportación a PDF)",
2234
2542
  exportFailed: "Error al exportar: {{message}}",
2235
2543
  forecastSoon: "La vista de pronóstico llegará pronto",
2236
2544
  },
@@ -2274,111 +2582,7 @@ const es = {
2274
2582
  first: "Primero",
2275
2583
  },
2276
2584
  editor: {
2277
- breadcrumb: "Configuración",
2278
- basic: "General",
2279
- title: "Título",
2280
- titlePlaceholder: "p. ej. Pipeline por trimestre",
2281
- description: "Descripción",
2282
- descriptionPlaceholder: "¿Qué muestra este informe?",
2283
- type: "Tipo de informe",
2284
- typeTabular: "Tabla — lista plana",
2285
- typeSummary: "Resumen — agrupado con totales",
2286
- typeMatrix: "Matriz — pivote filas × columnas",
2287
- typeJoined: "Combinado — varios bloques",
2288
- typeHelp: "Elige el diseño que mejor refleje lo que quieres ver.",
2289
- data: "Datos",
2290
- objectName: "Fuente de datos",
2291
- objectNamePlaceholder: "p. ej. opportunity",
2292
- objectNameHelp: "¿Qué objeto debe consultar este informe?",
2293
- limit: "Límite de filas",
2294
- limitPlaceholder: "p. ej. 100",
2295
- columns: "Columnas",
2296
- columnsHint: "Elige los campos que aparecerán como columnas. Añade una agregación (Suma, Recuento…) en los informes Resumen o Matriz.",
2297
- filters: "Filtros",
2298
- filtersHint: "Limita las filas incluidas en este informe.",
2299
- filtersComplex: "Este informe usa un filtro avanzado que no se puede editar aquí. Al guardar se mantendrá intacto.",
2300
- groupBy: "Agrupar por",
2301
- groupByHint: "Agrupa los datos y calcula subtotales.",
2302
- rows: "Filas",
2303
- rowsHint: "Agrupa las filas por estos campos.",
2304
- columnsAxis: "Columnas",
2305
- columnsAxisHint: "Pivota estos campos en la parte superior.",
2306
- values: "Valores",
2307
- valuesHint: "Números mostrados en cada celda. Elige uno o varios campos y añade una agregación (Suma, Recuento…).",
2308
- grouping: "Agrupación",
2309
- addGrouping: "Añadir agrupación",
2310
- dateGranularity: "Granularidad de fecha",
2311
- dateGranularityNone: "(valor original)",
2312
- day: "Día",
2313
- week: "Semana",
2314
- month: "Mes",
2315
- quarter: "Trimestre",
2316
- year: "Año",
2317
- sortAsc: "Ascendente",
2318
- sortDesc: "Descendente",
2319
- chart: "Gráfico",
2320
- chartHint: "Visualización opcional junto a la tabla.",
2321
- chartType: "Tipo de gráfico",
2322
- chartTitle: "Título del gráfico",
2323
- chartTitlePlaceholder: "Por defecto, el título del informe",
2324
- chartXAxis: "Eje X (categoría)",
2325
- chartYAxis: "Eje Y (valor)",
2326
- chartShowLegend: "Mostrar leyenda",
2327
- chartShowDataLabels: "Mostrar etiquetas de datos",
2328
- chartNone: "(sin gráfico)",
2329
- chartBar: "Barras",
2330
- chartLine: "Líneas",
2331
- chartArea: "Áreas",
2332
- chartPie: "Circular",
2333
- chartDonut: "Anillo",
2334
- chartFunnel: "Embudo",
2335
- validationNeedsObject: "Selecciona una fuente de datos antes de añadir columnas.",
2336
- validationMatrixNeedsRowsCols: "Los informes de matriz necesitan al menos una fila y una columna.",
2337
- validationSummaryNeedsRows: "Los informes de resumen necesitan al menos un campo de agrupación.",
2338
- blocks: "Bloques",
2339
- blocksHint: "Cada bloque es su propia tabla o gráfico. Los filtros del bloque se combinan (Y) con el filtro del informe.",
2340
- addBlock: "Añadir bloque",
2341
- removeBlock: "Eliminar bloque",
2342
- blockName: "Nombre del bloque",
2343
- blockNamePlaceholder: "nombre_unico_del_bloque",
2344
- blockLabel: "Etiqueta a mostrar",
2345
- blockLabelPlaceholder: "Se muestra encima del bloque",
2346
- blockDescription: "Descripción",
2347
- blockDescriptionPlaceholder: "Contexto opcional para este bloque",
2348
- validationJoinedNeedsBlocks: "Los informes combinados necesitan al menos un bloque.",
2349
- validationBlockNameRequired: "Cada bloque debe tener un nombre no vacío.",
2350
- validationBlockNameDuplicate: "Los nombres de bloque deben ser únicos dentro del informe.",
2351
- validationBlockNeedsColumns: "Cada bloque debe tener al menos una columna.",
2352
- noneOption: "(ninguno)",
2353
- addCondition: "Añadir condición",
2354
- combineLogic: "Combinar con",
2355
- opContains: "contiene",
2356
- opIsEmpty: "está vacío",
2357
- opIsNotEmpty: "no está vacío",
2358
- formatAuto: "Auto",
2359
- formatCurrency: "Moneda",
2360
- formatPercent: "Porcentaje",
2361
- formatInteger: "Entero",
2362
- formatDate: "Fecha",
2363
- formatDatetime: "Fecha y hora",
2364
- columnLabelPlaceholder: "Sobrescribir etiqueta",
2365
- aggregateColumn: "Agregación",
2366
- formatColumn: "Formato",
2367
- addColumns: "Añadir columnas",
2368
- searchFields: "Buscar campos…",
2369
- noMatchingFields: "Ningún campo coincide con tu búsqueda.",
2370
- noFieldsAvailable: "No hay campos disponibles.",
2371
- columnsCount: "{n} columna(s) seleccionada(s)",
2372
- columnsEmpty: "Aún no hay columnas seleccionadas.",
2373
- fieldPickerTitle: "Seleccionar campos",
2374
- fieldPickerDescription: "Elija uno o más campos para agregar. Use el campo de búsqueda para filtrar la lista.",
2375
- fieldPickerChangeTitle: "Cambiar campo",
2376
- fieldPickerAddGroupingTitle: "Agregar agrupación",
2377
- fieldPickerEmpty: "(Seleccionar campo)",
2378
- fieldPickerSelected: "{n} seleccionado(s)",
2379
- fieldPickerClear: "Limpiar selección",
2380
- fieldPickerAdd: "Agregar",
2381
- fieldPickerAddN: "Agregar {n}",
2585
+ panelTitle: "Editar informe",
2382
2586
  },
2383
2587
  },
2384
2588
  organizations: {
@@ -2395,6 +2599,140 @@ const es = {
2395
2599
  emptyDescription: "Crea tu primera organización para empezar.",
2396
2600
  noMatches: "Ninguna organización coincide con tu búsqueda.",
2397
2601
  },
2602
+ organization: {
2603
+ roles: {
2604
+ owner: 'Propietario',
2605
+ admin: 'Administrador',
2606
+ delegatedAdmin: 'Administrador delegado',
2607
+ member: 'Miembro',
2608
+ },
2609
+ errors: {
2610
+ notAllowedToInvite: 'No tiene permiso para invitar usuarios a esta organización.',
2611
+ notAllowedToInviteWithRole: 'No tiene permiso para invitar a un usuario con este rol.',
2612
+ alreadyInvited: 'Este usuario ya ha sido invitado a esta organización.',
2613
+ organizationExists: 'Esa organización ya existe.',
2614
+ slugTaken: 'Ese slug ya está en uso.',
2615
+ notAllowedToCreate: 'No tiene permiso para crear una organización nueva.',
2616
+ notTheRecipient: 'No es el destinatario de esta invitación.',
2617
+ invitationNotFound: 'Esta invitación ya no existe o ha caducado.',
2618
+ unknown: 'Algo salió mal. Inténtelo de nuevo.',
2619
+ },
2620
+ backToList: "Volver a las organizaciones",
2621
+ notFound: "Organización no encontrada",
2622
+ notFoundDescription: "Esta organización no existe o no tienes acceso.",
2623
+ tabs: {
2624
+ members: "Miembros",
2625
+ invitations: "Invitaciones",
2626
+ settings: "Configuración",
2627
+ },
2628
+ members: {
2629
+ title: "Miembros",
2630
+ inviteMember: "Invitar miembro",
2631
+ inviteRestrictedNote: "Solo los administradores de la organización pueden invitar a miembros.",
2632
+ removeMember: "Eliminar miembro",
2633
+ removeConfirmTitle: "¿Eliminar miembro?",
2634
+ removeConfirmDescription: "Se eliminará a {{name}} de la organización y perderá el acceso de inmediato.",
2635
+ removeConfirmAction: "Eliminar",
2636
+ memberRemoved: "Miembro eliminado",
2637
+ removeFailed: "No se pudo eliminar al miembro",
2638
+ roleUpdated: "Rol actualizado",
2639
+ roleUpdateFailed: "No se pudo actualizar el rol",
2640
+ memberActions: 'Acciones del miembro',
2641
+ loadFailed: 'No se pudieron cargar los miembros',
2642
+ },
2643
+ invitations: {
2644
+ title: "Invitaciones",
2645
+ empty: "No hay invitaciones.",
2646
+ expiresAt: "Caduca",
2647
+ linkCopied: "Enlace de invitación copiado",
2648
+ copyFailed: "No se pudo copiar el enlace",
2649
+ canceled: "Invitación cancelada",
2650
+ cancelFailed: "No se pudo cancelar la invitación",
2651
+ cancelTitle: "¿Cancelar la invitación?",
2652
+ cancelDescription: "Se revocará la invitación de {{email}}.",
2653
+ cancelAction: "Cancelar invitación",
2654
+ inviteTitle: "Invitar a un miembro",
2655
+ inviteDescription: "Recibirá una invitación para unirse a esta organización.",
2656
+ emailLabel: "Correo electrónico",
2657
+ roleLabel: "Rol",
2658
+ placementLabel: "Asignación (opcional)",
2659
+ placementDescription: "Se aplica cuando se acepta la invitación. Solo se listan las unidades y los puestos que puedes delegar.",
2660
+ businessUnitLabel: "Unidad de negocio",
2661
+ businessUnitPlaceholder: "Sin asignación",
2662
+ positionsLabel: "Puestos",
2663
+ sendInvite: "Enviar invitación",
2664
+ sentTitle: "Invitación creada",
2665
+ sentDescription: "Comparte el enlace de abajo con la persona invitada. Tendrá que iniciar sesión para aceptarla.",
2666
+ linkLabel: "Enlace de aceptación",
2667
+ invitedAs: "{{email}} invitado como {{role}}",
2668
+ copyLinkLabel: 'Copiar enlace de invitación',
2669
+ loadFailed: 'No se pudieron cargar las invitaciones',
2670
+ inviteFailed: 'No se pudo invitar al miembro',
2671
+ status: {
2672
+ all: "Todas",
2673
+ pending: "Pendiente",
2674
+ accepted: "Aceptada",
2675
+ rejected: "Rechazada",
2676
+ canceled: "Cancelada",
2677
+ },
2678
+ },
2679
+ settings: {
2680
+ generalTitle: "General",
2681
+ generalDescription: "Actualiza la información de tu organización.",
2682
+ readOnlyNote: "Solo los propietarios pueden cambiar la configuración.",
2683
+ nameLabel: "Nombre de la organización",
2684
+ slugLabel: "Slug",
2685
+ logoLabel: "Logo",
2686
+ logoUpload: "Subir",
2687
+ logoReplace: "Reemplazar",
2688
+ logoClear: "Quitar",
2689
+ logoUploaded: "Logo subido: guarda para aplicarlo",
2690
+ logoUploadFailed: "No se pudo subir el logo",
2691
+ save: "Guardar cambios",
2692
+ saved: "Configuración guardada",
2693
+ saveFailed: "No se pudo guardar la configuración",
2694
+ leaveTitle: "Salir de la organización",
2695
+ leaveDescription: "Perderás el acceso a esta organización.",
2696
+ leaveAction: "Salir",
2697
+ leaveConfirmTitle: "¿Salir de la organización?",
2698
+ leaveConfirmDescription: "¿Seguro que quieres salir de {{name}}? Perderás el acceso de inmediato.",
2699
+ leaveConfirmAction: "Salir",
2700
+ leftOrg: "Has salido de la organización",
2701
+ leaveFailed: "No se pudo salir de la organización",
2702
+ dangerZone: "Zona de peligro",
2703
+ deleteTitle: "Eliminar organización",
2704
+ deleteDescription: "Elimina permanentemente esta organización y todos sus datos.",
2705
+ deleteAction: "Eliminar",
2706
+ deleteConfirmTitle: "¿Eliminar la organización?",
2707
+ deleteConfirmDescription: "Esta acción es irreversible. Todos los datos se eliminarán de forma permanente. Escribe el slug de la organización para confirmar.",
2708
+ deleteConfirmSlugLabel: "Escribe «{{slug}}» para confirmar",
2709
+ deleteConfirmAction: "Eliminar organización",
2710
+ deleted: "Organización eliminada",
2711
+ deleteFailed: "No se pudo eliminar la organización",
2712
+ },
2713
+ accept: {
2714
+ title: "Te han invitado",
2715
+ description: "Te han invitado a unirte a {{orgName}} como {{role}}.",
2716
+ errorTitle: "Invitación no disponible",
2717
+ goToOrgs: "Ir a las organizaciones",
2718
+ loading: "Cargando la invitación…",
2719
+ organization: "Organización",
2720
+ role: "Rol",
2721
+ expiresAt: "Caduca",
2722
+ accept: "Aceptar invitación",
2723
+ accepted: "Invitación aceptada",
2724
+ acceptFailed: "No se pudo aceptar la invitación",
2725
+ decline: "Rechazar",
2726
+ declined: "Invitación rechazada",
2727
+ declineFailed: "No se pudo rechazar la invitación",
2728
+ },
2729
+ switcher: {
2730
+ label: "Cambiar de organización",
2731
+ groupLabel: "Organización de trabajo",
2732
+ groupHint: "Los registros nuevos se crean aquí. Las vistas muestran datos de todas tus organizaciones.",
2733
+ manageMembers: "Administrar miembros",
2734
+ },
2735
+ },
2398
2736
  notifications: {
2399
2737
  regionLabel: "Notificaciones",
2400
2738
  groupCount: "{{count}} notificaciones",
@@ -2408,6 +2746,9 @@ const es = {
2408
2746
  viewApprovals: "Ver aprobaciones",
2409
2747
  noPendingApprovals: "Sin aprobaciones pendientes",
2410
2748
  openApprovalsInbox: "Abrir bandeja de aprobaciones",
2749
+ badgeTotal: "{{total}} en total",
2750
+ badgeNotifications: "{{unread}} notificaciones",
2751
+ badgeApprovals: "{{approvals}} aprobaciones pendientes",
2411
2752
  emptyUnread: "Todo al día",
2412
2753
  filterUnread: "No leídos",
2413
2754
  filterAll: "Todos",
@@ -2694,6 +3035,7 @@ const es = {
2694
3035
  dismiss: "Descartar",
2695
3036
  openOnCloud: "Abrir en la nube",
2696
3037
  backHome: "Volver al inicio",
3038
+ updateTo: "Actualizar",
2697
3039
  },
2698
3040
  install: {
2699
3041
  dialogTitle: "Instalar {{name}}",
@@ -2710,6 +3052,37 @@ const es = {
2710
3052
  localManifestConflict: "{{message}}\nNota: Una aplicación local ya tiene este manifest_id. Primero elimínela de objectstack.config.ts.",
2711
3053
  localUnauthorized: "Primero inicie sesión en este runtime.",
2712
3054
  localMarketplaceUnavailable: "Este runtime no tiene configurado OS_CLOUD_URL.",
3055
+ updateTo: "Actualizar → v{{version}}",
3056
+ installedVersion: "Instalado v{{version}}",
3057
+ },
3058
+ // objectui#3546 — the MarketplacePage "Your organization" strip.
3059
+ org: {
3060
+ heading: "Su organización",
3061
+ install: "Instalar",
3062
+ installed: "{{name}} instalado",
3063
+ installedBadge: "Instalado",
3064
+ installing: "Instalando…",
3065
+ },
3066
+ // ADR-0025 PD4 §3.5/§3.11 — the pre-install consent panel
3067
+ // (PluginDisclosure.tsx). `runtime` is a CLOSED enum: spec
3068
+ // PluginRuntimeSchema = z.enum(['node', 'sandbox', 'worker']).
3069
+ disclosure: {
3070
+ containsCode: "Este paquete contiene código",
3071
+ reviewed: "Revisado y aprobado",
3072
+ unreviewed: "Sin revisar todavía",
3073
+ signed: "Firmado",
3074
+ grantsIntro: "Al instalarlo, este paquete recibirá:",
3075
+ services: "Servicios de la plataforma",
3076
+ hooks: "Hooks de ciclo de vida",
3077
+ network: "Acceso a la red",
3078
+ fs: "Acceso al sistema de archivos",
3079
+ noPermissions: "No solicita permisos especiales.",
3080
+ acknowledge: "Entiendo que este paquete ejecuta código y recibe los permisos anteriores.",
3081
+ runtime: {
3082
+ node: "En el proceso · confianza total",
3083
+ sandbox: "En sandbox",
3084
+ worker: "Fuera del proceso",
3085
+ },
2713
3086
  },
2714
3087
  uninstall: {
2715
3088
  confirm: "¿Desinstalar {{manifestId}} v{{version}} de este runtime?\n\nEl manifiesto en caché será eliminado.",
@@ -2929,16 +3302,16 @@ const es = {
2929
3302
  loadFailedTitle: 'No se pudo cargar la vista previa del borrador',
2930
3303
  loadFailedDescription: 'No se pudo leer la capa de borrador. Reintenta o comprueba tu conexión.',
2931
3304
  notReadyTitle: '«{{app}}» aún no está en el borrador',
2932
- notReadyDescription: 'La compilación puede seguir en curso, o falló antes de preparar esta aplicación. Revisa la conversación para ver el estado — este panel se actualiza cuando llegan borradores.',
3305
+ notReadyDescription: 'La compilación puede seguir en curso, o falló antes de preparar esta aplicación. Revise la conversación para ver el estado — este panel se actualiza cuando llegan borradores.',
2933
3306
  nothingTitle: 'Nada que previsualizar todavía',
2934
3307
  retry: 'Reintentar',
2935
3308
  },
2936
3309
  draftBar: {
2937
- messageClean: "Vista previa del borrador: no hay cambios sin publicar; todo lo que ve aquí ya está activo.",
3310
+ messageClean: "Vista previa del borrador — no hay cambios sin publicar; todo lo que ve aquí ya está activo.",
2938
3311
  sampleDataTitle: "Los datos de ejemplo aparecen tras publicar",
2939
3312
  sampleDataBody: "Está viendo la estructura de su aplicación. Publíquela para cargar registros de ejemplo y activarla.",
2940
3313
  publishCta: "Publicar para verlo activo",
2941
- message: 'Vista previa de borrador — estás viendo cambios sin publicar. Nada está en producción hasta que publiques.',
3314
+ message: 'Vista previa del borrador — está viendo cambios sin publicar. Nada de lo que ve aquí está activo hasta que publique.',
2942
3315
  publish: 'Publicar',
2943
3316
  publishing: 'Publicando…',
2944
3317
  exit: 'Salir de la vista previa',
@@ -2959,6 +3332,34 @@ const es = {
2959
3332
  confirmNote: 'Publicar libera atómicamente los {{count}} borradores pendientes de este paquete.',
2960
3333
  publishConfirm: 'Publicar todo',
2961
3334
  },
3335
+ // ADR-0045 — the materialized-but-unlisted app banner
3336
+ // (UnpublishedAppBar.tsx), sibling of draftBar above.
3337
+ unpublishedBar: {
3338
+ message: 'Aplicación sin publicar — totalmente funcional, pero solo la ven los creadores. Publíquela para que sus usuarios la vean.',
3339
+ publish: 'Publicar',
3340
+ publishing: 'Publicando…',
3341
+ published: '¡Publicado! La aplicación ya es visible para sus usuarios.',
3342
+ publishFailed: 'Error al publicar',
3343
+ },
3344
+ // ADR-0067 — the append-only build/revert timeline (CommitTimeline.tsx);
3345
+ // `button` is the banner's entry point into it.
3346
+ history: {
3347
+ button: 'Historial',
3348
+ title: 'Historial de compilaciones',
3349
+ description: 'Todos los cambios de esta aplicación, los más recientes primero. Deshaga cualquier paso para revertirlo — no hace falta confirmar la publicación.',
3350
+ loadFailed: 'No se pudo cargar el historial:',
3351
+ loadFailedUnavailable: 'Almacén de commits temporalmente inaccesible — esta lectura no se produjo, por lo que no se muestra ningún historial. Vuelva a intentarlo en un momento.',
3352
+ loading: 'Cargando historial…',
3353
+ empty: 'Aún no hay historial para esta aplicación.',
3354
+ revertLabel: 'Se deshizo un cambio',
3355
+ applyLabel: 'Cambio de compilación',
3356
+ revert: 'deshacer',
3357
+ items: 'elementos',
3358
+ revertAction: 'Deshacer',
3359
+ reverted: 'Deshecho — el cambio se ha revertido.',
3360
+ revertFailed: 'Error al deshacer',
3361
+ revertUnavailable: 'Almacén de commits temporalmente inaccesible — es posible que la reversión no se haya aplicado. Vuelva a abrir este historial para comprobarlo antes de reintentar.',
3362
+ },
2962
3363
  },
2963
3364
  filterBuilder: {
2964
3365
  where: "Donde",
@@ -3003,5 +3404,91 @@ const es = {
3003
3404
  addSort: "Agregar orden",
3004
3405
  removeSort: "Quitar orden",
3005
3406
  },
3407
+ collaboration: {
3408
+ commentCount: "{{count}} comentarios",
3409
+ commentCountOne: "{{count}} comentario",
3410
+ resolvedSuffix: " · Resuelto",
3411
+ sortComments: "Ordenar comentarios",
3412
+ sortOldest: "Más antiguos",
3413
+ sortNewest: "Más recientes",
3414
+ resolve: "Resolver",
3415
+ reopen: "Reabrir",
3416
+ justNow: "ahora mismo",
3417
+ minutesAgo: "hace {{count}} min",
3418
+ hoursAgo: "hace {{count}} h",
3419
+ daysAgo: "hace {{count}} d",
3420
+ edited: "(editado)",
3421
+ reactionCount: "{{count}} reacciones",
3422
+ reactionCountOne: "{{count}} reacción",
3423
+ addThumbsUp: "Agregar me gusta",
3424
+ reply: "Responder",
3425
+ reactThumbsUp: "Reaccionar con me gusta",
3426
+ reactHeart: "Reaccionar con corazón",
3427
+ cancelReply: "Cancelar respuesta",
3428
+ replyingTo: "Respondiendo a {{name}}…",
3429
+ replyingToComment: "Respondiendo al comentario…",
3430
+ commentPlaceholder: "Agregar un comentario… (usa @ para mencionar)",
3431
+ send: "Enviar",
3432
+ presentUserCount: "{{count}} usuarios presentes",
3433
+ presentUserCountOne: "{{count}} usuario presente",
3434
+ moreUserCount: "{{count}} usuarios más",
3435
+ moreUserCountOne: "{{count}} usuario más",
3436
+ userStatusTitle: "{{name}} ({{status}})",
3437
+ statusActive: "activo",
3438
+ statusIdle: "inactivo",
3439
+ statusAway: "ausente",
3440
+ },
3441
+ wizard: {
3442
+ missingRequired: "Complete los campos obligatorios: {{fields}}",
3443
+ },
3444
+ appManagement: {
3445
+ title: "Aplicaciones",
3446
+ subtitle: "Gestione todas las aplicaciones configuradas",
3447
+ newApp: "Nueva aplicación",
3448
+ searchLabel: "Buscar aplicaciones",
3449
+ searchPlaceholder: "Buscar aplicaciones…",
3450
+ selectedCount: "{{n}} seleccionadas",
3451
+ bulkEnable: "Habilitar",
3452
+ bulkDisable: "Deshabilitar",
3453
+ selectAll: "Seleccionar todo ({{n}})",
3454
+ empty: "No se encontraron aplicaciones.",
3455
+ defaultBadge: "Predeterminada",
3456
+ active: "Activa",
3457
+ inactive: "Inactiva",
3458
+ selectApp: "Seleccionar {{name}}",
3459
+ openApp: "Abrir aplicación",
3460
+ openAppNamed: "Abrir {{name}}",
3461
+ editApp: "Editar aplicación",
3462
+ editAppNamed: "Editar {{name}}",
3463
+ editWithAi: "Editar con IA",
3464
+ editWithAiNamed: "Editar {{name}} con IA",
3465
+ enableApp: "Habilitar aplicación",
3466
+ disableApp: "Deshabilitar aplicación",
3467
+ enableAppNamed: "Habilitar {{name}}",
3468
+ disableAppNamed: "Deshabilitar {{name}}",
3469
+ setDefault: "Establecer como predeterminada",
3470
+ setDefaultNamed: "Establecer {{name}} como predeterminada",
3471
+ deleteApp: "Eliminar aplicación",
3472
+ deleteAppNamed: "Eliminar {{name}}",
3473
+ confirmDelete: "Haga clic de nuevo para confirmar la eliminación",
3474
+ confirmDeleteNamed: "Confirmar la eliminación de {{name}}",
3475
+ toast: {
3476
+ noClient: "No se puede acceder al servicio de metadatos",
3477
+ unknownError: "error desconocido",
3478
+ appEnabled: "{{name}} habilitada",
3479
+ appDisabled: "{{name}} deshabilitada",
3480
+ toggleFailed: "Error al cambiar el estado de la aplicación: {{reason}}",
3481
+ setDefaultDone: "{{name}} establecida como predeterminada",
3482
+ setDefaultFailed: "Error al establecer la aplicación predeterminada: {{reason}}",
3483
+ appDeleted: "{{name}} eliminada",
3484
+ deleteFailed: "Error al eliminar la aplicación: {{reason}}",
3485
+ bulkEnabled: "{{n}} aplicaciones habilitadas",
3486
+ bulkDisabled: "{{n}} aplicaciones deshabilitadas",
3487
+ bulkFailed: "Error en {{n}}: {{details}}",
3488
+ bulkFailureEntry: "{{name}} ({{reason}})",
3489
+ bulkFailureJoiner: "; ",
3490
+ bulkOperationFailed: "Error en la operación masiva: {{reason}}",
3491
+ },
3492
+ },
3006
3493
  };
3007
3494
  export default es;