@object-ui/i18n 17.3.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 +1295 -1
  2. package/README.md +0 -13
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +11 -1
  5. package/dist/locales/ar.d.ts +466 -107
  6. package/dist/locales/ar.js +559 -153
  7. package/dist/locales/de.d.ts +466 -107
  8. package/dist/locales/de.js +574 -175
  9. package/dist/locales/en.d.ts +502 -143
  10. package/dist/locales/en.js +678 -145
  11. package/dist/locales/es.d.ts +466 -107
  12. package/dist/locales/es.js +553 -155
  13. package/dist/locales/fr.d.ts +466 -107
  14. package/dist/locales/fr.js +553 -152
  15. package/dist/locales/index.d.ts +4734 -1144
  16. package/dist/locales/ja.d.ts +466 -107
  17. package/dist/locales/ja.js +545 -146
  18. package/dist/locales/ko.d.ts +466 -107
  19. package/dist/locales/ko.js +551 -153
  20. package/dist/locales/pt.d.ts +466 -107
  21. package/dist/locales/pt.js +552 -154
  22. package/dist/locales/ru.d.ts +466 -107
  23. package/dist/locales/ru.js +563 -153
  24. package/dist/locales/zh.d.ts +501 -142
  25. package/dist/locales/zh.js +542 -142
  26. package/dist/pickLocalized.d.ts +21 -0
  27. package/dist/pickLocalized.js +40 -7
  28. package/dist/provider.d.ts +83 -1
  29. package/dist/provider.js +303 -29
  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 +50 -2
  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 +4 -3
@@ -1,4 +1,18 @@
1
1
  const ru = {
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: 'Вы работаете от имени {{user}} — все действия записываются на этого пользователя.',
9
+ startedBy: 'Начато администратором {{admin}}.',
10
+ stop: 'Прекратить работу от чужого имени',
11
+ stopping: 'Завершение…',
12
+ stopFailed: 'Не удалось прекратить работу от чужого имени: {{reason}}',
13
+ notRestored: 'Сервер принял запрос, но не восстановил сеанс администратора — вы всё ещё работаете от имени {{user}}. Выйдите и войдите снова, чтобы завершить.',
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,32 @@ const ru = {
16
30
  other: 'Другое',
17
31
  },
18
32
  },
33
+ // objectui#3546 slice six — сводка шести граней авторизации в
34
+ // PermissionFacetLink (только чтение) плюс ссылка в Studio.
35
+ //
36
+ // Четыре счётных значения записаны как «Существительное: {{count}}» — этот
37
+ // приём в паке уже применён 25 раз (lookup.recordCount, notifications.
38
+ // groupCount, approvalsInbox.bulkApproved …) и он верен при ЛЮБОМ числе, так
39
+ // что для категорий few/many, которых в паке нет, базовый ключ даёт
40
+ // правильный русский, а не английский. Поэтому `_one` здесь совпадает с
41
+ // базовым ключом — форма не зависит от числа.
42
+ perm: {
43
+ facet: {
44
+ none: "Нет",
45
+ more: "+{{count}} ещё",
46
+ objects: "Объектов: {{count}}",
47
+ objects_one: "Объектов: {{count}}",
48
+ fields: "Правил для полей: {{count}}",
49
+ fields_one: "Правил для полей: {{count}}",
50
+ rls: "Политик RLS: {{count}}",
51
+ rls_one: "Политик RLS: {{count}}",
52
+ tabs: "Правил для вкладок: {{count}}",
53
+ tabs_one: "Правил для вкладок: {{count}}",
54
+ adminScope: "Делегированное администрирование настроено",
55
+ designInStudio: "Дизайн в Studio →",
56
+ designInStudioHint: "Дизайн в Studio",
57
+ },
58
+ },
19
59
  lookup: {
20
60
  recentlyUsed: 'Недавние',
21
61
  allResults: 'Все результаты',
@@ -46,13 +86,12 @@ const ru = {
46
86
  common: {
47
87
  addToFavorites: "Добавить в избранное",
48
88
  removeFromFavorites: "Удалить из избранного",
49
- loading: "Загрузка...",
89
+ loading: "Загрузка…",
50
90
  save: "Сохранить",
51
91
  cancel: "Отмена",
52
92
  delete: "Удалить",
53
93
  edit: "Редактировать",
54
94
  create: "Создать",
55
- search: "Поиск",
56
95
  filter: "Фильтр",
57
96
  reset: "Сбросить",
58
97
  confirm: "Подтвердить",
@@ -76,7 +115,7 @@ const ru = {
76
115
  required: "Обязательно",
77
116
  optional: "Необязательно",
78
117
  selectOption: "Выберите вариант",
79
- select: "Выбрать...",
118
+ select: "Выбрать…",
80
119
  openChat: "Открыть чат",
81
120
  closeChat: "Закрыть чат",
82
121
  closePanel: "Закрыть панель",
@@ -85,6 +124,11 @@ const ru = {
85
124
  itemCountOne: "{{count}} элемент",
86
125
  toggleSidebar: "Переключить боковую панель",
87
126
  package: "Пакет",
127
+ done: "Готово",
128
+ editInStudio: "Редактировать в Studio",
129
+ record: "Запись",
130
+ retry: "Повторить",
131
+ printDialogHint: "Открывает диалог печати браузера (это не экспорт в PDF)",
88
132
  },
89
133
  actions: {
90
134
  decisionOutput: {
@@ -116,6 +160,9 @@ const ru = {
116
160
  submitFailed: "Не удалось сохранить. Попробуйте ещё раз.",
117
161
  discardTitle: "Отменить изменения?",
118
162
  discardMessage: "Есть несохранённые изменения. Если закрыть форму сейчас, правки будут потеряны.",
163
+ // objectui#4024 — the create/edit dialog's `sr-only` accessible
164
+ // description, used when the form declares no `description` of its own.
165
+ dialogDescriptionFallback: "Заполните поля формы, затем отправьте или отмените.",
119
166
  keepEditing: "Продолжить редактирование",
120
167
  discard: "Отменить",
121
168
  conflictTitle: "Конфликт сохранения",
@@ -184,7 +231,7 @@ const ru = {
184
231
  richText: {
185
232
  format: "Формат: {{format}}",
186
233
  basicEditorHint: "Редактор форматированного текста (базовый)",
187
- placeholder: "Введите текст...",
234
+ placeholder: "Введите текст…",
188
235
  },
189
236
  options: {
190
237
  empty: "Нет доступных вариантов",
@@ -250,7 +297,7 @@ const ru = {
250
297
  saveAll: "Сохранить всё ({{count}})",
251
298
  addRecord: "Добавить запись",
252
299
  open: "Открыть",
253
- search: "Поиск...",
300
+ search: "Поиск…",
254
301
  modified: "{{count}} строк изменено",
255
302
  saveFailed: 'Не удалось сохранить',
256
303
  selected: "{{count}} выбрано",
@@ -294,7 +341,7 @@ const ru = {
294
341
  delete: "Удалить",
295
342
  export: "Экспорт",
296
343
  exportAs: "Экспорт в {{format}}",
297
- loading: "Загрузка таблицы...",
344
+ loading: "Загрузка таблицы…",
298
345
  errorLoading: "Ошибка загрузки таблицы",
299
346
  pullToRefresh: "Потяните для обновления",
300
347
  refreshing: "Обновление…",
@@ -305,6 +352,22 @@ const ru = {
305
352
  yes: "Да",
306
353
  no: "Нет",
307
354
  systemFields: "Система",
355
+ // objectui#4024 — column-footer aggregate prefixes, keyed by the spec's
356
+ // `ColumnSummary` vocabulary. `pattern` owns the label/value join so this
357
+ // pack controls its own separator and word order.
358
+ summary: {
359
+ pattern: "{{label}}: {{value}}",
360
+ count: "Количество",
361
+ countEmpty: "Пустые",
362
+ countFilled: "Заполненные",
363
+ countUnique: "Уникальные",
364
+ percentEmpty: "Пустые",
365
+ percentFilled: "Заполненные",
366
+ sum: "Сумма",
367
+ avg: "Среднее",
368
+ min: "Мин.",
369
+ max: "Макс.",
370
+ },
308
371
  toolbar: {
309
372
  densityMode: "Плотность",
310
373
  densityCompact: "Компактный",
@@ -418,12 +481,12 @@ const ru = {
418
481
  templateName: "Название шаблона",
419
482
  save: "Сохранить",
420
483
  deleteTemplate: "Удалить шаблон",
421
- savedMapping: 'Saved mapping:',
422
- chooseSavedMapping: 'Choose a saved mapping…',
423
- manualMapping: '— Map columns manually —',
424
- transform: 'Transform',
425
- savedMappingHint: 'Mapping “{{name}}” applies rename + transforms + type coercion on the server. Column mapping is read-only.',
426
- savedMappingPreviewNote: 'The preview shows your source columns; on import, mapping “{{name}}” applies rename, transforms and type coercion on the server.',
484
+ savedMapping: 'Сохранённое сопоставление:',
485
+ chooseSavedMapping: 'Выбрать сохранённое сопоставление…',
486
+ manualMapping: '— Сопоставить столбцы вручную —',
487
+ transform: 'Преобразование',
488
+ savedMappingHint: 'Сопоставление «{{name}}» применяет на сервере переименование + преобразования + приведение типов. Сопоставление столбцов доступно только для чтения.',
489
+ savedMappingPreviewNote: 'В предпросмотре показаны исходные столбцы; при импорте сопоставление «{{name}}» применяет на сервере переименование, преобразования и приведение типов.',
427
490
  csvColumn: "Столбец",
428
491
  mapsTo: "Сопоставляется с",
429
492
  typeMismatch: "Похоже на {{type}}",
@@ -483,6 +546,8 @@ const ru = {
483
546
  loadErrorUnauthorizedMessage: "Сессия истекла или вы вышли из системы. Войдите снова, чтобы просмотреть эти записи.",
484
547
  loadErrorRejectedTitle: "Запрос этого представления отклонён",
485
548
  loadErrorRejectedMessage: "Сервер не смог обработать фильтр или параметры запроса этого представления. Обычно помогает сброс фильтров; если представление сохранено в таком виде, исправить его должен администратор.",
549
+ loadErrorApiDisabledTitle: "Этот объект недоступен через API",
550
+ loadErrorApiDisabledMessage: "Страница не может загрузить записи, потому что объект не открыт через API. Это настройка самого объекта, а не права доступа — администратор должен включить доступ по API, чтобы эта страница заработала.",
486
551
  retry: "Повторить",
487
552
  managedBy: {
488
553
  system: {
@@ -507,7 +572,7 @@ const ru = {
507
572
  },
508
573
  },
509
574
  refresh: "Обновить",
510
- loading: 'Loading records...',
575
+ loading: "Загрузка записей…",
511
576
  recordCount: "{{count}} записей",
512
577
  recordCountOne: "{{count}} запись",
513
578
  addRecord: "Добавить запись",
@@ -519,7 +584,8 @@ const ru = {
519
584
  sort: "Сортировка",
520
585
  sortRecords: "Сортировка записей",
521
586
  sortByIdSuffix: "(по ID)",
522
- sortRelationalHint: "Столбцы, ссылающиеся на другую запись, здесь не показаны: их можно сортировать только по сохранённому ID, а не по имени, которое видно в ячейке. Чтобы сортировать по этому имени, добавьте поле-формулу с ним.",
587
+ sortRelationalHint: "Столбцы, ссылающиеся на другую запись, здесь не показаны: их можно сортировать только по сохранённому ID, а не по имени, которое видно в ячейке. Чтобы сортировать по этому имени, денормализуйте его в этот объект — как сохраняемое поле, которое записывается при изменении источника, — и сортируйте по нему. Не поле-формула: она виртуальна, столбец для неё не хранится, и сервер отказывается сортировать по ней.",
588
+ resetSortToDefault: "Сбросить к сортировке представления",
523
589
  group: "Группировка",
524
590
  groupBy: "Группировать по",
525
591
  export: "Экспорт",
@@ -577,13 +643,16 @@ const ru = {
577
643
  },
578
644
  kanban: {
579
645
  uncategorized: "Без категории",
646
+ columns: "колонок",
580
647
  addCard: "Добавить карточку",
581
648
  addColumn: "Добавить колонку",
582
649
  moveCard: "Переместить карточку",
583
650
  deleteCard: "Удалить карточку",
584
651
  deleteColumn: "Удалить колонку",
585
652
  noCards: "Нет карточек",
586
- cardTitlePlaceholder: "Введите название карточки...",
653
+ cardTitlePlaceholder: "Введите название карточки…",
654
+ requiredFieldsTitle: "Заполните обязательные поля",
655
+ requiredFieldsDescription: "Это перемещение делает поля ниже обязательными. Заполните их, чтобы продолжить.",
587
656
  },
588
657
  timeline: {
589
658
  bucket: {
@@ -596,6 +665,13 @@ const ru = {
596
665
  noDate: "Без даты",
597
666
  unassigned: "Не назначено",
598
667
  },
668
+ scale: {
669
+ week: "Неделя {{n}}",
670
+ quarter: "{{quarter}} кв. {{year}}",
671
+ },
672
+ gantt: {
673
+ rowLabel: "Элементы",
674
+ },
599
675
  },
600
676
  gantt: {
601
677
  viewMode: {
@@ -642,6 +718,18 @@ const ru = {
642
718
  ff: "Окончание → Окончание",
643
719
  sf: "Начало → Окончание",
644
720
  },
721
+ linkEnd: {
722
+ start: "Начало",
723
+ end: "Конец",
724
+ },
725
+ link: {
726
+ rejected: {
727
+ self: "Задача не может зависеть от самой себя.",
728
+ locked: "Эта строка заблокирована и не может принять новую зависимость.",
729
+ group: "Сводная строка не может быть целью зависимости — свяжите одну из её задач.",
730
+ cycle: "Эта связь создаст циклическую зависимость.",
731
+ },
732
+ },
645
733
  conflict: {
646
734
  title: "Конфликт расписания",
647
735
  body: "Это перемещение противоречит ограничениям зависимостей. Автоматически перепланировать затронутые задачи ({{count}})?",
@@ -650,8 +738,8 @@ const ru = {
650
738
  },
651
739
  autoScheduleDlg: {
652
740
  title: "Автопланирование",
653
- body: "Сдвинуть {count} задач(и) на более поздний срок, чтобы соблюсти связи зависимостей?",
654
- skipped: "{count} заблокированных задач(и) также нарушают связи и были пропущены.",
741
+ body: "Сдвинуть {{count}} задач(и) на более поздний срок, чтобы соблюсти связи зависимостей?",
742
+ skipped: "{{count}} заблокированных задач(и) также нарушают связи и были пропущены.",
655
743
  confirm: "Применить",
656
744
  cancel: "Отмена",
657
745
  none: "Все зависимости соблюдены — перепланировать нечего.",
@@ -688,6 +776,7 @@ const ru = {
688
776
  exportPng: "Экспортировать в PNG",
689
777
  exportPdf: "Экспортировать в PDF",
690
778
  saveLayout: "Сохранить компоновку",
779
+ refresh: "Обновить",
691
780
  undo: "Отменить",
692
781
  redo: "Повторить",
693
782
  prevPeriod: "Предыдущий период",
@@ -728,11 +817,11 @@ const ru = {
728
817
  defaultBadge: "по умолчанию",
729
818
  tabActionsFor: "Действия с представлением {{name}}",
730
819
  readonlyAriaLabel: "Представление только для чтения",
731
- readonlyTooltip: "Системное представление — скопируйте для настройки.",
820
+ readonlyTooltip: "Системное представление — определено в коде, только для чтения.",
732
821
  },
733
822
  designer: {
734
- undo: 'Undo',
735
- redo: 'Redo',
823
+ undo: "Отменить",
824
+ redo: "Повторить",
736
825
  },
737
826
  detail: {
738
827
  editInlineHint: "Дважды щёлкните для редактирования",
@@ -774,13 +863,15 @@ const ru = {
774
863
  relatedRecords: "{{count}} записей",
775
864
  relatedRecordOne: "{{count}} запись",
776
865
  noRelatedRecords: "Связанные записи не найдены",
777
- loading: "Загрузка...",
866
+ loading: "Загрузка…",
778
867
  copyToClipboard: "Копировать в буфер обмена",
779
868
  copied: "Скопировано!",
780
869
  deleteConfirmation: "Вы уверены, что хотите удалить эту запись?",
870
+ deleted: "Запись удалена",
781
871
  editRecord: "Редактировать запись",
782
872
  viewAll: "Показать все",
783
873
  new: "Создать",
874
+ add: "Добавить",
784
875
  emptyValue: "—",
785
876
  activity: "Активность",
786
877
  editRow: "Редактировать",
@@ -791,7 +882,7 @@ const ru = {
791
882
  nextPage: "Далее",
792
883
  pageOf: "Страница {{current}} из {{total}}",
793
884
  sortBy: "Сортировать по",
794
- filterPlaceholder: "Фильтр...",
885
+ filterPlaceholder: "Фильтр…",
795
886
  highlightFields: "Ключевые поля",
796
887
  comments: "Комментарии",
797
888
  searchComments: "Поиск комментариев…",
@@ -856,6 +947,7 @@ const ru = {
856
947
  loadMore: "Загрузить ещё",
857
948
  edited: "(изменено)",
858
949
  via: "через {{source}}",
950
+ viewSource: "Показать источник",
859
951
  replyCount: "{{count}} ответ",
860
952
  replyCountPlural: "{{count}} ответов",
861
953
  replyPlaceholder: "Ответить…",
@@ -897,11 +989,20 @@ const ru = {
897
989
  concurrentUpdateReload: "Загрузить текущую версию",
898
990
  concurrentUpdateOverwrite: "Всё равно перезаписать",
899
991
  concurrentUpdateCancel: "Отмена",
992
+ concurrentUpdateRecordLabel: "этой записи",
900
993
  openInNewTab: "Открыть в новой вкладке",
901
994
  history: "История",
995
+ historyEmpty: "Истории пока нет",
902
996
  deleteRowTitle: "Удалить запись",
903
997
  createdBy: "Создано",
904
998
  updatedBy: "Обновлено",
999
+ // objectui#3863 — base key, and in ru this is the slot users actually hit: `few`
1000
+ // (2-4) and `many` (5-20, 25-30, …) are unenumerated, so before this key those
1001
+ // counts rendered ENGLISH. The value therefore cannot agree with the numeral —
1002
+ // it uses the «Существительное: {{count}}» form this pack already writes 22 times
1003
+ // (lookup.recordCount `Записей: {{count}}`, notifications.groupCount), which is
1004
+ // correct for EVERY Russian count. `_one` keeps the agreeing form for 1/21/31/…
1005
+ showEmptyRelated: "+ Пустых: {{count}}",
905
1006
  showEmptyRelated_one: "+ {{count}} пустое",
906
1007
  showEmptyRelated_other: "+ {{count}} пустых",
907
1008
  copyEmail: "Копировать email",
@@ -913,7 +1014,8 @@ const ru = {
913
1014
  },
914
1015
  chart: {
915
1016
  noData: "Нет данных для графика",
916
- loading: "Загрузка графика...",
1017
+ loading: "Загрузка графика…",
1018
+ nullCategory: "(Не указано)",
917
1019
  },
918
1020
  map: {
919
1021
  searchLocations: "Поиск местоположений…",
@@ -935,8 +1037,8 @@ const ru = {
935
1037
  properties: "Свойства",
936
1038
  connections: "Соединения",
937
1039
  quickConnect: "Быстрое соединение",
938
- fromPlaceholder: "От...",
939
- toPlaceholder: "К...",
1040
+ fromPlaceholder: "От…",
1041
+ toPlaceholder: "К…",
940
1042
  connect: "Соединить",
941
1043
  label: "Метка",
942
1044
  type: "Тип",
@@ -984,6 +1086,7 @@ const ru = {
984
1086
  },
985
1087
  dashboard: {
986
1088
  noRows: "Нет строк",
1089
+ loading: "Загрузка…",
987
1090
  pickMeasures: "Выберите меры (значения) для этого виджета набора данных.",
988
1091
  datasetUnsupported: "Этот источник данных не поддерживает запросы к наборам данных.",
989
1092
  details: "Подробности",
@@ -1077,7 +1180,7 @@ const ru = {
1077
1180
  faviconUrl: "Favicon URL",
1078
1181
  preview: "Предпросмотр",
1079
1182
  complete: "Завершить",
1080
- snakeCaseHint: "Must be snake_case (e.g. my_app)",
1183
+ snakeCaseHint: "Должно быть в формате snake_case (например, my_app)",
1081
1184
  modeEdit: "Редактировать",
1082
1185
  modePreview: "Предпросмотр",
1083
1186
  modeCode: "Код",
@@ -1241,6 +1344,7 @@ const ru = {
1241
1344
  },
1242
1345
  },
1243
1346
  console: {
1347
+ saveAdvisoryTitle: "Сохранено — проверка авторинга выдала рекомендаций: {{count}}",
1244
1348
  settingsHub: {
1245
1349
  title: "Настройки",
1246
1350
  subtitle: "Настройте рабочее пространство, интеграции и флаги функций.",
@@ -1307,7 +1411,7 @@ const ru = {
1307
1411
  shareTitle: "Поделиться этим диалогом",
1308
1412
  shareDisabledTitle: "Начните диалог, чтобы включить публикацию",
1309
1413
  newChat: "Создать",
1310
- searchChats: "Поиск по чатам...",
1414
+ searchChats: "Поиск по чатам…",
1311
1415
  noChatsYet: "Чатов пока нет",
1312
1416
  noChatsDescription: "Начните новый диалог, и он появится здесь.",
1313
1417
  noMatchingChats: "Подходящих чатов нет.",
@@ -1316,18 +1420,18 @@ const ru = {
1316
1420
  deleteConversation: "Удалить диалог",
1317
1421
  saveRename: "Сохранить название",
1318
1422
  cancelRename: "Отменить переименование",
1319
- loadingHistory: "Загрузка истории диалога...",
1423
+ loadingHistory: "Загрузка истории диалога…",
1320
1424
  conversationReady: "Диалог готов",
1321
1425
  preparingConversation: "Подготовка нового диалога",
1322
1426
  offlineDemoMode: "Автономный демонстрационный режим — список агентов недоступен",
1323
1427
  sendFailedRateLimited: "Вы отправляете сообщения слишком часто. Ваше сообщение сохранено ниже — подождите немного и попробуйте снова.",
1324
1428
  sendFailedGeneric: "Не удалось отправить сообщение. Оно сохранено ниже — попробуйте ещё раз.",
1325
- askAgent: "Спросить {{agent}}...",
1429
+ askAgent: "Спросить {{agent}}…",
1326
1430
  assistant: "Ассистент",
1327
1431
  liveCanvas: "Живой предпросмотр — {{app}} (черновик)",
1328
1432
  liveCanvasUnlisted: "Работающее приложение — {{app}} (скрыто до публикации)",
1329
- loadingAgents: "Загрузка агентов...",
1330
- askAnything: "Спросите о чём угодно...",
1433
+ loadingAgents: "Загрузка агентов…",
1434
+ askAnything: "Спросите о чём угодно…",
1331
1435
  emptyTitle: "Начните диалог",
1332
1436
  emptyDescription: "Спросите о чём угодно — ассистент видит контекст вашего текущего приложения.",
1333
1437
  switchAssistant: "Сменить ассистента",
@@ -1430,9 +1534,60 @@ const ru = {
1430
1534
  createSeed: "Сгенерировать примеры данных",
1431
1535
  createPackage: "Создать пакет приложения",
1432
1536
  },
1537
+ // objectui#3546 slice four — the AI console surfaces: the /ai chat page's app switcher,
1538
+ // connection banner and plan/publish cards, the ChatDock chrome, and the
1539
+ // conversation-list date buckets. `group.*` is the template-key family
1540
+ // `console.ai.group.${key}` (ConversationsSidebar), enumerated from the
1541
+ // ConversationGroupKey union — all five members, no wildcard.
1542
+ collapseToDock: "Свернуть в боковую панель",
1543
+ switchApp: "Сменить приложение",
1544
+ switchAppLabel: "Диалоги сборки по приложениям",
1545
+ newApp: "Новое приложение",
1546
+ connectionWaiting: "Ожидание сервера…",
1547
+ connectionStalled: "Всё ещё выполняется…",
1548
+ connectionOffline: "Соединение потеряно — переподключение…",
1549
+ designingPlan: "Проектирование вашего приложения…",
1550
+ designingPlanHint: {
1551
+ data: "Определяю данные, которые вы будете отслеживать…",
1552
+ objects: "Формирую объекты и их поля…",
1553
+ relations: "Соединяю связанные записи…",
1554
+ lookups: "Настраиваю связи и подстановки…",
1555
+ views: "Планирую экраны и представления…",
1556
+ forms: "Размещаю формы и списки…",
1557
+ defaults: "Добавляю разумные значения по умолчанию и проверки…",
1558
+ dashboard: "Набрасываю дашборд для отслеживания…",
1559
+ review: "Перепроверяю, что структура согласована…",
1560
+ finalize: "Собираю план воедино…",
1561
+ },
1562
+ planBuilding: "Сборка…",
1563
+ planBuilt: "Собрано",
1564
+ planDeferred: "Ещё не собрано",
1565
+ planReady: "План готов. Соберите его сейчас или скажите, что нужно скорректировать.",
1566
+ published: "Опубликовано",
1567
+ publishFailed: "Не удалось опубликовать",
1568
+ unavailableTitle: "Ассистент ИИ недоступен",
1569
+ unavailableDescription: "В этой среде ассистент ИИ не включён. Всё остальное работает как обычно.",
1570
+ unavailableError: "Не удалось связаться с сервисом ИИ. Возможно, он временно недоступен — повторите попытку или вернитесь на главную.",
1571
+ unavailableRetry: "Повторить",
1572
+ unavailableHome: "На главную",
1573
+ dock: {
1574
+ title: "Ассистент",
1575
+ description: "Чат с ассистентом ИИ",
1576
+ resize: "Изменить размер чата",
1577
+ collapse: "Свернуть чат",
1578
+ maximize: "Открыть на всю страницу",
1579
+ open: "Открыть ассистента",
1580
+ },
1581
+ group: {
1582
+ today: "Сегодня",
1583
+ yesterday: "Вчера",
1584
+ previous7Days: "Предыдущие 7 дней",
1585
+ previous30Days: "Предыдущие 30 дней",
1586
+ older: "Ранее",
1587
+ },
1433
1588
  },
1434
1589
  title: "Консоль ObjectStack",
1435
- initializing: "Инициализация приложения...",
1590
+ initializing: "Инициализация приложения…",
1436
1591
  loadingHint: "Настройка нового окружения может занять некоторое время.",
1437
1592
  breadcrumb: {
1438
1593
  dashboards: "Панели",
@@ -1440,6 +1595,31 @@ const ru = {
1440
1595
  reports: "Отчёты",
1441
1596
  system: "Система",
1442
1597
  },
1598
+ // objectui#4024 — the single-namespace settings screen. Its sibling
1599
+ // `settingsHub` above already resolved through this pack; the view was the
1600
+ // one file still carrying English literals.
1601
+ settingsView: {
1602
+ backToHub: "Все настройки",
1603
+ back: "Назад",
1604
+ noNamespace: "Пространство имён не выбрано.",
1605
+ loadError: "Не удалось загрузить настройки",
1606
+ saved: "Настройки сохранены",
1607
+ saveFailed: "Ошибка сохранения",
1608
+ lockedByEnv: "Заблокировано окружением: {{key}}",
1609
+ lockedByEnvNoKey: "Заблокировано окружением",
1610
+ actionSucceeded: "Действие выполнено",
1611
+ actionFailed: "Действие не выполнено",
1612
+ discard: "Отменить",
1613
+ saveChanges: "Сохранить изменения",
1614
+ unsavedCount: "Несохранённых изменений: {{count}}",
1615
+ unsavedCount_one: "{{count}} несохранённое изменение",
1616
+ unsavedCount_other: "{{count}} несохранённых изменений",
1617
+ cryptoRefusalTitle: "Эта установка не может шифровать секреты",
1618
+ cryptoRefusalSubjectSuffix: "объявлен зашифрованным, поэтому ничего не было записано.",
1619
+ cryptoRefusalNoSubject: "Значение, объявленное зашифрованным, было отклонено, поэтому ничего не было записано.",
1620
+ cryptoRefusalToast: "Не удалось зашифровать секреты: {{subject}}",
1621
+ cryptoRefusalToastNoSubject: "Не удалось зашифровать секреты",
1622
+ },
1443
1623
  loadingSteps: {
1444
1624
  connecting: "Подключение к источнику данных",
1445
1625
  loadingConfig: "Загрузка конфигурации",
@@ -1469,6 +1649,7 @@ const ru = {
1469
1649
  general: "Общие",
1470
1650
  navigation: "Навигация",
1471
1651
  dataViews: "Представления данных",
1652
+ aiChat: "Ассистент ИИ",
1472
1653
  preferences: "Настройки",
1473
1654
  },
1474
1655
  openCommandPalette: "Открыть палитру команд",
@@ -1479,11 +1660,13 @@ const ru = {
1479
1660
  createRecord: "Создать новую запись",
1480
1661
  refreshData: "Обновить данные",
1481
1662
  editRecord: "Редактировать выбранную запись",
1663
+ newChat: "Новый чат",
1664
+ toggleChatsList: "Переключить список чатов",
1482
1665
  toggleDarkMode: "Переключить тёмный режим",
1483
1666
  },
1484
1667
  commandPalette: {
1485
1668
  title: "Палитра команд",
1486
- placeholder: "Введите команду или поиск...",
1669
+ placeholder: "Введите команду или поиск…",
1487
1670
  noResults: "Результаты не найдены.",
1488
1671
  objects: "Объекты",
1489
1672
  dashboards: "Панели мониторинга",
@@ -1509,6 +1692,12 @@ const ru = {
1509
1692
  goHome: "На главную",
1510
1693
  errorDetails: "Подробности ошибки (только для разработки)",
1511
1694
  },
1695
+ // objectui#3546 slice four — the console's catch-all route (AppContent `RouteNotFound`).
1696
+ notFound: {
1697
+ title: "Страница не найдена",
1698
+ description: "Открытый URL не соответствует ни одному представлению в этом приложении.",
1699
+ back: "Назад",
1700
+ },
1512
1701
  theme: {
1513
1702
  toggle: "Переключить тему",
1514
1703
  light: "Светлая",
@@ -1524,8 +1713,10 @@ const ru = {
1524
1713
  viewNameHelp: "Машинный ключ (snake_case). Заполняется автоматически из заголовка — при желании измените.",
1525
1714
  viewNameRequired: "Введите ключ (строчные буквы, цифры, подчёркивание). Для нелатинских заголовков автозаполнение не работает.",
1526
1715
  viewNameInvalid: "Используйте строчные латинские буквы, цифры и подчёркивания; начните с буквы или подчёркивания.",
1527
- systemViewReadonly: 'System view defined in code - duplicate to customize.',
1528
- expandToPage: 'Open as full page',
1716
+ systemViewReadonly: "Системное представление определено в коде — только для чтения.",
1717
+ cannotEditMetaView: "Это встроенное представление, определённое в коде, — изменить его нельзя.",
1718
+ cannotDeleteMetaView: "Это встроенное представление, определённое в коде, — удалить его нельзя.",
1719
+ expandToPage: "Открыть на всю страницу",
1529
1720
  objectNotFound: "Объект не найден",
1530
1721
  objectNotFoundDescription: "Объект «{{objectName}}» не существует в текущей конфигурации.",
1531
1722
  objectNotFoundHint: "Проверьте настройки навигации приложения или выберите другой объект на боковой панели.",
@@ -1557,7 +1748,7 @@ const ru = {
1557
1748
  exportPrintHint: "Форматы экспорта, печать и отображение количества записей",
1558
1749
  showAllFields: "Показать все",
1559
1750
  hideAllFields: "Скрыть все",
1560
- searchFields: "Поиск полей...",
1751
+ searchFields: "Поиск полей…",
1561
1752
  title: "Заголовок",
1562
1753
  description: "Описание",
1563
1754
  data: "Данные",
@@ -1596,7 +1787,7 @@ const ru = {
1596
1787
  longitudeField: "Поле долготы",
1597
1788
  imageField: "Поле изображения",
1598
1789
  dateField: "Поле даты",
1599
- selectField: "Выберите поле...",
1790
+ selectField: "Выберите поле…",
1600
1791
  gridOptionsHint: "Представление таблицы использует столбцы, настроенные выше.",
1601
1792
  groupBy: "Группировать по",
1602
1793
  prefixField: "Поле префикса",
@@ -1659,7 +1850,7 @@ const ru = {
1659
1850
  latitudeFieldHelp: "Поле с широтой (только гео-поля).",
1660
1851
  longitudeFieldHelp: "Поле с долготой (только гео-поля).",
1661
1852
  imageFieldHelp: "Обложка галереи берётся из этого поля изображения или вложений.",
1662
- selectOption: "Выбрать...",
1853
+ selectOption: "Выбрать…",
1663
1854
  noEligibleFieldForType: "Нет подходящих полей этого типа. Сначала добавьте его к объекту.",
1664
1855
  viewTypeUnavailable: "У этого объекта нет поля, которое может служить \"{{field}}\".",
1665
1856
  viewTypeUnavailableShort: "Не поддерживается этим объектом.",
@@ -1709,7 +1900,7 @@ const ru = {
1709
1900
  ufDropdown: "Выпадающий список",
1710
1901
  ufTabs: "Вкладки",
1711
1902
  ufToggle: "Переключатель",
1712
- ufAddField: "+ Добавить поле фильтра...",
1903
+ ufAddField: "+ Добавить поле фильтра…",
1713
1904
  ufNoFields: "Поля недоступны",
1714
1905
  ufAddTab: "+ Добавить вкладку",
1715
1906
  ufTabLabel: "Метка",
@@ -1769,7 +1960,7 @@ const ru = {
1769
1960
  passwordPlaceholder: "Введите пароль",
1770
1961
  forgotPasswordText: "Забыли пароль?",
1771
1962
  submitButton: "Войти",
1772
- submittingButton: "Вход...",
1963
+ submittingButton: "Вход…",
1773
1964
  noAccountText: "Нет аккаунта?",
1774
1965
  signUpText: "Зарегистрироваться",
1775
1966
  errors: {
@@ -1777,6 +1968,18 @@ const ru = {
1777
1968
  invalidCredentials: "Неверный email или пароль. Попробуйте ещё раз.",
1778
1969
  emailNotVerified: "Пожалуйста, подтвердите email перед входом.",
1779
1970
  },
1971
+ // objectui#3546 slice three — phone/OTP sign-in. `{seconds}` is LoginForm's own
1972
+ // literal `.replace()` hole, not i18next interpolation: keep the single braces.
1973
+ emailOrPhoneLabel: "Электронная почта или номер телефона",
1974
+ emailOrPhonePlaceholder: "name@example.com или +1 555 000 0000",
1975
+ phoneLabel: "Номер телефона",
1976
+ phonePlaceholder: "+1 555 000 0000",
1977
+ otpCodeLabel: "Код подтверждения",
1978
+ otpCodePlaceholder: "6-значный код",
1979
+ sendOtpButton: "Получить код",
1980
+ resendOtpCountdownText: "Отправить снова через {seconds} с",
1981
+ usePhoneOtpText: "Войти по коду подтверждения",
1982
+ usePasswordSignInText: "Войти с паролем",
1780
1983
  },
1781
1984
  register: {
1782
1985
  title: "Создать аккаунт",
@@ -1792,7 +1995,7 @@ const ru = {
1792
1995
  passwordMismatchError: "Пароли не совпадают",
1793
1996
  passwordTooShortError: "Пароль должен содержать не менее 8 символов",
1794
1997
  submitButton: "Создать аккаунт",
1795
- submittingButton: "Создание аккаунта...",
1998
+ submittingButton: "Создание аккаунта…",
1796
1999
  hasAccountText: "Уже есть аккаунт?",
1797
2000
  signInText: "Войти",
1798
2001
  errors: {
@@ -1813,12 +2016,26 @@ const ru = {
1813
2016
  emailLabel: "Электронная почта",
1814
2017
  emailPlaceholder: "name@example.com",
1815
2018
  submitButton: "Отправить ссылку для сброса",
1816
- submittingButton: "Отправка...",
2019
+ submittingButton: "Отправка…",
1817
2020
  successTitle: "Проверьте почту",
1818
2021
  successDescription: "Мы отправили ссылку для сброса пароля на {{email}}. Пожалуйста, проверьте свою почту.",
1819
2022
  backToSignInText: "Вернуться к входу",
1820
2023
  rememberPasswordText: "Помните свой пароль?",
1821
2024
  signInText: "Войти",
2025
+ // objectui#3546 slice three — the SMS reset branch of the same form.
2026
+ phoneLabel: "Номер телефона",
2027
+ phonePlaceholder: "+1 555 000 0000",
2028
+ otpCodeLabel: "Код подтверждения",
2029
+ otpCodePlaceholder: "6-значный код",
2030
+ sendOtpButton: "Получить код",
2031
+ resendOtpCountdownText: "Отправить снова через {seconds} с",
2032
+ newPasswordLabel: "Новый пароль",
2033
+ newPasswordPlaceholder: "Введите новый пароль",
2034
+ resetButton: "Сбросить пароль",
2035
+ usePhoneResetText: "Сбросить по SMS-коду",
2036
+ useEmailResetText: "Сбросить по электронной почте",
2037
+ phoneSuccessTitle: "Пароль сброшен",
2038
+ phoneSuccessDescription: "Ваш пароль сброшен. Теперь вы можете войти с новым паролем.",
1822
2039
  },
1823
2040
  resetPassword: {
1824
2041
  title: "Установить новый пароль",
@@ -1857,6 +2074,8 @@ const ru = {
1857
2074
  backToLogin: "Вернуться ко входу",
1858
2075
  checkSpam: "Не получили письмо? Проверьте папку \"Спам\" или обратитесь в поддержку.",
1859
2076
  or: "Или",
2077
+ // objectui#3546 slice three.
2078
+ resendUnavailable: "Возможно, отправка писем не настроена для этой среды. Если проблема повторяется, обратитесь в поддержку.",
1860
2079
  },
1861
2080
  setup: {
1862
2081
  welcomeTitle: "Добро пожаловать в ObjectStack",
@@ -1895,6 +2114,9 @@ const ru = {
1895
2114
  invalidDescription: "В URL не указан код устройства.",
1896
2115
  loading: "Загрузка…",
1897
2116
  cancel: "Отмена",
2117
+ // objectui#3546 slice three — device-authorization plugin switched off.
2118
+ disabledTitle: "Авторизация устройств не включена",
2119
+ disabledDescription: "В этой инсталляции авторизация устройств не включена, поэтому это устройство здесь одобрить нельзя.",
1898
2120
  },
1899
2121
  shell: {
1900
2122
  tenantHostHint: "Вы входите в это рабочее пространство",
@@ -1934,6 +2156,29 @@ const ru = {
1934
2156
  },
1935
2157
  },
1936
2158
  },
2159
+ // objectui#3546 slice three — the /oauth/consent screen.
2160
+ oauth: {
2161
+ consent: {
2162
+ title: "{{appName}} запрашивает доступ к вашему аккаунту",
2163
+ request: "{{appName}} запрашивает разрешение{{suffix}}.",
2164
+ unknownApp: "приложение",
2165
+ willAllow: "Это приложение сможет:",
2166
+ scope: {
2167
+ openid: "Подтверждать вашу личность",
2168
+ profile: "Читать основной профиль (имя, фото)",
2169
+ email: "Читать ваш адрес электронной почты",
2170
+ offlineAccess: "Оставаться в системе (обновление доступа)",
2171
+ },
2172
+ deny: "Отклонить",
2173
+ authorize: "Разрешить",
2174
+ submitting: "Авторизация…",
2175
+ granted: "Доступ предоставлен",
2176
+ denied: "Доступ запрещён",
2177
+ noRedirect: "Сервер не вернул URL для перенаправления.",
2178
+ failed: "Не удалось выдать согласие",
2179
+ footer: "Вы можете отозвать доступ в любое время в настройках аккаунта.",
2180
+ },
2181
+ },
1937
2182
  profile: {
1938
2183
  title: "Профиль",
1939
2184
  subtitle: "Управляйте настройками своей учётной записи",
@@ -1995,6 +2240,8 @@ const ru = {
1995
2240
  invite: "Пригласить участника",
1996
2241
  members: "Участники",
1997
2242
  settings: "Настройки рабочего пространства",
2243
+ multiOrgDisabled: "Создание новых организаций отключено в этой среде.",
2244
+ createFailed: 'Не удалось создать рабочее пространство',
1998
2245
  },
1999
2246
  help: {
2000
2247
  onThisPage: "На этой странице",
@@ -2005,7 +2252,7 @@ const ru = {
2005
2252
  },
2006
2253
  sidebar: {
2007
2254
  packageManagement: "Управление пакетами",
2008
- searchNavigation: "Поиск по навигации...",
2255
+ searchNavigation: "Поиск по навигации…",
2009
2256
  settings: "Настройки",
2010
2257
  help: "Помощь",
2011
2258
  helpTooltip: "Помощь и документация",
@@ -2029,8 +2276,8 @@ const ru = {
2029
2276
  switchObject: "Сменить объект",
2030
2277
  connection: {
2031
2278
  connected: "Подключено",
2032
- connecting: "Подключение...",
2033
- reconnecting: "Переподключение...",
2279
+ connecting: "Подключение…",
2280
+ reconnecting: "Переподключение…",
2034
2281
  disconnected: "Отключено",
2035
2282
  error: "Ошибка подключения",
2036
2283
  },
@@ -2069,6 +2316,15 @@ const ru = {
2069
2316
  publishing: "Публикация…",
2070
2317
  published: "Опубликовано! Изменения вступили в силу.",
2071
2318
  publishFailed: "Не удалось опубликовать",
2319
+ // objectui#3546 slice six — seedWarn совпадает с console.ai.seedWarn по
2320
+ // английскому тексту, поэтому берём тот же перевод. В двух счётных
2321
+ // строках число вынесено в конец («…: {{count}}») — так пак пишет
2322
+ // количества, скобочные формы вида «файл(ов)» здесь не нужны.
2323
+ nothing: "Публиковать нечего.",
2324
+ probeWarn: "Опубликовано, но проверка выявила проблемы.",
2325
+ seedWarn: "Опубликовано, но часть примеров данных загрузить не удалось.",
2326
+ publishedVerified: "Опубликовано и проверено — активных строк примеров данных: {{count}}.",
2327
+ capabilityWarn: "Проверка при создании — несуществующих ссылок на возможности: {{count}}.",
2072
2328
  },
2073
2329
  title: "Главная",
2074
2330
  subtitle: "Панель вашего рабочего пространства",
@@ -2082,7 +2338,7 @@ const ru = {
2082
2338
  title: "Требует вашего внимания",
2083
2339
  empty: "Всё выполнено",
2084
2340
  },
2085
- loading: "Загрузка рабочего пространства...",
2341
+ loading: "Загрузка рабочего пространства…",
2086
2342
  recent: "Недавние",
2087
2343
  starred: "Избранные",
2088
2344
  welcome: "Добро пожаловать в ObjectUI",
@@ -2143,6 +2399,9 @@ const ru = {
2143
2399
  roles: "Роли",
2144
2400
  configuration: "Конфигурация",
2145
2401
  createApp: "Создать приложение",
2402
+ administration: "Администрирование",
2403
+ datasources: "Источники данных",
2404
+ documentation: "Документация",
2146
2405
  },
2147
2406
  appSwitcher: {
2148
2407
  switchApplication: "Сменить приложение",
@@ -2182,7 +2441,7 @@ const ru = {
2182
2441
  search: {
2183
2442
  title: "Поиск",
2184
2443
  back: "Назад",
2185
- placeholder: "Поиск объектов, панелей, страниц, отчётов...",
2444
+ placeholder: "Поиск объектов, панелей, страниц, отчётов…",
2186
2445
  inputAriaLabel: "Поиск объектов, панелей, страниц, отчётов",
2187
2446
  resultsCount: "{{count}} результат для \"{{query}}\"",
2188
2447
  resultsCountPlural: "{{count}} результатов для \"{{query}}\"",
@@ -2201,6 +2460,7 @@ const ru = {
2201
2460
  empty: {
2202
2461
  objectNotFound: "Объект не найден",
2203
2462
  objectNotFoundDescription: "Определение объекта \"{{name}}\" отсутствует. Проверьте конфигурацию или вернитесь назад.",
2463
+ interfacePageSourceMissing: "Эта интерфейсная страница ссылается на \"{{name}}\", который недоступен.",
2204
2464
  pageNotFound: "Страница не найдена",
2205
2465
  pageNotFoundDescription: "Страница \"{{name}}\" не найдена. Возможно, она была удалена или переименована.",
2206
2466
  dashboardNotFound: "Панель не найдена",
@@ -2209,6 +2469,11 @@ const ru = {
2209
2469
  reportNotFoundDescription: "Отчёт \"{{name}}\" не найден. Возможно, он был удалён или переименован.",
2210
2470
  noAppsConfigured: "Нет приложений",
2211
2471
  noAppsConfiguredDescription: "Нет зарегистрированных приложений. Создайте первое приложение или посетите системные настройки.",
2472
+ appNotAvailable: "Приложение недоступно",
2473
+ appNotAvailableDescription: "Это приложение пока недоступно — возможно, публикация ещё идёт. Повторите попытку через мгновение.",
2474
+ appAccessDenied: "У вас нет доступа к этому приложению",
2475
+ appAccessDeniedDescription: "Это приложение существует, но у вашей учётной записи нет прав на его открытие. Обратитесь к администратору за доступом.",
2476
+ appAccessDeniedHome: "На главную",
2212
2477
  createFirstApp: "Создать приложение",
2213
2478
  systemSettings: "Системные настройки",
2214
2479
  back: "Назад",
@@ -2280,7 +2545,7 @@ const ru = {
2280
2545
  deleteFailed: "Не удалось удалить представление",
2281
2546
  },
2282
2547
  dashboardActions: {
2283
- pdfPreparing: "Подготовка экспорта PDF…",
2548
+ printDialogOpening: "Открывается диалог печати браузера (это не экспорт в PDF)",
2284
2549
  exportFailed: "Ошибка экспорта: {{message}}",
2285
2550
  forecastSoon: "Прогнозное представление скоро будет",
2286
2551
  },
@@ -2324,111 +2589,7 @@ const ru = {
2324
2589
  first: "Первый",
2325
2590
  },
2326
2591
  editor: {
2327
- breadcrumb: "Конфигурация",
2328
- basic: "Основное",
2329
- title: "Заголовок",
2330
- titlePlaceholder: "напр., Воронка по кварталам",
2331
- description: "Описание",
2332
- descriptionPlaceholder: "Что показывает этот отчёт?",
2333
- type: "Тип отчёта",
2334
- typeTabular: "Табличный — плоский список",
2335
- typeSummary: "Сводный — группировка с итогами",
2336
- typeMatrix: "Матричный — сводка строки × столбцы",
2337
- typeJoined: "Объединённый — несколько блоков",
2338
- typeHelp: "Выберите макет, который соответствует тому, что хотите увидеть.",
2339
- data: "Данные",
2340
- objectName: "Источник данных",
2341
- objectNamePlaceholder: "напр., opportunity",
2342
- objectNameHelp: "К какому объекту обращается этот отчёт?",
2343
- limit: "Лимит строк",
2344
- limitPlaceholder: "напр., 100",
2345
- columns: "Столбцы",
2346
- columnsHint: "Выберите поля для столбцов. В сводных и матричных отчётах добавляйте агрегаты (Сумма, Количество…).",
2347
- filters: "Фильтры",
2348
- filtersHint: "Ограничьте строки, попадающие в отчёт.",
2349
- filtersComplex: "В отчёте используется расширенный фильтр, который нельзя редактировать здесь. При сохранении он останется без изменений.",
2350
- groupBy: "Группировать по",
2351
- groupByHint: "Сгруппируйте данные и посчитайте промежуточные итоги.",
2352
- rows: "Строки",
2353
- rowsHint: "Сгруппировать строки по этим полям.",
2354
- columnsAxis: "Столбцы",
2355
- columnsAxisHint: "Развернуть эти поля по горизонтали.",
2356
- values: "Значения",
2357
- valuesHint: "Числа в каждой ячейке. Выберите одно или несколько полей и задайте агрегат (Сумма, Количество…).",
2358
- grouping: "Группировка",
2359
- addGrouping: "Добавить группировку",
2360
- dateGranularity: "Гранулярность даты",
2361
- dateGranularityNone: "(исходное значение)",
2362
- day: "День",
2363
- week: "Неделя",
2364
- month: "Месяц",
2365
- quarter: "Квартал",
2366
- year: "Год",
2367
- sortAsc: "По возрастанию",
2368
- sortDesc: "По убыванию",
2369
- chart: "График",
2370
- chartHint: "Дополнительная визуализация рядом с таблицей.",
2371
- chartType: "Тип графика",
2372
- chartTitle: "Заголовок графика",
2373
- chartTitlePlaceholder: "По умолчанию — заголовок отчёта",
2374
- chartXAxis: "Ось X (категория)",
2375
- chartYAxis: "Ось Y (значение)",
2376
- chartShowLegend: "Показывать легенду",
2377
- chartShowDataLabels: "Показывать подписи данных",
2378
- chartNone: "(без графика)",
2379
- chartBar: "Столбчатый",
2380
- chartLine: "Линейный",
2381
- chartArea: "Областной",
2382
- chartPie: "Круговой",
2383
- chartDonut: "Кольцевой",
2384
- chartFunnel: "Воронка",
2385
- validationNeedsObject: "Выберите источник данных перед добавлением столбцов.",
2386
- validationMatrixNeedsRowsCols: "Для матричного отчёта нужны хотя бы одна строка и один столбец.",
2387
- validationSummaryNeedsRows: "Для сводного отчёта нужно хотя бы одно поле группировки.",
2388
- blocks: "Блоки",
2389
- blocksHint: "Каждый блок — отдельная таблица или график. Фильтры блока объединяются с фильтром отчёта по И.",
2390
- addBlock: "Добавить блок",
2391
- removeBlock: "Удалить блок",
2392
- blockName: "Имя блока",
2393
- blockNamePlaceholder: "уникальное_имя_блока",
2394
- blockLabel: "Отображаемое название",
2395
- blockLabelPlaceholder: "Показывается над блоком",
2396
- blockDescription: "Описание",
2397
- blockDescriptionPlaceholder: "Необязательный контекст для блока",
2398
- validationJoinedNeedsBlocks: "Объединённый отчёт должен содержать хотя бы один блок.",
2399
- validationBlockNameRequired: "У каждого блока должно быть непустое имя.",
2400
- validationBlockNameDuplicate: "Имена блоков в отчёте должны быть уникальными.",
2401
- validationBlockNeedsColumns: "В каждом блоке должна быть хотя бы одна колонка.",
2402
- noneOption: "(нет)",
2403
- addCondition: "Добавить условие",
2404
- combineLogic: "Объединить с",
2405
- opContains: "содержит",
2406
- opIsEmpty: "пусто",
2407
- opIsNotEmpty: "не пусто",
2408
- formatAuto: "Авто",
2409
- formatCurrency: "Валюта",
2410
- formatPercent: "Процент",
2411
- formatInteger: "Целое число",
2412
- formatDate: "Дата",
2413
- formatDatetime: "Дата и время",
2414
- columnLabelPlaceholder: "Переопределить подпись",
2415
- aggregateColumn: "Агрегат",
2416
- formatColumn: "Формат",
2417
- addColumns: "Добавить столбцы",
2418
- searchFields: "Поиск полей…",
2419
- noMatchingFields: "Нет полей, соответствующих запросу.",
2420
- noFieldsAvailable: "Полей нет.",
2421
- columnsCount: "{n} столбец(ов) выбрано",
2422
- columnsEmpty: "Столбцы ещё не выбраны.",
2423
- fieldPickerTitle: "Выбрать поля",
2424
- fieldPickerDescription: "Выберите одно или несколько полей для добавления. Используйте поиск для фильтрации.",
2425
- fieldPickerChangeTitle: "Изменить поле",
2426
- fieldPickerAddGroupingTitle: "Добавить группировку",
2427
- fieldPickerEmpty: "(Выбрать поле)",
2428
- fieldPickerSelected: "{n} выбрано",
2429
- fieldPickerClear: "Сбросить выбор",
2430
- fieldPickerAdd: "Добавить",
2431
- fieldPickerAddN: "Добавить {n}",
2592
+ panelTitle: "Редактировать отчёт",
2432
2593
  },
2433
2594
  },
2434
2595
  organizations: {
@@ -2445,6 +2606,140 @@ const ru = {
2445
2606
  emptyDescription: "Создайте свою первую организацию, чтобы начать.",
2446
2607
  noMatches: "Нет организаций, соответствующих запросу.",
2447
2608
  },
2609
+ organization: {
2610
+ roles: {
2611
+ owner: 'Владелец',
2612
+ admin: 'Администратор',
2613
+ delegatedAdmin: 'Делегированный администратор',
2614
+ member: 'Участник',
2615
+ },
2616
+ errors: {
2617
+ notAllowedToInvite: 'У вас нет прав приглашать пользователей в эту организацию.',
2618
+ notAllowedToInviteWithRole: 'У вас нет прав приглашать пользователя с этой ролью.',
2619
+ alreadyInvited: 'Этот пользователь уже приглашён в эту организацию.',
2620
+ organizationExists: 'Такая организация уже существует.',
2621
+ slugTaken: 'Этот идентификатор уже занят.',
2622
+ notAllowedToCreate: 'У вас нет прав создавать новую организацию.',
2623
+ notTheRecipient: 'Вы не являетесь получателем этого приглашения.',
2624
+ invitationNotFound: 'Это приглашение больше не существует или истекло.',
2625
+ unknown: 'Что-то пошло не так. Попробуйте ещё раз.',
2626
+ },
2627
+ backToList: "Назад к организациям",
2628
+ notFound: "Организация не найдена",
2629
+ notFoundDescription: "Эта организация не существует или у вас нет к ней доступа.",
2630
+ tabs: {
2631
+ members: "Участники",
2632
+ invitations: "Приглашения",
2633
+ settings: "Настройки",
2634
+ },
2635
+ members: {
2636
+ title: "Участники",
2637
+ inviteMember: "Пригласить участника",
2638
+ inviteRestrictedNote: "Только администраторы организации могут приглашать участников.",
2639
+ removeMember: "Удалить участника",
2640
+ removeConfirmTitle: "Удалить участника?",
2641
+ removeConfirmDescription: "{{name}} будет удалён из организации и сразу потеряет доступ.",
2642
+ removeConfirmAction: "Удалить",
2643
+ memberRemoved: "Участник удалён",
2644
+ removeFailed: "Не удалось удалить участника",
2645
+ roleUpdated: "Роль обновлена",
2646
+ roleUpdateFailed: "Не удалось обновить роль",
2647
+ memberActions: 'Действия с участником',
2648
+ loadFailed: 'Не удалось загрузить участников',
2649
+ },
2650
+ invitations: {
2651
+ title: "Приглашения",
2652
+ empty: "Приглашений нет.",
2653
+ expiresAt: "Истекает",
2654
+ linkCopied: "Ссылка на приглашение скопирована",
2655
+ copyFailed: "Не удалось скопировать ссылку",
2656
+ canceled: "Приглашение отменено",
2657
+ cancelFailed: "Не удалось отменить приглашение",
2658
+ cancelTitle: "Отменить приглашение?",
2659
+ cancelDescription: "Приглашение для {{email}} будет отозвано.",
2660
+ cancelAction: "Отменить приглашение",
2661
+ inviteTitle: "Пригласить участника",
2662
+ inviteDescription: "Человек получит приглашение вступить в эту организацию.",
2663
+ emailLabel: "Электронная почта",
2664
+ roleLabel: "Роль",
2665
+ placementLabel: "Назначение (необязательно)",
2666
+ placementDescription: "Применяется при принятии приглашения. Показаны только подразделения и должности, которые вы можете делегировать.",
2667
+ businessUnitLabel: "Бизнес-подразделение",
2668
+ businessUnitPlaceholder: "Без назначения",
2669
+ positionsLabel: "Должности",
2670
+ sendInvite: "Отправить приглашение",
2671
+ sentTitle: "Приглашение создано",
2672
+ sentDescription: "Отправьте ссылку ниже приглашённому. Чтобы принять приглашение, ему нужно войти в систему.",
2673
+ linkLabel: "Ссылка для принятия",
2674
+ invitedAs: "{{email}} приглашён как {{role}}",
2675
+ copyLinkLabel: 'Скопировать ссылку-приглашение',
2676
+ loadFailed: 'Не удалось загрузить приглашения',
2677
+ inviteFailed: 'Не удалось пригласить участника',
2678
+ status: {
2679
+ all: "Все",
2680
+ pending: "Ожидает",
2681
+ accepted: "Принято",
2682
+ rejected: "Отклонено",
2683
+ canceled: "Отменено",
2684
+ },
2685
+ },
2686
+ settings: {
2687
+ generalTitle: "Общие",
2688
+ generalDescription: "Обновите сведения об организации.",
2689
+ readOnlyNote: "Изменять настройки могут только владельцы.",
2690
+ nameLabel: "Название организации",
2691
+ slugLabel: "Слаг",
2692
+ logoLabel: "Логотип",
2693
+ logoUpload: "Загрузить",
2694
+ logoReplace: "Заменить",
2695
+ logoClear: "Удалить",
2696
+ logoUploaded: "Логотип загружен — сохраните, чтобы применить",
2697
+ logoUploadFailed: "Не удалось загрузить логотип",
2698
+ save: "Сохранить изменения",
2699
+ saved: "Настройки сохранены",
2700
+ saveFailed: "Не удалось сохранить настройки",
2701
+ leaveTitle: "Покинуть организацию",
2702
+ leaveDescription: "Вы потеряете доступ к этой организации.",
2703
+ leaveAction: "Покинуть",
2704
+ leaveConfirmTitle: "Покинуть организацию?",
2705
+ leaveConfirmDescription: "Вы уверены, что хотите покинуть {{name}}? Доступ будет потерян немедленно.",
2706
+ leaveConfirmAction: "Покинуть",
2707
+ leftOrg: "Вы покинули организацию",
2708
+ leaveFailed: "Не удалось покинуть организацию",
2709
+ dangerZone: "Опасная зона",
2710
+ deleteTitle: "Удалить организацию",
2711
+ deleteDescription: "Безвозвратно удалить эту организацию и все её данные.",
2712
+ deleteAction: "Удалить",
2713
+ deleteConfirmTitle: "Удалить организацию?",
2714
+ deleteConfirmDescription: "Это действие необратимо. Все данные будут удалены безвозвратно. Введите слаг организации для подтверждения.",
2715
+ deleteConfirmSlugLabel: "Введите «{{slug}}» для подтверждения",
2716
+ deleteConfirmAction: "Удалить организацию",
2717
+ deleted: "Организация удалена",
2718
+ deleteFailed: "Не удалось удалить организацию",
2719
+ },
2720
+ accept: {
2721
+ title: "Вас пригласили",
2722
+ description: "Вас пригласили присоединиться к {{orgName}} в роли {{role}}.",
2723
+ errorTitle: "Приглашение недоступно",
2724
+ goToOrgs: "Перейти к организациям",
2725
+ loading: "Загрузка приглашения…",
2726
+ organization: "Организация",
2727
+ role: "Роль",
2728
+ expiresAt: "Истекает",
2729
+ accept: "Принять приглашение",
2730
+ accepted: "Приглашение принято",
2731
+ acceptFailed: "Не удалось принять приглашение",
2732
+ decline: "Отклонить",
2733
+ declined: "Приглашение отклонено",
2734
+ declineFailed: "Не удалось отклонить приглашение",
2735
+ },
2736
+ switcher: {
2737
+ label: "Переключить организацию",
2738
+ groupLabel: "Рабочая организация",
2739
+ groupHint: "Новые записи создаются здесь. В представлениях отображаются данные из всех ваших организаций.",
2740
+ manageMembers: "Управление участниками",
2741
+ },
2742
+ },
2448
2743
  notifications: {
2449
2744
  regionLabel: "Уведомления",
2450
2745
  groupCount: "Уведомлений: {{count}}",
@@ -2458,6 +2753,9 @@ const ru = {
2458
2753
  viewApprovals: "Показать утверждения",
2459
2754
  noPendingApprovals: "Нет ожидающих утверждений",
2460
2755
  openApprovalsInbox: "Открыть входящие утверждений",
2756
+ badgeTotal: "Всего: {{total}}",
2757
+ badgeNotifications: "{{unread}} уведомлений",
2758
+ badgeApprovals: "{{approvals}} ожидающих утверждений",
2461
2759
  emptyUnread: "Всё прочитано",
2462
2760
  filterUnread: "Непрочитанные",
2463
2761
  filterAll: "Все",
@@ -2744,6 +3042,7 @@ const ru = {
2744
3042
  dismiss: "Закрыть",
2745
3043
  openOnCloud: "Открыть в облаке",
2746
3044
  backHome: "На главную",
3045
+ updateTo: "Обновить",
2747
3046
  },
2748
3047
  install: {
2749
3048
  dialogTitle: "Установить {{name}}",
@@ -2760,6 +3059,37 @@ const ru = {
2760
3059
  localManifestConflict: "{{message}}\nПримечание: Локальное приложение уже имеет этот manifest_id. Сначала удалите его из objectstack.config.ts.",
2761
3060
  localUnauthorized: "Сначала войдите в этот рантайм.",
2762
3061
  localMarketplaceUnavailable: "OS_CLOUD_URL не настроен.",
3062
+ updateTo: "Обновить → v{{version}}",
3063
+ installedVersion: "Установлено v{{version}}",
3064
+ },
3065
+ // objectui#3546 — the MarketplacePage "Your organization" strip.
3066
+ org: {
3067
+ heading: "Ваша организация",
3068
+ install: "Установить",
3069
+ installed: "Установлено {{name}}",
3070
+ installedBadge: "Установлено",
3071
+ installing: "Установка…",
3072
+ },
3073
+ // ADR-0025 PD4 §3.5/§3.11 — the pre-install consent panel
3074
+ // (PluginDisclosure.tsx). `runtime` is a CLOSED enum: spec
3075
+ // PluginRuntimeSchema = z.enum(['node', 'sandbox', 'worker']).
3076
+ disclosure: {
3077
+ containsCode: "Этот пакет содержит код",
3078
+ reviewed: "Проверено и одобрено",
3079
+ unreviewed: "Ещё не проверено",
3080
+ signed: "Подписано",
3081
+ grantsIntro: "При установке пакет получит:",
3082
+ services: "Сервисы платформы",
3083
+ hooks: "Хуки жизненного цикла",
3084
+ network: "Доступ к сети",
3085
+ fs: "Доступ к файловой системе",
3086
+ noPermissions: "Не запрашивает особых разрешений.",
3087
+ acknowledge: "Я понимаю, что этот пакет выполняет код и получает указанные выше разрешения.",
3088
+ runtime: {
3089
+ node: "В процессе · полное доверие",
3090
+ sandbox: "В песочнице",
3091
+ worker: "Вне процесса",
3092
+ },
2763
3093
  },
2764
3094
  uninstall: {
2765
3095
  confirm: "Удалить {{manifestId}} v{{version}}?\n\nКэшированный манифест будет удалён.",
@@ -3009,6 +3339,34 @@ const ru = {
3009
3339
  confirmNote: 'Публикация атомарно выпускает все {{count}} ожидающих черновиков этого пакета.',
3010
3340
  publishConfirm: 'Опубликовать всё',
3011
3341
  },
3342
+ // ADR-0045 — the materialized-but-unlisted app banner
3343
+ // (UnpublishedAppBar.tsx), sibling of draftBar above.
3344
+ unpublishedBar: {
3345
+ message: 'Неопубликованное приложение — полностью работает, но видно только создателям. Опубликуйте, чтобы его увидели ваши пользователи.',
3346
+ publish: 'Опубликовать',
3347
+ publishing: 'Публикация…',
3348
+ published: 'Опубликовано! Приложение теперь видно вашим пользователям.',
3349
+ publishFailed: 'Не удалось опубликовать',
3350
+ },
3351
+ // ADR-0067 — the append-only build/revert timeline (CommitTimeline.tsx);
3352
+ // `button` is the banner's entry point into it.
3353
+ history: {
3354
+ button: 'История',
3355
+ title: 'История сборок',
3356
+ description: 'Все изменения этого приложения, новые сверху. Любой шаг можно отменить — подтверждать публикацию не нужно.',
3357
+ loadFailed: 'Не удалось загрузить историю:',
3358
+ loadFailedUnavailable: 'Хранилище коммитов временно недоступно — это чтение не выполнено, поэтому история не показана. Повторите попытку через мгновение.',
3359
+ loading: 'Загрузка истории…',
3360
+ empty: 'Истории для этого приложения пока нет.',
3361
+ revertLabel: 'Изменение отменено',
3362
+ applyLabel: 'Изменение сборки',
3363
+ revert: 'отмена',
3364
+ items: 'элементов',
3365
+ revertAction: 'Отменить',
3366
+ reverted: 'Отменено — изменение возвращено.',
3367
+ revertFailed: 'Не удалось отменить',
3368
+ revertUnavailable: 'Хранилище коммитов временно недоступно — отмена могла не примениться. Откройте историю заново и проверьте, прежде чем повторять.',
3369
+ },
3012
3370
  },
3013
3371
  filterBuilder: {
3014
3372
  where: "Где",
@@ -3087,5 +3445,57 @@ const ru = {
3087
3445
  statusIdle: "бездействует",
3088
3446
  statusAway: "отошёл",
3089
3447
  },
3448
+ wizard: {
3449
+ missingRequired: "Заполните обязательные поля: {{fields}}",
3450
+ },
3451
+ appManagement: {
3452
+ title: "Приложения",
3453
+ subtitle: "Управление всеми настроенными приложениями",
3454
+ newApp: "Новое приложение",
3455
+ searchLabel: "Поиск приложений",
3456
+ searchPlaceholder: "Поиск приложений…",
3457
+ selectedCount: "Выбрано: {{n}}",
3458
+ bulkEnable: "Включить",
3459
+ bulkDisable: "Отключить",
3460
+ selectAll: "Выбрать все ({{n}})",
3461
+ empty: "Приложения не найдены.",
3462
+ defaultBadge: "По умолчанию",
3463
+ active: "Активно",
3464
+ inactive: "Неактивно",
3465
+ selectApp: "Выбрать {{name}}",
3466
+ openApp: "Открыть приложение",
3467
+ openAppNamed: "Открыть {{name}}",
3468
+ editApp: "Редактировать приложение",
3469
+ editAppNamed: "Редактировать {{name}}",
3470
+ editWithAi: "Редактировать с ИИ",
3471
+ editWithAiNamed: "Редактировать {{name}} с ИИ",
3472
+ enableApp: "Включить приложение",
3473
+ disableApp: "Отключить приложение",
3474
+ enableAppNamed: "Включить {{name}}",
3475
+ disableAppNamed: "Отключить {{name}}",
3476
+ setDefault: "Установить по умолчанию",
3477
+ setDefaultNamed: "Установить {{name}} по умолчанию",
3478
+ deleteApp: "Удалить приложение",
3479
+ deleteAppNamed: "Удалить {{name}}",
3480
+ confirmDelete: "Нажмите ещё раз для подтверждения удаления",
3481
+ confirmDeleteNamed: "Подтвердить удаление {{name}}",
3482
+ toast: {
3483
+ noClient: "Не удаётся подключиться к службе метаданных",
3484
+ unknownError: "неизвестная ошибка",
3485
+ appEnabled: "{{name}} включено",
3486
+ appDisabled: "{{name}} отключено",
3487
+ toggleFailed: "Не удалось изменить состояние приложения: {{reason}}",
3488
+ setDefaultDone: "{{name}} установлено по умолчанию",
3489
+ setDefaultFailed: "Не удалось установить приложение по умолчанию: {{reason}}",
3490
+ appDeleted: "{{name}} удалено",
3491
+ deleteFailed: "Не удалось удалить приложение: {{reason}}",
3492
+ bulkEnabled: "Включено приложений: {{n}}",
3493
+ bulkDisabled: "Отключено приложений: {{n}}",
3494
+ bulkFailed: "Не удалось для {{n}}: {{details}}",
3495
+ bulkFailureEntry: "{{name}} ({{reason}})",
3496
+ bulkFailureJoiner: "; ",
3497
+ bulkOperationFailed: "Массовая операция не выполнена: {{reason}}",
3498
+ },
3499
+ },
3090
3500
  };
3091
3501
  export default ru;