@stapel/workspaces-react 0.17.0 → 0.19.1
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.
- package/CHANGELOG.md +218 -0
- package/README.md +39 -8
- package/dist/api/generated/schema.d.ts +187 -60
- package/dist/api/generated/schema.d.ts.map +1 -1
- package/dist/default/ActiveWorkspace.d.ts +43 -0
- package/dist/default/ActiveWorkspace.d.ts.map +1 -0
- package/dist/default/ActiveWorkspace.js +33 -0
- package/dist/default/ActiveWorkspace.js.map +1 -0
- package/dist/default/AuditTrailPane.d.ts +12 -0
- package/dist/default/AuditTrailPane.d.ts.map +1 -0
- package/dist/default/AuditTrailPane.js +154 -0
- package/dist/default/AuditTrailPane.js.map +1 -0
- package/dist/default/InvitationsPane.d.ts +19 -0
- package/dist/default/InvitationsPane.d.ts.map +1 -0
- package/dist/default/InvitationsPane.js +217 -0
- package/dist/default/InvitationsPane.js.map +1 -0
- package/dist/default/InviteAcceptPage.d.ts +7 -0
- package/dist/default/InviteAcceptPage.d.ts.map +1 -1
- package/dist/default/InviteAcceptPage.js +74 -38
- package/dist/default/InviteAcceptPage.js.map +1 -1
- package/dist/default/MembersManager.d.ts +12 -4
- package/dist/default/MembersManager.d.ts.map +1 -1
- package/dist/default/MembersManager.js +320 -84
- package/dist/default/MembersManager.js.map +1 -1
- package/dist/default/RoleSelectField.d.ts +64 -0
- package/dist/default/RoleSelectField.d.ts.map +1 -0
- package/dist/default/RoleSelectField.js +78 -0
- package/dist/default/RoleSelectField.js.map +1 -0
- package/dist/default/WorkspaceSettings.d.ts +7 -1
- package/dist/default/WorkspaceSettings.d.ts.map +1 -1
- package/dist/default/WorkspaceSettings.js +203 -45
- package/dist/default/WorkspaceSettings.js.map +1 -1
- package/dist/default/WorkspacesPage.d.ts +13 -0
- package/dist/default/WorkspacesPage.d.ts.map +1 -0
- package/dist/default/WorkspacesPage.js +109 -0
- package/dist/default/WorkspacesPage.js.map +1 -0
- package/dist/default/index.d.ts +28 -7
- package/dist/default/index.d.ts.map +1 -1
- package/dist/default/index.js +24 -7
- package/dist/default/index.js.map +1 -1
- package/dist/default/parts.d.ts +104 -0
- package/dist/default/parts.d.ts.map +1 -0
- package/dist/default/parts.js +143 -0
- package/dist/default/parts.js.map +1 -0
- package/dist/headless/Members.d.ts +59 -14
- package/dist/headless/Members.d.ts.map +1 -1
- package/dist/headless/Members.js +35 -10
- package/dist/headless/Members.js.map +1 -1
- package/dist/headless/RoleSelect.d.ts +9 -3
- package/dist/headless/RoleSelect.d.ts.map +1 -1
- package/dist/headless/RoleSelect.js +3 -2
- package/dist/headless/RoleSelect.js.map +1 -1
- package/dist/i18n/es.d.ts +11 -12
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +267 -14
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.es.gen.js +5 -0
- package/dist/i18n/generated/errors.es.gen.js.map +1 -1
- package/dist/i18n/generated/errors.gen.d.ts +30 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.gen.js +15 -0
- package/dist/i18n/generated/errors.gen.js.map +1 -1
- package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.ru.gen.js +5 -0
- package/dist/i18n/generated/errors.ru.gen.js.map +1 -1
- package/dist/i18n/keys.d.ts +209 -1
- package/dist/i18n/keys.d.ts.map +1 -1
- package/dist/i18n/keys.js +410 -4
- package/dist/i18n/keys.js.map +1 -1
- package/dist/i18n/ru.d.ts +7 -2
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +209 -4
- package/dist/i18n/ru.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model/format.d.ts +56 -0
- package/dist/model/format.d.ts.map +1 -0
- package/dist/model/format.js +125 -0
- package/dist/model/format.js.map +1 -0
- package/dist/model/selection.d.ts +15 -0
- package/dist/model/selection.d.ts.map +1 -1
- package/dist/model/selection.js +18 -1
- package/dist/model/selection.js.map +1 -1
- package/dist/nav/manifest.d.ts +45 -0
- package/dist/nav/manifest.d.ts.map +1 -0
- package/dist/nav/manifest.js +77 -0
- package/dist/nav/manifest.js.map +1 -0
- package/llms.txt +11 -10
- package/manifest.json +281 -69
- package/package.json +18 -12
- package/src/analytics/generated/events.json +1 -1
- package/src/api/generated/schema.ts +187 -60
- package/src/default/ActiveWorkspace.tsx +97 -0
- package/src/default/AuditTrailPane.tsx +309 -0
- package/src/default/InvitationsPane.tsx +501 -0
- package/src/default/InviteAcceptPage.tsx +187 -90
- package/src/default/MembersManager.tsx +832 -222
- package/src/default/RoleSelectField.tsx +187 -0
- package/src/default/WorkspaceSettings.tsx +540 -125
- package/src/default/WorkspacesPage.tsx +394 -0
- package/src/default/index.ts +28 -7
- package/src/default/parts.tsx +315 -0
- package/src/headless/Members.tsx +84 -16
- package/src/headless/RoleSelect.tsx +12 -5
- package/src/i18n/es.ts +326 -14
- package/src/i18n/generated/errors.es.gen.ts +5 -0
- package/src/i18n/generated/errors.gen.ts +15 -0
- package/src/i18n/generated/errors.json +37 -0
- package/src/i18n/generated/errors.ru.gen.ts +5 -0
- package/src/i18n/keys.ts +462 -5
- package/src/i18n/ru.ts +259 -5
- package/src/index.ts +1 -0
- package/src/model/format.ts +158 -0
- package/src/model/selection.tsx +19 -1
- package/src/nav/manifest.ts +120 -0
- package/dist/default/ErrorAlert.d.ts +0 -8
- package/dist/default/ErrorAlert.d.ts.map +0 -1
- package/dist/default/ErrorAlert.js +0 -30
- package/dist/default/ErrorAlert.js.map +0 -1
- package/src/default/ErrorAlert.tsx +0 -47
package/dist/i18n/ru.js
CHANGED
|
@@ -12,9 +12,14 @@ export { workspacesErrorBundleRu } from "./generated/errors.ru.gen.js";
|
|
|
12
12
|
* error texts (from stapel-workspaces's `translations/errors.ru.json`
|
|
13
13
|
* catalog, seeded from the curated stapel-translate corpus — `pnpm
|
|
14
14
|
* gen:errors`) are spread first for coverage by construction; the
|
|
15
|
-
* hand-written ru UI copy for the pair-owned
|
|
16
|
-
*
|
|
15
|
+
* hand-written ru UI copy for the pair-owned `WORKSPACES_I18N_KEYS` follows.
|
|
16
|
+
* Override any key by registering a host bundle AFTER this one
|
|
17
17
|
* (merge-priority convention — see keys.ts).
|
|
18
|
+
*
|
|
19
|
+
* PLURALS. Russian takes four CLDR categories where English takes two, so a
|
|
20
|
+
* `*.count` family ships `one`/`few`/`many`/`other` here and `one`/`other`
|
|
21
|
+
* there. That asymmetry is the translation being right, not a key being
|
|
22
|
+
* wrong — `useTPlural` picks the category from the reader's locale.
|
|
18
23
|
*/
|
|
19
24
|
export const workspacesI18nBundleRu = {
|
|
20
25
|
// Backend error codes — generated ru texts (coverage by construction).
|
|
@@ -22,6 +27,11 @@ export const workspacesI18nBundleRu = {
|
|
|
22
27
|
// workspaces-react UI (hand-written ru mirror of the en copy in keys.ts)
|
|
23
28
|
"workspaces.error.unknown": "Что-то пошло не так. Попробуйте ещё раз.",
|
|
24
29
|
"workspaces.retry": "Попробовать снова",
|
|
30
|
+
"workspaces.dialog.close": "Закрыть",
|
|
31
|
+
"workspaces.cancel": "Отмена",
|
|
32
|
+
"workspaces.pager.prev": "Назад",
|
|
33
|
+
"workspaces.pager.next": "Дальше",
|
|
34
|
+
"workspaces.pager.position": "Страница {page}",
|
|
25
35
|
"workspaces.list.loading": "Загрузка рабочих пространств…",
|
|
26
36
|
"workspaces.list.empty": "Пока нет рабочих пространств.",
|
|
27
37
|
"workspaces.list.load_failed": "Не удалось загрузить ваши рабочие пространства. Это сбой на нашей стороне, а не признак того, что их у вас нет.",
|
|
@@ -30,7 +40,8 @@ export const workspacesI18nBundleRu = {
|
|
|
30
40
|
"workspaces.members.loading": "Загрузка участников…",
|
|
31
41
|
"workspaces.members.empty": "Пока нет участников.",
|
|
32
42
|
"workspaces.members.load_failed": "Не удалось загрузить список участников.",
|
|
33
|
-
"workspaces.roles.load_failed": "Не удалось загрузить список ролей, поэтому
|
|
43
|
+
"workspaces.roles.load_failed": "Не удалось загрузить список ролей, поэтому изменить роль сейчас нельзя. Это не значит, что в рабочем пространстве нет ролей.",
|
|
44
|
+
"workspaces.roles.empty": "На этой установке роли не заданы, выбирать не из чего.",
|
|
34
45
|
"workspaces.members.invite": "Пригласить",
|
|
35
46
|
"workspaces.members.inviting": "Приглашение…",
|
|
36
47
|
"workspaces.members.update_role": "Изменить роль",
|
|
@@ -43,20 +54,113 @@ export const workspacesI18nBundleRu = {
|
|
|
43
54
|
"workspaces.settings.field.name": "Название рабочего пространства",
|
|
44
55
|
"workspaces.settings.field.slug": "URL-идентификатор",
|
|
45
56
|
"workspaces.settings.field.type": "Тип",
|
|
57
|
+
"workspaces.settings.type.personal": "Личное",
|
|
58
|
+
"workspaces.settings.type.work": "Рабочее",
|
|
46
59
|
"workspaces.settings.save": "Сохранить изменения",
|
|
47
|
-
"workspaces.settings.blocked.
|
|
60
|
+
"workspaces.settings.blocked.cannot_manage": "Ваша роль не может менять настройки этого рабочего пространства.",
|
|
48
61
|
"workspaces.settings.blocked.name_required": "Введите название рабочего пространства.",
|
|
62
|
+
"workspaces.settings.blocked.unchanged": "Пока ничего не изменилось.",
|
|
49
63
|
"workspaces.settings.saving": "Сохранение…",
|
|
50
64
|
"workspaces.settings.danger_zone.title": "Опасная зона",
|
|
51
65
|
"workspaces.settings.danger_zone.delete": "Удалить рабочее пространство",
|
|
52
66
|
"workspaces.settings.danger_zone.delete_confirm": "Удалить это рабочее пространство? Действие необратимо.",
|
|
67
|
+
"workspaces.settings.danger_zone.delete_confirm_body": "Все сразу потеряют доступ. Данные, которые хранят о нём другие сервисы, удаляются по их собственным правилам хранения.",
|
|
68
|
+
"workspaces.settings.danger_zone.blocked": "Это рабочее пространство удалить нельзя.",
|
|
69
|
+
"workspaces.settings.security.title": "Безопасность",
|
|
70
|
+
"workspaces.settings.security.subtitle": "Правила, которым должны соответствовать все участники.",
|
|
71
|
+
"workspaces.settings.security.require_mfa": "Требовать двухфакторную аутентификацию",
|
|
72
|
+
"workspaces.settings.security.require_mfa_hint": "Участники без подтверждённого второго фактора не допускаются, пока не добавят его.",
|
|
73
|
+
"workspaces.settings.security.policies_label": "Что потребовать при первом входе у аккаунтов, созданных этим пространством",
|
|
74
|
+
"workspaces.settings.security.policies_hint": "Независимые требования, а не альтернативы — организация может потребовать оба.",
|
|
75
|
+
"workspaces.settings.security.policy.password_change": "Сменить пароль",
|
|
76
|
+
"workspaces.settings.security.policy.mfa_enroll": "Настроить двухфакторную аутентификацию",
|
|
77
|
+
"workspaces.settings.security.save": "Сохранить настройки безопасности",
|
|
78
|
+
"workspaces.settings.security.saving": "Сохранение…",
|
|
79
|
+
"workspaces.settings.security.blocked.capability": "Ваша роль не может менять настройки безопасности.",
|
|
80
|
+
"workspaces.settings.security.step_up_notice": "Перед сохранением мы попросим подтвердить вашу личность.",
|
|
81
|
+
"workspaces.settings.security.mfa.status_title": "Как выполняется политика",
|
|
82
|
+
"workspaces.settings.security.mfa.state_label": "Состояние",
|
|
83
|
+
"workspaces.settings.security.mfa.state.pending": "Ждём первой проверки",
|
|
84
|
+
"workspaces.settings.security.mfa.state.enforcing": "Проверяем участников",
|
|
85
|
+
"workspaces.settings.security.mfa.state.enforced": "Действует",
|
|
86
|
+
"workspaces.settings.security.mfa.state.failed": "Последняя проверка не удалась",
|
|
87
|
+
"workspaces.settings.security.mfa.state.other": "Неизвестное состояние ({state})",
|
|
88
|
+
"workspaces.settings.security.mfa.checked_count": "Проверено участников: {count}",
|
|
89
|
+
"workspaces.settings.security.mfa.checked_count.one": "Проверен {count} участник",
|
|
90
|
+
"workspaces.settings.security.mfa.checked_count.few": "Проверено {count} участника",
|
|
91
|
+
"workspaces.settings.security.mfa.checked_count.many": "Проверено {count} участников",
|
|
92
|
+
"workspaces.settings.security.mfa.checked_count.other": "Проверено участников: {count}",
|
|
93
|
+
"workspaces.settings.security.mfa.noncompliant_count": "Отстранено без второго фактора: {count}",
|
|
94
|
+
"workspaces.settings.security.mfa.noncompliant_count.one": "{count} участник отстранён — нет второго фактора",
|
|
95
|
+
"workspaces.settings.security.mfa.noncompliant_count.few": "{count} участника отстранены — нет второго фактора",
|
|
96
|
+
"workspaces.settings.security.mfa.noncompliant_count.many": "{count} участников отстранены — нет второго фактора",
|
|
97
|
+
"workspaces.settings.security.mfa.noncompliant_count.other": "Отстранено без второго фактора: {count}",
|
|
98
|
+
"workspaces.settings.security.mfa.unverified_count": "Ещё не проверено: {count}",
|
|
99
|
+
"workspaces.settings.security.mfa.unverified_count.one": "{count} участник ещё не проверен",
|
|
100
|
+
"workspaces.settings.security.mfa.unverified_count.few": "{count} участника ещё не проверены",
|
|
101
|
+
"workspaces.settings.security.mfa.unverified_count.many": "{count} участников ещё не проверены",
|
|
102
|
+
"workspaces.settings.security.mfa.unverified_count.other": "Ещё не проверено: {count}",
|
|
103
|
+
"workspaces.settings.security.mfa.attempts_count": "Проверок выполнено: {count}",
|
|
104
|
+
"workspaces.settings.security.mfa.attempts_count.one": "Выполнена {count} проверка",
|
|
105
|
+
"workspaces.settings.security.mfa.attempts_count.few": "Выполнено {count} проверки",
|
|
106
|
+
"workspaces.settings.security.mfa.attempts_count.many": "Выполнено {count} проверок",
|
|
107
|
+
"workspaces.settings.security.mfa.attempts_count.other": "Проверок выполнено: {count}",
|
|
108
|
+
"workspaces.settings.security.mfa.last_attempt": "Последняя проверка {date}",
|
|
109
|
+
"workspaces.settings.security.mfa.completed_at": "Полное покрытие с {date}",
|
|
110
|
+
"workspaces.settings.security.mfa.last_error": "Последняя ошибка: {error}",
|
|
111
|
+
"workspaces.settings.security.mfa.unverified_hint": "Пока политика включена, непроверенных участников не пускают. Попросите их добавить второй фактор — число выше нужно довести до нуля.",
|
|
112
|
+
"workspaces.settings.security.mfa.off": "Двухфакторная аутентификация в этом рабочем пространстве не требуется.",
|
|
113
|
+
"workspaces.settings.security.mfa.no_status_yet": "Двухфакторная аутентификация здесь обязательна. Проверка ещё не проходила, поэтому никто не подтверждён.",
|
|
53
114
|
"workspaces.members.title": "Участники",
|
|
54
115
|
"workspaces.members.subtitle": "Управляйте доступом к рабочему пространству.",
|
|
116
|
+
"workspaces.members.count": "Участников: {count}",
|
|
117
|
+
"workspaces.members.count.one": "{count} участник",
|
|
118
|
+
"workspaces.members.count.few": "{count} участника",
|
|
119
|
+
"workspaces.members.count.many": "{count} участников",
|
|
120
|
+
"workspaces.members.count.other": "Участников: {count}",
|
|
121
|
+
"workspaces.members.joined": "Присоединился {date}",
|
|
122
|
+
"workspaces.members.last_seen": "Был здесь {date}",
|
|
123
|
+
"workspaces.members.last_seen_never": "Ещё не открывал это пространство",
|
|
124
|
+
"workspaces.members.search_placeholder": "Поиск по имени или email",
|
|
125
|
+
"workspaces.members.role_picker_label": "Роль участника {member}",
|
|
126
|
+
"workspaces.members.blocked.read_only": "Вы видите, кто здесь, но не можете это менять.",
|
|
127
|
+
"workspaces.members.mfa_label": "Второй фактор",
|
|
128
|
+
"workspaces.members.mfa.compliant": "подтверждён",
|
|
129
|
+
"workspaces.members.mfa.noncompliant": "отсутствует",
|
|
130
|
+
"workspaces.members.mfa.unknown": "ещё не проверяли",
|
|
131
|
+
"workspaces.members.suspended": "Отстранён",
|
|
132
|
+
"workspaces.members.suspended.no_mfa": "Отстранён до подтверждения второго фактора.",
|
|
133
|
+
"workspaces.members.provisioned": "Создан администратором",
|
|
55
134
|
"workspaces.members.invite_dialog.title": "Пригласить участников",
|
|
56
135
|
"workspaces.members.invite_dialog.emails_label": "Email-адреса",
|
|
57
136
|
"workspaces.members.invite_dialog.emails_placeholder": "Введите email и нажмите Enter",
|
|
58
137
|
"workspaces.members.invite_dialog.role_label": "Роль",
|
|
138
|
+
"workspaces.members.invite_dialog.name_label": "Имя (необязательно)",
|
|
139
|
+
"workspaces.members.invite_dialog.name_placeholder": "Показывается, пока человек не задаст своё",
|
|
140
|
+
"workspaces.members.invite_dialog.submit": "Отправить приглашения",
|
|
141
|
+
"workspaces.members.invite_dialog.blocked.no_emails": "Введите хотя бы один email-адрес.",
|
|
142
|
+
"workspaces.members.invite_dialog.blocked.bad_email": "{email} — это не email-адрес.",
|
|
59
143
|
"workspaces.members.remove_confirm": "Удалить этого участника?",
|
|
144
|
+
"workspaces.members.remove_confirm_body": "{member} сразу потеряет доступ к рабочему пространству. Позже его можно пригласить снова.",
|
|
145
|
+
"workspaces.members.remove.blocked.last_owner": "Это единственный владелец рабочего пространства. Сначала назначьте владельцем кого-то ещё.",
|
|
146
|
+
"workspaces.members.remove.blocked.self": "Это вы. Попросите другого владельца или администратора удалить вас из пространства.",
|
|
147
|
+
"workspaces.members.reset_password": "Сбросить пароль",
|
|
148
|
+
"workspaces.members.reset_password.blocked.self": "Это вы. Свой пароль меняют в настройках аккаунта — здесь действие выполняется над чужим.",
|
|
149
|
+
"workspaces.members.reset_password_dialog.title": "Сбросить пароль участника {member}?",
|
|
150
|
+
"workspaces.members.reset_password_dialog.body": "Текущий пароль перестанет работать сразу, и участник узнает, что это сделали вы. Новый пароль в письме не отправляется.",
|
|
151
|
+
"workspaces.members.reset_password_dialog.step_up": "Перед выполнением мы попросим подтвердить, что это вы.",
|
|
152
|
+
"workspaces.members.reset_password_dialog.submit": "Сбросить пароль",
|
|
153
|
+
"workspaces.members.reset_password_dialog.done": "У участника {member} новый пароль.",
|
|
154
|
+
"workspaces.members.reset_password_dialog.generated": "Одноразовый пароль",
|
|
155
|
+
"workspaces.members.reset_password_dialog.generated_hint": "Показывается один раз и больше никогда. Передайте его по каналу, которому доверяете; свой пароль участник задаст при первом входе.",
|
|
156
|
+
"workspaces.members.reset_password_dialog.not_notified": "Сообщить было некуда — передайте пароль сами.",
|
|
157
|
+
"workspaces.members.rename": "Переименовать",
|
|
158
|
+
"workspaces.members.rename_dialog.title": "Исправить имя",
|
|
159
|
+
"workspaces.members.rename_dialog.label": "Отображаемое имя",
|
|
160
|
+
"workspaces.members.rename_dialog.placeholder": "Оставьте пустым, чтобы убрать имя",
|
|
161
|
+
"workspaces.members.rename_dialog.hint": "Это имя человека во всём продукте, а не заметка внутри этого пространства.",
|
|
162
|
+
"workspaces.members.rename_dialog.submit": "Сохранить имя",
|
|
163
|
+
"workspaces.members.rename_dialog.blocked.unchanged": "Сначала измените имя.",
|
|
60
164
|
"workspaces.members.role.owner": "Владелец",
|
|
61
165
|
"workspaces.members.role.admin": "Администратор",
|
|
62
166
|
"workspaces.members.role.member": "Участник",
|
|
@@ -66,6 +170,90 @@ export const workspacesI18nBundleRu = {
|
|
|
66
170
|
"workspaces.role.admin": "Администратор",
|
|
67
171
|
"workspaces.role.member": "Участник",
|
|
68
172
|
"workspaces.role.viewer": "Наблюдатель",
|
|
173
|
+
"workspaces.role.rank_caption": "Ранг {rank}",
|
|
174
|
+
// Workspaces page
|
|
175
|
+
"workspaces.page.title": "Рабочие пространства",
|
|
176
|
+
"workspaces.page.subtitle": "Все пространства, где вы состоите.",
|
|
177
|
+
"workspaces.list.count": "Пространств: {count}",
|
|
178
|
+
"workspaces.list.count.one": "{count} пространство",
|
|
179
|
+
"workspaces.list.count.few": "{count} пространства",
|
|
180
|
+
"workspaces.list.count.many": "{count} пространств",
|
|
181
|
+
"workspaces.list.count.other": "Пространств: {count}",
|
|
182
|
+
"workspaces.list.member_count": "Участников: {count}",
|
|
183
|
+
"workspaces.list.member_count.one": "{count} участник",
|
|
184
|
+
"workspaces.list.member_count.few": "{count} участника",
|
|
185
|
+
"workspaces.list.member_count.many": "{count} участников",
|
|
186
|
+
"workspaces.list.member_count.other": "Участников: {count}",
|
|
187
|
+
"workspaces.list.owner_line": "Владелец: {owner}",
|
|
188
|
+
"workspaces.list.your_role": "Ваша роль",
|
|
189
|
+
"workspaces.list.open": "Открыть",
|
|
190
|
+
"workspaces.list.preferred": "Основное",
|
|
191
|
+
"workspaces.list.set_preferred": "Сделать основным",
|
|
192
|
+
"workspaces.list.clear_preferred": "Убрать признак основного",
|
|
193
|
+
"workspaces.list.empty_hint": "Создайте пространство, чтобы приглашать людей и держать работу вместе.",
|
|
194
|
+
"workspaces.list.guest_notice": "Вы здесь как гость. Гость открывает то, что ему прислали, но не состоит в рабочем пространстве.",
|
|
195
|
+
"workspaces.list.instance_closed": "Попросите приглашение у того, кто управляет этой установкой.",
|
|
196
|
+
"workspaces.list.create_dialog.title": "Новое рабочее пространство",
|
|
197
|
+
"workspaces.list.create_dialog.name_label": "Название",
|
|
198
|
+
"workspaces.list.create_dialog.name_placeholder": "например, «Акме Инжиниринг»",
|
|
199
|
+
"workspaces.list.create_dialog.submit": "Создать рабочее пространство",
|
|
200
|
+
"workspaces.list.create_dialog.blocked.no_name": "Введите название.",
|
|
201
|
+
"workspaces.list.blocked.create_policy": "На этой установке создавать пространства может только её владелец.",
|
|
202
|
+
// Invitation administration
|
|
203
|
+
"workspaces.invitations.title": "Приглашения",
|
|
204
|
+
"workspaces.invitations.subtitle": "Кого пригласили и кто ещё не присоединился.",
|
|
205
|
+
"workspaces.invitations.count": "Приглашений: {count}",
|
|
206
|
+
"workspaces.invitations.count.one": "{count} приглашение",
|
|
207
|
+
"workspaces.invitations.count.few": "{count} приглашения",
|
|
208
|
+
"workspaces.invitations.count.many": "{count} приглашений",
|
|
209
|
+
"workspaces.invitations.count.other": "Приглашений: {count}",
|
|
210
|
+
"workspaces.invitations.empty": "Никто не ждёт приглашения.",
|
|
211
|
+
"workspaces.invitations.expires_label": "Истекает",
|
|
212
|
+
"workspaces.invitations.sent_label": "Отправлено",
|
|
213
|
+
"workspaces.invitations.sent_never": "Письмо ещё не отправлялось",
|
|
214
|
+
"workspaces.invitations.search_placeholder": "Поиск по email",
|
|
215
|
+
"workspaces.invitations.filter_label": "Показать",
|
|
216
|
+
"workspaces.invitations.filter.pending": "Ожидают",
|
|
217
|
+
"workspaces.invitations.filter.never_accepted": "Так и не приняты",
|
|
218
|
+
"workspaces.invitations.filter.all": "Все",
|
|
219
|
+
"workspaces.invitations.status.pending": "Ожидает",
|
|
220
|
+
"workspaces.invitations.status.accepted": "Принято",
|
|
221
|
+
"workspaces.invitations.status.declined": "Отклонено",
|
|
222
|
+
"workspaces.invitations.status.revoked": "Отозвано",
|
|
223
|
+
"workspaces.invitations.status.expired": "Истекло",
|
|
224
|
+
"workspaces.invitations.resend": "Отправить снова",
|
|
225
|
+
"workspaces.invitations.resend_confirm": "Отправить приглашение ещё раз?",
|
|
226
|
+
"workspaces.invitations.resend_confirm_body": "На адрес {email} уйдёт новая ссылка, а прежняя перестанет работать.",
|
|
227
|
+
"workspaces.invitations.revoke": "Отозвать",
|
|
228
|
+
"workspaces.invitations.revoke_confirm": "Отозвать это приглашение?",
|
|
229
|
+
"workspaces.invitations.revoke_confirm_body": "Ссылка на {email} перестанет работать. Человеку об этом не сообщат; позже его можно пригласить снова.",
|
|
230
|
+
"workspaces.invitations.rename": "Переименовать",
|
|
231
|
+
"workspaces.invitations.rename_dialog.title": "Исправить имя приглашённого",
|
|
232
|
+
"workspaces.invitations.blocked.terminal": "Это приглашение уже принято, отклонено, отозвано или истекло.",
|
|
233
|
+
"workspaces.invitations.blocked.resend_terminal": "Отправить повторно можно только ожидающее или истёкшее приглашение.",
|
|
234
|
+
"workspaces.invitations.blocked.row_closed": "Это приглашение закрыто — с ним больше ничего не сделать.",
|
|
235
|
+
"workspaces.invitations.blocked.row_resend_only": "Срок приглашения истёк. Остаётся только отправить его заново.",
|
|
236
|
+
// Membership history
|
|
237
|
+
"workspaces.audit.title": "История участия",
|
|
238
|
+
"workspaces.audit.subtitle": "Кто впустил человека, кто вывел и когда.",
|
|
239
|
+
"workspaces.audit.empty": "Здесь пока ничего не происходило.",
|
|
240
|
+
"workspaces.audit.filter_label": "Событие",
|
|
241
|
+
"workspaces.audit.filter.all": "Все события",
|
|
242
|
+
"workspaces.audit.actor_unknown": "Система",
|
|
243
|
+
"workspaces.audit.by": "выполнил(а) {actor}",
|
|
244
|
+
"workspaces.audit.role_line": "Роль: {role}",
|
|
245
|
+
"workspaces.audit.action.invitation_created": "Приглашение отправлено",
|
|
246
|
+
"workspaces.audit.action.invitation_accepted": "Приглашение принято",
|
|
247
|
+
"workspaces.audit.action.invitation_revoked": "Приглашение отозвано",
|
|
248
|
+
"workspaces.audit.action.invitation_declined": "Приглашение отклонено",
|
|
249
|
+
"workspaces.audit.action.account_created_by_invitation": "Аккаунт создан по приглашению",
|
|
250
|
+
"workspaces.audit.action.member_joined": "Присоединился к пространству",
|
|
251
|
+
"workspaces.audit.action.member_provisioned": "Добавлен администратором",
|
|
252
|
+
"workspaces.audit.action.member_removed": "Удалён из пространства",
|
|
253
|
+
"workspaces.audit.action.member_role_changed": "Роль изменена",
|
|
254
|
+
"workspaces.audit.action.member_suspended": "Доступ приостановлен",
|
|
255
|
+
"workspaces.audit.action.member_unsuspended": "Доступ восстановлен",
|
|
256
|
+
"workspaces.audit.action.deleted": "Рабочее пространство удалено",
|
|
69
257
|
// Invite accept flow (org-program §B4)
|
|
70
258
|
"workspaces.invite.loading": "Загрузка приглашения…",
|
|
71
259
|
"workspaces.invite.acceptTitle": "Присоединиться к {workspace}",
|
|
@@ -73,12 +261,16 @@ export const workspacesI18nBundleRu = {
|
|
|
73
261
|
"workspaces.invite.emailLine": "Приглашение для {email}",
|
|
74
262
|
"workspaces.invite.joinCta": "Присоединиться",
|
|
75
263
|
"workspaces.invite.declineCta": "Отклонить",
|
|
264
|
+
"workspaces.invite.declineConfirm": "Отклонить это приглашение?",
|
|
265
|
+
"workspaces.invite.declineConfirmBody": "Пространству сообщат об отказе, и ссылка перестанет работать. Если передумаете, попросите новое приглашение.",
|
|
76
266
|
"workspaces.invite.accepted": "Вы присоединились к {workspace}.",
|
|
77
267
|
"workspaces.invite.declined": "Приглашение отклонено.",
|
|
78
268
|
"workspaces.invite.unavailable.expired": "Срок приглашения истёк. Попросите новое.",
|
|
79
269
|
"workspaces.invite.unavailable.revoked": "Приглашение было отозвано.",
|
|
80
270
|
"workspaces.invite.unavailable.accepted": "Приглашение уже использовано.",
|
|
81
271
|
"workspaces.invite.unavailable.declined": "Приглашение было отклонено.",
|
|
272
|
+
"workspaces.invite.unavailable.next_step": "Попросите администратора «{workspace}» прислать новое приглашение.",
|
|
273
|
+
"workspaces.invite.exitCta": "К своим рабочим пространствам",
|
|
82
274
|
"workspaces.invite.wrongAccount": "Приглашение для другого аккаунта",
|
|
83
275
|
"workspaces.invite.wrongAccountHint": "Вы вошли как {email}, а приглашение отправлено на {invited}. Смените аккаунт, чтобы продолжить.",
|
|
84
276
|
"workspaces.invite.switchAccountCta": "Сменить аккаунт",
|
|
@@ -91,6 +283,19 @@ export const workspacesI18nBundleRu = {
|
|
|
91
283
|
"workspaces.invite.retryCta": "Попробовать ещё раз",
|
|
92
284
|
"workspaces.invite.basicDataTitle": "Настройте профиль",
|
|
93
285
|
"workspaces.invite.basicDataContinueCta": "Продолжить",
|
|
286
|
+
"workspaces.invite.blocked.busy": "Заканчиваем начатый шаг…",
|
|
287
|
+
// A workspace-scoped screen with no active workspace
|
|
288
|
+
"workspaces.active.choose.title": "Выберите пространство",
|
|
289
|
+
"workspaces.active.choose.hint": "Этот экран управляет одним пространством за раз. Выберите его на странице «Рабочие пространства» и вернитесь сюда.",
|
|
290
|
+
"workspaces.active.none.title": "Вы пока не состоите ни в одном пространстве",
|
|
291
|
+
"workspaces.active.none.hint": "Создайте пространство или попросите владельца пригласить вас — тогда здесь появится чем управлять.",
|
|
292
|
+
// Nav manifest labels
|
|
293
|
+
"workspaces.nav.workspaces": "Рабочие пространства",
|
|
294
|
+
"workspaces.nav.settings": "Пространство",
|
|
295
|
+
"workspaces.nav.members": "Участники",
|
|
296
|
+
"workspaces.nav.invitations": "Приглашения",
|
|
297
|
+
"workspaces.nav.audit": "История",
|
|
298
|
+
"workspaces.nav.invite": "Приглашение",
|
|
94
299
|
};
|
|
95
300
|
/**
|
|
96
301
|
* Register the pair's `ru` locale into a core i18n engine (call once at
|
package/dist/i18n/ru.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ru.js","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE
|
|
1
|
+
{"version":3,"file":"ru.js","sourceRoot":"","sources":["../../src/i18n/ru.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export { createWorkspacesRuntime } from "./model/runtime.js";
|
|
|
22
22
|
export type { WorkspacesRuntime, CreateWorkspacesRuntimeOptions, } from "./model/runtime.js";
|
|
23
23
|
export { WorkspacesRuntimeContext, useWorkspacesRuntime, useWorkspacesApi, useWorkspacesAnalytics, } from "./model/context.js";
|
|
24
24
|
export { workspacesQueryKeys } from "./model/queryKeys.js";
|
|
25
|
-
export { WorkspaceSelectionProvider, useWorkspaceSelection, } from "./model/selection.js";
|
|
25
|
+
export { WorkspaceSelectionProvider, useWorkspaceSelection, useOptionalWorkspaceSelection, } from "./model/selection.js";
|
|
26
26
|
export type { WorkspaceSelection, WorkspaceSelectionProviderProps, WorkspaceSelectionSource, WorkspaceSelectionUrlBinding, } from "./model/selection.js";
|
|
27
27
|
export { useWorkspaces, useWorkspace, useMembers, useAudit, useCanCreateWorkspace, useInvitations, useInfiniteInvitations, useRoles, useInstanceShape, useInvitationPreview, useCapabilities, useCapabilityGate, } from "./model/queries.js";
|
|
28
28
|
export type { CapabilitiesResult, CapabilityGate } from "./model/queries.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAK9C,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,YAAY,EACV,gBAAgB,IAAI,0BAA0B,EAC9C,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtE,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EACV,iBAAiB,EACjB,8BAA8B,GAC/B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ export { createWorkspacesRuntime } from "./model/runtime.js";
|
|
|
22
22
|
export { WorkspacesRuntimeContext, useWorkspacesRuntime, useWorkspacesApi, useWorkspacesAnalytics, } from "./model/context.js";
|
|
23
23
|
export { workspacesQueryKeys } from "./model/queryKeys.js";
|
|
24
24
|
// ── model (active-workspace selection: URL > localStorage > backend) ─────────
|
|
25
|
-
export { WorkspaceSelectionProvider, useWorkspaceSelection, } from "./model/selection.js";
|
|
25
|
+
export { WorkspaceSelectionProvider, useWorkspaceSelection, useOptionalWorkspaceSelection, } from "./model/selection.js";
|
|
26
26
|
// ── model (read hooks) ───────────────────────────────────────────────────────
|
|
27
27
|
export { useWorkspaces, useWorkspace, useMembers, useAudit, useCanCreateWorkspace, useInvitations, useInfiniteInvitations, useRoles, useInstanceShape, useInvitationPreview, useCapabilities, useCapabilityGate, } from "./model/queries.js";
|
|
28
28
|
// ── model (the mandate axis: anonymous / guest / member / unresolved) ────────
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAI7D,gFAAgF;AAChF,4EAA4E;AAC5E,4EAA4E;AAC5E,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAMrE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOtE,gFAAgF;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAK7D,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,gFAAgF;AAChF,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAI7D,gFAAgF;AAChF,4EAA4E;AAC5E,4EAA4E;AAC5E,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAMrE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOtE,gFAAgF;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAK7D,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,gFAAgF;AAChF,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,sBAAsB,CAAC;AAQ9B,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,qBAAqB,EACrB,cAAc,EACd,sBAAsB,EACtB,QAAQ,EACR,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,gFAAgF;AAChF,wEAAwE;AACxE,wEAAwE;AACxE,gEAAgE;AAChE,6EAA6E;AAC7E,yEAAyE;AACzE,yBAAyB;AACzB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,gFAAgF;AAChF,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AA4C9B,gFAAgF;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,gFAAgF;AAChF,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAGxB,gFAAgF;AAChF,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** What {@link useWorkspaceFormat} hands a skin. Every method takes the wire
|
|
2
|
+
* value verbatim — including `null`/`undefined`, which are normal on this
|
|
3
|
+
* contract (`accepted_at: null` while an invitation is pending) — and returns
|
|
4
|
+
* `null` for "there is nothing to typeset", never the string "null". */
|
|
5
|
+
export interface WorkspaceFormat {
|
|
6
|
+
/** An absolute instant in the reader's calendar: `23 Sept 2026, 09:00`. */
|
|
7
|
+
dateTime(iso: string | null | undefined): string | null;
|
|
8
|
+
/** Date only, no clock: `23 Sept 2026`. For a day-grained fact (joined). */
|
|
9
|
+
date(iso: string | null | undefined): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Clock only: `09:00`. For a row inside a list already grouped under its
|
|
12
|
+
* day — repeating the date on every line of a journal is how three events
|
|
13
|
+
* an hour apart end up printing one timestamp three times.
|
|
14
|
+
*/
|
|
15
|
+
time(iso: string | null | undefined): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* How long ago / how far ahead, in words: `3 days ago`, `in 2 hours`.
|
|
18
|
+
* Anything under a minute is "now" in every language `Intl` knows, which is
|
|
19
|
+
* what `second`'s own formatting says less well.
|
|
20
|
+
*/
|
|
21
|
+
relative(iso: string | null | undefined): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* The pair's standard timestamp line: relative first (what a person
|
|
24
|
+
* actually wants), absolute in parentheses (what a support agent quotes).
|
|
25
|
+
* `3 days ago (23 Sept 2026, 09:00)`.
|
|
26
|
+
*/
|
|
27
|
+
timestamp(iso: string | null | undefined): string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build the formatter for one locale. Exported for tests and for hosts that
|
|
31
|
+
* format outside React; components use {@link useWorkspaceFormat}.
|
|
32
|
+
*
|
|
33
|
+
* `now` is injectable because "3 days ago" is a function of two instants and
|
|
34
|
+
* a test that cannot name the second one has to sleep or to accept whatever
|
|
35
|
+
* the clock says.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createWorkspaceFormat(locale: string, now?: () => Date): WorkspaceFormat;
|
|
38
|
+
/**
|
|
39
|
+
* The formatter bound to the host's CURRENT locale — the one a skin uses.
|
|
40
|
+
*
|
|
41
|
+
* Not memoized on purpose: `Intl.DateTimeFormat` is itself cached by the
|
|
42
|
+
* engine per (locale, options), and a stale formatter after a locale switch
|
|
43
|
+
* is the bug this hook exists to make impossible.
|
|
44
|
+
*/
|
|
45
|
+
export declare function useWorkspaceFormat(): WorkspaceFormat;
|
|
46
|
+
/**
|
|
47
|
+
* A registry key nobody wrote a label for, as a word: `secretary` →
|
|
48
|
+
* `Secretary`, `site_admin` → `Site admin`.
|
|
49
|
+
*
|
|
50
|
+
* The fallback under `RoleSelect`'s `labelFor` and the audit pane's action
|
|
51
|
+
* labels. It never invents meaning — it only stops a raw snake_case token
|
|
52
|
+
* from sitting lowercase beside title-cased copy, which is what the visual
|
|
53
|
+
* pass caught. A deployment that wants the real word ships the i18n key.
|
|
54
|
+
*/
|
|
55
|
+
export declare function titleCaseKey(key: string): string;
|
|
56
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/model/format.ts"],"names":[],"mappings":"AA+BA;;;wEAGwE;AACxE,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACxD,4EAA4E;IAC5E,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACpD;;;;OAIG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACpD;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACxD;;;;OAIG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;CAC1D;AAQD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,GAAG,GAAE,MAAM,IAAuB,GACjC,eAAe,CAqDjB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAGpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIhD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine values → typeset text.
|
|
3
|
+
*
|
|
4
|
+
* The visual pass found `2026-09-23T09:00:00Z` wrapped mid-token across two
|
|
5
|
+
* lines on a screen whose reader needed "in 23 days", and `secretary`
|
|
6
|
+
* rendered lowercase beside title-cased builtin roles. Both are the same
|
|
7
|
+
* defect: a wire value put straight on the glass. This module is the pair's
|
|
8
|
+
* side of the fix — one place that turns an ISO instant into the reader's own
|
|
9
|
+
* calendar, and one place that turns an unlabelled registry key into a word.
|
|
10
|
+
*
|
|
11
|
+
* `@stapel/core` carries no date formatter today (checked: `packages/core/src`
|
|
12
|
+
* has `i18n/`, `flows/`, no `format*`), so these live here, in the model
|
|
13
|
+
* layer, where a skin can reach them and a host can too. They are candidates
|
|
14
|
+
* for core the moment a second pair needs them — noted in the wave's REQUESTS
|
|
15
|
+
* file rather than copied.
|
|
16
|
+
*
|
|
17
|
+
* Everything is `Intl`, so the calendar, the month names and the word for
|
|
18
|
+
* "yesterday" come from the reader's locale rather than from us.
|
|
19
|
+
*/
|
|
20
|
+
import { useI18n } from "@stapel/core";
|
|
21
|
+
/** Seconds in the units `Intl.RelativeTimeFormat` speaks, largest first. */
|
|
22
|
+
const RELATIVE_UNITS = [
|
|
23
|
+
["year", 31_536_000],
|
|
24
|
+
["month", 2_592_000],
|
|
25
|
+
["week", 604_800],
|
|
26
|
+
["day", 86_400],
|
|
27
|
+
["hour", 3_600],
|
|
28
|
+
["minute", 60],
|
|
29
|
+
];
|
|
30
|
+
function parse(iso) {
|
|
31
|
+
if (iso === null || iso === undefined || iso === "")
|
|
32
|
+
return null;
|
|
33
|
+
const date = new Date(iso);
|
|
34
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the formatter for one locale. Exported for tests and for hosts that
|
|
38
|
+
* format outside React; components use {@link useWorkspaceFormat}.
|
|
39
|
+
*
|
|
40
|
+
* `now` is injectable because "3 days ago" is a function of two instants and
|
|
41
|
+
* a test that cannot name the second one has to sleep or to accept whatever
|
|
42
|
+
* the clock says.
|
|
43
|
+
*/
|
|
44
|
+
export function createWorkspaceFormat(locale, now = () => new Date()) {
|
|
45
|
+
// `Intl` throws on a malformed locale tag; a bad tag must not take a screen
|
|
46
|
+
// down over a date caption, so it degrades to the runtime default.
|
|
47
|
+
const safeLocale = (() => {
|
|
48
|
+
try {
|
|
49
|
+
return Intl.DateTimeFormat.supportedLocalesOf([locale])[0] ?? locale;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
})();
|
|
55
|
+
const dateTimeFormat = new Intl.DateTimeFormat(safeLocale, {
|
|
56
|
+
dateStyle: "medium",
|
|
57
|
+
timeStyle: "short",
|
|
58
|
+
});
|
|
59
|
+
const dateFormat = new Intl.DateTimeFormat(safeLocale, { dateStyle: "medium" });
|
|
60
|
+
const timeFormat = new Intl.DateTimeFormat(safeLocale, { timeStyle: "short" });
|
|
61
|
+
const relativeFormat = new Intl.RelativeTimeFormat(safeLocale, { numeric: "auto" });
|
|
62
|
+
function relative(iso) {
|
|
63
|
+
const date = parse(iso);
|
|
64
|
+
if (date === null)
|
|
65
|
+
return null;
|
|
66
|
+
const deltaSeconds = (date.getTime() - now().getTime()) / 1000;
|
|
67
|
+
const magnitude = Math.abs(deltaSeconds);
|
|
68
|
+
for (const [unit, seconds] of RELATIVE_UNITS) {
|
|
69
|
+
if (magnitude < seconds)
|
|
70
|
+
continue;
|
|
71
|
+
return relativeFormat.format(Math.round(deltaSeconds / seconds), unit);
|
|
72
|
+
}
|
|
73
|
+
return relativeFormat.format(0, "second");
|
|
74
|
+
}
|
|
75
|
+
function dateTime(iso) {
|
|
76
|
+
const date = parse(iso);
|
|
77
|
+
return date === null ? null : dateTimeFormat.format(date);
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
dateTime,
|
|
81
|
+
date: (iso) => {
|
|
82
|
+
const date = parse(iso);
|
|
83
|
+
return date === null ? null : dateFormat.format(date);
|
|
84
|
+
},
|
|
85
|
+
time: (iso) => {
|
|
86
|
+
const date = parse(iso);
|
|
87
|
+
return date === null ? null : timeFormat.format(date);
|
|
88
|
+
},
|
|
89
|
+
relative,
|
|
90
|
+
timestamp: (iso) => {
|
|
91
|
+
const near = relative(iso);
|
|
92
|
+
const exact = dateTime(iso);
|
|
93
|
+
if (near === null || exact === null)
|
|
94
|
+
return null;
|
|
95
|
+
return `${near} (${exact})`;
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The formatter bound to the host's CURRENT locale — the one a skin uses.
|
|
101
|
+
*
|
|
102
|
+
* Not memoized on purpose: `Intl.DateTimeFormat` is itself cached by the
|
|
103
|
+
* engine per (locale, options), and a stale formatter after a locale switch
|
|
104
|
+
* is the bug this hook exists to make impossible.
|
|
105
|
+
*/
|
|
106
|
+
export function useWorkspaceFormat() {
|
|
107
|
+
const i18n = useI18n();
|
|
108
|
+
return createWorkspaceFormat(i18n.locale);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A registry key nobody wrote a label for, as a word: `secretary` →
|
|
112
|
+
* `Secretary`, `site_admin` → `Site admin`.
|
|
113
|
+
*
|
|
114
|
+
* The fallback under `RoleSelect`'s `labelFor` and the audit pane's action
|
|
115
|
+
* labels. It never invents meaning — it only stops a raw snake_case token
|
|
116
|
+
* from sitting lowercase beside title-cased copy, which is what the visual
|
|
117
|
+
* pass caught. A deployment that wants the real word ships the i18n key.
|
|
118
|
+
*/
|
|
119
|
+
export function titleCaseKey(key) {
|
|
120
|
+
const words = key.replace(/[_-]+/g, " ").trim();
|
|
121
|
+
if (words.length === 0)
|
|
122
|
+
return key;
|
|
123
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/model/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -156,4 +156,19 @@ export declare function WorkspaceSelectionProvider(props: WorkspaceSelectionProv
|
|
|
156
156
|
* prevent.
|
|
157
157
|
*/
|
|
158
158
|
export declare function useWorkspaceSelection(): WorkspaceSelection;
|
|
159
|
+
/**
|
|
160
|
+
* The same resolution, for a component that must still RENDER when no
|
|
161
|
+
* provider is above it — `null` means "this app has not wired the selection",
|
|
162
|
+
* which is a state to draw, not a crash.
|
|
163
|
+
*
|
|
164
|
+
* The nav contract hands a mounted screen a route, never an ambient scope, so
|
|
165
|
+
* the four workspace-scoped admin screens read the active workspace from HERE
|
|
166
|
+
* (the seam the container writes through `switchTo`) rather than from a path
|
|
167
|
+
* segment. A screen mounted in a shell that never wrapped the tree would then
|
|
168
|
+
* be a white page — this accessor is what lets it be a designed "choose a
|
|
169
|
+
* workspace" instead. Application code that legitimately requires the
|
|
170
|
+
* provider should keep using {@link useWorkspaceSelection}: a silent `null`
|
|
171
|
+
* read as "no workspace yet" is the blank screen this pair exists to prevent.
|
|
172
|
+
*/
|
|
173
|
+
export declare function useOptionalWorkspaceSelection(): WorkspaceSelection | null;
|
|
159
174
|
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/model/selection.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAW,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAS9D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;6EAE6E;AAC7E,MAAM,MAAM,wBAAwB,GAChC,KAAK,GACL,OAAO,GACP,YAAY,GACZ,kBAAkB,GAClB,UAAU,GACV,YAAY,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAG,aAAa,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KACpE,IAAI,CAAC;CACX;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IAChD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAuBD,oDAAoD;AACpD,MAAM,WAAW,+BACf,SAAQ,4BAA4B;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,+BAA+B,GACrC,YAAY,CA8Nd;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAQ1D"}
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/model/selection.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAW,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAS9D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;6EAE6E;AAC7E,MAAM,MAAM,wBAAwB,GAChC,KAAK,GACL,OAAO,GACP,YAAY,GACZ,kBAAkB,GAClB,UAAU,GACV,YAAY,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAG,aAAa,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KACpE,IAAI,CAAC;CACX;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IAChD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAuBD,oDAAoD;AACpD,MAAM,WAAW,+BACf,SAAQ,4BAA4B;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,+BAA+B,GACrC,YAAY,CA8Nd;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAQ1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,IAAI,kBAAkB,GAAG,IAAI,CAEzE"}
|