diff --git a/src/panels/config/scene/ha-scene-dashboard.ts b/src/panels/config/scene/ha-scene-dashboard.ts index b112b0047c..59006227e9 100644 --- a/src/panels/config/scene/ha-scene-dashboard.ts +++ b/src/panels/config/scene/ha-scene-dashboard.ts @@ -1,7 +1,8 @@ import { + mdiContentDuplicate, + mdiDelete, mdiHelpCircle, mdiInformationOutline, - mdiPencil, mdiPencilOff, mdiPlay, mdiPlus, @@ -9,7 +10,6 @@ import { import "@polymer/paper-tooltip/paper-tooltip"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { ifDefined } from "lit/directives/if-defined"; import memoizeOne from "memoize-one"; import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event"; import { computeStateName } from "../../../common/entity/compute_state_name"; @@ -23,9 +23,19 @@ import "../../../components/ha-fab"; import "../../../components/ha-icon-button"; import "../../../components/ha-state-icon"; import "../../../components/ha-svg-icon"; +import "../../../components/ha-icon-overflow-menu"; import { forwardHaptic } from "../../../data/haptics"; -import { activateScene, SceneEntity } from "../../../data/scene"; -import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; +import { + activateScene, + deleteScene, + getSceneConfig, + SceneEntity, + showSceneEditor, +} from "../../../data/scene"; +import { + showAlertDialog, + showConfirmationDialog, +} from "../../../dialogs/generic/show-dialog-box"; import "../../../layouts/hass-tabs-subpage-data-table"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant, Route } from "../../../types"; @@ -67,26 +77,8 @@ class HaSceneDashboard extends LitElement { } ); - private _columns = memoizeOne( - (_language): DataTableColumnContainer => ({ - activate: { - title: "", - label: this.hass.localize( - "ui.panel.config.scene.picker.headers.activate" - ), - type: "icon-button", - template: (_toggle, scene) => - html` - - `, - }, + private _columns = memoizeOne((_language): DataTableColumnContainer => { + const columns: DataTableColumnContainer = { icon: { title: "", label: this.hass.localize("ui.panel.config.scene.picker.headers.state"), @@ -101,56 +93,73 @@ class HaSceneDashboard extends LitElement { direction: "asc", grows: true, }, - info: { + only_editable: { title: "", - label: this.hass.localize( - "ui.panel.config.scene.picker.headers.show_info" - ), - type: "icon-button", - template: (_info, scene) => html` - - `, - }, - edit: { - title: "", - label: this.hass.localize("ui.panel.config.scene.picker.headers.edit"), - type: "icon-button", - template: (_info, scene: any) => html` - - - - ${!scene.attributes.id + template: (_info, scene: any) => + !scene.attributes.id ? html` ${this.hass.localize( "ui.panel.config.scene.picker.only_editable" )} + ` - : ""} - `, + : "", }, - }) - ); + }; + + columns.actions = { + title: "", + type: "overflow-menu", + template: (_: string, scene: any) => + html` + this._showInfo(scene), + }, + { + path: mdiPlay, + label: this.hass.localize( + "ui.panel.config.scene.picker.activate" + ), + action: () => this._activateScene(scene), + }, + { + path: mdiContentDuplicate, + label: this.hass.localize( + "ui.panel.config.scene.picker.duplicate" + ), + action: () => this._duplicate(scene), + disabled: !scene.attributes.id, + }, + { + label: this.hass.localize( + "ui.panel.config.scene.picker.delete" + ), + path: mdiDelete, + action: () => this._deleteConfirm(scene), + warning: scene.attributes.id, + disabled: !scene.attributes.id, + }, + ]} + > + + `, + }; + + return columns; + }); protected render(): TemplateResult { return html` @@ -226,15 +235,11 @@ class HaSceneDashboard extends LitElement { this._filterValue = undefined; } - private _showInfo(ev) { - ev.stopPropagation(); - const entityId = ev.currentTarget.scene.entity_id; - fireEvent(this, "hass-more-info", { entityId }); + private _showInfo(scene: SceneEntity) { + fireEvent(this, "hass-more-info", { entityId: scene.entity_id }); } - private _activateScene = async (ev) => { - ev.stopPropagation(); - const scene = ev.currentTarget.scene as SceneEntity; + private _activateScene = async (scene: SceneEntity) => { await activateScene(this.hass, scene.entity_id); showToast(this, { message: this.hass.localize( @@ -246,6 +251,34 @@ class HaSceneDashboard extends LitElement { forwardHaptic("light"); }; + private _deleteConfirm(scene: SceneEntity): void { + showConfirmationDialog(this, { + text: this.hass!.localize("ui.panel.config.scene.picker.delete_confirm"), + confirmText: this.hass!.localize("ui.common.delete"), + dismissText: this.hass!.localize("ui.common.cancel"), + confirm: () => this._delete(scene), + }); + } + + private async _delete(scene: SceneEntity): Promise { + if (scene.attributes.id) { + await deleteScene(this.hass, scene.attributes.id); + } + } + + private async _duplicate(scene) { + if (scene.attributes.id) { + const config = await getSceneConfig(this.hass, scene.attributes.id); + showSceneEditor({ + ...config, + id: undefined, + name: `${config?.name} (${this.hass.localize( + "ui.panel.config.scene.picker.duplicate" + )})`, + }); + } + } + private _showHelp() { showAlertDialog(this, { title: this.hass.localize("ui.panel.config.scene.picker.header"), diff --git a/src/translations/en.json b/src/translations/en.json index c73f2ac15a..2e05baaf2b 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2324,8 +2324,10 @@ "add_scene": "Add scene", "only_editable": "Only scenes defined in scenes.yaml are editable.", "edit_scene": "Edit scene", - "show_info_scene": "Show info about scene", + "show_info": "[%key:ui::panel::config::automation::editor::show_info%]", + "activate": "Activate", "delete_scene": "Delete scene", + "delete": "[%key:ui::common::delete%]", "delete_confirm": "Are you sure you want to delete this scene?", "duplicate_scene": "Duplicate scene", "duplicate": "[%key:ui::common::duplicate%]",