mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 16:26:43 +00:00
Add support for service translations (#17264)
* Add support for service translations * Add selector translation support
This commit is contained in:
parent
bf4cf310f3
commit
e46f0224c6
@ -89,6 +89,10 @@ export class HaServiceControl extends LitElement {
|
|||||||
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
|
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
|
||||||
|
|
||||||
protected willUpdate(changedProperties: PropertyValues<this>) {
|
protected willUpdate(changedProperties: PropertyValues<this>) {
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
this.hass.loadBackendTranslation("services");
|
||||||
|
this.hass.loadBackendTranslation("selector");
|
||||||
|
}
|
||||||
if (!changedProperties.has("value")) {
|
if (!changedProperties.has("value")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -342,6 +346,20 @@ export class HaServiceControl extends LitElement {
|
|||||||
|
|
||||||
const filteredFields = this._filterFields(serviceData, this._value);
|
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
|
return html`<ha-service-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._value?.service}
|
.value=${this._value?.service}
|
||||||
@ -349,9 +367,7 @@ export class HaServiceControl extends LitElement {
|
|||||||
@value-changed=${this._serviceChanged}
|
@value-changed=${this._serviceChanged}
|
||||||
></ha-service-picker>
|
></ha-service-picker>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
${serviceData?.description
|
${description ? html`<p>${description}</p>` : ""}
|
||||||
? html`<p>${serviceData?.description}</p>`
|
|
||||||
: ""}
|
|
||||||
${this._manifest
|
${this._manifest
|
||||||
? html` <a
|
? html` <a
|
||||||
href=${this._manifest.is_built_in
|
href=${this._manifest.is_built_in
|
||||||
@ -402,7 +418,9 @@ export class HaServiceControl extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.value=${this._value?.data?.entity_id}
|
.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}
|
@value-changed=${this._entityPicked}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>`
|
></ha-entity-picker>`
|
||||||
@ -437,8 +455,18 @@ export class HaServiceControl extends LitElement {
|
|||||||
@change=${this._checkboxChanged}
|
@change=${this._checkboxChanged}
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
></ha-checkbox>`}
|
></ha-checkbox>`}
|
||||||
<span slot="heading">${dataField.name || dataField.key}</span>
|
<span slot="heading"
|
||||||
<span slot="description">${dataField?.description}</span>
|
>${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
|
<ha-selector
|
||||||
.disabled=${this.disabled ||
|
.disabled=${this.disabled ||
|
||||||
(showOptional &&
|
(showOptional &&
|
||||||
@ -453,12 +481,22 @@ export class HaServiceControl extends LitElement {
|
|||||||
? this._value.data[dataField.key]
|
? this._value.data[dataField.key]
|
||||||
: undefined}
|
: undefined}
|
||||||
.placeholder=${dataField.default}
|
.placeholder=${dataField.default}
|
||||||
|
.localizeValue=${this._localizeValueCallback}
|
||||||
></ha-selector>
|
></ha-selector>
|
||||||
</ha-settings-row>`
|
</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) {
|
private _checkboxChanged(ev) {
|
||||||
const checked = ev.currentTarget.checked;
|
const checked = ev.currentTarget.checked;
|
||||||
const key = ev.currentTarget.key;
|
const key = ev.currentTarget.key;
|
||||||
|
@ -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);
|
|
@ -27,6 +27,12 @@ class HaServicePicker extends LitElement {
|
|||||||
|
|
||||||
@state() private _filter?: string;
|
@state() private _filter?: string;
|
||||||
|
|
||||||
|
protected willUpdate() {
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
this.hass.loadBackendTranslation("services");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
<ha-combo-box
|
<ha-combo-box
|
||||||
@ -71,7 +77,11 @@ class HaServicePicker extends LitElement {
|
|||||||
result.push({
|
result.push({
|
||||||
service: `${domain}.${service}`,
|
service: `${domain}.${service}`,
|
||||||
name: `${domainToName(localize, domain)}: ${
|
name: `${domainToName(localize, domain)}: ${
|
||||||
services[domain][service].name || service
|
this.hass.localize(
|
||||||
|
`component.${domain}.services.${service}.name`
|
||||||
|
) ||
|
||||||
|
services[domain][service].name ||
|
||||||
|
service
|
||||||
}`,
|
}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -165,12 +165,14 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
|
|
||||||
if (config.service) {
|
if (config.service) {
|
||||||
const [domain, serviceName] = config.service.split(".", 2);
|
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(
|
return hass.localize(
|
||||||
`${actionTranslationBaseKey}.service.description.service_based_on_name`,
|
`${actionTranslationBaseKey}.service.description.service_based_on_name`,
|
||||||
{
|
{
|
||||||
name: service
|
name: service
|
||||||
? `${domainToName(hass.localize, domain)}: ${service.name}`
|
? `${domainToName(hass.localize, domain)}: ${service}`
|
||||||
: config.service,
|
: config.service,
|
||||||
targets: formatListWithAnds(hass.locale, targets),
|
targets: formatListWithAnds(hass.locale, targets),
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,8 @@ export type TranslationCategory =
|
|||||||
| "system_health"
|
| "system_health"
|
||||||
| "application_credentials"
|
| "application_credentials"
|
||||||
| "issues"
|
| "issues"
|
||||||
| "selector";
|
| "selector"
|
||||||
|
| "services";
|
||||||
|
|
||||||
export const fetchTranslationPreferences = (hass: HomeAssistant) =>
|
export const fetchTranslationPreferences = (hass: HomeAssistant) =>
|
||||||
fetchFrontendUserData(hass.connection, "language");
|
fetchFrontendUserData(hass.connection, "language");
|
||||||
|
@ -574,6 +574,7 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
|
|||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this.hass.loadBackendTranslation("title");
|
this.hass.loadBackendTranslation("title");
|
||||||
|
this.hass.loadBackendTranslation("services");
|
||||||
if (isComponentLoaded(this.hass, "cloud")) {
|
if (isComponentLoaded(this.hass, "cloud")) {
|
||||||
this._updateCloudStatus();
|
this._updateCloudStatus();
|
||||||
this.addEventListener("connection-status", (ev) => {
|
this.addEventListener("connection-status", (ev) => {
|
||||||
|
@ -10,7 +10,6 @@ import {
|
|||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import "../../../../../components/ha-circular-progress";
|
import "../../../../../components/ha-circular-progress";
|
||||||
import "../../../../../components/ha-service-description";
|
|
||||||
import {
|
import {
|
||||||
DEVICE_MESSAGE_TYPES,
|
DEVICE_MESSAGE_TYPES,
|
||||||
LOG_OUTPUT,
|
LOG_OUTPUT,
|
||||||
@ -259,12 +258,6 @@ class ZHAAddDevicesPage extends LitElement {
|
|||||||
right: 0;
|
right: 0;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
ha-service-description {
|
|
||||||
margin-top: 16px;
|
|
||||||
margin-left: 16px;
|
|
||||||
display: block;
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
.search-button {
|
.search-button {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
|
@ -11,7 +11,6 @@ import "../../../../../components/buttons/ha-call-service-button";
|
|||||||
import "../../../../../components/entity/state-badge";
|
import "../../../../../components/entity/state-badge";
|
||||||
import "../../../../../components/ha-area-picker";
|
import "../../../../../components/ha-area-picker";
|
||||||
import "../../../../../components/ha-card";
|
import "../../../../../components/ha-card";
|
||||||
import "../../../../../components/ha-service-description";
|
|
||||||
import { updateDeviceRegistryEntry } from "../../../../../data/device_registry";
|
import { updateDeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||||
import {
|
import {
|
||||||
EntityRegistryEntry,
|
EntityRegistryEntry,
|
||||||
|
@ -6,7 +6,6 @@ import "../../../../../components/buttons/ha-call-service-button";
|
|||||||
import "../../../../../components/entity/state-badge";
|
import "../../../../../components/entity/state-badge";
|
||||||
import "../../../../../components/ha-area-picker";
|
import "../../../../../components/ha-area-picker";
|
||||||
import "../../../../../components/ha-card";
|
import "../../../../../components/ha-card";
|
||||||
import "../../../../../components/ha-service-description";
|
|
||||||
import {
|
import {
|
||||||
CONFIGURED,
|
CONFIGURED,
|
||||||
INCOMPLETE_PAIRING_STATUSES,
|
INCOMPLETE_PAIRING_STATUSES,
|
||||||
|
@ -60,9 +60,12 @@ export const handleAction = async (
|
|||||||
const [domain, service] = actionConfig.service.split(".", 2);
|
const [domain, service] = actionConfig.service.split(".", 2);
|
||||||
const serviceDomains = hass.services;
|
const serviceDomains = hass.services;
|
||||||
if (domain in serviceDomains && service in serviceDomains[domain]) {
|
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)}: ${
|
serviceName = `${domainToName(localize, domain)}: ${
|
||||||
serviceDomains[domain][service].name || service
|
localize(`component.${domain}.services.${serviceName}.name`) ||
|
||||||
|
serviceDomains[domain][service].name ||
|
||||||
|
service
|
||||||
}`;
|
}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user