Add overflow menu for scene picker (#13621)

This commit is contained in:
Paul Bottein 2022-09-06 16:48:09 +02:00 committed by GitHub
parent e6862daa38
commit df72e5099e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 108 additions and 73 deletions

View File

@ -1,7 +1,8 @@
import { import {
mdiContentDuplicate,
mdiDelete,
mdiHelpCircle, mdiHelpCircle,
mdiInformationOutline, mdiInformationOutline,
mdiPencil,
mdiPencilOff, mdiPencilOff,
mdiPlay, mdiPlay,
mdiPlus, mdiPlus,
@ -9,7 +10,6 @@ import {
import "@polymer/paper-tooltip/paper-tooltip"; import "@polymer/paper-tooltip/paper-tooltip";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event"; import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event";
import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeStateName } from "../../../common/entity/compute_state_name";
@ -23,9 +23,19 @@ import "../../../components/ha-fab";
import "../../../components/ha-icon-button"; import "../../../components/ha-icon-button";
import "../../../components/ha-state-icon"; import "../../../components/ha-state-icon";
import "../../../components/ha-svg-icon"; import "../../../components/ha-svg-icon";
import "../../../components/ha-icon-overflow-menu";
import { forwardHaptic } from "../../../data/haptics"; import { forwardHaptic } from "../../../data/haptics";
import { activateScene, SceneEntity } from "../../../data/scene"; import {
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; 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 "../../../layouts/hass-tabs-subpage-data-table";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import { HomeAssistant, Route } from "../../../types"; import { HomeAssistant, Route } from "../../../types";
@ -67,26 +77,8 @@ class HaSceneDashboard extends LitElement {
} }
); );
private _columns = memoizeOne( private _columns = memoizeOne((_language): DataTableColumnContainer => {
(_language): DataTableColumnContainer => ({ const columns: DataTableColumnContainer = {
activate: {
title: "",
label: this.hass.localize(
"ui.panel.config.scene.picker.headers.activate"
),
type: "icon-button",
template: (_toggle, scene) =>
html`
<ha-icon-button
.scene=${scene}
.label=${this.hass.localize(
"ui.panel.config.scene.picker.activate_scene"
)}
.path=${mdiPlay}
@click=${this._activateScene}
></ha-icon-button>
`,
},
icon: { icon: {
title: "", title: "",
label: this.hass.localize("ui.panel.config.scene.picker.headers.state"), label: this.hass.localize("ui.panel.config.scene.picker.headers.state"),
@ -101,56 +93,73 @@ class HaSceneDashboard extends LitElement {
direction: "asc", direction: "asc",
grows: true, grows: true,
}, },
info: { only_editable: {
title: "", title: "",
label: this.hass.localize( template: (_info, scene: any) =>
"ui.panel.config.scene.picker.headers.show_info" !scene.attributes.id
),
type: "icon-button",
template: (_info, scene) => html`
<ha-icon-button
.scene=${scene}
@click=${this._showInfo}
.label=${this.hass.localize(
"ui.panel.config.scene.picker.show_info_scene"
)}
.path=${mdiInformationOutline}
></ha-icon-button>
`,
},
edit: {
title: "",
label: this.hass.localize("ui.panel.config.scene.picker.headers.edit"),
type: "icon-button",
template: (_info, scene: any) => html`
<a
href=${ifDefined(
scene.attributes.id
? `/config/scene/edit/${scene.attributes.id}`
: undefined
)}
>
<ha-icon-button
.disabled=${!scene.attributes.id}
.label=${this.hass.localize(
"ui.panel.config.scene.picker.edit_scene"
)}
.path=${scene.attributes.id ? mdiPencil : mdiPencilOff}
></ha-icon-button>
</a>
${!scene.attributes.id
? html` ? html`
<paper-tooltip animation-delay="0" position="left"> <paper-tooltip animation-delay="0" position="left">
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.scene.picker.only_editable" "ui.panel.config.scene.picker.only_editable"
)} )}
</paper-tooltip> </paper-tooltip>
<ha-svg-icon
.path=${mdiPencilOff}
style="color: var(--secondary-text-color)"
></ha-svg-icon>
` `
: ""} : "",
`,
}, },
}) };
);
columns.actions = {
title: "",
type: "overflow-menu",
template: (_: string, scene: any) =>
html`
<ha-icon-overflow-menu
.hass=${this.hass}
narrow
.items=${[
{
path: mdiInformationOutline,
label: this.hass.localize(
"ui.panel.config.scene.picker.show_info"
),
action: () => 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,
},
]}
>
</ha-icon-overflow-menu>
`,
};
return columns;
});
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
@ -226,15 +235,11 @@ class HaSceneDashboard extends LitElement {
this._filterValue = undefined; this._filterValue = undefined;
} }
private _showInfo(ev) { private _showInfo(scene: SceneEntity) {
ev.stopPropagation(); fireEvent(this, "hass-more-info", { entityId: scene.entity_id });
const entityId = ev.currentTarget.scene.entity_id;
fireEvent(this, "hass-more-info", { entityId });
} }
private _activateScene = async (ev) => { private _activateScene = async (scene: SceneEntity) => {
ev.stopPropagation();
const scene = ev.currentTarget.scene as SceneEntity;
await activateScene(this.hass, scene.entity_id); await activateScene(this.hass, scene.entity_id);
showToast(this, { showToast(this, {
message: this.hass.localize( message: this.hass.localize(
@ -246,6 +251,34 @@ class HaSceneDashboard extends LitElement {
forwardHaptic("light"); 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<void> {
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() { private _showHelp() {
showAlertDialog(this, { showAlertDialog(this, {
title: this.hass.localize("ui.panel.config.scene.picker.header"), title: this.hass.localize("ui.panel.config.scene.picker.header"),

View File

@ -2324,8 +2324,10 @@
"add_scene": "Add scene", "add_scene": "Add scene",
"only_editable": "Only scenes defined in scenes.yaml are editable.", "only_editable": "Only scenes defined in scenes.yaml are editable.",
"edit_scene": "Edit scene", "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_scene": "Delete scene",
"delete": "[%key:ui::common::delete%]",
"delete_confirm": "Are you sure you want to delete this scene?", "delete_confirm": "Are you sure you want to delete this scene?",
"duplicate_scene": "Duplicate scene", "duplicate_scene": "Duplicate scene",
"duplicate": "[%key:ui::common::duplicate%]", "duplicate": "[%key:ui::common::duplicate%]",