From e46f0224c68ed3736f3a85e7802d03733f4500a0 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 11 Jul 2023 02:37:04 +0200 Subject: [PATCH] Add support for service translations (#17264) * Add support for service translations * Add selector translation support --- src/components/ha-service-control.ts | 50 ++++++++++++++++--- src/components/ha-service-description.js | 27 ---------- src/components/ha-service-picker.ts | 12 ++++- src/data/script_i18n.ts | 6 ++- src/data/translation.ts | 3 +- src/panels/config/ha-panel-config.ts | 1 + .../zha/zha-add-devices-page.ts | 7 --- .../integration-panels/zha/zha-device-card.ts | 1 - .../zha/zha-device-pairing-status-card.ts | 1 - src/panels/lovelace/common/handle-action.ts | 7 ++- 10 files changed, 67 insertions(+), 48 deletions(-) delete mode 100644 src/components/ha-service-description.js diff --git a/src/components/ha-service-control.ts b/src/components/ha-service-control.ts index 21e5289e5f..5abd368056 100644 --- a/src/components/ha-service-control.ts +++ b/src/components/ha-service-control.ts @@ -89,6 +89,10 @@ export class HaServiceControl extends LitElement { @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; protected willUpdate(changedProperties: PropertyValues) { + if (!this.hasUpdated) { + this.hass.loadBackendTranslation("services"); + this.hass.loadBackendTranslation("selector"); + } if (!changedProperties.has("value")) { return; } @@ -342,6 +346,20 @@ export class HaServiceControl extends LitElement { const filteredFields = this._filterFields(serviceData, this._value); + const domain = this._value?.service + ? computeDomain(this._value.service) + : undefined; + const serviceName = this._value?.service + ? computeObjectId(this._value.service) + : undefined; + + const description = + (serviceName && + this.hass.localize( + `component.${domain}.services.${serviceName}.description` + )) || + serviceData?.description; + return html`
- ${serviceData?.description - ? html`

${serviceData?.description}

` - : ""} + ${description ? html`

${description}

` : ""} ${this._manifest ? html` ` @@ -437,8 +455,18 @@ export class HaServiceControl extends LitElement { @change=${this._checkboxChanged} slot="prefix" >`} - ${dataField.name || dataField.key} - ${dataField?.description} + ${this.hass.localize( + `component.${domain}.services.${serviceName}.fields.${dataField.key}.name` + ) || + dataField.name || + dataField.key} + ${this.hass.localize( + `component.${domain}.services.${serviceName}.fields.${dataField.key}.description` + ) || dataField?.description} ` : ""; })}`; } + private _localizeValueCallback = (key: string) => { + if (!this._value?.service) { + return ""; + } + return this.hass.localize( + `component.${computeDomain(this._value.service)}.selector.${key}` + ); + }; + private _checkboxChanged(ev) { const checked = ev.currentTarget.checked; const key = ev.currentTarget.key; diff --git a/src/components/ha-service-description.js b/src/components/ha-service-description.js deleted file mode 100644 index c2d3359bcc..0000000000 --- a/src/components/ha-service-description.js +++ /dev/null @@ -1,27 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -class HaServiceDescription extends PolymerElement { - static get template() { - return html` [[_getDescription(hass, domain, service)]] `; - } - - static get properties() { - return { - hass: Object, - domain: String, - service: String, - }; - } - - _getDescription(hass, domain, service) { - const domainServices = hass.services[domain]; - if (!domainServices) return ""; - const serviceObject = domainServices[service]; - if (!serviceObject) return ""; - return serviceObject.description; - } -} - -customElements.define("ha-service-description", HaServiceDescription); diff --git a/src/components/ha-service-picker.ts b/src/components/ha-service-picker.ts index 76532a331d..9ef0dc670a 100644 --- a/src/components/ha-service-picker.ts +++ b/src/components/ha-service-picker.ts @@ -27,6 +27,12 @@ class HaServicePicker extends LitElement { @state() private _filter?: string; + protected willUpdate() { + if (!this.hasUpdated) { + this.hass.loadBackendTranslation("services"); + } + } + protected render() { return html` ( if (config.service) { const [domain, serviceName] = config.service.split(".", 2); - const service = hass.services[domain][serviceName]; + const service = + hass.localize(`component.${domain}.services.${serviceName}.name`) || + hass.services[domain][serviceName]?.name; return hass.localize( `${actionTranslationBaseKey}.service.description.service_based_on_name`, { name: service - ? `${domainToName(hass.localize, domain)}: ${service.name}` + ? `${domainToName(hass.localize, domain)}: ${service}` : config.service, targets: formatListWithAnds(hass.locale, targets), } diff --git a/src/data/translation.ts b/src/data/translation.ts index 99a7f7b521..bc8165578a 100644 --- a/src/data/translation.ts +++ b/src/data/translation.ts @@ -69,7 +69,8 @@ export type TranslationCategory = | "system_health" | "application_credentials" | "issues" - | "selector"; + | "selector" + | "services"; export const fetchTranslationPreferences = (hass: HomeAssistant) => fetchFrontendUserData(hass.connection, "language"); diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts index 7004f32a5f..2db32736be 100644 --- a/src/panels/config/ha-panel-config.ts +++ b/src/panels/config/ha-panel-config.ts @@ -574,6 +574,7 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) { protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); this.hass.loadBackendTranslation("title"); + this.hass.loadBackendTranslation("services"); if (isComponentLoaded(this.hass, "cloud")) { this._updateCloudStatus(); this.addEventListener("connection-status", (ev) => { diff --git a/src/panels/config/integrations/integration-panels/zha/zha-add-devices-page.ts b/src/panels/config/integrations/integration-panels/zha/zha-add-devices-page.ts index 31d30b88fd..f75b9607bb 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-add-devices-page.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-add-devices-page.ts @@ -10,7 +10,6 @@ import { } from "lit"; import { customElement, property, state } from "lit/decorators"; import "../../../../../components/ha-circular-progress"; -import "../../../../../components/ha-service-description"; import { DEVICE_MESSAGE_TYPES, LOG_OUTPUT, @@ -259,12 +258,6 @@ class ZHAAddDevicesPage extends LitElement { right: 0; color: var(--primary-color); } - ha-service-description { - margin-top: 16px; - margin-left: 16px; - display: block; - color: grey; - } .search-button { margin-top: 16px; margin-left: 16px; diff --git a/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts b/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts index 7bbc64fa67..5d4f476491 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-device-card.ts @@ -11,7 +11,6 @@ import "../../../../../components/buttons/ha-call-service-button"; import "../../../../../components/entity/state-badge"; import "../../../../../components/ha-area-picker"; import "../../../../../components/ha-card"; -import "../../../../../components/ha-service-description"; import { updateDeviceRegistryEntry } from "../../../../../data/device_registry"; import { EntityRegistryEntry, diff --git a/src/panels/config/integrations/integration-panels/zha/zha-device-pairing-status-card.ts b/src/panels/config/integrations/integration-panels/zha/zha-device-pairing-status-card.ts index 42768533ce..c4a8668ebd 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-device-pairing-status-card.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-device-pairing-status-card.ts @@ -6,7 +6,6 @@ import "../../../../../components/buttons/ha-call-service-button"; import "../../../../../components/entity/state-badge"; import "../../../../../components/ha-area-picker"; import "../../../../../components/ha-card"; -import "../../../../../components/ha-service-description"; import { CONFIGURED, INCOMPLETE_PAIRING_STATUSES, diff --git a/src/panels/lovelace/common/handle-action.ts b/src/panels/lovelace/common/handle-action.ts index 83deadf5db..febf1c848f 100644 --- a/src/panels/lovelace/common/handle-action.ts +++ b/src/panels/lovelace/common/handle-action.ts @@ -60,9 +60,12 @@ export const handleAction = async ( const [domain, service] = actionConfig.service.split(".", 2); const serviceDomains = hass.services; if (domain in serviceDomains && service in serviceDomains[domain]) { - const localize = await hass.loadBackendTranslation("title"); + await hass.loadBackendTranslation("title"); + const localize = await hass.loadBackendTranslation("services"); serviceName = `${domainToName(localize, domain)}: ${ - serviceDomains[domain][service].name || service + localize(`component.${domain}.services.${serviceName}.name`) || + serviceDomains[domain][service].name || + service }`; } }