From 0c647a791bec2b9c27831d6542fd96868334877a Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Tue, 13 Oct 2026 20:07:09 +0400 Subject: [PATCH] fix(i18n): toast, boot labels and AI tool text found in review - The Space Missions cancellation failure toast read "[object Object]" in every language: the options object was passed as the message. The English message is the second argument again, the translation the third. - Header text is translated before panel chrome builds its collapse labels, so the dock and display toggles no longer read "Expand VISUAL PRESETS" in another language. - The voice "show data layers" result keeps the English layer name (row data-layer-name), not the translated row text. - The Google 3D unavailable reason is translated in full. Co-Authored-By: Claude Opus 5.5 --- src/i18n/locales/es.json | 4 +++- src/i18n/locales/ru.json | 4 +++- src/maps/availability.js | 9 +++++++-- src/ui/applicationShell.js | 3 ++- src/ui/contextLayerChanges.js | 1 + src/ui/layerPanel.js | 6 ++++++ src/voice/gevActions.js | 6 +++++- 7 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 7f512c95d..b2901c984 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -2028,5 +2028,7 @@ "{duration}s + {hold}s": "{duration} s + {hold} s", "Configured Source": "Fuente configurada", "subject": "sujeto", - "{value}m": "{value} m" + "{value}m": "{value} m", + "Google 3D tiles unavailable — check the key's API restrictions, quota, or network": "Teselas de Google 3D no disponibles: revisa las restricciones de API de la clave, la cuota o la red", + "Needs {envVars} — add it in Provider Settings — or a Cesium ion token for the ion-hosted route": "Necesita {envVars} — añádela en Ajustes de proveedores — o un token de Cesium ion para la ruta alojada en ion" } diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index 605f82c66..1b840bf7e 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -2060,5 +2060,7 @@ "{duration}s + {hold}s": "{duration} с + {hold} с", "Configured Source": "Настроенный источник", "subject": "объект", - "{value}m": "{value} м" + "{value}m": "{value} м", + "Google 3D tiles unavailable — check the key's API restrictions, quota, or network": "Тайлы Google 3D недоступны — проверьте ограничения API ключа, квоту или сеть", + "Needs {envVars} — add it in Provider Settings — or a Cesium ion token for the ion-hosted route": "Нужен {envVars} — добавьте его в «Настройках провайдеров» — или токен Cesium ion для маршрута через ion" } diff --git a/src/maps/availability.js b/src/maps/availability.js index 1ffa600ab..30ef3e6c6 100644 --- a/src/maps/availability.js +++ b/src/maps/availability.js @@ -14,7 +14,12 @@ import { t } from '../i18n/index.js'; */ export function photorealUnavailableReason(hasCredentials) { if (hasCredentials) - return "Google 3D tiles unavailable — check the key's API restrictions, quota, or network"; + return t( + "Google 3D tiles unavailable — check the key's API restrictions, quota, or network", + ); const envVars = keySetupRequirementEnvVars('google-maps'); - return `${t('Needs {envVars} — add it in Provider Settings', { envVars })} — or a Cesium ion token for the ion-hosted route`; + return t( + 'Needs {envVars} — add it in Provider Settings — or a Cesium ion token for the ion-hosted route', + { envVars }, + ); } diff --git a/src/ui/applicationShell.js b/src/ui/applicationShell.js index 9d2db757c..ca352c93d 100644 --- a/src/ui/applicationShell.js +++ b/src/ui/applicationShell.js @@ -569,10 +569,11 @@ export class StyleManager extends ShellFacade { }); this._initUI(); this._initMapStackControl(); + // Headers first: panel chrome builds its toggle labels from them. + this._applyRuntimeStaticHeaderText(); this._initPanelChrome(); this._initLocaleSelector(); this._sizeDisplayLabelColumn(); - this._applyRuntimeStaticHeaderText(); this._initLeftPanelAdaptiveLayout(); this._initRightPanelAdaptiveLayout(); this._initRadioPanel(); diff --git a/src/ui/contextLayerChanges.js b/src/ui/contextLayerChanges.js index 4a00780f5..5e9dc125a 100644 --- a/src/ui/contextLayerChanges.js +++ b/src/ui/contextLayerChanges.js @@ -69,6 +69,7 @@ export function _handleContextLayerChange(change) { ); return true; }, + 'Space Missions cancellation could not restore the previous layer state', // i18n-ignore: English message; the toast shows localizedMessage { localizedMessage: t( 'Space Missions cancellation could not restore the previous layer state', diff --git a/src/ui/layerPanel.js b/src/ui/layerPanel.js index 75cecad62..65157aab3 100644 --- a/src/ui/layerPanel.js +++ b/src/ui/layerPanel.js @@ -129,6 +129,10 @@ const PANEL_LABELS = { 'local-firms': msg('Active Fires'), }; +function englishPanelLabel(layer) { + return PANEL_LABELS[layer.id] || LAYER_NAME_KEYS[layer.id] || layer.name; +} + // The panel's own English names win, as before i18n; module names otherwise. function panelLabel(layer) { if (PANEL_LABELS[layer.id]) return t(PANEL_LABELS[layer.id]); @@ -378,6 +382,8 @@ export class LayerPanel { const row = document.createElement('div'); row.className = 'data-toggle-row'; row.dataset.layerId = layer.id; + // English name for voice tools, which must not receive translated text. + row.dataset.layerName = englishPanelLabel(layer); const topRow = document.createElement('div'); topRow.className = 'data-toggle-top'; diff --git a/src/voice/gevActions.js b/src/voice/gevActions.js index ac6ec1b9b..f3350f7c8 100644 --- a/src/voice/gevActions.js +++ b/src/voice/gevActions.js @@ -3003,7 +3003,11 @@ function focusDataLayerRow(layerId) { void row.offsetWidth; row.classList.add('gev-voice-focus'); window.setTimeout(() => row.classList.remove('gev-voice-focus'), 3000); - const name = row.querySelector('.data-name')?.textContent?.trim() || layerId; + // The English name: tool results stay English whatever the UI language. + const name = + row.dataset.layerName || + row.querySelector('.data-name')?.textContent?.trim() || + layerId; return { id: layerId, name }; }