From 4761036816231b768b2180c9cd4dd3dcd60b753e Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 18:28:53 +0200 Subject: [PATCH] Show if script is unavailable and why (#17051) --- src/panels/config/script/ha-script-editor.ts | 81 ++++++++++++++------ src/panels/config/script/ha-script-picker.ts | 10 ++- 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 73f9104dbf..a64a53b9fa 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -60,6 +60,8 @@ import { documentationUrl } from "../../../util/documentation-url"; import { showToast } from "../../../util/toast"; import "./blueprint-script-editor"; import "./manual-script-editor"; +import { UNAVAILABLE } from "../../../data/entity"; +import { validateConfig } from "../../../data/config"; export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @property({ attribute: false }) public hass!: HomeAssistant; @@ -92,6 +94,8 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @query("ha-yaml-editor", true) private _yamlEditor?: HaYamlEditor; + @state() private _validationErrors?: (string | TemplateResult)[]; + private _schema = memoizeOne( ( hasID: boolean, @@ -160,6 +164,10 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { return nothing; } + const stateObj = this._entityId + ? this.hass.states[this._entityId] + : undefined; + const useBlueprint = "use_blueprint" in this._config; const schema = this._schema( @@ -302,6 +310,26 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { "yaml-mode": this._mode === "yaml", })}" > + ${this._errors || stateObj?.state === UNAVAILABLE + ? html` + + ${this._errors || this._validationErrors} + + ` + : ""} + ${this._readOnly + ? html` + ${this.hass.localize("ui.panel.config.script.editor.read_only")} + + ${this.hass.localize("ui.panel.config.script.editor.migrate")} + + ` + : ""} ${this._mode === "gui" ? html`
- ${this._errors - ? html` - - ${this._errors} - - ` - : ""}
- ${this.hass.localize( - "ui.panel.config.script.editor.read_only" - )} - - ${this.hass.localize( - "ui.panel.config.script.editor.migrate" - )} - - ` - : ""} - ${this._errors - ? html` - ${this._errors} - ` - : ""} + ent.platform === "script" && ent.unique_id === this.scriptId + ); + this._entityId = entity?.entity_id; + this._checkValidation(); }, (resp) => { const entity = this.entityRegistry.find( @@ -479,6 +489,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { if (changedProps.has("entityId") && this.entityId) { getScriptStateConfig(this.hass, this.entityId).then((c) => { this._config = this._normalizeConfig(c.config); + this._checkValidation(); }); const regEntry = this.entityRegistry.find( (ent) => ent.entity_id === this.entityId @@ -502,6 +513,28 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { return config; } + private async _checkValidation() { + this._validationErrors = undefined; + if (!this._entityId || !this._config) { + return; + } + const stateObj = this.hass.states[this._entityId]; + if (stateObj?.state !== UNAVAILABLE) { + return; + } + const validation = await validateConfig(this.hass, { + action: this._config.sequence, + }); + this._validationErrors = Object.entries(validation).map(([key, value]) => + value.valid + ? "" + : html`${this.hass.localize( + `ui.panel.config.automation.editor.${key}s.header` + )}: + ${value.error}
` + ); + } + private _computeLabelCallback = ( schema: SchemaUnion>, data: HaFormDataContainer diff --git a/src/panels/config/script/ha-script-picker.ts b/src/panels/config/script/ha-script-picker.ts index 491d13599d..7433bb98e5 100644 --- a/src/panels/config/script/ha-script-picker.ts +++ b/src/panels/config/script/ha-script-picker.ts @@ -12,6 +12,7 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { differenceInDays } from "date-fns/esm"; +import { styleMap } from "lit/directives/style-map"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { formatShortDateTime } from "../../../common/datetime/format_date_time"; import { relativeTime } from "../../../common/datetime/relative_time"; @@ -49,6 +50,7 @@ import { showNewAutomationDialog } from "../automation/show-dialog-new-automatio import { EntityRegistryEntry } from "../../../data/entity_registry"; import { findRelated } from "../../../data/search"; import { fetchBlueprints } from "../../../data/blueprint"; +import { UNAVAILABLE } from "../../../data/entity"; @customElement("ha-script-picker") class HaScriptPicker extends LitElement { @@ -100,7 +102,13 @@ class HaScriptPicker extends LitElement { ), type: "icon", template: (_icon, script) => - html``, + html``, }, name: { title: this.hass.localize("ui.panel.config.script.picker.headers.name"),