From 9e900b5fdd5aeb81c23e79a8fcccced942db02cc Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 24 Jun 2024 13:35:10 +0200 Subject: [PATCH 1/6] substituteBlueprint --- src/data/automation.ts | 16 +++++++++++++- src/data/blueprint.ts | 13 ++++++++++++ .../automation/blueprint-automation-editor.ts | 21 +++++++++++++++++-- .../config/automation/ha-automation-editor.ts | 17 +++------------ 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/data/automation.ts b/src/data/automation.ts index 4b5292b2138e..6e04358cb8f3 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -352,8 +352,22 @@ export const saveAutomationConfig = ( config: AutomationConfig ) => hass.callApi("POST", `config/automation/config/${id}`, config); +export const normalizeAutomationConfig = ( + config: AutomationConfig +): AutomationConfig => { + // Normalize data: ensure trigger, action and condition are lists + // Happens when people copy paste their automations into the config + for (const key of ["trigger", "condition", "action"]) { + const value = config[key]; + if (value && !Array.isArray(value)) { + config[key] = [value]; + } + } + return config; +}; + export const showAutomationEditor = (data?: Partial) => { - initialAutomationEditorData = data; + initialAutomationEditorData = normalizeAutomationConfig(data); navigate("/config/automation/edit/new"); }; diff --git a/src/data/blueprint.ts b/src/data/blueprint.ts index 222da542af7a..1e450707bb09 100644 --- a/src/data/blueprint.ts +++ b/src/data/blueprint.ts @@ -91,3 +91,16 @@ export const getBlueprintSourceType = ( } return "community"; }; + +export const substituteBlueprint = ( + hass: HomeAssistant, + domain: BlueprintDomain, + path: string, + input: Record +) => + hass.callWS({ + type: "blueprint/substitute", + domain, + path, + input, + }); diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index 83a7c7bb991a..0d3ead939aaf 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -3,8 +3,11 @@ import { HassEntity } from "home-assistant-js-websocket"; import { html, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import "../../../components/ha-alert"; -import { BlueprintAutomationConfig } from "../../../data/automation"; -import { fetchBlueprints } from "../../../data/blueprint"; +import { + BlueprintAutomationConfig, + showAutomationEditor, +} from "../../../data/automation"; +import { fetchBlueprints, substituteBlueprint } from "../../../data/blueprint"; import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor"; import "../../../components/ha-markdown"; @@ -65,6 +68,20 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor { entity_id: this.stateObj.entity_id, }); } + + private async _substituteBlueprint(): Promise { + const substitute = await substituteBlueprint( + this.hass, + "automation", + this.config.use_blueprint.path, + this.config.use_blueprint.input || {} + ); + showAutomationEditor({ + alias: this.config.alias, + description: `${this.config.description ? this.config.description : this._blueprint?.metadata.description} (Originated from blueprint ${this._blueprint?.metadata.name})`, + ...substitute.substituted_config, + }); + } } declare global { interface HTMLElementTagNameMap { diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 0cfac00e717b..89b7f573efb3 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -44,6 +44,7 @@ import { fetchAutomationFileConfig, getAutomationEditorInitData, getAutomationStateConfig, + normalizeAutomationConfig, saveAutomationConfig, showAutomationEditor, triggerAutomationActions, @@ -441,7 +442,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { if (changedProps.has("entityId") && this.entityId) { getAutomationStateConfig(this.hass, this.entityId).then((c) => { - this._config = this._normalizeConfig(c.config); + this._config = normalizeAutomationConfig(c.config); this._checkValidation(); }); this._entityId = this.entityId; @@ -497,18 +498,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ); } - private _normalizeConfig(config: AutomationConfig): AutomationConfig { - // Normalize data: ensure trigger, action and condition are lists - // Happens when people copy paste their automations into the config - for (const key of ["trigger", "condition", "action"]) { - const value = config[key]; - if (value && !Array.isArray(value)) { - config[key] = [value]; - } - } - return config; - } - private async _loadConfig() { try { const config = await fetchAutomationFileConfig( @@ -517,7 +506,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ); this._dirty = false; this._readOnly = false; - this._config = this._normalizeConfig(config); + this._config = normalizeAutomationConfig(config); this._checkValidation(); } catch (err: any) { const entityRegistry = await fetchEntityRegistry(this.hass.connection); From b369e0561cb85e27b4cbc177aa43b0428b31f85f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 24 Jun 2024 14:54:31 +0200 Subject: [PATCH 2/6] WIP ux --- src/data/automation.ts | 10 +-- src/data/blueprint.ts | 7 +- .../automation/blueprint-automation-editor.ts | 72 +++++++++++++++---- .../config/automation/ha-automation-editor.ts | 23 +++++- .../automation/manual-automation-editor.ts | 4 +- .../blueprint/blueprint-generic-editor.ts | 2 + src/translations/en.json | 1 + 7 files changed, 98 insertions(+), 21 deletions(-) diff --git a/src/data/automation.ts b/src/data/automation.ts index 6e04358cb8f3..ea20b874c811 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -352,9 +352,11 @@ export const saveAutomationConfig = ( config: AutomationConfig ) => hass.callApi("POST", `config/automation/config/${id}`, config); -export const normalizeAutomationConfig = ( - config: AutomationConfig -): AutomationConfig => { +export const normalizeAutomationConfig = < + T extends Partial | AutomationConfig, +>( + config: T +): T => { // Normalize data: ensure trigger, action and condition are lists // Happens when people copy paste their automations into the config for (const key of ["trigger", "condition", "action"]) { @@ -367,7 +369,7 @@ export const normalizeAutomationConfig = ( }; export const showAutomationEditor = (data?: Partial) => { - initialAutomationEditorData = normalizeAutomationConfig(data); + initialAutomationEditorData = data; navigate("/config/automation/edit/new"); }; diff --git a/src/data/blueprint.ts b/src/data/blueprint.ts index 1e450707bb09..52163542315a 100644 --- a/src/data/blueprint.ts +++ b/src/data/blueprint.ts @@ -1,4 +1,5 @@ import { HomeAssistant } from "../types"; +import { ManualAutomationConfig } from "./automation"; import { Selector } from "./selector"; export type BlueprintDomain = "automation" | "script"; @@ -42,6 +43,10 @@ export interface BlueprintImportResult { validation_errors: string[] | null; } +export interface BlueprintSubstituteResult { + substituted_config: ManualAutomationConfig; +} + export const fetchBlueprints = (hass: HomeAssistant, domain: BlueprintDomain) => hass.callWS({ type: "blueprint/list", domain }); @@ -98,7 +103,7 @@ export const substituteBlueprint = ( path: string, input: Record ) => - hass.callWS({ + hass.callWS({ type: "blueprint/substitute", domain, path, diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index 0d3ead939aaf..799fdc1c5def 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -2,14 +2,19 @@ import "@material/mwc-button/mwc-button"; import { HassEntity } from "home-assistant-js-websocket"; import { html, nothing } from "lit"; import { customElement, property } from "lit/decorators"; +import { navigate } from "../../../common/navigate"; +import { nextRender } from "../../../common/util/render-status"; import "../../../components/ha-alert"; +import "../../../components/ha-markdown"; import { BlueprintAutomationConfig, + normalizeAutomationConfig, showAutomationEditor, } from "../../../data/automation"; import { fetchBlueprints, substituteBlueprint } from "../../../data/blueprint"; +import { showConfirmationDialog } from "../../lovelace/custom-card-helpers"; import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor"; -import "../../../components/ha-markdown"; +import "./manual-automation-editor"; @customElement("blueprint-automation-editor") export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor { @@ -69,18 +74,59 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor { }); } - private async _substituteBlueprint(): Promise { - const substitute = await substituteBlueprint( - this.hass, - "automation", - this.config.use_blueprint.path, - this.config.use_blueprint.input || {} - ); - showAutomationEditor({ - alias: this.config.alias, - description: `${this.config.description ? this.config.description : this._blueprint?.metadata.description} (Originated from blueprint ${this._blueprint?.metadata.name})`, - ...substitute.substituted_config, - }); + public async substituteBlueprint(): Promise { + try { + const substitute = await substituteBlueprint( + this.hass, + "automation", + this.config.use_blueprint.path, + this.config.use_blueprint.input || {} + ); + + const config = normalizeAutomationConfig(substitute.substituted_config); + + const convert = await showConfirmationDialog(this, { + title: "Take control of blueprint automation", + text: html``, + confirmText: "Create automation", + }); + + if (convert) { + if (this.dirty) { + const confirmed = await showConfirmationDialog(this, { + title: "Unsaved changes", + text: "You have unsaved changes. Do you want to continue and lose these changes?", + confirmText: "Continue", + }); + if (!confirmed) { + return; + } + } + while ( + location.pathname === "/config/automation/edit/new" && + history.length > 1 + ) { + history.back(); + // eslint-disable-next-line no-await-in-loop + await nextRender(); + } + if (location.pathname === "/config/automation/edit/new") { + navigate("/config/automation"); + await nextRender(); + } + showAutomationEditor({ + alias: this.config.alias, + description: `${this.config.description ? this.config.description : this._blueprint && "metadata" in this._blueprint ? this._blueprint.metadata.description : ""}${this._blueprint && "metadata" in this._blueprint ? `(Originated from blueprint ${this._blueprint?.metadata.name})` : ""}`, + ...substitute.substituted_config, + }); + } + } catch (err: any) { + alert(`Failed to substitute blueprint: ${err.message}`); + } } } declare global { diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 89b7f573efb3..30dccd80551c 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -6,6 +6,7 @@ import { mdiDebugStepOver, mdiDelete, mdiDotsVertical, + mdiFileEdit, mdiInformationOutline, mdiPlay, mdiPlayCircleOutline, @@ -218,7 +219,16 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { > ` - : nothing} + : html` + ${this.hass.localize( + "ui.panel.config.automation.editor.subtitute_blueprint" + )} + + `} @@ -344,6 +355,8 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { .stateObj=${stateObj} .config=${this._config} .disabled=${Boolean(this._readOnly)} + .readOnly=${Boolean(this._readOnly)} + .dirty=${this._dirty} @value-changed=${this._valueChanged} @duplicate=${this._duplicate} > @@ -433,7 +446,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { } this._config = { ...baseConfig, - ...initData, + ...(initData ? normalizeAutomationConfig(initData) : initData), } as AutomationConfig; this._entityId = undefined; this._readOnly = false; @@ -627,6 +640,12 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { } }; + private _substituteBlueprint() { + this.renderRoot + .querySelector("blueprint-automation-editor") + ?.substituteBlueprint(); + } + private async _duplicate() { const result = this._readOnly ? await showConfirmationDialog(this, { diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index ceb4da52e033..fcfdb0d74a44 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -32,13 +32,15 @@ export class HaManualAutomationEditor extends LitElement { @property({ type: Boolean }) public disabled = false; + @property({ type: Boolean }) public readOnly = false; + @property({ attribute: false }) public config!: ManualAutomationConfig; @property({ attribute: false }) public stateObj?: HassEntity; protected render() { return html` - ${this.disabled + ${this.readOnly ? html` ${this.hass.localize("ui.panel.config.automation.editor.read_only")} diff --git a/src/panels/config/blueprint/blueprint-generic-editor.ts b/src/panels/config/blueprint/blueprint-generic-editor.ts index bae63f6dc7e3..640f4727866b 100644 --- a/src/panels/config/blueprint/blueprint-generic-editor.ts +++ b/src/panels/config/blueprint/blueprint-generic-editor.ts @@ -29,6 +29,8 @@ export abstract class HaBlueprintGenericEditor extends LitElement { @property({ type: Boolean }) public disabled = false; + @property({ type: Boolean }) public dirty = false; + @property({ type: Boolean, reflect: true }) public narrow = false; @state() protected _blueprints?: Blueprints; diff --git a/src/translations/en.json b/src/translations/en.json index e5a7b264ce26..9a5f4d015247 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2759,6 +2759,7 @@ "unavailable": "Automation is unavailable", "migrate": "Migrate", "duplicate": "[%key:ui::common::duplicate%]", + "subtitute_blueprint": "Take control of automation", "run": "[%key:ui::panel::config::automation::editor::actions::run%]", "rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]", "show_trace": "Traces", From 643cc491d51db83cb2eaaa4729125fbbc36fd879 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 25 Jun 2024 18:21:14 +0200 Subject: [PATCH 3/6] Simplify feature --- .../automation/blueprint-automation-editor.ts | 66 +------------------ .../config/automation/ha-automation-editor.ts | 60 ++++++++++++----- .../automation/manual-automation-editor.ts | 4 +- .../blueprint/blueprint-generic-editor.ts | 2 - src/translations/en.json | 2 +- 5 files changed, 47 insertions(+), 87 deletions(-) diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index 799fdc1c5def..90fe16a13070 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -2,17 +2,10 @@ import "@material/mwc-button/mwc-button"; import { HassEntity } from "home-assistant-js-websocket"; import { html, nothing } from "lit"; import { customElement, property } from "lit/decorators"; -import { navigate } from "../../../common/navigate"; -import { nextRender } from "../../../common/util/render-status"; import "../../../components/ha-alert"; import "../../../components/ha-markdown"; -import { - BlueprintAutomationConfig, - normalizeAutomationConfig, - showAutomationEditor, -} from "../../../data/automation"; -import { fetchBlueprints, substituteBlueprint } from "../../../data/blueprint"; -import { showConfirmationDialog } from "../../lovelace/custom-card-helpers"; +import { BlueprintAutomationConfig } from "../../../data/automation"; +import { fetchBlueprints } from "../../../data/blueprint"; import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor"; import "./manual-automation-editor"; @@ -73,61 +66,6 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor { entity_id: this.stateObj.entity_id, }); } - - public async substituteBlueprint(): Promise { - try { - const substitute = await substituteBlueprint( - this.hass, - "automation", - this.config.use_blueprint.path, - this.config.use_blueprint.input || {} - ); - - const config = normalizeAutomationConfig(substitute.substituted_config); - - const convert = await showConfirmationDialog(this, { - title: "Take control of blueprint automation", - text: html``, - confirmText: "Create automation", - }); - - if (convert) { - if (this.dirty) { - const confirmed = await showConfirmationDialog(this, { - title: "Unsaved changes", - text: "You have unsaved changes. Do you want to continue and lose these changes?", - confirmText: "Continue", - }); - if (!confirmed) { - return; - } - } - while ( - location.pathname === "/config/automation/edit/new" && - history.length > 1 - ) { - history.back(); - // eslint-disable-next-line no-await-in-loop - await nextRender(); - } - if (location.pathname === "/config/automation/edit/new") { - navigate("/config/automation"); - await nextRender(); - } - showAutomationEditor({ - alias: this.config.alias, - description: `${this.config.description ? this.config.description : this._blueprint && "metadata" in this._blueprint ? this._blueprint.metadata.description : ""}${this._blueprint && "metadata" in this._blueprint ? `(Originated from blueprint ${this._blueprint?.metadata.name})` : ""}`, - ...substitute.substituted_config, - }); - } - } catch (err: any) { - alert(`Failed to substitute blueprint: ${err.message}`); - } - } } declare global { interface HTMLElementTagNameMap { diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 30dccd80551c..f2d39862c6b3 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -41,6 +41,7 @@ import "../../../components/ha-yaml-editor"; import { AutomationConfig, AutomationEntity, + BlueprintAutomationConfig, deleteAutomation, fetchAutomationFileConfig, getAutomationEditorInitData, @@ -67,6 +68,7 @@ import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-a import { showAutomationRenameDialog } from "./automation-rename-dialog/show-dialog-automation-rename"; import "./blueprint-automation-editor"; import "./manual-automation-editor"; +import { substituteBlueprint } from "../../../data/blueprint"; declare global { interface HTMLElementTagNameMap { @@ -219,16 +221,21 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { > ` - : html` - ${this.hass.localize( - "ui.panel.config.automation.editor.subtitute_blueprint" - )} - - `} + : html` + + ${this.hass.localize( + "ui.panel.config.automation.editor.take_control" + )} + + + `} @@ -355,8 +361,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { .stateObj=${stateObj} .config=${this._config} .disabled=${Boolean(this._readOnly)} - .readOnly=${Boolean(this._readOnly)} - .dirty=${this._dirty} @value-changed=${this._valueChanged} @duplicate=${this._duplicate} > @@ -640,10 +644,32 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { } }; - private _substituteBlueprint() { - this.renderRoot - .querySelector("blueprint-automation-editor") - ?.substituteBlueprint(); + private async _takeControl() { + const config = this._config as BlueprintAutomationConfig; + + const confirmation = await showConfirmationDialog(this, { + title: "Take control of automation?", + text: "This automation is using a blueprint. By taking control, you will be able to edit it directly. Are you sure you want to take control?", + }); + + if (!confirmation) return; + + const result = await substituteBlueprint( + this.hass, + "automation", + config.use_blueprint.path, + config.use_blueprint.input || {} + ); + + const newConfig = { + alias: config.alias, + description: config.description, + ...normalizeAutomationConfig(result.substituted_config), + }; + + this._config = newConfig; + this._dirty = true; + this._errors = undefined; } private async _duplicate() { diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index fcfdb0d74a44..ceb4da52e033 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -32,15 +32,13 @@ export class HaManualAutomationEditor extends LitElement { @property({ type: Boolean }) public disabled = false; - @property({ type: Boolean }) public readOnly = false; - @property({ attribute: false }) public config!: ManualAutomationConfig; @property({ attribute: false }) public stateObj?: HassEntity; protected render() { return html` - ${this.readOnly + ${this.disabled ? html` ${this.hass.localize("ui.panel.config.automation.editor.read_only")} diff --git a/src/panels/config/blueprint/blueprint-generic-editor.ts b/src/panels/config/blueprint/blueprint-generic-editor.ts index 640f4727866b..bae63f6dc7e3 100644 --- a/src/panels/config/blueprint/blueprint-generic-editor.ts +++ b/src/panels/config/blueprint/blueprint-generic-editor.ts @@ -29,8 +29,6 @@ export abstract class HaBlueprintGenericEditor extends LitElement { @property({ type: Boolean }) public disabled = false; - @property({ type: Boolean }) public dirty = false; - @property({ type: Boolean, reflect: true }) public narrow = false; @state() protected _blueprints?: Blueprints; diff --git a/src/translations/en.json b/src/translations/en.json index 9a5f4d015247..8b1b3fd453a5 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2759,7 +2759,7 @@ "unavailable": "Automation is unavailable", "migrate": "Migrate", "duplicate": "[%key:ui::common::duplicate%]", - "subtitute_blueprint": "Take control of automation", + "take_control": "Take control", "run": "[%key:ui::panel::config::automation::editor::actions::run%]", "rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]", "show_trace": "Traces", From 88abea4e5e541cd287144c0b06a25bb8860d29aa Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 26 Jun 2024 10:12:20 +0200 Subject: [PATCH 4/6] Add take control to scripts --- src/data/blueprint.ts | 14 ++++-- .../config/automation/ha-automation-editor.ts | 9 ++-- src/panels/config/script/ha-script-editor.ts | 48 +++++++++++++++++++ src/translations/en.json | 1 + 4 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/data/blueprint.ts b/src/data/blueprint.ts index 52163542315a..a0e9f2562da3 100644 --- a/src/data/blueprint.ts +++ b/src/data/blueprint.ts @@ -1,5 +1,6 @@ import { HomeAssistant } from "../types"; import { ManualAutomationConfig } from "./automation"; +import { ManualScriptConfig } from "./script"; import { Selector } from "./selector"; export type BlueprintDomain = "automation" | "script"; @@ -43,8 +44,9 @@ export interface BlueprintImportResult { validation_errors: string[] | null; } -export interface BlueprintSubstituteResult { - substituted_config: ManualAutomationConfig; +export interface BlueprintSubstituteResults { + automation: { substituted_config: ManualAutomationConfig }; + script: { substituted_config: ManualScriptConfig }; } export const fetchBlueprints = (hass: HomeAssistant, domain: BlueprintDomain) => @@ -97,13 +99,15 @@ export const getBlueprintSourceType = ( return "community"; }; -export const substituteBlueprint = ( +export const substituteBlueprint = < + T extends BlueprintDomain = BlueprintDomain, +>( hass: HomeAssistant, - domain: BlueprintDomain, + domain: T, path: string, input: Record ) => - hass.callWS({ + hass.callWS({ type: "blueprint/substitute", domain, path, diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index f2d39862c6b3..ef6aa5bb0b9c 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -221,7 +221,9 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { > ` - : html` + : nothing} + ${useBlueprint + ? html` - `} + ` + : nothing} ` : nothing} + ${useBlueprint + ? html` + + ${this.hass.localize( + "ui.panel.config.script.editor.take_control" + )} + + + ` + : nothing} Date: Wed, 26 Jun 2024 10:28:33 +0200 Subject: [PATCH 5/6] Add translations and catch error --- .../config/automation/ha-automation-editor.ts | 76 +++++++++++-------- src/panels/config/script/ha-script-editor.ts | 76 +++++++++++-------- src/translations/en.json | 10 +++ 3 files changed, 98 insertions(+), 64 deletions(-) diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index ef6aa5bb0b9c..939c00af531c 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -222,6 +222,23 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ` : nothing} + + + ${this.hass.localize( + this._readOnly + ? "ui.panel.config.automation.editor.migrate" + : "ui.panel.config.automation.editor.duplicate" + )} + + + ${useBlueprint ? html` - ${this.hass.localize( - this._readOnly - ? "ui.panel.config.automation.editor.migrate" - : "ui.panel.config.automation.editor.duplicate" - )} - - -
  • @@ -651,28 +652,39 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { const config = this._config as BlueprintAutomationConfig; const confirmation = await showConfirmationDialog(this, { - title: "Take control of automation?", - text: "This automation is using a blueprint. By taking control, you will be able to edit it directly. Are you sure you want to take control?", + title: this.hass!.localize( + "ui.panel.config.automation.editor.take_control_confirmation.title" + ), + text: this.hass!.localize( + "ui.panel.config.automation.editor.take_control_confirmation.text" + ), + confirmText: this.hass!.localize( + "ui.panel.config.automation.editor.take_control_confirmation.action" + ), }); if (!confirmation) return; - const result = await substituteBlueprint( - this.hass, - "automation", - config.use_blueprint.path, - config.use_blueprint.input || {} - ); + try { + const result = await substituteBlueprint( + this.hass, + "automation", + config.use_blueprint.path, + config.use_blueprint.input || {} + ); - const newConfig = { - ...normalizeAutomationConfig(result.substituted_config), - alias: config.alias, - description: config.description, - }; + const newConfig = { + ...normalizeAutomationConfig(result.substituted_config), + alias: config.alias, + description: config.description, + }; - this._config = newConfig; - this._dirty = true; - this._errors = undefined; + this._config = newConfig; + this._dirty = true; + this._errors = undefined; + } catch (err: any) { + this._errors = err.message; + } } private async _duplicate() { diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index db2ab9510f72..c11a0dc524eb 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -214,6 +214,23 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ` : nothing} + + + ${this.hass.localize( + this._readOnly + ? "ui.panel.config.script.editor.migrate" + : "ui.panel.config.script.editor.duplicate" + )} + + + ${useBlueprint ? html` - ${this.hass.localize( - this._readOnly - ? "ui.panel.config.script.editor.migrate" - : "ui.panel.config.script.editor.duplicate" - )} - - -
  • @@ -625,28 +626,39 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { const config = this._config as BlueprintScriptConfig; const confirmation = await showConfirmationDialog(this, { - title: "Take control of automation?", - text: "This automation is using a blueprint. By taking control, you will be able to edit it directly. Are you sure you want to take control?", + title: this.hass!.localize( + "ui.panel.config.script.editor.take_control_confirmation.title" + ), + text: this.hass!.localize( + "ui.panel.config.script.editor.take_control_confirmation.text" + ), + confirmText: this.hass!.localize( + "ui.panel.config.script.editor.take_control_confirmation.action" + ), }); if (!confirmation) return; - const result = await substituteBlueprint( - this.hass, - "script", - config.use_blueprint.path, - config.use_blueprint.input || {} - ); + try { + const result = await substituteBlueprint( + this.hass, + "script", + config.use_blueprint.path, + config.use_blueprint.input || {} + ); - const newConfig = { - ...this._normalizeConfig(result.substituted_config), - alias: config.alias, - description: config.description, - }; + const newConfig = { + ...this._normalizeConfig(result.substituted_config), + alias: config.alias, + description: config.description, + }; - this._config = newConfig; - this._dirty = true; - this._errors = undefined; + this._config = newConfig; + this._dirty = true; + this._errors = undefined; + } catch (err: any) { + this._errors = err.message; + } } private async _duplicate() { diff --git a/src/translations/en.json b/src/translations/en.json index 630d21a37d68..fb5d2927c3df 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2760,6 +2760,11 @@ "migrate": "Migrate", "duplicate": "[%key:ui::common::duplicate%]", "take_control": "Take control", + "take_control_confirmation": { + "title": "Take control of automation?", + "text": "This automation is using a blueprint. By taking control, your automation will be converted into a regular automation using triggers, conditions and actions. You will be able to edit it directly and you won't be able to convert it back to a blueprint.", + "action": "Take control" + }, "run": "[%key:ui::panel::config::automation::editor::actions::run%]", "rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]", "show_trace": "Traces", @@ -3631,6 +3636,11 @@ "rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]", "change_mode": "[%key:ui::panel::config::automation::editor::change_mode%]", "take_control": "[%key:ui::panel::config::automation::editor::take_control%]", + "take_control_confirmation": { + "title": "Take control of script?", + "text": "This script is using a blueprint. By taking control, your script will be converted into a regular automation using actions. You will be able to edit it directly and you won't be able to convert it back to a blueprint.", + "action": "[%key:ui::panel::config::automation::editor::take_control_confirmation::action%]" + }, "read_only": "This script cannot be edited from the UI, because it is not stored in the ''scripts.yaml'' file.", "unavailable": "Script is unavailable", "migrate": "Migrate", From ed91c9d358b9e576c6e32f03a11c6fc74b1f8672 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 26 Jun 2024 10:46:46 +0200 Subject: [PATCH 6/6] Clean import --- src/panels/config/automation/blueprint-automation-editor.ts | 1 - src/panels/config/script/blueprint-script-editor.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index 90fe16a13070..959230be5f97 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -7,7 +7,6 @@ import "../../../components/ha-markdown"; import { BlueprintAutomationConfig } from "../../../data/automation"; import { fetchBlueprints } from "../../../data/blueprint"; import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor"; -import "./manual-automation-editor"; @customElement("blueprint-automation-editor") export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor { diff --git a/src/panels/config/script/blueprint-script-editor.ts b/src/panels/config/script/blueprint-script-editor.ts index ba388f5e0d75..bc7b624a0cb3 100644 --- a/src/panels/config/script/blueprint-script-editor.ts +++ b/src/panels/config/script/blueprint-script-editor.ts @@ -2,10 +2,10 @@ import "@material/mwc-button/mwc-button"; import { html, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import "../../../components/ha-alert"; -import { BlueprintScriptConfig } from "../../../data/script"; +import "../../../components/ha-markdown"; import { fetchBlueprints } from "../../../data/blueprint"; +import { BlueprintScriptConfig } from "../../../data/script"; import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor"; -import "../../../components/ha-markdown"; @customElement("blueprint-script-editor") export class HaBlueprintScriptEditor extends HaBlueprintGenericEditor {