fix(i18n): add missing save/importTitle keys, sync admin keys across all languages
Local Build and Deploy / deploy (push) Successful in 1m6s

This commit is contained in:
openhands committed 2026-07-17 20:46:58 +02:00
1 parent 06610e9ae3
commit b78d691281
22 files changed
+4125 -186

No files matched your search

+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+14 -12
View File
@@ -1592,7 +1592,7 @@
}, },
"embedPage": { "embedPage": {
"title": "Radio Embed", "title": "Radio Embed",
"subtitle": "Copy-ready embed code for the live stream. Read-only \u2014 nothing here writes to the database. Configure the stream URL in Radio Settings (radio_stream_url).", "subtitle": "Copy-ready embed code for the live stream. Read-only — nothing here writes to the database. Configure the stream URL in Radio Settings (radio_stream_url).",
"streamUrl": "Stream URL", "streamUrl": "Stream URL",
"configured": "Configured", "configured": "Configured",
"missing": "Missing", "missing": "Missing",
@@ -1609,7 +1609,7 @@
"audioSnippet": "Audio player snippet", "audioSnippet": "Audio player snippet",
"audioSnippetDesc": "Drop-in HTML5 audio player pointed straight at the stream. Works anywhere plain HTML is allowed.", "audioSnippetDesc": "Drop-in HTML5 audio player pointed straight at the stream. Works anywhere plain HTML is allowed.",
"iframeSnippet": "Iframe wrapper snippet", "iframeSnippet": "Iframe wrapper snippet",
"iframeSnippetDesc": "Embeds the site\u2019s own radio player page in an iframe \u2014 keeps your styling and now-playing info. Adjust width/height to taste.", "iframeSnippetDesc": "Embeds the site’s own radio player page in an iframe — keeps your styling and now-playing info. Adjust width/height to taste.",
"audioUnsupported": "Your browser does not support the audio element." "audioUnsupported": "Your browser does not support the audio element."
}, },
"banners": { "banners": {
@@ -1619,7 +1619,7 @@
"addBanner": "Add banner", "addBanner": "Add banner",
"createBanner": "Create banner", "createBanner": "Create banner",
"deleteBanner": "Delete banner", "deleteBanner": "Delete banner",
"noBanners": "No banners yet \u2014 add one above.", "noBanners": "No banners yet — add one above.",
"existing": "Existing banners ({count})", "existing": "Existing banners ({count})",
"save": "Save", "save": "Save",
"delete": "Delete", "delete": "Delete",
@@ -1650,7 +1650,7 @@
"description": "Description", "description": "Description",
"createRank": "Create rank", "createRank": "Create rank",
"existing": "Existing ranks ({count})", "existing": "Existing ranks ({count})",
"noRanks": "No ranks yet \u2014 add one above.", "noRanks": "No ranks yet — add one above.",
"activeLabel": "active", "activeLabel": "active",
"inactiveLabel": "inactive", "inactiveLabel": "inactive",
"save": "Save", "save": "Save",
@@ -1677,13 +1677,13 @@
}, },
"apiKeysForm": { "apiKeysForm": {
"title": "Radio API Keys", "title": "Radio API Keys",
"subtitle": "API keys for external radio integrations (radio_api_keys). Keys are generated server-side and shown masked \u2014 copy the full value from the database when first issued.", "subtitle": "API keys for external radio integrations (radio_api_keys). Keys are generated server-side and shown masked — copy the full value from the database when first issued.",
"dbError": "Could not load API keys (database unavailable).", "dbError": "Could not load API keys (database unavailable).",
"totalKeys": "Total keys", "totalKeys": "Total keys",
"active": "Active", "active": "Active",
"inactive": "Inactive", "inactive": "Inactive",
"generateKey": "Generate key", "generateKey": "Generate key",
"generateHint": "The secret key is generated automatically with cryptographic randomness \u2014 you do not enter it.", "generateHint": "The secret key is generated automatically with cryptographic randomness — you do not enter it.",
"name": "Name", "name": "Name",
"namePlaceholder": "AzureCast bridge", "namePlaceholder": "AzureCast bridge",
"rateLimit": "Rate limit (requests/min)", "rateLimit": "Rate limit (requests/min)",
@@ -1691,7 +1691,7 @@
"allowedIpsPlaceholder": "comma-separated, blank = any", "allowedIpsPlaceholder": "comma-separated, blank = any",
"generate": "Generate key", "generate": "Generate key",
"existingKeys": "Existing keys ({count})", "existingKeys": "Existing keys ({count})",
"noKeys": "No API keys yet \u2014 generate one above.", "noKeys": "No API keys yet — generate one above.",
"colName": "Name", "colName": "Name",
"colKey": "Key", "colKey": "Key",
"colAllowedIps": "Allowed IPs", "colAllowedIps": "Allowed IPs",
@@ -1743,12 +1743,12 @@
"artist": "Artist", "artist": "Artist",
"album": "Album", "album": "Album",
"artworkUrl": "Artwork URL", "artworkUrl": "Artwork URL",
"artworkUrlPlaceholder": "https://\u2026/cover.png", "artworkUrlPlaceholder": "https://…/cover.png",
"duration": "Duration (seconds)", "duration": "Duration (seconds)",
"durationPlaceholder": "e.g. 215", "durationPlaceholder": "e.g. 215",
"sortOrder": "Sort order", "sortOrder": "Sort order",
"playlist": "Playlist ({count})", "playlist": "Playlist ({count})",
"noTracks": "No AutoDJ tracks yet \u2014 add one above.", "noTracks": "No AutoDJ tracks yet — add one above.",
"colOrder": "Order", "colOrder": "Order",
"colTitle": "Title", "colTitle": "Title",
"colArtist": "Artist", "colArtist": "Artist",
@@ -1766,7 +1766,7 @@
}, },
"monitoring": { "monitoring": {
"title": "Radio Monitoring", "title": "Radio Monitoring",
"subtitle": "Read-only live probe of the configured radio endpoints (radio_now_playing_api_url, radio_listeners_api_url). Each request fails soft with a {timeout}s timeout \u2014 no data is written. Configure URLs under Settings.", "subtitle": "Read-only live probe of the configured radio endpoints (radio_now_playing_api_url, radio_listeners_api_url). Each request fails soft with a {timeout}s timeout — no data is written. Configure URLs under Settings.",
"stream": "Stream", "stream": "Stream",
"online": "Online", "online": "Online",
"offline": "Offline", "offline": "Offline",
@@ -1781,7 +1781,7 @@
"noNowPlayingHint": "no now-playing API set", "noNowPlayingHint": "no now-playing API set",
"noListenersHint": "no listeners API set", "noListenersHint": "no listeners API set",
"endpointDiagnostics": "Endpoint diagnostics", "endpointDiagnostics": "Endpoint diagnostics",
"diagnosticsLegend": "<span class=\"inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-green-600/20 text-[var(--color-text)]\">OK</span> reachable \u00b7 <span class=\"inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]\">WARN</span> not configured \u00b7 <span class=\"inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-red-500/22 text-[var(--color-text)]\">ERROR</span> fetch failed / timed out.", "diagnosticsLegend": "<span class=\"inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-green-600/20 text-[var(--color-text)]\">OK</span> reachable · <span class=\"inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]\">WARN</span> not configured · <span class=\"inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-red-500/22 text-[var(--color-text)]\">ERROR</span> fetch failed / timed out.",
"streamUrl": "Stream URL", "streamUrl": "Stream URL",
"unreachable": "unreachable", "unreachable": "unreachable",
"refresh": "Refresh" "refresh": "Refresh"
@@ -2164,7 +2164,9 @@
"auditTime": "Time", "auditTime": "Time",
"auditUser": "User", "auditUser": "User",
"auditAction": "Action", "auditAction": "Action",
"auditTarget": "Target" "auditTarget": "Target",
"save": "Save",
"importTitle": "Import permissions"
}, },
"rooms": { "rooms": {
"title": "Rooms", "title": "Rooms",
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+23 -2
View File
@@ -1855,7 +1855,26 @@
"colTimestamp": "Data", "colTimestamp": "Data",
"filterByUser": "Filtra per utente…", "filterByUser": "Filtra per utente…",
"filterByAction": "Filtra per azione…", "filterByAction": "Filtra per azione…",
"clearFilters": "Pulisci filtri" "clearFilters": "Pulisci filtri",
"noResults": "No matching activities",
"colStaff": "Staff",
"colWhen": "When",
"searchPlaceholder": "Search action, description or IP…",
"totalActivities": "Total activities",
"onThisPage": "On this page",
"recent": "Last minute",
"authorizationErrors": "Authorization errors",
"authorizationOnly": "Auth errors only",
"allActivities": "All activities",
"staffId": "Staff ID",
"actionType": "Action type",
"filter": "Filter",
"activities": "{count} activities",
"staffWithId": "#{id} {name}",
"userPrefix": "user",
"pagination": "Page {page} of {pages} · {total} total",
"next": "Next",
"prev": "Previous"
}, },
"wordfilter": { "wordfilter": {
"title": "Filtro parole", "title": "Filtro parole",
@@ -2011,7 +2030,9 @@
"auditUser": "Utente", "auditUser": "Utente",
"auditAction": "Azione", "auditAction": "Azione",
"auditTarget": "Destinatario", "auditTarget": "Destinatario",
"selectAllMatching": "Select all {count} matching" "selectAllMatching": "Select all {count} matching",
"save": "Save",
"importTitle": "Import permissions"
}, },
"rooms": { "rooms": {
"title": "Stanze", "title": "Stanze",
+3 -1
View File
@@ -1968,7 +1968,9 @@
"auditTime": "Tijd", "auditTime": "Tijd",
"auditUser": "Gebruiker", "auditUser": "Gebruiker",
"auditAction": "Actie", "auditAction": "Actie",
"auditTarget": "Doel" "auditTarget": "Doel",
"save": "Opslaan",
"importTitle": "Permissies importeren"
}, },
"rooms": { "rooms": {
"title": "Kamers", "title": "Kamers",
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff
+215 -9
View File
File diff suppressed because it is too large. Load diff