feat: module-owned i18n with merge-at-boot translation loading
Each module can now ship its own i18n/ directory with translation files (default_de.json, default_en.json). At boot time, ModuleI18nLoader preloads core translations then merges module translations on top via Reflection into I18n::$strings — the t() helper stays unchanged. - Add i18nPath property to ModuleManifest - Add ModuleI18nLoader with Reflection-based preload - Extract 59 module-exclusive keys from core i18n into module files (notifications: 8, bookmarks: 41, addressbook: 10) - Expand TranslationKeysTest to scan modules/ and validate against merged core + module translations - Add ModuleI18nContractTest for per-module de/en parity and completeness Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -295,7 +295,6 @@
|
||||
"Profile image": "Profilbild",
|
||||
"Profile": "Profil",
|
||||
"Profile description": "Profilbeschreibung",
|
||||
"About": "Über",
|
||||
"Info": "Info",
|
||||
"Search results": "Suchergebnisse",
|
||||
"Result": "Ergebnis",
|
||||
@@ -470,10 +469,6 @@
|
||||
"Status & meta": "Status & Meta",
|
||||
"Audit": "Audit",
|
||||
"Overview": "Übersicht",
|
||||
"Quick actions": "Schnellaktionen",
|
||||
"Send email": "E-Mail senden",
|
||||
"Call phone": "Telefon anrufen",
|
||||
"Call mobile": "Mobil anrufen",
|
||||
"Choose color": "Farbe wählen",
|
||||
"Be careful - this resets the tenants color": "Achtung – das setzt die Primärfarbe des Mandanten zurück",
|
||||
"Code": "Code",
|
||||
@@ -520,13 +515,11 @@
|
||||
"Department can not be created": "Abteilung kann nicht erstellt werden",
|
||||
"Department can not be updated": "Abteilung kann nicht aktualisiert werden",
|
||||
"Delete this department?": "Diese Abteilung wirklich löschen?",
|
||||
"Delete this bookmark?": "Dieses Lesezeichen wirklich löschen?",
|
||||
"Delete department": "Abteilung löschen",
|
||||
"This will permanently delete this department.": "Diese Abteilung wird dauerhaft gelöscht.",
|
||||
"Assigned departments": "Zugewiesene Abteilungen",
|
||||
"Select departments": "Abteilungen auswählen",
|
||||
"Departments for tenant": "Abteilungen für Mandant",
|
||||
"No departments": "Keine Abteilungen",
|
||||
"No departments available for this tenant": "Für diesen Mandanten sind keine Abteilungen verfügbar",
|
||||
"Assign tenants first to select departments": "Bitte zuerst Mandanten zuweisen, um Abteilungen auszuwählen",
|
||||
"No tenants available": "Keine Mandanten verfügbar",
|
||||
@@ -549,7 +542,6 @@
|
||||
"Delete permission": "Berechtigung löschen",
|
||||
"This will permanently delete this role.": "Diese Rolle wird dauerhaft gelöscht.",
|
||||
"This will permanently delete this permission.": "Diese Berechtigung wird dauerhaft gelöscht.",
|
||||
"This action cannot be undone.": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"Description": "Beschreibung",
|
||||
"Description cannot be empty": "Beschreibung darf nicht leer sein",
|
||||
"Status is invalid": "Status ist ungültig",
|
||||
@@ -647,7 +639,6 @@
|
||||
"SMTP security": "SMTP Sicherheit",
|
||||
"SMTP from address": "Absender-Adresse",
|
||||
"SMTP from name": "Absendername",
|
||||
"Address book": "Adressbuch",
|
||||
"Mobile": "Mobil",
|
||||
"Short dial": "Kurzwahl",
|
||||
"setting.smtp_host": "SMTP-Serveradresse (z.B. smtp.example.com)",
|
||||
@@ -659,7 +650,6 @@
|
||||
"setting.smtp_from_name": "Absendername für ausgehende Nachrichten",
|
||||
"High contrast": "Hoher Kontrast",
|
||||
"Toggle contrast": "Kontrast umschalten",
|
||||
"View in address book": "Im Adressbuch ansehen",
|
||||
"Organization & Quality": "Organisation & Qualität",
|
||||
"Email security": "E-Mail Sicherheit",
|
||||
"API": "API",
|
||||
@@ -813,8 +803,6 @@
|
||||
"Please fill required custom field: %s": "Bitte Pflicht-Zusatzfeld ausfüllen: %s",
|
||||
"Invalid value for %s": "Ungültiger Wert für %s",
|
||||
"Please select": "Bitte auswählen",
|
||||
"From": "Von",
|
||||
"To": "Bis",
|
||||
"perm.custom_fields.manage": "Mandanten-Zusatzfelder verwalten",
|
||||
"perm.custom_fields.edit_values": "Benutzer-Zusatzfelder bearbeiten",
|
||||
"Label": "Bezeichnung",
|
||||
@@ -999,7 +987,6 @@
|
||||
"Import another file": "Weitere Datei importieren",
|
||||
"No row errors found": "Keine Zeilenfehler gefunden",
|
||||
"Row": "Zeile",
|
||||
"Code": "Code",
|
||||
"Message": "Nachricht",
|
||||
"No upload file provided": "Keine Upload-Datei übergeben",
|
||||
"Upload exceeds the maximum size": "Upload überschreitet die maximale Dateigröße",
|
||||
@@ -1212,7 +1199,6 @@
|
||||
"Actor tenant": "Akteur-Mandant",
|
||||
"Event details": "Ereignisdetails",
|
||||
"Target type": "Zieltyp",
|
||||
"Request ID": "Request-ID",
|
||||
"IP hash": "IP-Hash",
|
||||
"User agent hash": "User-Agent-Hash",
|
||||
"Channel": "Kanal",
|
||||
@@ -1299,45 +1285,5 @@
|
||||
"Session expiring": "Sitzung läuft ab",
|
||||
"Your session will expire in {countdown}. Would you like to continue?": "Ihre Sitzung läuft in {countdown} ab. Möchten Sie fortfahren?",
|
||||
"Extend session": "Sitzung verlängern",
|
||||
"Log out": "Abmelden",
|
||||
"Bookmarks": "Lesezeichen",
|
||||
"Bookmark this page": "Seite als Lesezeichen speichern",
|
||||
"Save bookmark": "Lesezeichen speichern",
|
||||
"Bookmark name": "Lesezeichen-Name",
|
||||
"Delete bookmark": "Lesezeichen löschen",
|
||||
"No bookmarks yet": "Noch keine Lesezeichen",
|
||||
"New group": "Neue Gruppe",
|
||||
"No group": "Keine Gruppe",
|
||||
"Assign to group": "Gruppe zuweisen",
|
||||
"Group name": "Gruppenname",
|
||||
"Delete group": "Gruppe löschen",
|
||||
"Group": "Gruppe",
|
||||
"Icon": "Symbol",
|
||||
"Maximum bookmarks reached": "Maximale Anzahl an Lesezeichen erreicht",
|
||||
"Edit bookmark": "Lesezeichen bearbeiten",
|
||||
"Save changes": "Änderungen speichern",
|
||||
"Bookmark saved": "Lesezeichen gespeichert",
|
||||
"Bookmark updated": "Lesezeichen aktualisiert",
|
||||
"Bookmark deleted": "Lesezeichen gelöscht",
|
||||
"Group created": "Gruppe erstellt",
|
||||
"Group deleted": "Gruppe gelöscht",
|
||||
"Group delete failed": "Gruppe konnte nicht gelöscht werden",
|
||||
"Delete group and keep bookmarks?": "Gruppe löschen und enthaltene Lesezeichen behalten?",
|
||||
"Bookmark action failed": "Lesezeichen-Aktion fehlgeschlagen",
|
||||
"Group action failed": "Gruppen-Aktion fehlgeschlagen",
|
||||
"Reorder saved": "Sortierung gespeichert",
|
||||
"Reorder failed": "Sortierung fehlgeschlagen",
|
||||
"Move group up": "Gruppe nach oben",
|
||||
"Move group down": "Gruppe nach unten",
|
||||
"Move bookmark up": "Lesezeichen nach oben",
|
||||
"Move bookmark down": "Lesezeichen nach unten",
|
||||
"Group actions": "Gruppenaktionen",
|
||||
"Bookmark actions": "Lesezeichenaktionen",
|
||||
"Bookmark name is required": "Lesezeichen-Name ist erforderlich",
|
||||
"Bookmark URL is invalid": "Lesezeichen-URL ist ungültig",
|
||||
"Group not found": "Gruppe nicht gefunden",
|
||||
"Edit group": "Gruppe bearbeiten",
|
||||
"Group updated": "Gruppe aktualisiert",
|
||||
"Group name is required": "Gruppenname ist erforderlich",
|
||||
"Maximum groups reached": "Maximale Anzahl an Gruppen erreicht"
|
||||
"Log out": "Abmelden"
|
||||
}
|
||||
|
||||
@@ -295,7 +295,6 @@
|
||||
"Profile image": "Profile image",
|
||||
"Profile": "Profile",
|
||||
"Profile description": "Profile description",
|
||||
"About": "About",
|
||||
"Info": "Info",
|
||||
"Search results": "Search results",
|
||||
"Result": "Result",
|
||||
@@ -470,10 +469,6 @@
|
||||
"Status & meta": "Status & meta",
|
||||
"Audit": "Audit",
|
||||
"Overview": "Overview",
|
||||
"Quick actions": "Quick actions",
|
||||
"Send email": "Send email",
|
||||
"Call phone": "Call phone",
|
||||
"Call mobile": "Call mobile",
|
||||
"Choose color": "Choose color",
|
||||
"Be careful - this resets the tenants color": "Be careful - this resets the tenant color",
|
||||
"Code": "Code",
|
||||
@@ -520,13 +515,11 @@
|
||||
"Department can not be created": "Department can not be created",
|
||||
"Department can not be updated": "Department can not be updated",
|
||||
"Delete this department?": "Delete this department?",
|
||||
"Delete this bookmark?": "Delete this bookmark?",
|
||||
"Delete department": "Delete department",
|
||||
"This will permanently delete this department.": "This will permanently delete this department.",
|
||||
"Assigned departments": "Assigned departments",
|
||||
"Select departments": "Select departments",
|
||||
"Departments for tenant": "Departments for tenant",
|
||||
"No departments": "No departments",
|
||||
"No departments available for this tenant": "No departments available for this tenant",
|
||||
"Assign tenants first to select departments": "Assign tenants first to select departments",
|
||||
"No tenants available": "No tenants available",
|
||||
@@ -549,7 +542,6 @@
|
||||
"Delete permission": "Delete permission",
|
||||
"This will permanently delete this role.": "This will permanently delete this role.",
|
||||
"This will permanently delete this permission.": "This will permanently delete this permission.",
|
||||
"This action cannot be undone.": "This action cannot be undone.",
|
||||
"Description": "Description",
|
||||
"Description cannot be empty": "Description cannot be empty",
|
||||
"Status is invalid": "Status is invalid",
|
||||
@@ -647,7 +639,6 @@
|
||||
"SMTP security": "SMTP security",
|
||||
"SMTP from address": "SMTP from address",
|
||||
"SMTP from name": "SMTP from name",
|
||||
"Address book": "Address book",
|
||||
"Mobile": "Mobile",
|
||||
"Short dial": "Short dial",
|
||||
"setting.smtp_host": "SMTP server host (e.g. smtp.example.com)",
|
||||
@@ -659,7 +650,6 @@
|
||||
"setting.smtp_from_name": "From name for outgoing emails",
|
||||
"High contrast": "High contrast",
|
||||
"Toggle contrast": "Toggle contrast",
|
||||
"View in address book": "View in address book",
|
||||
"Organization & Quality": "Organization & Quality",
|
||||
"Email security": "Email security",
|
||||
"API": "API",
|
||||
@@ -813,8 +803,6 @@
|
||||
"Please fill required custom field: %s": "Please fill required custom field: %s",
|
||||
"Invalid value for %s": "Invalid value for %s",
|
||||
"Please select": "Please select",
|
||||
"From": "From",
|
||||
"To": "To",
|
||||
"perm.custom_fields.manage": "Manage tenant custom fields",
|
||||
"perm.custom_fields.edit_values": "Edit user custom field values",
|
||||
"Label": "Label",
|
||||
@@ -999,7 +987,6 @@
|
||||
"Import another file": "Import another file",
|
||||
"No row errors found": "No row errors found",
|
||||
"Row": "Row",
|
||||
"Code": "Code",
|
||||
"Message": "Message",
|
||||
"No upload file provided": "No upload file provided",
|
||||
"Upload exceeds the maximum size": "Upload exceeds the maximum size",
|
||||
@@ -1212,7 +1199,6 @@
|
||||
"Actor tenant": "Actor tenant",
|
||||
"Event details": "Event details",
|
||||
"Target type": "Target type",
|
||||
"Request ID": "Request ID",
|
||||
"IP hash": "IP hash",
|
||||
"User agent hash": "User agent hash",
|
||||
"Channel": "Channel",
|
||||
@@ -1299,45 +1285,5 @@
|
||||
"Session expiring": "Session expiring",
|
||||
"Your session will expire in {countdown}. Would you like to continue?": "Your session will expire in {countdown}. Would you like to continue?",
|
||||
"Extend session": "Extend session",
|
||||
"Log out": "Log out",
|
||||
"Bookmarks": "Bookmarks",
|
||||
"Bookmark this page": "Bookmark this page",
|
||||
"Save bookmark": "Save bookmark",
|
||||
"Bookmark name": "Bookmark name",
|
||||
"Delete bookmark": "Delete bookmark",
|
||||
"No bookmarks yet": "No bookmarks yet",
|
||||
"New group": "New group",
|
||||
"No group": "No group",
|
||||
"Assign to group": "Assign to group",
|
||||
"Group name": "Group name",
|
||||
"Delete group": "Delete group",
|
||||
"Group": "Group",
|
||||
"Icon": "Icon",
|
||||
"Maximum bookmarks reached": "Maximum bookmarks reached",
|
||||
"Edit bookmark": "Edit bookmark",
|
||||
"Save changes": "Save changes",
|
||||
"Bookmark saved": "Bookmark saved",
|
||||
"Bookmark updated": "Bookmark updated",
|
||||
"Bookmark deleted": "Bookmark deleted",
|
||||
"Group created": "Group created",
|
||||
"Group deleted": "Group deleted",
|
||||
"Group delete failed": "Group delete failed",
|
||||
"Delete group and keep bookmarks?": "Delete group and keep bookmarks?",
|
||||
"Bookmark action failed": "Bookmark action failed",
|
||||
"Group action failed": "Group action failed",
|
||||
"Reorder saved": "Reorder saved",
|
||||
"Reorder failed": "Reorder failed",
|
||||
"Move group up": "Move group up",
|
||||
"Move group down": "Move group down",
|
||||
"Move bookmark up": "Move bookmark up",
|
||||
"Move bookmark down": "Move bookmark down",
|
||||
"Group actions": "Group actions",
|
||||
"Bookmark actions": "Bookmark actions",
|
||||
"Bookmark name is required": "Bookmark name is required",
|
||||
"Bookmark URL is invalid": "Bookmark URL is invalid",
|
||||
"Group not found": "Group not found",
|
||||
"Edit group": "Edit group",
|
||||
"Group updated": "Group updated",
|
||||
"Group name is required": "Group name is required",
|
||||
"Maximum groups reached": "Maximum groups reached"
|
||||
"Log out": "Log out"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user