Add for to UI for template trigger (#15534)

This commit is contained in:
karwosts 2023-02-21 08:27:56 -08:00 committed by GitHub
parent 4e841c4a06
commit d00467a39c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 53 deletions

View File

@ -146,6 +146,7 @@ export interface TimeTrigger extends BaseTrigger {
export interface TemplateTrigger extends BaseTrigger {
platform: "template";
value_template: string;
for?: string | number | ForDict;
}
export interface EventTrigger extends BaseTrigger {

View File

@ -3,7 +3,7 @@ import secondsToDuration from "../common/datetime/seconds_to_duration";
import { ensureArray } from "../common/array/ensure-array";
import { computeStateName } from "../common/entity/compute_state_name";
import type { HomeAssistant } from "../types";
import { Condition, Trigger } from "./automation";
import { Condition, Trigger, ForDict } from "./automation";
import {
DeviceCondition,
DeviceTrigger,
@ -12,6 +12,18 @@ import {
} from "./device_automation";
import { formatAttributeName } from "./entity_attributes";
const describeDuration = (forTime: number | string | ForDict) => {
let duration: string | null;
if (typeof forTime === "number") {
duration = secondsToDuration(forTime);
} else if (typeof forTime === "string") {
duration = forTime;
} else {
duration = formatDuration(forTime);
}
return duration;
};
export const describeTrigger = (
trigger: Trigger,
hass: HomeAssistant,
@ -73,14 +85,7 @@ export const describeTrigger = (
}
if (trigger.for) {
let duration: string | null;
if (typeof trigger.for === "number") {
duration = secondsToDuration(trigger.for);
} else if (typeof trigger.for === "string") {
duration = trigger.for;
} else {
duration = formatDuration(trigger.for);
}
const duration = describeDuration(trigger.for);
if (duration) {
base += ` for ${duration}`;
}
@ -156,15 +161,7 @@ export const describeTrigger = (
}
if (trigger.for) {
let duration: string | null;
if (typeof trigger.for === "number") {
duration = secondsToDuration(trigger.for);
} else if (typeof trigger.for === "string") {
duration = trigger.for;
} else {
duration = formatDuration(trigger.for);
}
const duration = describeDuration(trigger.for);
if (duration) {
base += ` for ${duration}`;
}
@ -319,7 +316,14 @@ export const describeTrigger = (
// Template Trigger
if (trigger.platform === "template") {
return "When a template triggers";
let base = "When a template triggers";
if (trigger.for) {
const duration = describeDuration(trigger.for);
if (duration) {
base += ` for ${duration}`;
}
}
return base;
}
// Webhook Trigger
@ -440,14 +444,7 @@ export const describeCondition = (
base += ` ${entity} is ${states}`;
if (condition.for) {
let duration: string | null;
if (typeof condition.for === "number") {
duration = secondsToDuration(condition.for);
} else if (typeof condition.for === "string") {
duration = condition.for;
} else {
duration = formatDuration(condition.for);
}
const duration = describeDuration(condition.for);
if (duration) {
base += ` for ${duration}`;
}

View File

@ -1,9 +1,18 @@
import "../../../../../components/ha-textarea";
import { css, html, LitElement } from "lit";
import { html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators";
import type { TemplateTrigger } from "../../../../../data/automation";
import type { HomeAssistant } from "../../../../../types";
import { handleChangeEvent } from "../ha-automation-trigger-row";
import "../../../../../components/ha-form/ha-form";
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { hasTemplate } from "../../../../../common/string/has-template";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
const SCHEMA = [
{ name: "value_template", required: true, selector: { template: {} } },
{ name: "for", selector: { duration: {} } },
] as const;
@customElement("ha-automation-trigger-template")
export class HaTemplateTrigger extends LitElement {
@ -17,39 +26,60 @@ export class HaTemplateTrigger extends LitElement {
return { value_template: "" };
}
public willUpdate(changedProperties: PropertyValues) {
if (!changedProperties.has("trigger")) {
return;
}
// Check for templates in trigger. If found, revert to YAML mode.
if (this.trigger && hasTemplate(this.trigger.for)) {
fireEvent(
this,
"ui-mode-not-available",
Error(this.hass.localize("ui.errors.config.no_template_editor_support"))
);
}
}
protected render() {
const { value_template } = this.trigger;
const trgFor = createDurationData(this.trigger.for);
const data = {
...this.trigger,
for: trgFor,
};
return html`
<p>
${this.hass.localize(
"ui.panel.config.automation.editor.triggers.type.template.value_template"
)}
*
</p>
<ha-code-editor
.name=${"value_template"}
mode="jinja2"
<ha-form
.hass=${this.hass}
.value=${value_template}
.readOnly=${this.disabled}
autocomplete-entities
.data=${data}
.schema=${SCHEMA}
@value-changed=${this._valueChanged}
dir="ltr"
></ha-code-editor>
.computeLabel=${this._computeLabelCallback}
.disabled=${this.disabled}
></ha-form>
`;
}
private _valueChanged(ev: CustomEvent): void {
handleChangeEvent(this, ev);
ev.stopPropagation();
const newTrigger = ev.detail.value;
if (
newTrigger.for &&
Object.values(newTrigger.for).every((value) => value === 0)
) {
delete newTrigger.for;
}
fireEvent(this, "value-changed", { value: newTrigger });
}
static get styles() {
return css`
p {
margin-top: 0;
}
`;
}
private _computeLabelCallback = (
schema: SchemaUnion<typeof SCHEMA>
): string =>
this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.template.${schema.name}`
);
}
declare global {

View File

@ -2129,7 +2129,8 @@
},
"template": {
"label": "Template",
"value_template": "Value template"
"value_template": "Value template",
"for": "For"
},
"time": {
"type_value": "Fixed time",