@cosmicdrift/kumiko-bundled-features 0.207.0 → 0.208.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.
- package/package.json +9 -8
- package/src/admin-shell/__tests__/admin-shell.boot.test.ts +1 -1
- package/src/admin-shell/i18n.ts +17 -39
- package/src/admin-shell/web/i18n.ts +6 -11
- package/src/audit/i18n.ts +25 -41
- package/src/audit/web/i18n.ts +5 -9
- package/src/auth-email-password/__tests__/email-templates.test.ts +4 -0
- package/src/auth-email-password/email-templates.ts +97 -149
- package/src/auth-email-password/i18n.ts +6 -265
- package/src/auth-email-password/web/__tests__/confirm-account-unlock-screen.test.tsx +7 -7
- package/src/auth-email-password/web/__tests__/forgot-password-screen.test.tsx +14 -14
- package/src/auth-email-password/web/__tests__/invite-accept-screen.test.tsx +23 -25
- package/src/auth-email-password/web/__tests__/login-screen.test.tsx +60 -68
- package/src/auth-email-password/web/__tests__/request-account-unlock-screen.test.tsx +24 -24
- package/src/auth-email-password/web/__tests__/reset-password-screen.test.tsx +20 -20
- package/src/auth-email-password/web/__tests__/signup-complete-screen.test.tsx +9 -9
- package/src/auth-email-password/web/__tests__/signup-screen.test.tsx +11 -11
- package/src/auth-email-password/web/__tests__/test-utils.tsx +2 -2
- package/src/auth-email-password/web/__tests__/user-menu.test.tsx +3 -3
- package/src/auth-email-password/web/__tests__/verify-email-screen.test.tsx +3 -3
- package/src/auth-email-password/web/invite-accept-screen.tsx +3 -1
- package/src/auth-mfa/__tests__/errors-i18n-parity.test.ts +2 -4
- package/src/auth-mfa/i18n.ts +1 -3
- package/src/auth-mfa/web/__tests__/mfa-enable-screen.test.tsx +15 -15
- package/src/auth-mfa/web/__tests__/mfa-setup-preauth-screen.test.tsx +45 -49
- package/src/auth-mfa/web/__tests__/mfa-verify-screen.test.tsx +10 -10
- package/src/auth-mfa/web/i18n.ts +0 -126
- package/src/cap-counter/i18n.ts +5 -11
- package/src/compliance-profiles/i18n.ts +3 -11
- package/src/compliance-profiles/web/i18n.ts +0 -20
- package/src/config/i18n.ts +5 -5
- package/src/config/web/i18n.ts +1 -19
- package/src/custom-fields/web/i18n.ts +1 -18
- package/src/delivery/i18n.ts +3 -7
- package/src/delivery/web/i18n.ts +0 -20
- package/src/feature-toggles/i18n.ts +3 -11
- package/src/feature-toggles/web/i18n.ts +0 -24
- package/src/folders/web/i18n.ts +1 -51
- package/src/jobs/i18n.ts +40 -68
- package/src/jobs/web/i18n.ts +5 -9
- package/src/managed-pages/i18n.ts +23 -67
- package/src/managed-pages/web/i18n.ts +6 -11
- package/src/notes-history/i18n.ts +1 -1
- package/src/notes-history/web/i18n.ts +1 -17
- package/src/personal-access-tokens/i18n.ts +2 -6
- package/src/personal-access-tokens/web/i18n.ts +0 -72
- package/src/sessions/i18n.ts +17 -21
- package/src/tags/i18n.ts +2 -2
- package/src/tags/web/i18n.ts +1 -52
- package/src/template-resolver/web/__tests__/client-plugin.test.tsx +2 -2
- package/src/template-resolver/web/__tests__/editor-read-only.test.tsx +5 -5
- package/src/template-resolver/web/i18n.ts +0 -28
- package/src/tenant/__tests__/members-screens.boot.test.ts +0 -2
- package/src/tenant/i18n.ts +13 -27
- package/src/tenant/web/i18n.ts +0 -38
- package/src/tier-engine/i18n.ts +3 -39
- package/src/user/i18n.ts +14 -32
- package/src/user-data-rights/__tests__/default-mailers.test.ts +4 -0
- package/src/user-data-rights/__tests__/email-templates.test.ts +4 -0
- package/src/user-data-rights/__tests__/mail-default-bridge.integration.test.ts +2 -0
- package/src/user-data-rights/__tests__/run-export-jobs-cron-context.integration.test.ts +4 -0
- package/src/user-data-rights/email-templates.ts +55 -91
- package/src/user-data-rights/i18n.ts +18 -70
- package/src/user-data-rights/lib/default-mailers.ts +4 -1
- package/src/user-data-rights/web/__tests__/deletion-screens.test.tsx +11 -11
- package/src/user-data-rights/web/__tests__/public-deletion-gate.test.tsx +5 -5
- package/src/user-data-rights/web/i18n.ts +9 -157
- package/src/user-profile/i18n.ts +1 -71
|
@@ -11,96 +11,52 @@
|
|
|
11
11
|
// registriert. Die zwei customCss-Keys werden unconditional geliefert (schaden
|
|
12
12
|
// bei allowCustomCss:false nicht, sind aber Pflicht für Consumer die es aktivieren).
|
|
13
13
|
|
|
14
|
-
type LocalizedString = { readonly
|
|
14
|
+
type LocalizedString = { readonly en: string };
|
|
15
15
|
|
|
16
16
|
export const MANAGED_PAGES_I18N: Readonly<Record<string, LocalizedString>> = {
|
|
17
17
|
// Screen-Titel (global/unpräfixiert — screenTitleKey = screen:<id>.title)
|
|
18
|
-
"screen:page-list.title": {
|
|
19
|
-
"screen:page-edit.title": {
|
|
20
|
-
"screen:branding-settings.title": {
|
|
18
|
+
"screen:page-list.title": { en: "Pages" },
|
|
19
|
+
"screen:page-edit.title": { en: "Edit page" },
|
|
20
|
+
"screen:branding-settings.title": { en: "Branding" },
|
|
21
21
|
|
|
22
22
|
// Page-Entity Feld-Labels (managed-pages:entity:page:field:*)
|
|
23
|
-
"managed-pages:entity:page:field:slug": {
|
|
24
|
-
"managed-pages:entity:page:field:lang": {
|
|
25
|
-
"managed-pages:entity:page:field:title": {
|
|
26
|
-
"managed-pages:entity:page:field:published": {
|
|
27
|
-
de: "Veröffentlicht",
|
|
28
|
-
en: "Published",
|
|
29
|
-
es: "Publicado",
|
|
30
|
-
},
|
|
23
|
+
"managed-pages:entity:page:field:slug": { en: "Slug" },
|
|
24
|
+
"managed-pages:entity:page:field:lang": { en: "Language" },
|
|
25
|
+
"managed-pages:entity:page:field:title": { en: "Title" },
|
|
26
|
+
"managed-pages:entity:page:field:published": { en: "Published" },
|
|
31
27
|
"managed-pages:entity:page:field:published:option:true": {
|
|
32
|
-
de: "Veröffentlicht",
|
|
33
28
|
en: "Published",
|
|
34
|
-
es: "Publicado",
|
|
35
|
-
},
|
|
36
|
-
"managed-pages:entity:page:field:published:option:false": {
|
|
37
|
-
de: "Entwurf",
|
|
38
|
-
en: "Draft",
|
|
39
|
-
es: "Borrador",
|
|
40
29
|
},
|
|
41
|
-
"managed-pages:entity:page:field:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
},
|
|
46
|
-
"managed-pages:entity:page:field:ogImage": { de: "OG-Bild", en: "OG image", es: "Imagen OG" },
|
|
47
|
-
"managed-pages:entity:page:field:body": { de: "Inhalt", en: "Content", es: "Contenido" },
|
|
30
|
+
"managed-pages:entity:page:field:published:option:false": { en: "Draft" },
|
|
31
|
+
"managed-pages:entity:page:field:description": { en: "Description" },
|
|
32
|
+
"managed-pages:entity:page:field:ogImage": { en: "OG image" },
|
|
33
|
+
"managed-pages:entity:page:field:body": { en: "Content" },
|
|
48
34
|
|
|
49
35
|
// Config-Edit Feld-Labels (managed-pages:entity:__config-edit__:field:*, camelCase Form-Keys)
|
|
50
|
-
"managed-pages:entity:__config-edit__:field:title": {
|
|
51
|
-
de: "Website-Titel",
|
|
52
|
-
en: "Site title",
|
|
53
|
-
es: "Título del sitio",
|
|
54
|
-
},
|
|
36
|
+
"managed-pages:entity:__config-edit__:field:title": { en: "Site title" },
|
|
55
37
|
"managed-pages:entity:__config-edit__:field:description": {
|
|
56
|
-
de: "Beschreibung",
|
|
57
38
|
en: "Description",
|
|
58
|
-
es: "Descripción",
|
|
59
|
-
},
|
|
60
|
-
"managed-pages:entity:__config-edit__:field:siteUrl": {
|
|
61
|
-
de: "Website-URL",
|
|
62
|
-
en: "Site URL",
|
|
63
|
-
es: "URL del sitio",
|
|
64
39
|
},
|
|
40
|
+
"managed-pages:entity:__config-edit__:field:siteUrl": { en: "Site URL" },
|
|
65
41
|
"managed-pages:entity:__config-edit__:field:accentColor": {
|
|
66
|
-
de: "Akzentfarbe",
|
|
67
42
|
en: "Accent color",
|
|
68
|
-
es: "Color de acento",
|
|
69
|
-
},
|
|
70
|
-
"managed-pages:entity:__config-edit__:field:logoUrl": {
|
|
71
|
-
de: "Logo-URL",
|
|
72
|
-
en: "Logo URL",
|
|
73
|
-
es: "URL del logo",
|
|
74
|
-
},
|
|
75
|
-
"managed-pages:entity:__config-edit__:field:layoutPreset": {
|
|
76
|
-
de: "Layout",
|
|
77
|
-
en: "Layout",
|
|
78
|
-
es: "Diseño",
|
|
79
43
|
},
|
|
44
|
+
"managed-pages:entity:__config-edit__:field:logoUrl": { en: "Logo URL" },
|
|
45
|
+
"managed-pages:entity:__config-edit__:field:layoutPreset": { en: "Layout" },
|
|
80
46
|
|
|
81
47
|
// Section-Header
|
|
82
|
-
"managed-pages:section.meta": {
|
|
83
|
-
"managed-pages:section.body": {
|
|
84
|
-
"managed-pages:branding.section.identity": {
|
|
48
|
+
"managed-pages:section.meta": { en: "Metadata" },
|
|
49
|
+
"managed-pages:section.body": { en: "Content" },
|
|
50
|
+
"managed-pages:branding.section.identity": { en: "Identity" },
|
|
85
51
|
|
|
86
52
|
// Row-Actions + Confirm (pageListScreen)
|
|
87
|
-
"managed-pages:actions.edit": {
|
|
88
|
-
"managed-pages:actions.delete": {
|
|
53
|
+
"managed-pages:actions.edit": { en: "Edit" },
|
|
54
|
+
"managed-pages:actions.delete": { en: "Delete" },
|
|
89
55
|
"managed-pages:confirms.page-delete": {
|
|
90
|
-
de: "Diese Seite wirklich löschen?",
|
|
91
56
|
en: "Delete this page?",
|
|
92
|
-
es: "¿Seguro que quieres eliminar esta página?",
|
|
93
57
|
},
|
|
94
58
|
|
|
95
59
|
// Nur bei allowCustomCss:true im Screen — unconditional geliefert
|
|
96
|
-
"managed-pages:entity:__config-edit__:field:customCss": {
|
|
97
|
-
|
|
98
|
-
en: "Custom CSS",
|
|
99
|
-
es: "CSS personalizado",
|
|
100
|
-
},
|
|
101
|
-
"managed-pages:branding.section.custom-css": {
|
|
102
|
-
de: "Eigenes CSS",
|
|
103
|
-
en: "Custom CSS",
|
|
104
|
-
es: "CSS personalizado",
|
|
105
|
-
},
|
|
60
|
+
"managed-pages:entity:__config-edit__:field:customCss": { en: "Custom CSS" },
|
|
61
|
+
"managed-pages:branding.section.custom-css": { en: "Custom CSS" },
|
|
106
62
|
};
|
|
@@ -9,16 +9,11 @@
|
|
|
9
9
|
// Server-Form) in die locale-first TranslationsByLocale-Form die der Client
|
|
10
10
|
// erwartet — kein Key-Duplikat, kein Drift.
|
|
11
11
|
|
|
12
|
-
import
|
|
12
|
+
import {
|
|
13
|
+
type TranslationsByLocale,
|
|
14
|
+
translationsByLocaleFromKeys,
|
|
15
|
+
} from "@cosmicdrift/kumiko-renderer";
|
|
13
16
|
import { MANAGED_PAGES_I18N } from "../i18n";
|
|
14
17
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
export const defaultTranslations: TranslationsByLocale = Object.fromEntries(
|
|
18
|
-
LOCALES.map((locale) => [
|
|
19
|
-
locale,
|
|
20
|
-
Object.fromEntries(
|
|
21
|
-
Object.entries(MANAGED_PAGES_I18N).map(([key, value]) => [key, value[locale]]),
|
|
22
|
-
),
|
|
23
|
-
]),
|
|
24
|
-
);
|
|
18
|
+
export const defaultTranslations: TranslationsByLocale =
|
|
19
|
+
translationsByLocaleFromKeys(MANAGED_PAGES_I18N);
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
// @runtime client
|
|
2
2
|
// Default translation bundle for the notes-history UI. notesHistoryClient()
|
|
3
3
|
// hangs it into the LocaleProvider as a fallback bundle — apps override
|
|
4
|
-
// individual keys via notesHistoryClient({ translations
|
|
4
|
+
// individual keys via notesHistoryClient({ translations }).
|
|
5
5
|
// Keys follow `notesHistory.<area>.<slug>`.
|
|
6
6
|
|
|
7
7
|
import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
8
8
|
|
|
9
9
|
export const defaultTranslations: TranslationsByLocale = {
|
|
10
|
-
de: {
|
|
11
|
-
"notesHistory.section.createMode": "Speichere zuerst den Eintrag, um Notizen anzulegen.",
|
|
12
|
-
"notesHistory.section.loading": "Lädt…",
|
|
13
|
-
"notesHistory.section.empty": "Noch keine Notizen.",
|
|
14
|
-
"notesHistory.section.working": "Speichert…",
|
|
15
|
-
"notesHistory.section.add": "Notiz hinzufügen",
|
|
16
|
-
"notesHistory.section.meta": "{author} · {date}",
|
|
17
|
-
},
|
|
18
10
|
en: {
|
|
19
11
|
"notesHistory.section.createMode": "Save the entity first to add notes.",
|
|
20
12
|
"notesHistory.section.loading": "Loading…",
|
|
@@ -23,12 +15,4 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
23
15
|
"notesHistory.section.add": "Add note",
|
|
24
16
|
"notesHistory.section.meta": "{author} · {date}",
|
|
25
17
|
},
|
|
26
|
-
es: {
|
|
27
|
-
"notesHistory.section.createMode": "Guarda primero la entrada para poder añadir notas.",
|
|
28
|
-
"notesHistory.section.loading": "Cargando…",
|
|
29
|
-
"notesHistory.section.empty": "Aún no hay notas.",
|
|
30
|
-
"notesHistory.section.working": "Guardando…",
|
|
31
|
-
"notesHistory.section.add": "Añadir nota",
|
|
32
|
-
"notesHistory.section.meta": "{author} · {date}",
|
|
33
|
-
},
|
|
34
18
|
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
type LocalizedString = { readonly
|
|
1
|
+
type LocalizedString = { readonly en: string };
|
|
2
2
|
|
|
3
3
|
export const PAT_FEATURE_I18N: Readonly<Record<string, LocalizedString>> = {
|
|
4
|
-
"screen:api-tokens.title": {
|
|
5
|
-
de: "Personal Access Tokens",
|
|
6
|
-
en: "Personal Access Tokens",
|
|
7
|
-
es: "Tokens de acceso personal",
|
|
8
|
-
},
|
|
4
|
+
"screen:api-tokens.title": { en: "Personal Access Tokens" },
|
|
9
5
|
};
|
|
@@ -2,43 +2,6 @@
|
|
|
2
2
|
import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
3
3
|
|
|
4
4
|
export const defaultTranslations: TranslationsByLocale = {
|
|
5
|
-
de: {
|
|
6
|
-
"pat.title": "Personal Access Tokens",
|
|
7
|
-
"pat.create.title": "Neuen Token erstellen",
|
|
8
|
-
"pat.create.subtitle":
|
|
9
|
-
"Wähle Berechtigungen und eine Gültigkeit. Der Token wird nur einmal angezeigt.",
|
|
10
|
-
"pat.create.name": "Name",
|
|
11
|
-
"pat.create.namePlaceholder": "z. B. CLI-Automatisierung",
|
|
12
|
-
"pat.create.scopes": "Zugriff pro Bereich",
|
|
13
|
-
"pat.level.none": "Kein Zugriff",
|
|
14
|
-
"pat.level.read": "Lesen",
|
|
15
|
-
"pat.level.write": "Lesen & Schreiben",
|
|
16
|
-
"pat.create.expiry": "Gültig bis",
|
|
17
|
-
"pat.create.submit": "Token erstellen",
|
|
18
|
-
"pat.create.needName": "Bitte einen Namen vergeben.",
|
|
19
|
-
"pat.create.needScope": "Bitte mindestens eine Berechtigung wählen.",
|
|
20
|
-
"pat.create.needPassword": "Bitte dein Passwort zur Bestätigung eingeben.",
|
|
21
|
-
"pat.create.currentPassword": "Passwort (zur Bestätigung)",
|
|
22
|
-
"pat.create.mfaCode": "2FA-Code (falls aktiviert)",
|
|
23
|
-
"pat.create.mfaCodePlaceholder": "6-stelliger Code",
|
|
24
|
-
"pat.expiry.30d": "30 Tage",
|
|
25
|
-
"pat.expiry.90d": "90 Tage",
|
|
26
|
-
"pat.expiry.1y": "1 Jahr",
|
|
27
|
-
"pat.expiry.never": "Unbegrenzt",
|
|
28
|
-
"pat.created.hint":
|
|
29
|
-
"Kopiere diesen Token jetzt — er wird aus Sicherheitsgründen nur dieses eine Mal angezeigt.",
|
|
30
|
-
"pat.created.copy": "Kopieren",
|
|
31
|
-
"pat.created.copied": "Kopiert ✓",
|
|
32
|
-
"pat.created.dismiss": "Fertig",
|
|
33
|
-
"pat.list.title": "Deine Tokens",
|
|
34
|
-
"pat.list.empty": "Noch keine Tokens.",
|
|
35
|
-
"pat.list.revoke": "Widerrufen",
|
|
36
|
-
"pat.list.revoked": "Widerrufen",
|
|
37
|
-
"pat.list.validUntil": "Gültig bis {date}",
|
|
38
|
-
"pat.list.neverExpires": "Unbegrenzt gültig",
|
|
39
|
-
"pat.list.created": "Erstellt {date}",
|
|
40
|
-
"pat.error.generic": "Aktion fehlgeschlagen.",
|
|
41
|
-
},
|
|
42
5
|
en: {
|
|
43
6
|
"pat.title": "Personal Access Tokens",
|
|
44
7
|
"pat.create.title": "Create a new token",
|
|
@@ -74,39 +37,4 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
74
37
|
"pat.list.created": "Created {date}",
|
|
75
38
|
"pat.error.generic": "Action failed.",
|
|
76
39
|
},
|
|
77
|
-
es: {
|
|
78
|
-
"pat.title": "Tokens de acceso personal",
|
|
79
|
-
"pat.create.title": "Crear un token nuevo",
|
|
80
|
-
"pat.create.subtitle": "Elige los permisos y una caducidad. El token solo se muestra una vez.",
|
|
81
|
-
"pat.create.name": "Nombre",
|
|
82
|
-
"pat.create.namePlaceholder": "p. ej. automatización de CLI",
|
|
83
|
-
"pat.create.scopes": "Acceso por ámbito",
|
|
84
|
-
"pat.level.none": "Sin acceso",
|
|
85
|
-
"pat.level.read": "Lectura",
|
|
86
|
-
"pat.level.write": "Lectura y escritura",
|
|
87
|
-
"pat.create.expiry": "Válido hasta",
|
|
88
|
-
"pat.create.submit": "Crear token",
|
|
89
|
-
"pat.create.needName": "Indica un nombre.",
|
|
90
|
-
"pat.create.needScope": "Selecciona al menos un permiso.",
|
|
91
|
-
"pat.create.needPassword": "Introduce tu contraseña para confirmar.",
|
|
92
|
-
"pat.create.currentPassword": "Contraseña (para confirmar)",
|
|
93
|
-
"pat.create.mfaCode": "Código 2FA (si está activado)",
|
|
94
|
-
"pat.create.mfaCodePlaceholder": "Código de 6 dígitos",
|
|
95
|
-
"pat.expiry.30d": "30 días",
|
|
96
|
-
"pat.expiry.90d": "90 días",
|
|
97
|
-
"pat.expiry.1y": "1 año",
|
|
98
|
-
"pat.expiry.never": "Sin caducidad",
|
|
99
|
-
"pat.created.hint": "Copia este token ahora — por seguridad solo se muestra esta vez.",
|
|
100
|
-
"pat.created.copy": "Copiar",
|
|
101
|
-
"pat.created.copied": "Copiado ✓",
|
|
102
|
-
"pat.created.dismiss": "Listo",
|
|
103
|
-
"pat.list.title": "Tus tokens",
|
|
104
|
-
"pat.list.empty": "Todavía no hay tokens.",
|
|
105
|
-
"pat.list.revoke": "Revocar",
|
|
106
|
-
"pat.list.revoked": "Revocado",
|
|
107
|
-
"pat.list.validUntil": "Válido hasta {date}",
|
|
108
|
-
"pat.list.neverExpires": "Sin caducidad",
|
|
109
|
-
"pat.list.created": "Creado el {date}",
|
|
110
|
-
"pat.error.generic": "La acción ha fallado.",
|
|
111
|
-
},
|
|
112
40
|
};
|
package/src/sessions/i18n.ts
CHANGED
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
// @runtime client
|
|
2
2
|
// Server + client i18n for the sessions operator screens.
|
|
3
3
|
|
|
4
|
-
type LocalizedString = { readonly
|
|
4
|
+
type LocalizedString = { readonly en: string };
|
|
5
5
|
|
|
6
6
|
export const SESSIONS_I18N: Readonly<Record<string, LocalizedString>> = {
|
|
7
|
-
"screen:session-list.title": {
|
|
8
|
-
"screen:session-detail.title": {
|
|
9
|
-
"sessions:nav.sessionList": {
|
|
10
|
-
"sessions.list.col.id": {
|
|
11
|
-
"sessions.list.col.userId": {
|
|
12
|
-
"sessions.list.col.createdAt": {
|
|
13
|
-
"sessions.list.col.expiresAt": {
|
|
14
|
-
"sessions.list.col.revokedAt": {
|
|
15
|
-
"sessions.list.action.open": {
|
|
16
|
-
"sessions.detail.field.id": {
|
|
17
|
-
"sessions.detail.field.userId": {
|
|
18
|
-
"sessions.detail.field.createdAt": {
|
|
19
|
-
"sessions.detail.field.expiresAt": {
|
|
20
|
-
"sessions.detail.field.revokedAt": {
|
|
21
|
-
"sessions.detail.field.ip": {
|
|
22
|
-
"sessions.detail.field.userAgent": {
|
|
23
|
-
de: "User-Agent",
|
|
24
|
-
en: "User agent",
|
|
25
|
-
es: "Agente de usuario",
|
|
26
|
-
},
|
|
7
|
+
"screen:session-list.title": { en: "Sessions" },
|
|
8
|
+
"screen:session-detail.title": { en: "Session" },
|
|
9
|
+
"sessions:nav.sessionList": { en: "Sessions" },
|
|
10
|
+
"sessions.list.col.id": { en: "ID" },
|
|
11
|
+
"sessions.list.col.userId": { en: "User ID" },
|
|
12
|
+
"sessions.list.col.createdAt": { en: "Created" },
|
|
13
|
+
"sessions.list.col.expiresAt": { en: "Expires" },
|
|
14
|
+
"sessions.list.col.revokedAt": { en: "Revoked" },
|
|
15
|
+
"sessions.list.action.open": { en: "Details" },
|
|
16
|
+
"sessions.detail.field.id": { en: "ID" },
|
|
17
|
+
"sessions.detail.field.userId": { en: "User ID" },
|
|
18
|
+
"sessions.detail.field.createdAt": { en: "Created" },
|
|
19
|
+
"sessions.detail.field.expiresAt": { en: "Expires" },
|
|
20
|
+
"sessions.detail.field.revokedAt": { en: "Revoked" },
|
|
21
|
+
"sessions.detail.field.ip": { en: "IP address" },
|
|
22
|
+
"sessions.detail.field.userAgent": { en: "User agent" },
|
|
27
23
|
};
|
package/src/tags/i18n.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
type LocalizedString = { readonly
|
|
1
|
+
type LocalizedString = { readonly en: string };
|
|
2
2
|
|
|
3
3
|
export const TAGS_FEATURE_I18N: Readonly<Record<string, LocalizedString>> = {
|
|
4
|
-
"screen:tag-list.title": {
|
|
4
|
+
"screen:tag-list.title": { en: "Tags" },
|
|
5
5
|
};
|
package/src/tags/web/i18n.ts
CHANGED
|
@@ -1,37 +1,11 @@
|
|
|
1
1
|
// @runtime client
|
|
2
2
|
// Default translation bundle for the tags UI. tagsClient() hangs it into the
|
|
3
3
|
// LocaleProvider as a fallback bundle — apps override individual keys via
|
|
4
|
-
// tagsClient({ translations
|
|
4
|
+
// tagsClient({ translations }). Keys follow `tags.<area>.<slug>`.
|
|
5
5
|
|
|
6
6
|
import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
7
7
|
|
|
8
8
|
export const defaultTranslations: TranslationsByLocale = {
|
|
9
|
-
de: {
|
|
10
|
-
"tags.section.createMode": "Speichere zuerst den Eintrag, um Tags zu setzen.",
|
|
11
|
-
"tags.section.loading": "Lädt…",
|
|
12
|
-
"tags.section.empty": "Keine Tags gefunden.",
|
|
13
|
-
"tags.section.working": "Speichert…",
|
|
14
|
-
"tags.section.none": "Keine Tags",
|
|
15
|
-
"tags.section.edit": "Tags bearbeiten",
|
|
16
|
-
"tags.manage.newLabel": "Neuer Tag",
|
|
17
|
-
"tags.manage.namePlaceholder": "Tag-Name",
|
|
18
|
-
"tags.manage.scopeLabel": "Geltungsbereich (Entity-Typ, leer = global)",
|
|
19
|
-
"tags.manage.scopePlaceholder": "z. B. note (leer = überall)",
|
|
20
|
-
"tags.manage.create": "Tag anlegen",
|
|
21
|
-
"tags.manage.edit": "Bearbeiten",
|
|
22
|
-
"tags.manage.save": "Speichern",
|
|
23
|
-
"tags.manage.cancel": "Abbrechen",
|
|
24
|
-
"tags.manage.delete": "Löschen",
|
|
25
|
-
"tags.manage.toggle": "Tag umschalten",
|
|
26
|
-
"tags.manage.usage": "{count}×",
|
|
27
|
-
"tags.manage.deleteConfirmTitle": "Tag „{name}“ löschen?",
|
|
28
|
-
"tags.manage.deleteConfirmDesc":
|
|
29
|
-
"Entfernt ihn von {count} Objekten. Das lässt sich nicht rückgängig machen.",
|
|
30
|
-
"tags.picker.title": "Tags",
|
|
31
|
-
"tags.picker.done": "Fertig",
|
|
32
|
-
"tags.filter.label": "Nach Tag filtern",
|
|
33
|
-
"tags.filter.clear": "Filter zurücksetzen",
|
|
34
|
-
},
|
|
35
9
|
en: {
|
|
36
10
|
"tags.section.createMode": "Save the entity first to add tags.",
|
|
37
11
|
"tags.section.loading": "Loading…",
|
|
@@ -57,29 +31,4 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
57
31
|
"tags.filter.label": "Filter by tag",
|
|
58
32
|
"tags.filter.clear": "Clear",
|
|
59
33
|
},
|
|
60
|
-
es: {
|
|
61
|
-
"tags.section.createMode": "Guarda primero la entrada para añadir etiquetas.",
|
|
62
|
-
"tags.section.loading": "Cargando…",
|
|
63
|
-
"tags.section.empty": "No se encontraron etiquetas.",
|
|
64
|
-
"tags.section.working": "Guardando…",
|
|
65
|
-
"tags.section.none": "Sin etiquetas",
|
|
66
|
-
"tags.section.edit": "Editar etiquetas",
|
|
67
|
-
"tags.manage.newLabel": "Nueva etiqueta",
|
|
68
|
-
"tags.manage.namePlaceholder": "Nombre de la etiqueta",
|
|
69
|
-
"tags.manage.scopeLabel": "Ámbito (tipo de entidad, vacío = global)",
|
|
70
|
-
"tags.manage.scopePlaceholder": "p. ej. nota (vacío = en todas partes)",
|
|
71
|
-
"tags.manage.create": "Crear etiqueta",
|
|
72
|
-
"tags.manage.edit": "Editar",
|
|
73
|
-
"tags.manage.save": "Guardar",
|
|
74
|
-
"tags.manage.cancel": "Cancelar",
|
|
75
|
-
"tags.manage.delete": "Eliminar",
|
|
76
|
-
"tags.manage.toggle": "Alternar etiqueta",
|
|
77
|
-
"tags.manage.usage": "{count}×",
|
|
78
|
-
"tags.manage.deleteConfirmTitle": "¿Eliminar la etiqueta «{name}»?",
|
|
79
|
-
"tags.manage.deleteConfirmDesc": "Se quitará de {count} objetos. Esto no se puede deshacer.",
|
|
80
|
-
"tags.picker.title": "Etiquetas",
|
|
81
|
-
"tags.picker.done": "Listo",
|
|
82
|
-
"tags.filter.label": "Filtrar por etiqueta",
|
|
83
|
-
"tags.filter.clear": "Quitar filtro",
|
|
84
|
-
},
|
|
85
34
|
};
|
|
@@ -254,7 +254,7 @@ describe("textBlocksClient — content collections", () => {
|
|
|
254
254
|
});
|
|
255
255
|
|
|
256
256
|
describe("textBlocksClient — plain contentFormat editor wiring", () => {
|
|
257
|
-
const localeResolver = createStaticLocaleResolver({ locale: "
|
|
257
|
+
const localeResolver = createStaticLocaleResolver({ locale: "en" });
|
|
258
258
|
|
|
259
259
|
function Wrapper({ children }: { readonly children: ReactNode }): ReactNode {
|
|
260
260
|
return (
|
|
@@ -298,7 +298,7 @@ describe("textBlocksClient — plain contentFormat editor wiring", () => {
|
|
|
298
298
|
});
|
|
299
299
|
|
|
300
300
|
describe("textBlocksClient — findContentFormat resolves collectionId to the registered editor", () => {
|
|
301
|
-
const localeResolver = createStaticLocaleResolver({ locale: "
|
|
301
|
+
const localeResolver = createStaticLocaleResolver({ locale: "en" });
|
|
302
302
|
const RichStub: ContentEditorComponent = () => <div data-testid="rich-stub-editor" />;
|
|
303
303
|
|
|
304
304
|
function RichStubWrapper({ children }: { readonly children: ReactNode }): ReactNode {
|
|
@@ -52,7 +52,7 @@ function getEditor() {
|
|
|
52
52
|
return Editor;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const localeResolver = createStaticLocaleResolver({ locale: "
|
|
55
|
+
const localeResolver = createStaticLocaleResolver({ locale: "en" });
|
|
56
56
|
|
|
57
57
|
function Wrapper({ children }: { readonly children: ReactNode }): ReactNode {
|
|
58
58
|
return (
|
|
@@ -80,7 +80,7 @@ describe("TextContentEditor — role-based write-access", () => {
|
|
|
80
80
|
const Editor = getEditor();
|
|
81
81
|
render(<Editor target={TARGET} onClose={() => {}} />, { wrapper: Wrapper });
|
|
82
82
|
|
|
83
|
-
const saveButton = screen.getByRole("button", { name: /
|
|
83
|
+
const saveButton = screen.getByRole("button", { name: /save/i });
|
|
84
84
|
expect(saveButton).toBeTruthy();
|
|
85
85
|
expect(saveButton.hasAttribute("disabled")).toBe(false);
|
|
86
86
|
|
|
@@ -93,7 +93,7 @@ describe("TextContentEditor — role-based write-access", () => {
|
|
|
93
93
|
const Editor = getEditor();
|
|
94
94
|
render(<Editor target={TARGET} onClose={() => {}} />, { wrapper: Wrapper });
|
|
95
95
|
|
|
96
|
-
expect(screen.getByRole("button", { name: /
|
|
96
|
+
expect(screen.getByRole("button", { name: /save/i })).toBeTruthy();
|
|
97
97
|
expect(screen.queryByText(/Read-only/)).toBeNull();
|
|
98
98
|
});
|
|
99
99
|
|
|
@@ -153,7 +153,7 @@ describe("TextContentEditor — handleSave", () => {
|
|
|
153
153
|
render(<Editor target={TARGET} onClose={() => {}} />, { wrapper: Wrapper });
|
|
154
154
|
|
|
155
155
|
await act(async () => {
|
|
156
|
-
fireEvent.click(screen.getByRole("button", { name: /
|
|
156
|
+
fireEvent.click(screen.getByRole("button", { name: /save/i }));
|
|
157
157
|
await Promise.resolve();
|
|
158
158
|
});
|
|
159
159
|
|
|
@@ -177,7 +177,7 @@ describe("TextContentEditor — handleSave", () => {
|
|
|
177
177
|
render(<Editor target={TARGET} onClose={() => {}} />, { wrapper: Wrapper });
|
|
178
178
|
|
|
179
179
|
await act(async () => {
|
|
180
|
-
fireEvent.click(screen.getByRole("button", { name: /
|
|
180
|
+
fireEvent.click(screen.getByRole("button", { name: /save/i }));
|
|
181
181
|
await Promise.resolve();
|
|
182
182
|
});
|
|
183
183
|
|
|
@@ -8,20 +8,6 @@
|
|
|
8
8
|
import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
9
9
|
|
|
10
10
|
export const defaultTranslations: TranslationsByLocale = {
|
|
11
|
-
de: {
|
|
12
|
-
"template-resolver.editor.titleLabel": "Titel",
|
|
13
|
-
"template-resolver.editor.contentLabel": "Inhalt",
|
|
14
|
-
"template-resolver.editor.save": "Speichern",
|
|
15
|
-
"template-resolver.editor.saving": "Speichern…",
|
|
16
|
-
"template-resolver.editor.created": "Neu angelegt.",
|
|
17
|
-
"template-resolver.editor.saved": "Gespeichert.",
|
|
18
|
-
"template-resolver.editor.saveFailed": "Speichern fehlgeschlagen.",
|
|
19
|
-
"template-resolver.editor.networkError": "Netzwerkfehler beim Speichern.",
|
|
20
|
-
"template-resolver.editor.loading": "Lädt aktuellen Stand…",
|
|
21
|
-
"template-resolver.editor.loadFailed": "Konnte Block nicht laden",
|
|
22
|
-
"template-resolver.editor.readOnly":
|
|
23
|
-
"Read-only — TenantAdmin- oder SystemAdmin-Rolle für Änderungen erforderlich.",
|
|
24
|
-
},
|
|
25
11
|
en: {
|
|
26
12
|
"template-resolver.editor.titleLabel": "Title",
|
|
27
13
|
"template-resolver.editor.contentLabel": "Content",
|
|
@@ -36,18 +22,4 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
36
22
|
"template-resolver.editor.readOnly":
|
|
37
23
|
"Read-only — TenantAdmin or SystemAdmin role required to make changes.",
|
|
38
24
|
},
|
|
39
|
-
es: {
|
|
40
|
-
"template-resolver.editor.titleLabel": "Título",
|
|
41
|
-
"template-resolver.editor.contentLabel": "Contenido",
|
|
42
|
-
"template-resolver.editor.save": "Guardar",
|
|
43
|
-
"template-resolver.editor.saving": "Guardando…",
|
|
44
|
-
"template-resolver.editor.created": "Creado.",
|
|
45
|
-
"template-resolver.editor.saved": "Guardado.",
|
|
46
|
-
"template-resolver.editor.saveFailed": "Error al guardar.",
|
|
47
|
-
"template-resolver.editor.networkError": "Error de red al guardar.",
|
|
48
|
-
"template-resolver.editor.loading": "Cargando versión actual…",
|
|
49
|
-
"template-resolver.editor.loadFailed": "No se pudo cargar el bloque",
|
|
50
|
-
"template-resolver.editor.readOnly":
|
|
51
|
-
"Solo lectura — se requiere el rol TenantAdmin o SystemAdmin para hacer cambios.",
|
|
52
|
-
},
|
|
53
25
|
};
|
|
@@ -5,7 +5,6 @@ import { AuthHandlers } from "../../auth-email-password/constants";
|
|
|
5
5
|
import { createConfigFeature } from "../../config/feature";
|
|
6
6
|
import { MEMBERS_SCREEN_ID, TenantHandlers, TenantQueries } from "../constants";
|
|
7
7
|
import { createTenantFeature } from "../feature";
|
|
8
|
-
import { defaultTranslations } from "../web/i18n";
|
|
9
8
|
|
|
10
9
|
describe("tenant members screen + handler access alignment", () => {
|
|
11
10
|
const features = [createConfigFeature(), createTenantFeature()];
|
|
@@ -38,7 +37,6 @@ describe("tenant members screen + handler access alignment", () => {
|
|
|
38
37
|
test("members nav label uses tenantClient i18n key (not feature:nav.* alias)", () => {
|
|
39
38
|
const nav = createTenantFeature().navs["members"];
|
|
40
39
|
expect(nav?.label).toBe("tenant.nav.members");
|
|
41
|
-
expect(defaultTranslations["de"]?.["tenant.nav.members"]).toBe("Team");
|
|
42
40
|
});
|
|
43
41
|
|
|
44
42
|
test("updateMemberRoles stays SystemAdmin/system-only (not on members screen)", () => {
|
package/src/tenant/i18n.ts
CHANGED
|
@@ -1,39 +1,25 @@
|
|
|
1
|
-
type LocalizedString = { readonly
|
|
1
|
+
type LocalizedString = { readonly en: string };
|
|
2
2
|
|
|
3
3
|
export const TENANT_I18N: Readonly<Record<string, LocalizedString>> = {
|
|
4
|
-
"screen:tenant-list.title": {
|
|
5
|
-
"screen:tenant-edit.title": {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
},
|
|
10
|
-
"
|
|
11
|
-
"tenant
|
|
12
|
-
"tenant:entity:tenant:field:
|
|
13
|
-
"tenant:entity:tenant:field:name": { de: "Name", en: "Name", es: "Nombre" },
|
|
14
|
-
"tenant:entity:tenant:field:isEnabled": { de: "Aktiv", en: "Enabled", es: "Activado" },
|
|
15
|
-
"tenant:entity:tenant:field:status": { de: "Status", en: "Status", es: "Estado" },
|
|
16
|
-
"tenant:entity:tenant:field:status:option:active": { de: "Aktiv", en: "Active", es: "Activo" },
|
|
4
|
+
"screen:tenant-list.title": { en: "Tenants" },
|
|
5
|
+
"screen:tenant-edit.title": { en: "Edit tenant" },
|
|
6
|
+
"screen:members.title": { en: "Team" },
|
|
7
|
+
"tenant.nav.members": { en: "Team" },
|
|
8
|
+
"tenant:entity:tenant:field:key": { en: "Key" },
|
|
9
|
+
"tenant:entity:tenant:field:name": { en: "Name" },
|
|
10
|
+
"tenant:entity:tenant:field:isEnabled": { en: "Enabled" },
|
|
11
|
+
"tenant:entity:tenant:field:status": { en: "Status" },
|
|
12
|
+
"tenant:entity:tenant:field:status:option:active": { en: "Active" },
|
|
17
13
|
"tenant:entity:tenant:field:status:option:destroyRequested": {
|
|
18
|
-
de: "Löschung angefordert",
|
|
19
14
|
en: "Destroy requested",
|
|
20
|
-
es: "Eliminación solicitada",
|
|
21
15
|
},
|
|
22
16
|
"tenant:entity:tenant:field:status:option:destroying": {
|
|
23
|
-
de: "Wird gelöscht",
|
|
24
17
|
en: "Destroying",
|
|
25
|
-
es: "Eliminándose",
|
|
26
18
|
},
|
|
27
19
|
"tenant:entity:tenant:field:status:option:destroyFailed": {
|
|
28
|
-
de: "Löschung fehlgeschlagen",
|
|
29
20
|
en: "Destroy failed",
|
|
30
|
-
es: "Eliminación fallida",
|
|
31
|
-
},
|
|
32
|
-
"tenant:entity:tenant:field:status:option:destroyed": {
|
|
33
|
-
de: "Gelöscht",
|
|
34
|
-
en: "Destroyed",
|
|
35
|
-
es: "Eliminado",
|
|
36
21
|
},
|
|
37
|
-
"tenant:entity:tenant:field:
|
|
38
|
-
"tenant:entity:tenant:field:isEnabled:option:
|
|
22
|
+
"tenant:entity:tenant:field:status:option:destroyed": { en: "Destroyed" },
|
|
23
|
+
"tenant:entity:tenant:field:isEnabled:option:true": { en: "Yes" },
|
|
24
|
+
"tenant:entity:tenant:field:isEnabled:option:false": { en: "No" },
|
|
39
25
|
};
|
package/src/tenant/web/i18n.ts
CHANGED
|
@@ -2,25 +2,6 @@
|
|
|
2
2
|
import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
3
3
|
|
|
4
4
|
export const defaultTranslations: TranslationsByLocale = {
|
|
5
|
-
de: {
|
|
6
|
-
"tenant.members.title": "Mitglieder",
|
|
7
|
-
"tenant.members.loading": "Lade Mitglieder…",
|
|
8
|
-
"tenant.members.active": "Aktive Mitglieder",
|
|
9
|
-
"tenant.members.invite.title": "Neue Einladung",
|
|
10
|
-
"tenant.members.invite.email": "E-Mail",
|
|
11
|
-
"tenant.members.invite.role": "Rolle",
|
|
12
|
-
"tenant.members.invite.submit": "Einladung senden",
|
|
13
|
-
"tenant.members.invite.submitting": "Einladung wird gesendet…",
|
|
14
|
-
"tenant.members.invite.success": "Einladung an {email} gesendet",
|
|
15
|
-
"tenant.members.pending": "Ausstehende Einladungen",
|
|
16
|
-
"tenant.members.pending.empty": "Keine ausstehenden Einladungen.",
|
|
17
|
-
"tenant.members.cancel": "Zurückziehen",
|
|
18
|
-
"tenant.members.col.userId": "User-ID",
|
|
19
|
-
"tenant.members.col.roles": "Rollen",
|
|
20
|
-
"tenant.members.col.email": "E-Mail",
|
|
21
|
-
"tenant.members.col.expires": "Gültig bis",
|
|
22
|
-
"tenant.nav.members": "Team",
|
|
23
|
-
},
|
|
24
5
|
en: {
|
|
25
6
|
"tenant.members.title": "Members",
|
|
26
7
|
"tenant.members.loading": "Loading members…",
|
|
@@ -40,23 +21,4 @@ export const defaultTranslations: TranslationsByLocale = {
|
|
|
40
21
|
"tenant.members.col.expires": "Valid until",
|
|
41
22
|
"tenant.nav.members": "Team",
|
|
42
23
|
},
|
|
43
|
-
es: {
|
|
44
|
-
"tenant.members.title": "Miembros",
|
|
45
|
-
"tenant.members.loading": "Cargando miembros…",
|
|
46
|
-
"tenant.members.active": "Miembros activos",
|
|
47
|
-
"tenant.members.invite.title": "Nueva invitación",
|
|
48
|
-
"tenant.members.invite.email": "Correo electrónico",
|
|
49
|
-
"tenant.members.invite.role": "Rol",
|
|
50
|
-
"tenant.members.invite.submit": "Enviar invitación",
|
|
51
|
-
"tenant.members.invite.submitting": "Enviando invitación…",
|
|
52
|
-
"tenant.members.invite.success": "Invitación enviada a {email}",
|
|
53
|
-
"tenant.members.pending": "Invitaciones pendientes",
|
|
54
|
-
"tenant.members.pending.empty": "No hay invitaciones pendientes.",
|
|
55
|
-
"tenant.members.cancel": "Cancelar",
|
|
56
|
-
"tenant.members.col.userId": "ID de usuario",
|
|
57
|
-
"tenant.members.col.roles": "Roles",
|
|
58
|
-
"tenant.members.col.email": "Correo electrónico",
|
|
59
|
-
"tenant.members.col.expires": "Válido hasta",
|
|
60
|
-
"tenant.nav.members": "Equipo",
|
|
61
|
-
},
|
|
62
24
|
};
|