Allow templates in service template/object selector (#16925)

This commit is contained in:
karwosts 2023-06-19 04:33:28 -07:00 committed by GitHub
parent 80f3d6aacb
commit 40c8301df0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 2 deletions

View File

@ -1,7 +1,10 @@
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { assert } from "superstruct";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { computeDomain } from "../../../../../common/entity/compute_domain";
import { computeObjectId } from "../../../../../common/entity/compute_object_id";
import { hasTemplate } from "../../../../../common/string/has-template";
import "../../../../../components/ha-service-control";
import { ServiceAction, serviceActionStruct } from "../../../../../data/script";
@ -20,6 +23,26 @@ export class HaServiceAction extends LitElement implements ActionElement {
@state() private _action!: ServiceAction;
private _fields = memoizeOne(
(
serviceDomains: HomeAssistant["services"],
domainService: string | undefined
): { fields: any } => {
if (!domainService) {
return { fields: {} };
}
const domain = computeDomain(domainService);
const service = computeObjectId(domainService);
if (!(domain in serviceDomains)) {
return { fields: {} };
}
if (!(service in serviceDomains[domain])) {
return { fields: {} };
}
return { fields: serviceDomains[domain][service].fields };
}
);
public static get defaultConfig() {
return { service: "", data: {} };
}
@ -34,7 +57,28 @@ export class HaServiceAction extends LitElement implements ActionElement {
fireEvent(this, "ui-mode-not-available", err);
return;
}
if (this.action && hasTemplate(this.action)) {
const fields = this._fields(
this.hass.services,
this.action?.service
).fields;
if (
this.action &&
(Object.entries(this.action).some(
([key, val]) => key !== "data" && hasTemplate(val)
) ||
(this.action.data &&
Object.entries(this.action.data).some(([key, val]) => {
const field = fields[key];
if (
field?.selector &&
("template" in field.selector || "object" in field.selector)
) {
return false;
}
return hasTemplate(val);
})))
) {
fireEvent(
this,
"ui-mode-not-available",

View File

@ -346,7 +346,27 @@ class HaPanelDevService extends LitElement {
}
private _checkUiSupported() {
if (this._serviceData && hasTemplate(this._serviceData)) {
const fields = this._fields(
this.hass.services,
this._serviceData?.service
).fields;
if (
this._serviceData &&
(Object.entries(this._serviceData).some(
([key, val]) => key !== "data" && hasTemplate(val)
) ||
(this._serviceData.data &&
Object.entries(this._serviceData.data).some(([key, val]) => {
const field = fields.find((f) => f.key === key);
if (
field?.selector &&
("template" in field.selector || "object" in field.selector)
) {
return false;
}
return hasTemplate(val);
})))
) {
this._yamlMode = true;
this._uiAvailable = false;
} else {