From d00467a39c77da4809bee7f368c3ffd25a113b13 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 21 Feb 2023 08:27:56 -0800 Subject: [PATCH] Add `for` to UI for template trigger (#15534) --- src/data/automation.ts | 1 + src/data/automation_i18n.ts | 51 ++++++------ .../types/ha-automation-trigger-template.ts | 80 +++++++++++++------ src/translations/en.json | 3 +- 4 files changed, 82 insertions(+), 53 deletions(-) diff --git a/src/data/automation.ts b/src/data/automation.ts index b3dba670f6..7ac5a88792 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -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 { diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index 564d5bf95d..876e2cbef3 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -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}`; } diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts index 3aa1c02367..b1c85eb460 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts @@ -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` -
- ${this.hass.localize( - "ui.panel.config.automation.editor.triggers.type.template.value_template" - )} - * -
-