@cosmicdrift/kumiko-renderer 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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.208.0",
|
|
4
4
|
"description": "Platform-agnostic React renderer for Kumiko screens. Contains the shared logic — primitives-contract, hooks, KumikoScreen, navigation & SSE abstractions — that any platform-specific renderer (web, native) composes. No DOM, no EventSource, no react-dom.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
19
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
18
|
+
"@cosmicdrift/kumiko-framework": "0.208.0",
|
|
19
|
+
"@cosmicdrift/kumiko-headless": "0.208.0",
|
|
20
20
|
"react": "^19.2.6",
|
|
21
21
|
"temporal-polyfill": "^0.3.2",
|
|
22
22
|
"zod": "^4.4.3"
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@testing-library/react": "^16.3.2",
|
|
26
26
|
"@types/react": "^19.2.14",
|
|
27
|
-
"jsdom": "^29.1.1"
|
|
27
|
+
"jsdom": "^29.1.1",
|
|
28
|
+
"@cosmicdrift/kumiko-locale-de": "0.208.0"
|
|
28
29
|
},
|
|
29
30
|
"repository": {
|
|
30
31
|
"type": "git",
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
ValidationError,
|
|
13
13
|
VersionConflictError,
|
|
14
14
|
} from "@cosmicdrift/kumiko-framework/errors";
|
|
15
|
+
import { localeDeBundle } from "@cosmicdrift/kumiko-locale-de";
|
|
15
16
|
import { REQUIRED_FIELD_I18N_KEY } from "../app/form-schema";
|
|
16
17
|
import { kumikoDefaultTranslations } from "../i18n-defaults";
|
|
17
18
|
|
|
@@ -40,13 +41,13 @@ const errorInstances = [
|
|
|
40
41
|
new ValidationError({ fields: [] }),
|
|
41
42
|
];
|
|
42
43
|
|
|
43
|
-
const de =
|
|
44
|
+
const de = localeDeBundle;
|
|
44
45
|
const en = kumikoDefaultTranslations["en"];
|
|
45
46
|
|
|
46
47
|
describe("kumikoDefaultTranslations covers every error i18nKey", () => {
|
|
47
48
|
for (const e of errorInstances) {
|
|
48
|
-
test(`${e.code} → ${e.i18nKey} has
|
|
49
|
-
expect(de
|
|
49
|
+
test(`${e.code} → ${e.i18nKey} has en default and de locale-package copy`, () => {
|
|
50
|
+
expect(de[e.i18nKey]).toBeTruthy();
|
|
50
51
|
expect(en?.[e.i18nKey]).toBeTruthy();
|
|
51
52
|
});
|
|
52
53
|
}
|
|
@@ -75,7 +76,7 @@ describe("kumikoDefaultTranslations covers every error i18nKey", () => {
|
|
|
75
76
|
// thrown by an error class, applied as a params.i18nKey override on a zod
|
|
76
77
|
// issue instead; still rendered through this last-resort bundle.
|
|
77
78
|
test("form-schema's required-field i18nKey has de+en default", () => {
|
|
78
|
-
expect(de
|
|
79
|
+
expect(de[REQUIRED_FIELD_I18N_KEY]).toBeTruthy();
|
|
79
80
|
expect(en?.[REQUIRED_FIELD_I18N_KEY]).toBeTruthy();
|
|
80
81
|
});
|
|
81
82
|
});
|
|
@@ -77,7 +77,7 @@ function renderField(field: EditFieldViewModel): void {
|
|
|
77
77
|
capturedBanner = undefined;
|
|
78
78
|
render(
|
|
79
79
|
<LocaleProvider
|
|
80
|
-
resolver={createStaticLocaleResolver({ locale: "
|
|
80
|
+
resolver={createStaticLocaleResolver({ locale: "en" })}
|
|
81
81
|
fallbackBundles={[kumikoDefaultTranslations]}
|
|
82
82
|
>
|
|
83
83
|
<PrimitivesProvider value={testPrimitives}>
|
|
@@ -109,7 +109,7 @@ describe.each([
|
|
|
109
109
|
renderField(field);
|
|
110
110
|
const children = capturedBanner?.children;
|
|
111
111
|
const childArray = Array.isArray(children) ? children : [children];
|
|
112
|
-
expect(childArray[0]).toBe("
|
|
112
|
+
expect(childArray[0]).toBe("This field type can't be edited here yet.");
|
|
113
113
|
const valuePreview = childArray[1] as { props: { children: unknown } } | false | undefined;
|
|
114
114
|
if (!valuePreview) throw new Error("expected a value-preview element");
|
|
115
115
|
expect(valuePreview.props.children).toBe(JSON.stringify(field.value));
|
|
@@ -121,7 +121,7 @@ describe("RenderField — unsupported-type Banner ohne Wert", () => {
|
|
|
121
121
|
renderField(baseField({ type: "jsonb", value: null }));
|
|
122
122
|
const children = capturedBanner?.children;
|
|
123
123
|
const childArray = Array.isArray(children) ? children : [children];
|
|
124
|
-
expect(childArray[0]).toBe("
|
|
124
|
+
expect(childArray[0]).toBe("This field type can't be edited here yet.");
|
|
125
125
|
expect(childArray[1]).toBeFalsy();
|
|
126
126
|
});
|
|
127
127
|
});
|
package/src/i18n-defaults.ts
CHANGED
|
@@ -1,222 +1,16 @@
|
|
|
1
|
-
// Framework
|
|
2
|
-
// (
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// Framework-Default-Bundle. Strings die die Renderer-Components hart
|
|
2
|
+
// brauchen (Save/Cancel/Delete-Buttons, Empty-States, Search-Placeholder,
|
|
3
|
+
// Nav-Toggle-aria-Labels, Validation-Reasons). createKumikoApp hängt das
|
|
4
|
+
// als ALLERLETZTEN Fallback in den LocaleProvider — Apps können
|
|
5
|
+
// einzelne Keys via clientFeatures.translations überschreiben.
|
|
6
6
|
//
|
|
7
|
-
// Convention:
|
|
8
|
-
//
|
|
9
|
-
// validation).
|
|
7
|
+
// Convention: alle Keys mit `kumiko.`-Prefix damit sie nicht mit
|
|
8
|
+
// App-Keys kollidieren. Sub-Pfade gruppieren nach Bereich (actions /
|
|
9
|
+
// list / nav / form / validation).
|
|
10
10
|
|
|
11
11
|
import type { TranslationsByLocale } from "./i18n";
|
|
12
12
|
|
|
13
13
|
export const kumikoDefaultTranslations: TranslationsByLocale = {
|
|
14
|
-
de: {
|
|
15
|
-
// Actions — buttons in RenderEdit, RenderList, confirm dialogs.
|
|
16
|
-
"kumiko.actions.save": "Speichern",
|
|
17
|
-
"kumiko.actions.cancel": "Abbrechen",
|
|
18
|
-
"kumiko.actions.delete": "Löschen",
|
|
19
|
-
"kumiko.actions.delete-confirm": "Wirklich löschen?",
|
|
20
|
-
"kumiko.actions.reload": "Neu laden",
|
|
21
|
-
"kumiko.actions.create": "Neu",
|
|
22
|
-
"kumiko.actions.edit": "Bearbeiten",
|
|
23
|
-
"kumiko.actions.copyLink": "Link kopieren",
|
|
24
|
-
"kumiko.actions.copyLinkCopied": "Kopiert!",
|
|
25
|
-
"kumiko.actions.next": "Weiter",
|
|
26
|
-
"kumiko.actions.back": "Zurück",
|
|
27
|
-
"kumiko.actions.finish": "Abschließen",
|
|
28
|
-
|
|
29
|
-
// Wizard step chrome (RenderEdit layout.mode="wizard").
|
|
30
|
-
"kumiko.wizard.step": "Schritt {current} von {total}",
|
|
31
|
-
"kumiko.wizard.step-with-title": "Schritt {current} von {total} · {title}",
|
|
32
|
-
|
|
33
|
-
// Version — Update-Awareness-Banner (UpdateChecker).
|
|
34
|
-
"kumiko.version.update-available": "Eine neue Version ist verfügbar.",
|
|
35
|
-
|
|
36
|
-
// Toast — Self-service Docs-Link-Default (useToast docsLinkLabel).
|
|
37
|
-
"kumiko.toast.learn-more": "Mehr erfahren",
|
|
38
|
-
|
|
39
|
-
// Field — aria-labels for the Date/Timestamp primitives.
|
|
40
|
-
"kumiko.field.open-calendar": "Kalender öffnen",
|
|
41
|
-
"kumiko.field.dateField.placeholderYear": "J",
|
|
42
|
-
"kumiko.field.dateField.placeholderMonth": "M",
|
|
43
|
-
"kumiko.field.dateField.placeholderDay": "T",
|
|
44
|
-
"kumiko.field.time": "Uhrzeit",
|
|
45
|
-
"kumiko.field.timezone": "Zeitzone",
|
|
46
|
-
"kumiko.field.locatedTzHint": "Zeit lokal am angegebenen Ort",
|
|
47
|
-
"kumiko.field.reference-created-no-id":
|
|
48
|
-
"Datensatz wurde angelegt, konnte aber nicht automatisch ausgewählt werden. Bitte manuell auswählen.",
|
|
49
|
-
"kumiko.field.unsupported": "Dieser Feldtyp kann hier noch nicht bearbeitet werden.",
|
|
50
|
-
"kumiko.field.embedded-list.add-row": "Zeile hinzufügen",
|
|
51
|
-
"kumiko.field.embedded-list.remove-row": "Zeile entfernen",
|
|
52
|
-
"kumiko.field.embedded-list.duplicate-row": "Zeile duplizieren",
|
|
53
|
-
"kumiko.field.embedded-list.move-up": "Nach oben verschieben",
|
|
54
|
-
"kumiko.field.embedded-list.move-down": "Nach unten verschieben",
|
|
55
|
-
"kumiko.field.embedded-list.empty": "Noch keine Zeilen.",
|
|
56
|
-
"kumiko.field.embedded-list.empty-cta": "Erste Zeile hinzufügen",
|
|
57
|
-
"kumiko.field.embedded-list.paste-rows-truncated":
|
|
58
|
-
"{count} eingefügte Zeile(n) wurden verworfen (maximale Zeilenzahl erreicht).",
|
|
59
|
-
"kumiko.field.embedded-list.paste-cells-unmatched":
|
|
60
|
-
"{count} Zelle(n) hatten keine passende Option und wurden nicht geändert.",
|
|
61
|
-
|
|
62
|
-
// List — DataTable Toolbar, Empty-State, Search.
|
|
63
|
-
"kumiko.list.search-placeholder": "Suchen…",
|
|
64
|
-
"kumiko.list.empty.title": "Noch keine Einträge.",
|
|
65
|
-
"kumiko.list.empty.hint": "Lege den ersten an, um loszulegen.",
|
|
66
|
-
"kumiko.list.no-entries": "Keine Einträge.",
|
|
67
|
-
"kumiko.list.end-of-list": "— Ende der Liste —",
|
|
68
|
-
|
|
69
|
-
// Pager — status line + prev/next/page aria-labels (DataTable pagination="pages").
|
|
70
|
-
"kumiko.pager.status": "{from}–{to} von {total}",
|
|
71
|
-
"kumiko.pager.previousPage": "Vorherige Seite",
|
|
72
|
-
"kumiko.pager.nextPage": "Nächste Seite",
|
|
73
|
-
"kumiko.pager.page": "Seite {entry}",
|
|
74
|
-
|
|
75
|
-
// Combobox — Tier 2.1c Searchable-Select.
|
|
76
|
-
"kumiko.combobox.search-placeholder": "Suchen…",
|
|
77
|
-
"kumiko.combobox.empty": "Keine Treffer.",
|
|
78
|
-
"kumiko.combobox.loading": "Lade…",
|
|
79
|
-
|
|
80
|
-
// Dashboard — default label for the "(all)" entry in the screen filter,
|
|
81
|
-
// when DashboardFilterDefinition.allLabel isn't set.
|
|
82
|
-
"kumiko.dashboard.filter.all": "Alle",
|
|
83
|
-
"kumiko.combobox.placeholder": "—",
|
|
84
|
-
|
|
85
|
-
// Widgets — Query-States (QueryTable, LoadingState, ErrorState).
|
|
86
|
-
"kumiko.widget.loading": "Lade…",
|
|
87
|
-
"kumiko.widget.error.title": "Konnte nicht geladen werden.",
|
|
88
|
-
|
|
89
|
-
// Widgets — UploadZone status line per file.
|
|
90
|
-
"kumiko.widget.upload.uploading": "Wird hochgeladen…",
|
|
91
|
-
"kumiko.widget.upload.done": "Hochgeladen",
|
|
92
|
-
"kumiko.widget.upload.error": "Fehlgeschlagen",
|
|
93
|
-
"kumiko.widget.upload.rejected-type": "Dateityp nicht erlaubt",
|
|
94
|
-
|
|
95
|
-
// Widgets — StepBar screen-reader text for completed steps whose number is visually replaced by a checkmark.
|
|
96
|
-
"kumiko.widget.step-bar.done": "Erledigt",
|
|
97
|
-
|
|
98
|
-
// Widgets — Drawer resize handle + maximize toggle aria-labels.
|
|
99
|
-
"kumiko.widget.drawer.restore": "Drawer-Breite zurücksetzen",
|
|
100
|
-
"kumiko.widget.drawer.maximize": "Drawer maximieren",
|
|
101
|
-
"kumiko.widget.drawer.resize": "Drawer-Größe ändern",
|
|
102
|
-
|
|
103
|
-
// Nav — Sidebar Tree (Toggle-aria-Labels).
|
|
104
|
-
"kumiko.nav.expand": "Aufklappen",
|
|
105
|
-
"kumiko.nav.collapse": "Zuklappen",
|
|
106
|
-
"kumiko.nav.search": "Navigation durchsuchen…",
|
|
107
|
-
"kumiko.nav.language": "Sprache",
|
|
108
|
-
|
|
109
|
-
// Workspace — Switcher-Trigger aria-Label (renderer-web).
|
|
110
|
-
"kumiko.workspace.switch": "Workspace wechseln",
|
|
111
|
-
"kumiko.workspace.select": "Workspace wählen",
|
|
112
|
-
|
|
113
|
-
// Dialog — Confirm-Buttons + Close-aria-Label.
|
|
114
|
-
"kumiko.dialog.confirm": "Bestätigen",
|
|
115
|
-
"kumiko.dialog.cancel": "Abbrechen",
|
|
116
|
-
"kumiko.dialog.close": "Schließen",
|
|
117
|
-
|
|
118
|
-
// AiTextField/AiTextArea — Ghost-Text-Hint, Toolbar-Aria-Labels, Diff-Dialog.
|
|
119
|
-
"kumiko.aiText.acceptHint": "Tab = übernehmen, Esc = verwerfen",
|
|
120
|
-
"kumiko.aiText.correct": "Korrigieren",
|
|
121
|
-
"kumiko.aiText.translate": "Übersetzen",
|
|
122
|
-
"kumiko.aiText.rewrite": "Umschreiben",
|
|
123
|
-
"kumiko.aiText.diff.before": "Vorher",
|
|
124
|
-
"kumiko.aiText.diff.after": "Nachher",
|
|
125
|
-
"kumiko.aiText.diff.generating": "Wird generiert…",
|
|
126
|
-
"kumiko.aiText.style.formal": "Formell",
|
|
127
|
-
"kumiko.aiText.style.casual": "Locker",
|
|
128
|
-
"kumiko.aiText.style.concise": "Kompakt",
|
|
129
|
-
"kumiko.aiText.style.expand": "Ausführlicher",
|
|
130
|
-
"kumiko.aiText.capExceeded": "Monatliches AI-Limit erreicht.",
|
|
131
|
-
|
|
132
|
-
// Row-Actions — error toast when an action write fails.
|
|
133
|
-
"kumiko.rowAction.failed": "Aktion fehlgeschlagen",
|
|
134
|
-
|
|
135
|
-
// ContentEditor — variable chip bar (VariableChips).
|
|
136
|
-
"kumiko.contentEditor.insertVariable": "{name} einfügen",
|
|
137
|
-
"kumiko.contentEditor.preview": "Vorschau",
|
|
138
|
-
"kumiko.contentEditor.editMode": "Bearbeiten",
|
|
139
|
-
"kumiko.contentEditor.bold": "Fett",
|
|
140
|
-
"kumiko.contentEditor.italic": "Kursiv",
|
|
141
|
-
"kumiko.contentEditor.heading1": "Überschrift 1",
|
|
142
|
-
"kumiko.contentEditor.heading2": "Überschrift 2",
|
|
143
|
-
"kumiko.contentEditor.bulletList": "Aufzählungsliste",
|
|
144
|
-
"kumiko.contentEditor.orderedList": "Nummerierte Liste",
|
|
145
|
-
|
|
146
|
-
// Config-Cascade — Source-Badges + Cascade-Panel (ConfigCascadeView).
|
|
147
|
-
"kumiko.config.source.user": "Mein Wert",
|
|
148
|
-
"kumiko.config.source.tenant": "Tenant",
|
|
149
|
-
"kumiko.config.source.system": "System",
|
|
150
|
-
"kumiko.config.source.appOverride": "App-Override",
|
|
151
|
-
"kumiko.config.source.computed": "Berechnet",
|
|
152
|
-
"kumiko.config.source.default": "Standard",
|
|
153
|
-
"kumiko.config.source.missing": "Fehlt",
|
|
154
|
-
"kumiko.config.cascade.noValue": "Kein Wert gesetzt",
|
|
155
|
-
"kumiko.config.cascade.activeMarker": "aktiv",
|
|
156
|
-
"kumiko.config.cascade.resetTo": "Überschreibung zurücksetzen ({scope})",
|
|
157
|
-
|
|
158
|
-
// Form — standard errors (app code can supply its own zod reasons,
|
|
159
|
-
// these are the last safety layer).
|
|
160
|
-
"kumiko.form.error.generic": "Etwas ist schiefgegangen.",
|
|
161
|
-
"kumiko.form.error.version-conflict":
|
|
162
|
-
"Datensatz wurde zwischenzeitlich geändert. Lade neu und versuche es erneut.",
|
|
163
|
-
"kumiko.form.extension.save-failed": "Ein Zusatzfeld konnte nicht gespeichert werden.",
|
|
164
|
-
"kumiko.form.draft.resume-multiple":
|
|
165
|
-
"Mehrere offene Entwürfe für dieses Formular gefunden. Welchen möchtest du fortsetzen?",
|
|
166
|
-
"kumiko.form.draft.resume-single":
|
|
167
|
-
"Ein offener Entwurf für dieses Formular gefunden. Möchtest du ihn fortsetzen?",
|
|
168
|
-
"kumiko.form.draft.start-new": "Neu beginnen",
|
|
169
|
-
|
|
170
|
-
// Validation — default reason codes from the framework. App code can
|
|
171
|
-
// inject its own via validation hooks; these are the generic ones.
|
|
172
|
-
"kumiko.validation.required": "Pflichtfeld.",
|
|
173
|
-
"kumiko.validation.invalid": "Ungültiger Wert.",
|
|
174
|
-
"kumiko.validation.too-short": "Zu kurz (mindestens {min} Zeichen).",
|
|
175
|
-
"kumiko.validation.too-long": "Zu lang (höchstens {max} Zeichen).",
|
|
176
|
-
"kumiko.validation.out-of-range": "Wert außerhalb des erlaubten Bereichs.",
|
|
177
|
-
|
|
178
|
-
// errors.validation.* — the canonical key namespace that server
|
|
179
|
-
// (ValidationError) and client (zod-bridge) produce for field issues.
|
|
180
|
-
// Codes = Zod 4 issue codes + framework-specific ones.
|
|
181
|
-
"errors.validation.invalid_type": "Ungültiger Wert.",
|
|
182
|
-
"errors.validation.too_small": "Zu klein oder zu kurz (Minimum: {minimum}).",
|
|
183
|
-
"errors.validation.too_big": "Zu groß oder zu lang (Maximum: {maximum}).",
|
|
184
|
-
"errors.validation.invalid_format": "Ungültiges Format.",
|
|
185
|
-
"errors.validation.not_multiple_of": "Muss ein Vielfaches von {divisor} sein.",
|
|
186
|
-
"errors.validation.unrecognized_keys": "Unbekannte Felder.",
|
|
187
|
-
"errors.validation.invalid_union": "Ungültiger Wert.",
|
|
188
|
-
"errors.validation.invalid_key": "Ungültiger Schlüssel.",
|
|
189
|
-
"errors.validation.invalid_element": "Ungültiger Eintrag.",
|
|
190
|
-
"errors.validation.invalid_value": "Ungültige Auswahl.",
|
|
191
|
-
"errors.validation.custom": "Ungültiger Wert.",
|
|
192
|
-
"errors.validation.unexpected_field": "Unbekanntes Feld.",
|
|
193
|
-
"errors.validation.out_of_bounds": "Wert außerhalb des erlaubten Bereichs.",
|
|
194
|
-
"errors.validation.invalid_option": "Ungültige Auswahl.",
|
|
195
|
-
"errors.validation.failed": "Validierung fehlgeschlagen.",
|
|
196
|
-
|
|
197
|
-
// errors.* — top-level error codes (one per httpStatus class). Last
|
|
198
|
-
// fallback when an app doesn't supply its own translation; deliberately
|
|
199
|
-
// generic (no technical entity/feature/key names shown to end users —
|
|
200
|
-
// those live in `details` for devs). Apps override per key.
|
|
201
|
-
"errors.feature.disabled": "Diese Funktion ist derzeit nicht verfügbar.",
|
|
202
|
-
"errors.access.denied": "Dazu hast du keine Berechtigung.",
|
|
203
|
-
"errors.notFound": "Nicht gefunden.",
|
|
204
|
-
"errors.conflict": "Konflikt — der Vorgang konnte nicht abgeschlossen werden.",
|
|
205
|
-
"errors.versionConflict":
|
|
206
|
-
"Der Datensatz wurde zwischenzeitlich geändert. Lade neu und versuche es erneut.",
|
|
207
|
-
"errors.uniqueViolation": "Dieser Eintrag existiert bereits.",
|
|
208
|
-
"errors.unprocessable": "Die Anfrage konnte nicht verarbeitet werden.",
|
|
209
|
-
"errors.unconfigured": "Diese Funktion ist noch nicht konfiguriert.",
|
|
210
|
-
"errors.internal": "Etwas ist schiefgegangen. Bitte versuche es später erneut.",
|
|
211
|
-
"errors.rate_limited": "Zu viele Anfragen. Bitte versuche es in Kürze erneut.",
|
|
212
|
-
"errors.cap.exceeded":
|
|
213
|
-
"Limit erreicht. Bitte Tarif upgraden oder auf die nächste Periode warten.",
|
|
214
|
-
"errors.download.urlMissing": "Download nicht verfügbar — bitte versuche es erneut.",
|
|
215
|
-
"auth.errors.originNotAllowed": "Zugriff von dieser Herkunft ist nicht erlaubt.",
|
|
216
|
-
"dispatcher.errors.network":
|
|
217
|
-
"Netzwerkfehler. Bitte überprüfe deine Verbindung und versuche es erneut.",
|
|
218
|
-
"dispatcher.errors.aborted": "Anfrage abgebrochen.",
|
|
219
|
-
},
|
|
220
14
|
en: {
|
|
221
15
|
"kumiko.actions.save": "Save",
|
|
222
16
|
"kumiko.actions.cancel": "Cancel",
|
|
@@ -389,208 +183,4 @@ export const kumikoDefaultTranslations: TranslationsByLocale = {
|
|
|
389
183
|
"dispatcher.errors.network": "Network error. Please check your connection and try again.",
|
|
390
184
|
"dispatcher.errors.aborted": "Request was cancelled.",
|
|
391
185
|
},
|
|
392
|
-
es: {
|
|
393
|
-
// Actions — buttons in RenderEdit, RenderList, confirm dialogs.
|
|
394
|
-
"kumiko.actions.save": "Guardar",
|
|
395
|
-
"kumiko.actions.cancel": "Cancelar",
|
|
396
|
-
"kumiko.actions.delete": "Eliminar",
|
|
397
|
-
"kumiko.actions.delete-confirm": "¿Seguro que quieres eliminar?",
|
|
398
|
-
"kumiko.actions.reload": "Recargar",
|
|
399
|
-
"kumiko.actions.create": "Nuevo",
|
|
400
|
-
"kumiko.actions.edit": "Editar",
|
|
401
|
-
"kumiko.actions.copyLink": "Copiar enlace",
|
|
402
|
-
"kumiko.actions.copyLinkCopied": "¡Copiado!",
|
|
403
|
-
"kumiko.actions.next": "Siguiente",
|
|
404
|
-
"kumiko.actions.back": "Atrás",
|
|
405
|
-
"kumiko.actions.finish": "Finalizar",
|
|
406
|
-
|
|
407
|
-
// Wizard step chrome (RenderEdit layout.mode="wizard").
|
|
408
|
-
"kumiko.wizard.step": "Paso {current} de {total}",
|
|
409
|
-
"kumiko.wizard.step-with-title": "Paso {current} de {total} · {title}",
|
|
410
|
-
|
|
411
|
-
// Version — Update-Awareness-Banner (UpdateChecker).
|
|
412
|
-
"kumiko.version.update-available": "Hay una nueva versión disponible.",
|
|
413
|
-
|
|
414
|
-
// Toast — Self-service Docs-Link-Default (useToast docsLinkLabel).
|
|
415
|
-
"kumiko.toast.learn-more": "Más información",
|
|
416
|
-
|
|
417
|
-
// Field — aria-labels for the Date/Timestamp primitives.
|
|
418
|
-
"kumiko.field.open-calendar": "Abrir calendario",
|
|
419
|
-
"kumiko.field.dateField.placeholderYear": "A",
|
|
420
|
-
"kumiko.field.dateField.placeholderMonth": "M",
|
|
421
|
-
"kumiko.field.dateField.placeholderDay": "D",
|
|
422
|
-
"kumiko.field.time": "Hora",
|
|
423
|
-
"kumiko.field.timezone": "Zona horaria",
|
|
424
|
-
"kumiko.field.locatedTzHint": "Hora local del lugar indicado",
|
|
425
|
-
"kumiko.field.reference-created-no-id":
|
|
426
|
-
"El registro se creó pero no se pudo seleccionar automáticamente. Selecciónalo manualmente.",
|
|
427
|
-
"kumiko.field.unsupported": "Este tipo de campo todavía no se puede editar aquí.",
|
|
428
|
-
"kumiko.field.embedded-list.add-row": "Añadir fila",
|
|
429
|
-
"kumiko.field.embedded-list.remove-row": "Quitar fila",
|
|
430
|
-
"kumiko.field.embedded-list.duplicate-row": "Duplicar fila",
|
|
431
|
-
"kumiko.field.embedded-list.move-up": "Mover arriba",
|
|
432
|
-
"kumiko.field.embedded-list.move-down": "Mover abajo",
|
|
433
|
-
"kumiko.field.embedded-list.empty": "Todavía no hay filas.",
|
|
434
|
-
"kumiko.field.embedded-list.empty-cta": "Añadir la primera fila",
|
|
435
|
-
"kumiko.field.embedded-list.paste-rows-truncated":
|
|
436
|
-
"Se descartaron {count} fila(s) pegadas (se alcanzó el número máximo de filas).",
|
|
437
|
-
"kumiko.field.embedded-list.paste-cells-unmatched":
|
|
438
|
-
"{count} celda(s) no tenían una opción coincidente y no se modificaron.",
|
|
439
|
-
|
|
440
|
-
// List — DataTable Toolbar, Empty-State, Search.
|
|
441
|
-
"kumiko.list.search-placeholder": "Buscar…",
|
|
442
|
-
"kumiko.list.empty.title": "Todavía no hay entradas.",
|
|
443
|
-
"kumiko.list.empty.hint": "Crea la primera para empezar.",
|
|
444
|
-
"kumiko.list.no-entries": "Sin entradas.",
|
|
445
|
-
"kumiko.list.end-of-list": "— Fin de la lista —",
|
|
446
|
-
|
|
447
|
-
// Pager — status line + prev/next/page aria-labels (DataTable pagination="pages").
|
|
448
|
-
"kumiko.pager.status": "{from}–{to} de {total}",
|
|
449
|
-
"kumiko.pager.previousPage": "Página anterior",
|
|
450
|
-
"kumiko.pager.nextPage": "Página siguiente",
|
|
451
|
-
"kumiko.pager.page": "Página {entry}",
|
|
452
|
-
|
|
453
|
-
// Combobox — Tier 2.1c Searchable-Select.
|
|
454
|
-
"kumiko.combobox.search-placeholder": "Buscar…",
|
|
455
|
-
"kumiko.combobox.empty": "Sin resultados.",
|
|
456
|
-
"kumiko.combobox.loading": "Cargando…",
|
|
457
|
-
|
|
458
|
-
// Dashboard — default label for the "(all)" entry in the screen filter,
|
|
459
|
-
// when DashboardFilterDefinition.allLabel isn't set.
|
|
460
|
-
"kumiko.dashboard.filter.all": "Todos",
|
|
461
|
-
"kumiko.combobox.placeholder": "—",
|
|
462
|
-
|
|
463
|
-
// Widgets — Query-States (QueryTable, LoadingState, ErrorState).
|
|
464
|
-
"kumiko.widget.loading": "Cargando…",
|
|
465
|
-
"kumiko.widget.error.title": "No se pudo cargar.",
|
|
466
|
-
|
|
467
|
-
// Widgets — UploadZone status line per file.
|
|
468
|
-
"kumiko.widget.upload.uploading": "Subiendo…",
|
|
469
|
-
"kumiko.widget.upload.done": "Subido",
|
|
470
|
-
"kumiko.widget.upload.error": "Fallido",
|
|
471
|
-
"kumiko.widget.upload.rejected-type": "Tipo de archivo no permitido",
|
|
472
|
-
|
|
473
|
-
// Widgets — StepBar screen-reader text for completed steps whose number is visually replaced by a checkmark.
|
|
474
|
-
"kumiko.widget.step-bar.done": "Hecho",
|
|
475
|
-
|
|
476
|
-
// Widgets — Drawer resize handle + maximize toggle aria-labels.
|
|
477
|
-
"kumiko.widget.drawer.restore": "Restablecer ancho del panel",
|
|
478
|
-
"kumiko.widget.drawer.maximize": "Maximizar panel",
|
|
479
|
-
"kumiko.widget.drawer.resize": "Cambiar tamaño del panel",
|
|
480
|
-
|
|
481
|
-
// Nav — Sidebar Tree (Toggle-aria-Labels).
|
|
482
|
-
"kumiko.nav.expand": "Expandir",
|
|
483
|
-
"kumiko.nav.collapse": "Contraer",
|
|
484
|
-
"kumiko.nav.search": "Buscar en la navegación…",
|
|
485
|
-
"kumiko.nav.language": "Idioma",
|
|
486
|
-
|
|
487
|
-
// Workspace — Switcher-Trigger aria-Label (renderer-web).
|
|
488
|
-
"kumiko.workspace.switch": "Cambiar de espacio de trabajo",
|
|
489
|
-
"kumiko.workspace.select": "Selecciona un espacio de trabajo",
|
|
490
|
-
|
|
491
|
-
// Dialog — Confirm-Buttons + Close-aria-Label.
|
|
492
|
-
"kumiko.dialog.confirm": "Confirmar",
|
|
493
|
-
"kumiko.dialog.cancel": "Cancelar",
|
|
494
|
-
"kumiko.dialog.close": "Cerrar",
|
|
495
|
-
|
|
496
|
-
// AiTextField/AiTextArea — Ghost-Text-Hint, Toolbar-Aria-Labels, Diff-Dialog.
|
|
497
|
-
"kumiko.aiText.acceptHint": "Tab = aceptar, Esc = descartar",
|
|
498
|
-
"kumiko.aiText.correct": "Corregir",
|
|
499
|
-
"kumiko.aiText.translate": "Traducir",
|
|
500
|
-
"kumiko.aiText.rewrite": "Reescribir",
|
|
501
|
-
"kumiko.aiText.diff.before": "Antes",
|
|
502
|
-
"kumiko.aiText.diff.after": "Después",
|
|
503
|
-
"kumiko.aiText.diff.generating": "Generando…",
|
|
504
|
-
"kumiko.aiText.style.formal": "Formal",
|
|
505
|
-
"kumiko.aiText.style.casual": "Informal",
|
|
506
|
-
"kumiko.aiText.style.concise": "Conciso",
|
|
507
|
-
"kumiko.aiText.style.expand": "Ampliar",
|
|
508
|
-
"kumiko.aiText.capExceeded": "Se alcanzó el límite mensual de IA.",
|
|
509
|
-
|
|
510
|
-
// Row-Actions — error toast when an action write fails.
|
|
511
|
-
"kumiko.rowAction.failed": "La acción falló",
|
|
512
|
-
|
|
513
|
-
// ContentEditor — variable chip bar (VariableChips).
|
|
514
|
-
"kumiko.contentEditor.insertVariable": "Insertar {name}",
|
|
515
|
-
"kumiko.contentEditor.preview": "Vista previa",
|
|
516
|
-
"kumiko.contentEditor.editMode": "Editar",
|
|
517
|
-
"kumiko.contentEditor.bold": "Negrita",
|
|
518
|
-
"kumiko.contentEditor.italic": "Cursiva",
|
|
519
|
-
"kumiko.contentEditor.heading1": "Encabezado 1",
|
|
520
|
-
"kumiko.contentEditor.heading2": "Encabezado 2",
|
|
521
|
-
"kumiko.contentEditor.bulletList": "Lista con viñetas",
|
|
522
|
-
"kumiko.contentEditor.orderedList": "Lista numerada",
|
|
523
|
-
|
|
524
|
-
// Config-Cascade — Source-Badges + Cascade-Panel (ConfigCascadeView).
|
|
525
|
-
"kumiko.config.source.user": "Mi valor",
|
|
526
|
-
"kumiko.config.source.tenant": "Tenant",
|
|
527
|
-
"kumiko.config.source.system": "Sistema",
|
|
528
|
-
"kumiko.config.source.appOverride": "Anulación de la app",
|
|
529
|
-
"kumiko.config.source.computed": "Calculado",
|
|
530
|
-
"kumiko.config.source.default": "Predeterminado",
|
|
531
|
-
"kumiko.config.source.missing": "Falta",
|
|
532
|
-
"kumiko.config.cascade.noValue": "Sin valor establecido",
|
|
533
|
-
"kumiko.config.cascade.activeMarker": "activo",
|
|
534
|
-
"kumiko.config.cascade.resetTo": "Restablecer anulación ({scope})",
|
|
535
|
-
|
|
536
|
-
// Form — standard errors (app code can supply its own zod reasons,
|
|
537
|
-
// these are the last safety layer).
|
|
538
|
-
"kumiko.form.error.generic": "Algo salió mal.",
|
|
539
|
-
"kumiko.form.error.version-conflict":
|
|
540
|
-
"El registro se modificó mientras tanto. Recarga e inténtalo de nuevo.",
|
|
541
|
-
"kumiko.form.extension.save-failed": "No se pudo guardar un campo adicional.",
|
|
542
|
-
"kumiko.form.draft.resume-multiple":
|
|
543
|
-
"Se encontraron varios borradores abiertos para este formulario. ¿Cuál quieres continuar?",
|
|
544
|
-
"kumiko.form.draft.resume-single":
|
|
545
|
-
"Se encontró un borrador abierto para este formulario. ¿Quieres continuarlo?",
|
|
546
|
-
"kumiko.form.draft.start-new": "Empezar de nuevo",
|
|
547
|
-
|
|
548
|
-
// Validation — default reason codes from the framework. App code can
|
|
549
|
-
// inject its own via validation hooks; these are the generic ones.
|
|
550
|
-
"kumiko.validation.required": "Campo obligatorio.",
|
|
551
|
-
"kumiko.validation.invalid": "Valor no válido.",
|
|
552
|
-
"kumiko.validation.too-short": "Demasiado corto (mínimo {min} caracteres).",
|
|
553
|
-
"kumiko.validation.too-long": "Demasiado largo (máximo {max} caracteres).",
|
|
554
|
-
"kumiko.validation.out-of-range": "Valor fuera del rango permitido.",
|
|
555
|
-
|
|
556
|
-
// errors.validation.* — the canonical key namespace that server
|
|
557
|
-
// (ValidationError) and client (zod-bridge) produce for field issues.
|
|
558
|
-
// Codes = Zod 4 issue codes + framework-specific ones.
|
|
559
|
-
"errors.validation.invalid_type": "Valor no válido.",
|
|
560
|
-
"errors.validation.too_small": "Demasiado pequeño o demasiado corto (mínimo: {minimum}).",
|
|
561
|
-
"errors.validation.too_big": "Demasiado grande o demasiado largo (máximo: {maximum}).",
|
|
562
|
-
"errors.validation.invalid_format": "Formato no válido.",
|
|
563
|
-
"errors.validation.not_multiple_of": "Debe ser un múltiplo de {divisor}.",
|
|
564
|
-
"errors.validation.unrecognized_keys": "Campos desconocidos.",
|
|
565
|
-
"errors.validation.invalid_union": "Valor no válido.",
|
|
566
|
-
"errors.validation.invalid_key": "Clave no válida.",
|
|
567
|
-
"errors.validation.invalid_element": "Entrada no válida.",
|
|
568
|
-
"errors.validation.invalid_value": "Selección no válida.",
|
|
569
|
-
"errors.validation.custom": "Valor no válido.",
|
|
570
|
-
"errors.validation.unexpected_field": "Campo desconocido.",
|
|
571
|
-
"errors.validation.out_of_bounds": "Valor fuera del rango permitido.",
|
|
572
|
-
"errors.validation.invalid_option": "Selección no válida.",
|
|
573
|
-
"errors.validation.failed": "Validación fallida.",
|
|
574
|
-
|
|
575
|
-
// errors.* — top-level error codes (one per httpStatus class). Last
|
|
576
|
-
// fallback when an app doesn't supply its own translation; deliberately
|
|
577
|
-
// generic (no technical entity/feature/key names shown to end users —
|
|
578
|
-
// those live in `details` for devs). Apps override per key.
|
|
579
|
-
"errors.feature.disabled": "Esta función no está disponible actualmente.",
|
|
580
|
-
"errors.access.denied": "No tienes permiso para hacer esto.",
|
|
581
|
-
"errors.notFound": "No encontrado.",
|
|
582
|
-
"errors.conflict": "Conflicto — no se pudo completar la operación.",
|
|
583
|
-
"errors.versionConflict":
|
|
584
|
-
"El registro se modificó mientras tanto. Recarga e inténtalo de nuevo.",
|
|
585
|
-
"errors.uniqueViolation": "Esta entrada ya existe.",
|
|
586
|
-
"errors.unprocessable": "No se pudo procesar la solicitud.",
|
|
587
|
-
"errors.unconfigured": "Esta función todavía no está configurada.",
|
|
588
|
-
"errors.internal": "Algo salió mal. Inténtalo de nuevo más tarde.",
|
|
589
|
-
"errors.rate_limited": "Demasiadas solicitudes. Inténtalo de nuevo en breve.",
|
|
590
|
-
"errors.cap.exceeded": "Límite alcanzado. Mejora tu plan o espera al siguiente período.",
|
|
591
|
-
"errors.download.urlMissing": "Descarga no disponible — inténtalo de nuevo.",
|
|
592
|
-
"auth.errors.originNotAllowed": "No se permiten solicitudes desde este origen.",
|
|
593
|
-
"dispatcher.errors.network": "Error de red. Comprueba tu conexión e inténtalo de nuevo.",
|
|
594
|
-
"dispatcher.errors.aborted": "Solicitud cancelada.",
|
|
595
|
-
},
|
|
596
186
|
};
|