diff --git a/src/components/ha-yaml-editor.ts b/src/components/ha-yaml-editor.ts index 3666fb09ea..4d2f4c2c59 100644 --- a/src/components/ha-yaml-editor.ts +++ b/src/components/ha-yaml-editor.ts @@ -105,6 +105,10 @@ export class HaYamlEditor extends LitElement { fireEvent(this, "value-changed", { value: parsed, isValid } as any); } + + get yaml() { + return this._editor?.value; + } } declare global { diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 72bfc2ced1..19fffa0298 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -1,5 +1,6 @@ import "@material/mwc-fab"; import { + mdiCheck, mdiContentDuplicate, mdiContentSave, mdiDelete, @@ -21,6 +22,7 @@ import { property, PropertyValues, TemplateResult, + query, } from "lit-element"; import { classMap } from "lit-html/directives/class-map"; import { navigate } from "../../../common/navigate"; @@ -28,6 +30,8 @@ import "../../../components/ha-button-menu"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; +import "../../../components/ha-yaml-editor"; +import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; import { AutomationConfig, AutomationEntity, @@ -89,6 +93,10 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { @internalProperty() private _entityId?: string; + @internalProperty() private _mode: "gui" | "yaml" = "gui"; + + @query("ha-yaml-editor", true) private _editor?: HaYamlEditor; + protected render(): TemplateResult { const stateObj = this._entityId ? this.hass.states[this._entityId] @@ -105,6 +113,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { corner="BOTTOM_START" slot="toolbar-icon" @action=${this._handleMenuAction} + activatable > + + ${this.hass.localize("ui.panel.config.automation.editor.edit_ui")} + ${this._mode === "gui" + ? html`` + : ``} + + + ${this.hass.localize("ui.panel.config.automation.editor.edit_yaml")} + ${this._mode === "yaml" + ? html`` + : ``} + + +
  • + ${this._errors} ` : ""} - - ${!this.narrow - ? html` ${this._config.alias} ` - : ""} - - ${this.hass.localize( - "ui.panel.config.automation.editor.introduction" - )} - - -
    - - - -

    - ${this.hass.localize( - "ui.panel.config.automation.editor.modes.description", - "documentation_link", - html` + ${!this.narrow + ? html` + ${this._config.alias} + ` + : ""} + + ${this.hass.localize( + "ui.panel.config.automation.editor.introduction" + )} + + +

    + + + +

    + ${this.hass.localize( + "ui.panel.config.automation.editor.modes.description", + "documentation_link", + html`${this.hass.localize( + "ui.panel.config.automation.editor.modes.documentation" + )}` + )} +

    + + + ${MODES.map( + (mode) => html` + + ${this.hass.localize( + `ui.panel.config.automation.editor.modes.${mode}` + ) || mode} + + ` + )} + + + ${this._config.mode && + MODES_MAX.includes(this._config.mode) + ? html` + ` + : html``} +
    + ${stateObj + ? html` +
    +
    + + ${this.hass.localize( + "ui.panel.config.automation.editor.enable_disable" + )} +
    + + ${this.hass.localize( + "ui.card.automation.trigger" + )} + +
    + ` + : ""} + + + + + + ${this.hass.localize( + "ui.panel.config.automation.editor.triggers.header" + )} + + +

    + ${this.hass.localize( + "ui.panel.config.automation.editor.triggers.introduction" + )} +

    + ${this.hass.localize( - "ui.panel.config.automation.editor.modes.documentation" - )}` - )} -

    - - - ${MODES.map( - (mode) => html` - - ${this.hass.localize( - `ui.panel.config.automation.editor.modes.${mode}` - ) || mode} - - ` - )} - - - ${this._config.mode && - MODES_MAX.includes(this._config.mode) - ? html` + ${this.hass.localize( + "ui.panel.config.automation.editor.triggers.learn_more" )} - type="number" - name="max" - .value=${this._config.max || "10"} - @value-changed=${this._valueChanged} + +
    + +
    + + + + ${this.hass.localize( + "ui.panel.config.automation.editor.conditions.header" + )} + + +

    + ${this.hass.localize( + "ui.panel.config.automation.editor.conditions.introduction" + )} +

    + - ` - : html``} -
    - ${stateObj - ? html` -
    + + + + + + + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.header" + )} + + +

    + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.introduction" + )} +

    +
    -
    - + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.learn_more" + )} + + + + + ` + : this._mode === "yaml" + ? html` + + ${!this.narrow + ? html` + ${this._config.alias} + ` + : ``} + +
    + + ${this.hass.localize( - "ui.panel.config.automation.editor.enable_disable" - )} -
    - - ${this.hass.localize( - "ui.card.automation.trigger" + "ui.panel.config.automation.editor.copy_to_clipboard" )}
    - ` - : ""} - - - - - - ${this.hass.localize( - "ui.panel.config.automation.editor.triggers.header" - )} - - -

    - ${this.hass.localize( - "ui.panel.config.automation.editor.triggers.introduction" - )} -

    - - ${this.hass.localize( - "ui.panel.config.automation.editor.triggers.learn_more" - )} - -
    - -
    - - - - ${this.hass.localize( - "ui.panel.config.automation.editor.conditions.header" - )} - - -

    - ${this.hass.localize( - "ui.panel.config.automation.editor.conditions.introduction" - )} -

    - - ${this.hass.localize( - "ui.panel.config.automation.editor.conditions.learn_more" - )} - -
    - -
    - - - - ${this.hass.localize( - "ui.panel.config.automation.editor.actions.header" - )} - - -

    - ${this.hass.localize( - "ui.panel.config.automation.editor.actions.introduction" - )} -

    - - ${this.hass.localize( - "ui.panel.config.automation.editor.actions.learn_more" - )} - -
    - -
    + ${stateObj + ? html` +
    +
    + + ${this.hass.localize( + "ui.panel.config.automation.editor.enable_disable" + )} +
    + + ${this.hass.localize( + "ui.card.automation.trigger" + )} + +
    + ` + : ""} + + + ` + : ``}
    ` : ""} @@ -512,6 +609,33 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { triggerAutomation(this.hass, (ev.target as any).stateObj.entity_id); } + private _preprocessYaml() { + const cleanConfig = this._config; + if (!cleanConfig) { + return {}; + } + + delete cleanConfig.id; + + return cleanConfig; + } + + private async _copyYaml() { + if (this._editor?.yaml) { + navigator.clipboard.writeText(this._editor.yaml); + } + } + + private _yamlChanged(ev: CustomEvent) { + ev.stopPropagation(); + if (!ev.detail.isValid) { + return; + } + this._config = ev.detail.value; + this._errors = undefined; + this._dirty = true; + } + private _backTapped(): void { if (this._dirty) { showConfirmationDialog(this, { @@ -571,9 +695,15 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { private async _handleMenuAction(ev: CustomEvent) { switch (ev.detail.index) { case 0: - this._duplicate(); + this._mode = "gui"; break; case 1: + this._mode = "yaml"; + break; + case 2: + this._duplicate(); + break; + case 3: this._deleteConfirm(); break; } diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 6e71e7b859..0bf1790075 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -1,5 +1,5 @@ import "@material/mwc-fab"; -import { mdiContentSave, mdiDelete, mdiDotsVertical } from "@mdi/js"; +import { mdiCheck, mdiContentSave, mdiDelete, mdiDotsVertical } from "@mdi/js"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-toolbar/app-toolbar"; import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light"; @@ -15,6 +15,7 @@ import { property, PropertyValues, TemplateResult, + query, } from "lit-element"; import { classMap } from "lit-html/directives/class-map"; import { computeObjectId } from "../../../common/entity/compute_object_id"; @@ -26,6 +27,8 @@ import "../../../components/ha-card"; import "../../../components/ha-icon-button"; import "../../../components/ha-icon-input"; import "../../../components/ha-svg-icon"; +import "../../../components/ha-yaml-editor"; +import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; import { Action, deleteScript, @@ -68,6 +71,10 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @internalProperty() private _errors?: string; + @internalProperty() private _mode: "gui" | "yaml" = "gui"; + + @query("ha-yaml-editor", true) private _editor?: HaYamlEditor; + protected render(): TemplateResult { return html` + + ${this.hass.localize("ui.panel.config.automation.editor.edit_ui")} + ${this._mode === "gui" + ? html`` + : ``} + + + ${this.hass.localize("ui.panel.config.automation.editor.edit_yaml")} + ${this._mode === "yaml" + ? html`` + : ``} + + +
  • + - ${this.hass.localize( - "ui.panel.config.automation.picker.delete_automation" - )} + ${this.hass.localize("ui.panel.config.script.editor.delete_script")} @@ -110,164 +149,214 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ${this._errors ? html`
    ${this._errors}
    ` : ""} -
    - ${this._config - ? html` - - ${!this.narrow - ? html` ${this._config.alias} ` - : ""} - - ${this.hass.localize( - "ui.panel.config.script.editor.introduction" - )} - - -
    - - - - - ${!this.scriptEntityId - ? html` + ${this._config + ? html` + + ${!this.narrow + ? html` + ${this._config.alias} + ` + : ""} + + ${this.hass.localize( + "ui.panel.config.script.editor.introduction" + )} + + +
    + + + + + ${!this.scriptEntityId + ? html` + ` + : ""} +

    + ${this.hass.localize( + "ui.panel.config.script.editor.modes.description", + "documentation_link", + html`${this.hass.localize( + "ui.panel.config.script.editor.modes.documentation" + )}` + )} +

    + + + ${MODES.map( + (mode) => html` + + ${this.hass.localize( + `ui.panel.config.script.editor.modes.${mode}` + ) || mode} + + ` + )} + + + ${this._config.mode && + MODES_MAX.includes(this._config.mode) + ? html` + ` + : html``} +
    + ${this.scriptEntityId + ? html` +
    + + + ${this.hass.localize( + "ui.card.script.execute" + )} + +
    + ` + : ``} +
    +
    + + + + ${this.hass.localize( + "ui.panel.config.script.editor.sequence" + )} + + +

    + ${this.hass.localize( + "ui.panel.config.script.editor.sequence_sentence" )} - .errorMessage=${this.hass.localize( - "ui.panel.config.script.editor.id_already_exists" - )} - .invalid=${this._idError} - .value=${this._entityId} - @value-changed=${this._idChanged} - > - ` - : ""} -

    - ${this.hass.localize( - "ui.panel.config.script.editor.modes.description", - "documentation_link", - html` + ${this.hass.localize( - "ui.panel.config.script.editor.modes.documentation" - )}` - )} -

    - - - ${MODES.map( - (mode) => html` - - ${this.hass.localize( - `ui.panel.config.script.editor.modes.${mode}` - ) || mode} - - ` - )} - - - ${this._config.mode && - MODES_MAX.includes(this._config.mode) - ? html` + ${this.hass.localize( + "ui.panel.config.script.editor.link_available_actions" )} - type="number" - name="max" - .value=${this._config.max || "10"} - @value-changed=${this._valueChanged} - > - ` - : html``} -
    - ${this.scriptEntityId - ? html` -
    - - - ${this.hass.localize("ui.card.script.execute")} - -
    - ` - : ``} -
    -
    - - - - ${this.hass.localize( - "ui.panel.config.script.editor.sequence" - )} - - -

    + + + + + ` + : ""} +

    + ` + : this._mode === "yaml" + ? html` + + ${!this.narrow + ? html`${this._config?.alias}` + : ``} + +
    + + ${this.hass.localize( - "ui.panel.config.script.editor.sequence_sentence" + "ui.panel.config.automation.editor.copy_to_clipboard" )} -

    - - ${this.hass.localize( - "ui.panel.config.script.editor.link_available_actions" - )} - - - - - ` - : ""} -
    + + + ${this.scriptEntityId + ? html` +
    + + + ${this.hass.localize("ui.card.script.execute")} + +
    + ` + : ``} +
    +
    + ` + : ``} ) { switch (ev.detail.index) { case 0: + this._mode = "gui"; + break; + case 1: + this._mode = "yaml"; + break; + case 2: this._deleteConfirm(); break; } diff --git a/src/translations/en.json b/src/translations/en.json index f751ba4b60..c0cfbd2c53 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1064,6 +1064,7 @@ }, "edit_yaml": "Edit as YAML", "edit_ui": "Edit with UI", + "copy_to_clipboard": "Copy to Clipboard", "triggers": { "name": "Trigger", "header": "Triggers",