Fallback to yaml for service data if unknown key is in data (#8595)

This commit is contained in:
Bram Kragten 2021-03-09 15:26:26 +01:00 committed by GitHub
parent 2e76b306c4
commit 68ea1abc05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -36,6 +36,7 @@ interface ExtHassService extends Omit<HassService, "fields"> {
example?: any; example?: any;
selector?: Selector; selector?: Selector;
}[]; }[];
hasSelector: string[];
} }
@customElement("ha-service-control") @customElement("ha-service-control")
@ -52,8 +53,6 @@ export class HaServiceControl extends LitElement {
@property({ type: Boolean }) public showAdvanced?: boolean; @property({ type: Boolean }) public showAdvanced?: boolean;
@internalProperty() private _serviceData?: ExtHassService;
@internalProperty() private _checkedKeys = new Set(); @internalProperty() private _checkedKeys = new Set();
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
@ -70,13 +69,11 @@ export class HaServiceControl extends LitElement {
this._checkedKeys = new Set(); this._checkedKeys = new Set();
} }
this._serviceData = this.value?.service const serviceData = this._getServiceInfo(this.value?.service);
? this._getServiceInfo(this.value.service)
: undefined;
if ( if (
this._serviceData && serviceData &&
"target" in this._serviceData && "target" in serviceData &&
(this.value?.data?.entity_id || (this.value?.data?.entity_id ||
this.value?.data?.area_id || this.value?.data?.area_id ||
this.value?.data?.device_id) this.value?.data?.device_id)
@ -119,7 +116,7 @@ export class HaServiceControl extends LitElement {
return ENTITY_COMPONENT_DOMAINS.includes(domain) ? [domain] : null; return ENTITY_COMPONENT_DOMAINS.includes(domain) ? [domain] : null;
}); });
private _getServiceInfo = memoizeOne((service: string): private _getServiceInfo = memoizeOne((service?: string):
| ExtHassService | ExtHassService
| undefined => { | undefined => {
if (!service) { if (!service) {
@ -147,23 +144,29 @@ export class HaServiceControl extends LitElement {
return { return {
...serviceDomains[domain][serviceName], ...serviceDomains[domain][serviceName],
fields, fields,
hasSelector: fields.length
? fields.filter((field) => field.selector).map((field) => field.key)
: [],
}; };
}); });
protected render() { protected render() {
const legacy = const serviceData = this._getServiceInfo(this.value?.service);
this._serviceData?.fields.length &&
!this._serviceData.fields.some((field) => field.selector); const shouldRenderServiceDataYaml =
(serviceData?.fields.length && !serviceData.hasSelector.length) ||
(serviceData &&
Object.keys(this.value?.data || {}).some(
(key) => !serviceData!.hasSelector.includes(key)
));
const entityId = const entityId =
legacy && shouldRenderServiceDataYaml &&
this._serviceData?.fields.find((field) => field.key === "entity_id"); serviceData?.fields.find((field) => field.key === "entity_id");
const hasOptional = Boolean( const hasOptional = Boolean(
!legacy && !shouldRenderServiceDataYaml &&
this._serviceData?.fields.some( serviceData?.fields.some((field) => field.selector && !field.required)
(field) => field.selector && !field.required
)
); );
return html`<ha-service-picker return html`<ha-service-picker
@ -171,8 +174,8 @@ export class HaServiceControl extends LitElement {
.value=${this.value?.service} .value=${this.value?.service}
@value-changed=${this._serviceChanged} @value-changed=${this._serviceChanged}
></ha-service-picker> ></ha-service-picker>
<p>${this._serviceData?.description}</p> <p>${serviceData?.description}</p>
${this._serviceData && "target" in this._serviceData ${serviceData && "target" in serviceData
? html`<ha-settings-row .narrow=${this.narrow}> ? html`<ha-settings-row .narrow=${this.narrow}>
${hasOptional ${hasOptional
? html`<div slot="prefix" class="checkbox-spacer"></div>` ? html`<div slot="prefix" class="checkbox-spacer"></div>`
@ -188,8 +191,8 @@ export class HaServiceControl extends LitElement {
)}</span )}</span
><ha-selector ><ha-selector
.hass=${this.hass} .hass=${this.hass}
.selector=${this._serviceData.target .selector=${serviceData.target
? { target: this._serviceData.target } ? { target: serviceData.target }
: { : {
target: { target: {
entity: { domain: computeDomain(this.value!.service) }, entity: { domain: computeDomain(this.value!.service) },
@ -209,7 +212,7 @@ export class HaServiceControl extends LitElement {
allow-custom-entity allow-custom-entity
></ha-entity-picker>` ></ha-entity-picker>`
: ""} : ""}
${legacy ${shouldRenderServiceDataYaml
? html`<ha-yaml-editor ? html`<ha-yaml-editor
.label=${this.hass.localize( .label=${this.hass.localize(
"ui.components.service-control.service_data" "ui.components.service-control.service_data"
@ -218,8 +221,12 @@ export class HaServiceControl extends LitElement {
.defaultValue=${this.value?.data} .defaultValue=${this.value?.data}
@value-changed=${this._dataChanged} @value-changed=${this._dataChanged}
></ha-yaml-editor>` ></ha-yaml-editor>`
: this._serviceData?.fields.map((dataField) => : serviceData?.fields.map((dataField) =>
dataField.selector && (!dataField.advanced || this.showAdvanced) dataField.selector &&
(!dataField.advanced ||
this.showAdvanced ||
(this.value?.data &&
this.value.data[dataField.key] !== undefined))
? html`<ha-settings-row .narrow=${this.narrow}> ? html`<ha-settings-row .narrow=${this.narrow}>
${dataField.required ${dataField.required
? hasOptional ? hasOptional