diff --git a/src/data/automation.ts b/src/data/automation.ts index 91591a595b..4f7d31d1eb 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -9,6 +9,7 @@ import { DeviceCondition, DeviceTrigger } from "./device_automation"; import { Action, MODES } from "./script"; export const AUTOMATION_DEFAULT_MODE: typeof MODES[number] = "single"; +export const AUTOMATION_DEFAULT_MAX = 10; export interface AutomationEntity extends HassEntityBase { attributes: HassEntityAttributeBase & { diff --git a/src/panels/config/automation/automation-mode-dialog/dialog-automation-mode.ts b/src/panels/config/automation/automation-mode-dialog/dialog-automation-mode.ts new file mode 100644 index 0000000000..a9af861658 --- /dev/null +++ b/src/panels/config/automation/automation-mode-dialog/dialog-automation-mode.ts @@ -0,0 +1,166 @@ +import "@material/mwc-button"; +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import { createCloseHeading } from "../../../../components/ha-dialog"; +import "../../../../components/ha-textfield"; +import "../../../../components/ha-select"; +import { HassDialog } from "../../../../dialogs/make-dialog-manager"; +import { haStyle, haStyleDialog } from "../../../../resources/styles"; +import type { HomeAssistant } from "../../../../types"; +import type { AutomationModeDialog } from "./show-dialog-automation-mode"; +import { + AUTOMATION_DEFAULT_MAX, + AUTOMATION_DEFAULT_MODE, +} from "../../../../data/automation"; +import { documentationUrl } from "../../../../util/documentation-url"; +import { isMaxMode, MODES } from "../../../../data/script"; +import "@material/mwc-list/mwc-list-item"; +import { stopPropagation } from "../../../../common/dom/stop_propagation"; + +@customElement("ha-dialog-automation-mode") +class DialogAutomationMode extends LitElement implements HassDialog { + @property({ attribute: false }) public hass!: HomeAssistant; + + @state() private _opened = false; + + private _params!: AutomationModeDialog; + + @state() private _newMode: typeof MODES[number] = AUTOMATION_DEFAULT_MODE; + + @state() private _newMax?: number; + + public showDialog(params: AutomationModeDialog): void { + this._opened = true; + this._params = params; + this._newMode = params.config.mode || AUTOMATION_DEFAULT_MODE; + this._newMax = isMaxMode(this._newMode) + ? params.config.max || AUTOMATION_DEFAULT_MAX + : undefined; + } + + public closeDialog(): void { + this._params.onClose(); + + if (this._opened) { + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + this._opened = false; + } + + protected render(): TemplateResult { + if (!this._opened) { + return html``; + } + + return html` + + ${this.hass.localize( + "ui.panel.config.automation.editor.modes.learn_more" + )} + `} + > + ${MODES.map( + (mode) => html` + + ${this.hass.localize( + `ui.panel.config.automation.editor.modes.${mode}` + ) || mode} + + ` + )} + + ${isMaxMode(this._newMode) + ? html` +
+ + ` + : html``} + + + ${this.hass.localize("ui.dialogs.generic.cancel")} + + + ${this.hass.localize("ui.panel.config.automation.editor.change_mode")} + +
+ `; + } + + private _modeChanged(ev) { + const mode = ev.target.value; + this._newMode = mode; + if (!isMaxMode(mode)) { + this._newMax = undefined; + } else if (!this._newMax) { + this._newMax = AUTOMATION_DEFAULT_MAX; + } + } + + private _valueChanged(ev: CustomEvent) { + ev.stopPropagation(); + const target = ev.target as any; + if (target.name === "max") { + this._newMax = Number(target.value); + } + } + + private _save(): void { + this._params.updateAutomation({ + ...this._params.config, + mode: this._newMode, + max: this._newMax, + }); + this.closeDialog(); + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + haStyleDialog, + css` + ha-select, + ha-textfield { + display: block; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-dialog-automation-mode": DialogAutomationMode; + } +} diff --git a/src/panels/config/automation/automation-mode-dialog/show-dialog-automation-mode.ts b/src/panels/config/automation/automation-mode-dialog/show-dialog-automation-mode.ts new file mode 100644 index 0000000000..3847ec252d --- /dev/null +++ b/src/panels/config/automation/automation-mode-dialog/show-dialog-automation-mode.ts @@ -0,0 +1,22 @@ +import { fireEvent } from "../../../../common/dom/fire_event"; +import type { AutomationConfig } from "../../../../data/automation"; + +export const loadAutomationModeDialog = () => + import("./dialog-automation-mode"); + +export interface AutomationModeDialog { + config: AutomationConfig; + updateAutomation: (config: AutomationConfig) => void; + onClose: () => void; +} + +export const showAutomationModeDialog = ( + element: HTMLElement, + dialogParams: AutomationModeDialog +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "ha-dialog-automation-mode", + dialogImport: loadAutomationModeDialog, + dialogParams, + }); +}; diff --git a/src/panels/config/automation/automation-rename-dialog/dialog-automation-rename.ts b/src/panels/config/automation/automation-rename-dialog/dialog-automation-rename.ts index e24ebc9e6c..2d55bfd117 100644 --- a/src/panels/config/automation/automation-rename-dialog/dialog-automation-rename.ts +++ b/src/panels/config/automation/automation-rename-dialog/dialog-automation-rename.ts @@ -7,6 +7,8 @@ import { HassDialog } from "../../../../dialogs/make-dialog-manager"; import { haStyle, haStyleDialog } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; import type { AutomationRenameDialog } from "./show-dialog-automation-rename"; +import "../../../../components/ha-textarea"; +import "../../../../components/ha-textfield"; @customElement("ha-dialog-automation-rename") class DialogAutomationRename extends LitElement implements HassDialog { @@ -51,7 +53,7 @@ class DialogAutomationRename extends LitElement implements HassDialog { > + ${this.hass.localize( + "ui.panel.config.automation.editor.disabled" + )} + + ${this.hass.localize( + "ui.panel.config.automation.editor.enable" + )} + + + ` + : ""} { + if (!this.hass || !this.stateObj) { + return; + } + await this.hass.callService("automation", "turn_on", { + entity_id: this.stateObj.entity_id, + }); + } + static get styles(): CSSResultGroup { return [ haStyle, @@ -220,6 +244,10 @@ export class HaBlueprintAutomationEditor extends LitElement { --settings-row-prefix-display: contents; border-top: 1px solid var(--divider-color); } + ha-alert { + margin-bottom: 16px; + display: block; + } `, ]; } diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 316dbe05d9..5abf51d1c6 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -3,6 +3,7 @@ import { mdiCheck, mdiContentDuplicate, mdiContentSave, + mdiDebugStepOver, mdiDelete, mdiDotsVertical, mdiInformationOutline, @@ -55,6 +56,7 @@ import { haStyle } from "../../../resources/styles"; import { HomeAssistant, Route } from "../../../types"; import { showToast } from "../../../util/toast"; import "../ha-config-section"; +import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-automation-mode"; import { showAutomationRenameDialog } from "./automation-rename-dialog/show-dialog-automation-rename"; import "./blueprint-automation-editor"; import "./manual-automation-editor"; @@ -161,11 +163,33 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ` : ""} - + ${this.hass.localize("ui.panel.config.automation.editor.rename")} + ${this._config && !("use_blueprint" in this._config) + ? html` + + ${this.hass.localize( + "ui.panel.config.automation.editor.change_mode" + )} + + + ` + : ""} + - ${!stateObj || stateObj.state === "off" + ${stateObj?.state === "off" ? this.hass.localize("ui.panel.config.automation.editor.enable") : this.hass.localize("ui.panel.config.automation.editor.disable")} @@ -270,18 +294,20 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ` : this._mode === "yaml" ? html` - ${!this.narrow + ${stateObj?.state === "off" ? html` - -
- ${this._config.alias || - this.hass.localize( - "ui.panel.config.automation.editor.default_name" + + ${this.hass.localize( + "ui.panel.config.automation.editor.disabled" + )} + + ${this.hass.localize( + "ui.panel.config.automation.editor.enable" )} -
-
+ + ` - : ``} + : ""} { + return new Promise((resolve) => { + showAutomationModeDialog(this, { + config: this._config!, + updateAutomation: (config) => { + this._config = config; + this._dirty = true; + this.requestUpdate(); + resolve(); + }, + onClose: () => resolve(), + }); + }); + } + private async _saveAutomation(): Promise { const id = this.automationId || String(Date.now()); if (!this._config!.alias) { diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index a3c7c36985..e6092cf251 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -1,21 +1,19 @@ import "@material/mwc-button/mwc-button"; -import { mdiHelpCircle, mdiRobot, mdiSort, mdiTextBoxEdit } from "@mdi/js"; +import { mdiHelpCircle, mdiSort, mdiTextBoxEdit } from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/entity/ha-entity-toggle"; import "../../../components/ha-card"; -import "../../../components/ha-textarea"; -import "../../../components/ha-textfield"; import "../../../components/ha-icon-button"; +import "../../../components/ha-alert"; import { - AUTOMATION_DEFAULT_MODE, Condition, ManualAutomationConfig, Trigger, } from "../../../data/automation"; -import { Action, isMaxMode, MODES } from "../../../data/script"; +import { Action } from "../../../data/script"; import { haStyle } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import { documentationUrl } from "../../../util/documentation-url"; @@ -43,71 +41,20 @@ export class HaManualAutomationEditor extends LitElement { protected render() { return html` - - ${this.stateObj && this.stateObj.state === "off" - ? html`
+ ${this.stateObj?.state === "off" + ? html` + ${this.hass.localize( "ui.panel.config.automation.editor.disabled" )} -
` - : ""} - - -

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

-
- ${this.hass.localize( - "ui.panel.config.automation.editor.modes.learn_more" - )} - `} - > - ${MODES.map( - (mode) => html` - - ${this.hass.localize( - `ui.panel.config.automation.editor.modes.${mode}` - ) || mode} - - ` - )} - - ${this.config.mode && isMaxMode(this.config.mode) - ? html` -
- - ` - : html``} -
-
-
- + + ${this.hass.localize( + "ui.panel.config.automation.editor.enable" + )} + + + ` + : ""}

${this.hass.localize( @@ -221,48 +168,6 @@ export class HaManualAutomationEditor extends LitElement { `; } - private _valueChanged(ev: CustomEvent) { - ev.stopPropagation(); - const target = ev.target as any; - const name = target.name; - if (!name) { - return; - } - let newVal = target.value; - if (target.type === "number") { - newVal = Number(newVal); - } - if ((this.config![name] || "") === newVal) { - return; - } - fireEvent(this, "value-changed", { - value: { ...this.config!, [name]: newVal }, - }); - } - - private _modeChanged(ev) { - const mode = ev.target.value; - - if ( - mode === this.config!.mode || - (!this.config!.mode && mode === MODES[0]) - ) { - return; - } - const value = { - ...this.config!, - mode, - }; - - if (!isMaxMode(mode)) { - delete value.max; - } - - fireEvent(this, "value-changed", { - value, - }); - } - private _triggerChanged(ev: CustomEvent): void { ev.stopPropagation(); fireEvent(this, "value-changed", { @@ -287,6 +192,15 @@ export class HaManualAutomationEditor extends LitElement { }); } + private async _enable(): Promise { + if (!this.hass || !this.stateObj) { + return; + } + await this.hass.callService("automation", "turn_on", { + entity_id: this.stateObj.entity_id, + }); + } + static get styles(): CSSResultGroup { return [ haStyle, @@ -300,10 +214,6 @@ export class HaManualAutomationEditor extends LitElement { .link-button-row { padding: 14px; } - ha-textarea, - ha-textfield { - display: block; - } p { margin-bottom: 0; @@ -320,6 +230,9 @@ export class HaManualAutomationEditor extends LitElement { display: flex; align-items: center; } + .header:first-child { + margin-top: -16px; + } .header .name { font-size: 20px; font-weight: 400; @@ -340,9 +253,6 @@ export class HaManualAutomationEditor extends LitElement { .card-content { padding: 16px; } - .card-content ha-textarea:first-child { - margin-top: -16px; - } .settings-icon { display: none; } diff --git a/src/translations/en.json b/src/translations/en.json index 2bfdcb136d..63dda9251d 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1847,6 +1847,7 @@ "no_blueprints": "You don't have any blueprints", "no_inputs": "This blueprint doesn't have any inputs." }, + "change_mode": "Change mode", "modes": { "label": "Mode", "learn_more": "Learn about modes",