Add response variable support to service action (#17046)

This commit is contained in:
Bram Kragten 2023-06-27 19:12:38 +02:00 committed by GitHub
parent 6b4300950d
commit cbe8be1573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 109 additions and 3 deletions

View File

@ -51,6 +51,7 @@ export const serviceActionStruct: Describe<ServiceAction> = assign(
entity_id: optional(string()),
target: optional(targetStruct),
data: optional(object()),
response_variable: optional(string()),
})
);

View File

@ -1,4 +1,11 @@
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
import {
css,
CSSResultGroup,
html,
LitElement,
nothing,
PropertyValues,
} from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { assert } from "superstruct";
@ -21,7 +28,9 @@ export class HaServiceAction extends LitElement implements ActionElement {
@property({ type: Boolean }) public narrow = false;
@state() private _action!: ServiceAction;
@state() private _action?: ServiceAction;
@state() private _responseChecked = false;
private _fields = memoizeOne(
(
@ -98,6 +107,12 @@ export class HaServiceAction extends LitElement implements ActionElement {
}
protected render() {
if (!this._action) {
return nothing;
}
const [domain, service] = this._action.service
? this._action.service.split(".", 2)
: [undefined, undefined];
return html`
<ha-service-control
.narrow=${this.narrow}
@ -107,6 +122,41 @@ export class HaServiceAction extends LitElement implements ActionElement {
.showAdvanced=${this.hass.userData?.showAdvanced}
@value-changed=${this._actionChanged}
></ha-service-control>
${domain && service && this.hass.services[domain]?.[service]?.response
? html`<ha-settings-row .narrow=${this.narrow}>
${this.hass.services[domain][service].response!.optional
? html`<ha-checkbox
.checked=${this._action.response_variable ||
this._responseChecked}
.disabled=${this.disabled}
@change=${this._responseCheckboxChanged}
slot="prefix"
></ha-checkbox>`
: html`<div slot="prefix" class="checkbox-spacer"></div>`}
<span slot="heading"
>${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.service.response_variable"
)}</span
>
<span slot="description">
${this.hass.services[domain][service].response!.optional
? this.hass.localize(
"ui.panel.config.automation.editor.actions.type.service.has_optional_response"
)
: this.hass.localize(
"ui.panel.config.automation.editor.actions.type.service.has_response"
)}
</span>
<ha-textfield
.value=${this._action.response_variable || ""}
.required=${!this.hass.services[domain][service].response!
.optional}
.disabled=${this.disabled ||
(!this._action.response_variable && !this._responseChecked)}
@change=${this._responseVariableChanged}
></ha-textfield>
</ha-settings-row>`
: nothing}
`;
}
@ -114,6 +164,39 @@ export class HaServiceAction extends LitElement implements ActionElement {
if (ev.detail.value === this._action) {
ev.stopPropagation();
}
const value = { ...this.action, ...ev.detail.value };
if ("response_variable" in this.action) {
const [domain, service] = this._action!.service
? this._action!.service.split(".", 2)
: [undefined, undefined];
if (
domain &&
service &&
this.hass.services[domain]?.[service] &&
!("response" in this.hass.services[domain][service])
) {
delete value.response_variable;
this._responseChecked = false;
}
}
fireEvent(this, "value-changed", { value });
}
private _responseVariableChanged(ev) {
const value = { ...this.action, response_variable: ev.target.value };
if (!ev.target.value) {
delete value.response_variable;
}
fireEvent(this, "value-changed", { value });
}
private _responseCheckboxChanged(ev) {
this._responseChecked = ev.target.checked;
if (!this._responseChecked) {
const value = { ...this.action };
delete value.response_variable;
fireEvent(this, "value-changed", { value });
}
}
static get styles(): CSSResultGroup {
@ -122,6 +205,25 @@ export class HaServiceAction extends LitElement implements ActionElement {
display: block;
margin: 0 -16px;
}
ha-settings-row {
margin: 0 -16px;
padding: var(--service-control-padding, 0 16px);
}
ha-settings-row {
--paper-time-input-justify-content: flex-end;
--settings-row-content-width: 100%;
--settings-row-prefix-display: contents;
border-top: var(
--service-control-items-border-top,
1px solid var(--divider-color)
);
}
ha-checkbox {
margin-left: -16px;
}
.checkbox-spacer {
width: 32px;
}
`;
}
}

View File

@ -2567,7 +2567,10 @@
"continue_on_error": "Continue on error",
"type": {
"service": {
"label": "Call service"
"label": "Call service",
"response_variable": "Response variable",
"has_optional_response": "This service can return a response, if you want to use the response, enter the name of a variable the response will be saved in",
"has_response": "This service returns a response, enter the name of a variable the response will be saved in"
},
"play_media": {
"label": "Play media"