1
0
mirror of https://github.com/home-assistant/frontend.git synced 2025-12-25 05:06:18 +00:00

Migrate ha-button-menu to ha-dropdown in scene panel

Co-authored-by: wendevlin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-05 11:39:22 +00:00
parent 950a773f7e
commit cecf0a95c8
2 changed files with 119 additions and 153 deletions

View File

@@ -52,9 +52,10 @@ import "../../../components/ha-filter-floor-areas";
import "../../../components/ha-filter-labels";
import "../../../components/ha-icon-button";
import "../../../components/ha-icon-overflow-menu";
import "../../../components/ha-md-divider";
import "@home-assistant/webawesome/dist/components/divider/divider";
import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import "../../../components/ha-md-menu";
import "../../../components/ha-md-menu-item";
import "../../../components/ha-state-icon";
import "../../../components/ha-sub-menu";
import "../../../components/ha-svg-icon";
@@ -437,29 +438,25 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
protected render(): TemplateResult {
const categoryItems = html`${this._categories?.map(
(category) =>
html`<ha-md-menu-item
html`<ha-dropdown-item
.value=${category.category_id}
.clickAction=${this._handleBulkCategory}
>
${category.icon
? html`<ha-icon slot="start" .icon=${category.icon}></ha-icon>`
: html`<ha-svg-icon slot="start" .path=${mdiTag}></ha-svg-icon>`}
<div slot="headline">${category.name}</div>
</ha-md-menu-item>`
? html`<ha-icon slot="icon" .icon=${category.icon}></ha-icon>`
: html`<ha-svg-icon slot="icon" .path=${mdiTag}></ha-svg-icon>`}
${category.name}
</ha-dropdown-item>`
)}
<ha-md-menu-item .value=${null} .clickAction=${this._handleBulkCategory}>
<div slot="headline">
${this.hass.localize(
"ui.panel.config.automation.picker.bulk_actions.no_category"
)}
</div>
</ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
<ha-md-menu-item .clickAction=${this._bulkCreateCategory}>
<div slot="headline">
${this.hass.localize("ui.panel.config.category.editor.add")}
</div>
</ha-md-menu-item>`;
<ha-dropdown-item .value=${null} .clickAction=${this._handleBulkCategory}>
${this.hass.localize(
"ui.panel.config.automation.picker.bulk_actions.no_category"
)}
</ha-dropdown-item>
<wa-divider></wa-divider>
<ha-dropdown-item .clickAction=${this._bulkCreateCategory}>
${this.hass.localize("ui.panel.config.category.editor.add")}
</ha-dropdown-item>`;
const labelItems = html` ${this._labels?.map((label) => {
const color = label.color ? computeCssColor(label.color) : undefined;
@@ -471,14 +468,14 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
this._selected.some((entityId) =>
this.hass.entities[entityId]?.labels.includes(label.label_id)
);
return html`<ha-md-menu-item
return html`<ha-dropdown-item
.value=${label.label_id}
.action=${selected ? "remove" : "add"}
@click=${this._handleBulkLabel}
keep-open
>
<ha-checkbox
slot="start"
slot="icon"
.checked=${selected}
.indeterminate=${partial}
reducedTouchTarget
@@ -492,45 +489,39 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
: nothing}
${label.name}
</ha-label>
</ha-md-menu-item>`;
</ha-dropdown-item>`;
})}
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
<ha-md-menu-item .clickAction=${this._bulkCreateLabel}>
<div slot="headline">
${this.hass.localize("ui.panel.config.labels.add_label")}
</div></ha-md-menu-item
>`;
<wa-divider></wa-divider>
<ha-dropdown-item .clickAction=${this._bulkCreateLabel}>
${this.hass.localize("ui.panel.config.labels.add_label")}
</ha-dropdown-item>`;
const areaItems = html`${Object.values(this.hass.areas).map(
(area) =>
html`<ha-md-menu-item
html`<ha-dropdown-item
.value=${area.area_id}
.clickAction=${this._handleBulkArea}
>
${area.icon
? html`<ha-icon slot="start" .icon=${area.icon}></ha-icon>`
? html`<ha-icon slot="icon" .icon=${area.icon}></ha-icon>`
: html`<ha-svg-icon
slot="start"
slot="icon"
.path=${mdiTextureBox}
></ha-svg-icon>`}
<div slot="headline">${area.name}</div>
</ha-md-menu-item>`
${area.name}
</ha-dropdown-item>`
)}
<ha-md-menu-item .value=${null} .clickAction=${this._handleBulkArea}>
<div slot="headline">
${this.hass.localize(
"ui.panel.config.devices.picker.bulk_actions.no_area"
)}
</div>
</ha-md-menu-item>
<ha-md-divider role="separator" tabindex="-1"></ha-md-divider>
<ha-md-menu-item .clickAction=${this._bulkCreateArea}>
<div slot="headline">
${this.hass.localize(
"ui.panel.config.devices.picker.bulk_actions.add_area"
)}
</div>
</ha-md-menu-item>`;
<ha-dropdown-item .value=${null} .clickAction=${this._handleBulkArea}>
${this.hass.localize(
"ui.panel.config.devices.picker.bulk_actions.no_area"
)}
</ha-dropdown-item>
<wa-divider></wa-divider>
<ha-dropdown-item .clickAction=${this._bulkCreateArea}>
${this.hass.localize(
"ui.panel.config.devices.picker.bulk_actions.add_area"
)}
</ha-dropdown-item>`;
const areasInOverflow =
(this._sizeController.value && this._sizeController.value < 900) ||
@@ -654,7 +645,7 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
></ha-filter-categories>
${!this.narrow
? html`<ha-md-button-menu slot="selection-bar">
? html`<ha-dropdown slot="selection-bar">
<ha-assist-chip
slot="trigger"
.label=${this.hass.localize(
@@ -667,10 +658,10 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
></ha-svg-icon>
</ha-assist-chip>
${categoryItems}
</ha-md-button-menu>
</ha-dropdown>
${labelsInOverflow
? nothing
: html`<ha-md-button-menu slot="selection-bar">
: html`<ha-dropdown slot="selection-bar">
<ha-assist-chip
slot="trigger"
.label=${this.hass.localize(
@@ -683,10 +674,10 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
></ha-svg-icon>
</ha-assist-chip>
${labelItems}
</ha-md-button-menu>`}
</ha-dropdown>`}
${areasInOverflow
? nothing
: html`<ha-md-button-menu slot="selection-bar">
: html`<ha-dropdown slot="selection-bar">
<ha-assist-chip
slot="trigger"
.label=${this.hass.localize(
@@ -699,13 +690,11 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
></ha-svg-icon>
</ha-assist-chip>
${areaItems}
</ha-md-button-menu>`}`
</ha-dropdown>`}`
: nothing}
${this.narrow || areasInOverflow
? html`
<ha-md-button-menu has-overflow slot="selection-bar">
${
this.narrow
? html` <ha-dropdown has-overflow slot="selection-bar">
${this.narrow
? html`<ha-assist-chip
.label=${this.hass.localize(
"ui.panel.config.automation.picker.bulk_action"
@@ -723,68 +712,50 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
"ui.panel.config.automation.picker.bulk_action"
)}
slot="trigger"
></ha-icon-button>`
}
<ha-svg-icon
slot="trailing-icon"
.path=${mdiMenuDown}
></ha-svg-icon
></ha-assist-chip>
${
this.narrow
></ha-icon-button>`}
${this.narrow
? html`<ha-sub-menu>
<ha-md-menu-item slot="item">
<div slot="headline">
${this.hass.localize(
"ui.panel.config.automation.picker.bulk_actions.move_category"
)}
</div>
<ha-dropdown-item slot="item">
${this.hass.localize(
"ui.panel.config.automation.picker.bulk_actions.move_category"
)}
<ha-svg-icon
slot="end"
slot="details"
.path=${mdiChevronRight}
></ha-svg-icon>
</ha-md-menu-item>
</ha-dropdown-item>
<ha-md-menu slot="menu">${categoryItems}</ha-md-menu>
</ha-sub-menu>`
: nothing
}
${
this.narrow || labelsInOverflow
: nothing}
${this.narrow || labelsInOverflow
? html`<ha-sub-menu>
<ha-md-menu-item slot="item">
<div slot="headline">
${this.hass.localize(
"ui.panel.config.automation.picker.bulk_actions.add_label"
)}
</div>
<ha-dropdown-item slot="item">
${this.hass.localize(
"ui.panel.config.automation.picker.bulk_actions.add_label"
)}
<ha-svg-icon
slot="end"
slot="details"
.path=${mdiChevronRight}
></ha-svg-icon>
</ha-md-menu-item>
</ha-dropdown-item>
<ha-md-menu slot="menu">${labelItems}</ha-md-menu>
</ha-sub-menu>`
: nothing
}
${
this.narrow || areasInOverflow
: nothing}
${this.narrow || areasInOverflow
? html`<ha-sub-menu>
<ha-md-menu-item slot="item">
<div slot="headline">
${this.hass.localize(
"ui.panel.config.devices.picker.bulk_actions.move_area"
)}
</div>
<ha-dropdown-item slot="item">
${this.hass.localize(
"ui.panel.config.devices.picker.bulk_actions.move_area"
)}
<ha-svg-icon
slot="end"
slot="details"
.path=${mdiChevronRight}
></ha-svg-icon>
</ha-md-menu-item>
</ha-dropdown-item>
<ha-md-menu slot="menu">${areaItems}</ha-md-menu>
</ha-sub-menu>`
: nothing
}
</ha-md-button-menu>`
: nothing}
</ha-dropdown>`
: nothing}
${!this.scenes.length
? html`<div class="empty" slot="empty">
@@ -1231,7 +1202,7 @@ ${rejected
ha-assist-chip {
--ha-assist-chip-container-shape: 10px;
}
ha-md-button-menu ha-assist-chip {
ha-dropdown ha-assist-chip {
--md-assist-chip-trailing-space: 8px;
}
ha-label {

View File

@@ -1,6 +1,6 @@
import "@home-assistant/webawesome/dist/components/divider/divider";
import { consume } from "@lit/context";
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import {
mdiCog,
mdiContentDuplicate,
@@ -32,8 +32,10 @@ import "../../../components/entity/ha-entities-picker";
import "../../../components/ha-alert";
import "../../../components/ha-area-picker";
import "../../../components/ha-button";
import "../../../components/ha-button-menu";
import "../../../components/ha-card";
import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import "../../../components/ha-fab";
import "../../../components/ha-icon-button";
import "../../../components/ha-icon-picker";
@@ -227,78 +229,70 @@ export class HaSceneEditor extends PreventUnsavedMixin(
? computeStateName(this._scene)
: this.hass.localize("ui.panel.config.scene.editor.default_name")}
>
<ha-button-menu
slot="toolbar-icon"
@action=${this._handleMenuAction}
activatable
>
<ha-dropdown slot="toolbar-icon" @wa-select=${this._handleMenuAction}>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-list-item
graphic="icon"
<ha-dropdown-item
value="apply"
.disabled=${!this.sceneId || this._mode === "live"}
>
<ha-svg-icon slot="icon" .path=${mdiPlay}></ha-svg-icon>
${this.hass.localize("ui.panel.config.scene.picker.apply")}
<ha-svg-icon slot="graphic" .path=${mdiPlay}></ha-svg-icon>
</ha-list-item>
<ha-list-item graphic="icon" .disabled=${!this.sceneId}>
${this.hass.localize("ui.panel.config.scene.picker.show_info")}
</ha-dropdown-item>
<ha-dropdown-item value="info" .disabled=${!this.sceneId}>
<ha-svg-icon
slot="graphic"
slot="icon"
.path=${mdiInformationOutline}
></ha-svg-icon>
</ha-list-item>
<ha-list-item graphic="icon" .disabled=${!this.sceneId}>
${this.hass.localize("ui.panel.config.scene.picker.show_info")}
</ha-dropdown-item>
<ha-dropdown-item value="settings" .disabled=${!this.sceneId}>
<ha-svg-icon slot="icon" .path=${mdiCog}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.automation.picker.show_settings"
)}
<ha-svg-icon slot="graphic" .path=${mdiCog}></ha-svg-icon>
</ha-list-item>
</ha-dropdown-item>
<ha-list-item graphic="icon" .disabled=${!this.sceneId}>
<ha-dropdown-item value="category" .disabled=${!this.sceneId}>
<ha-svg-icon slot="icon" .path=${mdiTag}></ha-svg-icon>
${this.hass.localize(
`ui.panel.config.scene.picker.${this._getCategory(this._entityRegistryEntries, this._scene?.entity_id) ? "edit_category" : "assign_category"}`
)}
<ha-svg-icon slot="graphic" .path=${mdiTag}></ha-svg-icon>
</ha-list-item>
</ha-dropdown-item>
<ha-list-item graphic="icon">
<ha-dropdown-item value="toggle_yaml">
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
${this.hass.localize(
`ui.panel.config.automation.editor.edit_${this._mode !== "yaml" ? "yaml" : "ui"}`
)}
<ha-svg-icon slot="graphic" .path=${mdiPlaylistEdit}></ha-svg-icon>
</ha-list-item>
</ha-dropdown-item>
<li divider role="separator"></li>
<wa-divider></wa-divider>
<ha-list-item .disabled=${!this.sceneId} graphic="icon">
<ha-dropdown-item value="duplicate" .disabled=${!this.sceneId}>
<ha-svg-icon slot="icon" .path=${mdiContentDuplicate}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.scene.picker.duplicate_scene"
)}
<ha-svg-icon
slot="graphic"
.path=${mdiContentDuplicate}
></ha-svg-icon>
</ha-list-item>
</ha-dropdown-item>
<ha-list-item
<ha-dropdown-item
value="delete"
.disabled=${!this.sceneId}
class=${classMap({ warning: Boolean(this.sceneId) })}
graphic="icon"
.variant=${this.sceneId ? "danger" : "default"}
>
${this.hass.localize("ui.panel.config.scene.picker.delete_scene")}
<ha-svg-icon
class=${classMap({ warning: Boolean(this.sceneId) })}
slot="graphic"
slot="icon"
.path=${mdiDelete}
>
</ha-svg-icon>
</ha-list-item>
</ha-button-menu>
></ha-svg-icon>
${this.hass.localize("ui.panel.config.scene.picker.delete_scene")}
</ha-dropdown-item>
</ha-dropdown>
${this._errors ? html` <div class="errors">${this._errors}</div> ` : ""}
${this._mode === "yaml" ? this._renderYamlMode() : this._renderUiMode()}
<ha-fab
@@ -652,24 +646,25 @@ export class HaSceneEditor extends PreventUnsavedMixin(
}
}
private async _handleMenuAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
private async _handleMenuAction(ev: CustomEvent) {
const item = ev.detail.item as HaDropdownItem;
switch (item.value) {
case "apply":
activateScene(this.hass, this._scene!.entity_id);
break;
case 1:
case "info":
fireEvent(this, "hass-more-info", { entityId: this._scene!.entity_id });
break;
case 2:
case "settings":
showMoreInfoDialog(this, {
entityId: this._scene!.entity_id,
view: "settings",
});
break;
case 3:
case "category":
this._editCategory(this._scene!);
break;
case 4:
case "toggle_yaml":
if (this._mode === "yaml") {
this._initEntities(this._config!);
this._exitYamlMode();
@@ -677,10 +672,10 @@ export class HaSceneEditor extends PreventUnsavedMixin(
this._enterYamlMode();
}
break;
case 5:
case "duplicate":
this._duplicate();
break;
case 6:
case "delete":
this._deleteTapped();
break;
}