Add support for service translations (#17264)

* Add support for service translations

* Add selector translation support
This commit is contained in:
Bram Kragten 2023-07-11 02:37:04 +02:00 committed by GitHub
parent bf4cf310f3
commit e46f0224c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 67 additions and 48 deletions

View File

@ -89,6 +89,10 @@ export class HaServiceControl extends LitElement {
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
protected willUpdate(changedProperties: PropertyValues<this>) {
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`<ha-service-picker
.hass=${this.hass}
.value=${this._value?.service}
@ -349,9 +367,7 @@ export class HaServiceControl extends LitElement {
@value-changed=${this._serviceChanged}
></ha-service-picker>
<div class="description">
${serviceData?.description
? html`<p>${serviceData?.description}</p>`
: ""}
${description ? html`<p>${description}</p>` : ""}
${this._manifest
? html` <a
href=${this._manifest.is_built_in
@ -402,7 +418,9 @@ export class HaServiceControl extends LitElement {
.hass=${this.hass}
.disabled=${this.disabled}
.value=${this._value?.data?.entity_id}
.label=${entityId.description}
.label=${this.hass.localize(
`component.${domain}.services.${serviceName}.fields.entity_id.description`
) || entityId.description}
@value-changed=${this._entityPicked}
allow-custom-entity
></ha-entity-picker>`
@ -437,8 +455,18 @@ export class HaServiceControl extends LitElement {
@change=${this._checkboxChanged}
slot="prefix"
></ha-checkbox>`}
<span slot="heading">${dataField.name || dataField.key}</span>
<span slot="description">${dataField?.description}</span>
<span slot="heading"
>${this.hass.localize(
`component.${domain}.services.${serviceName}.fields.${dataField.key}.name`
) ||
dataField.name ||
dataField.key}</span
>
<span slot="description"
>${this.hass.localize(
`component.${domain}.services.${serviceName}.fields.${dataField.key}.description`
) || dataField?.description}</span
>
<ha-selector
.disabled=${this.disabled ||
(showOptional &&
@ -453,12 +481,22 @@ export class HaServiceControl extends LitElement {
? this._value.data[dataField.key]
: undefined}
.placeholder=${dataField.default}
.localizeValue=${this._localizeValueCallback}
></ha-selector>
</ha-settings-row>`
: "";
})}`;
}
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;

View File

@ -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);

View File

@ -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`
<ha-combo-box
@ -71,7 +77,11 @@ class HaServicePicker extends LitElement {
result.push({
service: `${domain}.${service}`,
name: `${domainToName(localize, domain)}: ${
services[domain][service].name || service
this.hass.localize(
`component.${domain}.services.${service}.name`
) ||
services[domain][service].name ||
service
}`,
});
}

View File

@ -165,12 +165,14 @@ const tryDescribeAction = <T extends ActionType>(
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),
}

View File

@ -69,7 +69,8 @@ export type TranslationCategory =
| "system_health"
| "application_credentials"
| "issues"
| "selector";
| "selector"
| "services";
export const fetchTranslationPreferences = (hass: HomeAssistant) =>
fetchFrontendUserData(hass.connection, "language");

View File

@ -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) => {

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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
}`;
}
}