diff --git a/src/panels/config/automation/action/types/ha-automation-action-choose.ts b/src/panels/config/automation/action/types/ha-automation-action-choose.ts index ebea8d09f9..514376bf46 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-choose.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-choose.ts @@ -1,19 +1,41 @@ import { consume } from "@lit-labs/context"; import type { SortableEvent } from "sortablejs"; -import { mdiDelete, mdiPlus, mdiArrowUp, mdiArrowDown, mdiDrag } from "@mdi/js"; +import { + mdiDotsVertical, + mdiRenameBox, + mdiSort, + mdiContentDuplicate, + mdiDelete, + mdiPlus, + mdiArrowUp, + mdiArrowDown, + mdiDrag, +} from "@mdi/js"; +import deepClone from "deep-clone-simple"; import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit"; import { customElement, property, state } from "lit/decorators"; import { repeat } from "lit/directives/repeat"; +import type { ActionDetail } from "@material/mwc-list"; import { loadSortable, SortableInstance, } from "../../../../../resources/sortable.ondemand"; import { ensureArray } from "../../../../../common/array/ensure-array"; import { fireEvent } from "../../../../../common/dom/fire_event"; +import { capitalizeFirstLetter } from "../../../../../common/string/capitalize-first-letter"; import "../../../../../components/ha-button"; import "../../../../../components/ha-icon-button"; +import "../../../../../components/ha-button-menu"; import { Condition } from "../../../../../data/automation"; -import { Action, ChooseAction } from "../../../../../data/script"; +import { + Action, + ChooseAction, + ChooseActionChoice, +} from "../../../../../data/script"; +import { + showConfirmationDialog, + showPromptDialog, +} from "../../../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../../../resources/styles"; import { HomeAssistant } from "../../../../../types"; import { ActionElement } from "../ha-automation-action-row"; @@ -22,6 +44,8 @@ import { fullEntitiesContext } from "../../../../../data/context"; import { EntityRegistryEntry } from "../../../../../data/entity_registry"; import { sortableStyles } from "../../../../../resources/ha-sortable-style"; +const preventDefault = (ev) => ev.preventDefault(); + @customElement("ha-automation-action-choose") export class HaChooseAction extends LitElement implements ActionElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -53,13 +77,7 @@ export class HaChooseAction extends LitElement implements ActionElement { this._expandedStates[ev.target!.index] = ev.detail.expanded; } - private _getDescription(option, idx: number) { - if (option.alias) { - return option.alias; - } - if (this._expandedStates[idx]) { - return ""; - } + private _getDescription(option) { const conditions = ensureArray(option.conditions); if (!conditions || conditions.length === 0) { return this.hass.localize( @@ -103,7 +121,10 @@ export class HaChooseAction extends LitElement implements ActionElement { "number", idx + 1 )}: - ${this._getDescription(option, idx)} + ${option.alias || + (this._expandedStates[idx] + ? "" + : this._getDescription(option))} ${this.reOrderMode ? html` @@ -133,16 +154,71 @@ export class HaChooseAction extends LitElement implements ActionElement { ` : html` - + @action=${this._handleAction} + @click=${preventDefault} + fixed + > + + + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.rename" + )} + + + + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.re_order" + )} + + + + + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.duplicate" + )} + + + + + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.type.choose.remove_option" + )} + + + `}

@@ -220,6 +296,58 @@ export class HaChooseAction extends LitElement implements ActionElement { `; } + private async _handleAction(ev: CustomEvent) { + switch (ev.detail.index) { + case 0: + await this._renameAction(ev); + break; + case 1: + fireEvent(this, "re-order"); + break; + case 2: + this._duplicateOption(ev); + break; + case 3: + this._removeOption(ev); + break; + } + } + + private async _renameAction(ev: CustomEvent): Promise { + const index = (ev.target as any).idx; + const choose = this.action.choose + ? [...ensureArray(this.action.choose)] + : []; + const choice = choose[index]; + const alias = await showPromptDialog(this, { + title: this.hass.localize( + "ui.panel.config.automation.editor.actions.type.choose.change_alias" + ), + inputLabel: this.hass.localize( + "ui.panel.config.automation.editor.actions.type.choose.alias" + ), + inputType: "string", + placeholder: capitalizeFirstLetter(this._getDescription(choice)), + defaultValue: choice.alias, + confirmText: this.hass.localize("ui.common.submit"), + }); + if (alias !== null) { + if (alias === "") { + delete choose[index].alias; + } else { + choose[index].alias = alias; + } + fireEvent(this, "value-changed", { + value: { ...this.action, choose }, + }); + } + } + + private _duplicateOption(ev) { + const index = (ev.target as any).idx; + this._addOption(deepClone(ensureArray(this.action.choose)[index])); + } + protected firstUpdated() { ensureArray(this.action.choose).forEach(() => this._expandedStates.push(false) @@ -274,11 +402,11 @@ export class HaChooseAction extends LitElement implements ActionElement { }); } - private _addOption() { + private _addOption(opt?: ChooseActionChoice) { const choose = this.action.choose ? [...ensureArray(this.action.choose)] : []; - choose.push({ conditions: [], sequence: [] }); + choose.push(opt ?? { conditions: [], sequence: [] }); fireEvent(this, "value-changed", { value: { ...this.action, choose }, }); @@ -317,14 +445,27 @@ export class HaChooseAction extends LitElement implements ActionElement { } private _removeOption(ev: CustomEvent) { - const index = (ev.currentTarget as any).idx; - const choose = this.action.choose - ? [...ensureArray(this.action.choose)] - : []; - choose.splice(index, 1); - this._expandedStates.splice(index, 1); - fireEvent(this, "value-changed", { - value: { ...this.action, choose }, + const index = (ev.target as any).idx; + showConfirmationDialog(this, { + title: this.hass.localize( + "ui.panel.config.automation.editor.actions.type.choose.delete_confirm_title" + ), + text: this.hass.localize( + "ui.panel.config.automation.editor.actions.delete_confirm_text" + ), + dismissText: this.hass.localize("ui.common.cancel"), + confirmText: this.hass.localize("ui.common.delete"), + destructive: true, + confirm: () => { + const choose = this.action.choose + ? [...ensureArray(this.action.choose)] + : []; + choose.splice(index, 1); + this._expandedStates.splice(index, 1); + fireEvent(this, "value-changed", { + value: { ...this.action, choose }, + }); + }, }); } diff --git a/src/translations/en.json b/src/translations/en.json index 3077dd44e4..b33c002fd8 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2825,6 +2825,9 @@ "option": "Option {number}", "add_option": "Add option", "remove_option": "Remove option", + "change_alias": "Rename option", + "alias": "Option name", + "delete_confirm_title": "Remove option?", "option_description_additional": " {numberOfAdditionalConditions, plural,\n one {and 1 more condition}\n other {and {numberOfAdditionalConditions} more conditions}}", "conditions": "Conditions", "no_conditions": "[%key:ui::panel::config::devices::automation::conditions::no_conditions%]",