mirror of
https://github.com/home-assistant/frontend.git
synced 2026-02-15 07:25:54 +00:00
Migrate ha-button-menu to ha-dropdown in logs and forms (#29036)
Migrate four components from ha-button-menu to ha-dropdown: - error-log-card: overflow menu with log view switching - system-log-card: overflow menu for full logs - ha-filter-categories: category edit/delete actions - ha-form-optional_actions: add interaction dropdown Changes: - Replace ha-button-menu with ha-dropdown - Replace ha-list-item with ha-dropdown-item - Update event handlers from @action to @wa-select - Use value-based selection instead of index-based - Add proper accessibility labels to trigger buttons Part of #26537 Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { ActionDetail, SelectedDetail } from "@material/mwc-list";
|
||||
import type { SelectedDetail } from "@material/mwc-list";
|
||||
import {
|
||||
mdiDelete,
|
||||
mdiDotsVertical,
|
||||
@@ -25,7 +25,8 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin";
|
||||
import { showCategoryRegistryDetailDialog } from "../panels/config/category/show-dialog-category-registry-detail";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-button-menu";
|
||||
import "./ha-dropdown";
|
||||
import "./ha-dropdown-item";
|
||||
import "./ha-expansion-panel";
|
||||
import "./ha-icon";
|
||||
import "./ha-list";
|
||||
@@ -114,37 +115,36 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
||||
slot="graphic"
|
||||
></ha-svg-icon>`}
|
||||
${category.name}
|
||||
<ha-button-menu
|
||||
<ha-dropdown
|
||||
@click=${stopPropagation}
|
||||
@action=${this._handleAction}
|
||||
@wa-select=${this._handleAction}
|
||||
slot="meta"
|
||||
fixed
|
||||
.categoryId=${category.category_id}
|
||||
>
|
||||
<ha-icon-button
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
></ha-icon-button>
|
||||
<ha-list-item graphic="icon"
|
||||
><ha-svg-icon
|
||||
<ha-dropdown-item value="edit">
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiPencil}
|
||||
slot="graphic"
|
||||
></ha-svg-icon
|
||||
>${this.hass.localize(
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.category.editor.edit"
|
||||
)}</ha-list-item
|
||||
>
|
||||
<ha-list-item graphic="icon" class="warning"
|
||||
><ha-svg-icon
|
||||
class="warning"
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item value="delete" variant="danger">
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiDelete}
|
||||
slot="graphic"
|
||||
></ha-svg-icon
|
||||
>${this.hass.localize(
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.category.editor.delete"
|
||||
)}</ha-list-item
|
||||
>
|
||||
</ha-button-menu>
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
</ha-list-item>`
|
||||
)}
|
||||
</ha-list>
|
||||
@@ -174,13 +174,14 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
||||
private _handleAction(ev: CustomEvent<{ item: { value: string } }>) {
|
||||
const categoryId = (ev.currentTarget as any).categoryId;
|
||||
switch (ev.detail.index) {
|
||||
case 0:
|
||||
const action = ev.detail.item.value;
|
||||
switch (action) {
|
||||
case "edit":
|
||||
this._editCategory(categoryId);
|
||||
break;
|
||||
case 1:
|
||||
case "delete":
|
||||
this._deleteCategory(categoryId);
|
||||
break;
|
||||
}
|
||||
@@ -316,6 +317,9 @@ export class HaFilterCategories extends SubscribeMixin(LitElement) {
|
||||
--mdc-list-side-padding-right: 4px;
|
||||
--mdc-icon-button-size: 36px;
|
||||
}
|
||||
ha-dropdown-item {
|
||||
font-size: var(--ha-font-size-m);
|
||||
}
|
||||
.warning {
|
||||
color: var(--error-color);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ import { stopPropagation } from "../../common/dom/stop_propagation";
|
||||
import type { LocalizeFunc } from "../../common/translations/localize";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "../ha-button";
|
||||
import "../ha-list-item";
|
||||
import "../ha-dropdown";
|
||||
import "../ha-dropdown-item";
|
||||
import "../ha-svg-icon";
|
||||
import "./ha-form";
|
||||
import type {
|
||||
@@ -116,9 +117,8 @@ export class HaFormOptionalActions extends LitElement implements HaFormElement {
|
||||
: nothing}
|
||||
${hiddenActions.length > 0
|
||||
? html`
|
||||
<ha-button-menu
|
||||
@action=${this._handleAddAction}
|
||||
fixed
|
||||
<ha-dropdown
|
||||
@wa-select=${this._handleAddAction}
|
||||
@closed=${stopPropagation}
|
||||
>
|
||||
<ha-button slot="trigger" appearance="filled" size="small">
|
||||
@@ -129,26 +129,21 @@ export class HaFormOptionalActions extends LitElement implements HaFormElement {
|
||||
${hiddenActions.map((action) => {
|
||||
const actionSchema = schemaMap.get(action);
|
||||
return html`
|
||||
<ha-list-item>
|
||||
<ha-dropdown-item .value=${action}>
|
||||
${this.computeLabel && actionSchema
|
||||
? this.computeLabel(actionSchema)
|
||||
: action}
|
||||
</ha-list-item>
|
||||
</ha-dropdown-item>
|
||||
`;
|
||||
})}
|
||||
</ha-button-menu>
|
||||
</ha-dropdown>
|
||||
`
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleAddAction(ev: CustomEvent) {
|
||||
const hiddenActions = this._hiddenActions(
|
||||
this.schema.schema,
|
||||
this._displayActions ?? NO_ACTIONS
|
||||
);
|
||||
const index = ev.detail.index;
|
||||
const action = hiddenActions[index];
|
||||
private _handleAddAction(ev: CustomEvent<{ item: { value: string } }>) {
|
||||
const action = ev.detail.item.value;
|
||||
this._displayActions = [...(this._displayActions ?? []), action];
|
||||
}
|
||||
|
||||
@@ -161,6 +156,9 @@ export class HaFormOptionalActions extends LitElement implements HaFormElement {
|
||||
:host ha-form {
|
||||
display: block;
|
||||
}
|
||||
ha-dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import type { ActionDetail } from "@material/mwc-list";
|
||||
|
||||
import {
|
||||
mdiArrowCollapseDown,
|
||||
mdiCircle,
|
||||
@@ -31,10 +29,10 @@ import "../../../components/ha-alert";
|
||||
import "../../../components/ha-ansi-to-html";
|
||||
import type { HaAnsiToHtml } from "../../../components/ha-ansi-to-html";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-md-divider";
|
||||
import "../../../components/ha-md-menu";
|
||||
import "../../../components/ha-md-menu-item";
|
||||
@@ -249,32 +247,35 @@ class ErrorLogCard extends LitElement {
|
||||
: nothing}
|
||||
${(this.allowSwitch && this.provider === "core") || hasBoots
|
||||
? html`
|
||||
<ha-button-menu @action=${this._handleOverflowAction}>
|
||||
<ha-icon-button slot="trigger" .path=${mdiDotsVertical}>
|
||||
</ha-icon-button>
|
||||
<ha-dropdown @wa-select=${this._handleOverflowAction}>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.path=${mdiDotsVertical}
|
||||
.label=${localize("ui.common.menu")}
|
||||
></ha-icon-button>
|
||||
${this.allowSwitch && this.provider === "core"
|
||||
? html`<ha-list-item graphic="icon">
|
||||
? html`<ha-dropdown-item value="switch-log-view">
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
slot="icon"
|
||||
.path=${mdiFolderTextOutline}
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.logs.show_condensed_logs"
|
||||
)}
|
||||
</ha-list-item>`
|
||||
</ha-dropdown-item>`
|
||||
: nothing}
|
||||
${hasBoots
|
||||
? html`<ha-list-item graphic="icon">
|
||||
? html`<ha-dropdown-item value="toggle-boots">
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
slot="icon"
|
||||
.path=${mdiFormatListNumbered}
|
||||
></ha-svg-icon>
|
||||
${localize(
|
||||
`ui.panel.config.logs.${this._showBootsSelect ? "hide" : "show"}_haos_boots`
|
||||
)}
|
||||
</ha-list-item>`
|
||||
</ha-dropdown-item>`
|
||||
: nothing}
|
||||
</ha-button-menu>
|
||||
</ha-dropdown>
|
||||
`
|
||||
: nothing}
|
||||
</div>
|
||||
@@ -719,17 +720,14 @@ class ErrorLogCard extends LitElement {
|
||||
this._loadLogs();
|
||||
}
|
||||
|
||||
private _handleOverflowAction(ev: CustomEvent<ActionDetail>) {
|
||||
let index = ev.detail.index;
|
||||
if (this.provider === "core") {
|
||||
index--;
|
||||
}
|
||||
switch (index) {
|
||||
case -1:
|
||||
private _handleOverflowAction(ev: CustomEvent<{ item: { value: string } }>) {
|
||||
const action = ev.detail.item.value;
|
||||
switch (action) {
|
||||
case "switch-log-view":
|
||||
// @ts-ignore
|
||||
fireEvent(this, "switch-log-view");
|
||||
break;
|
||||
case 0:
|
||||
case "toggle-boots":
|
||||
this._showBootsSelect = !this._showBootsSelect;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import type { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import "../../../components/buttons/ha-call-service-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-list";
|
||||
import "../../../components/ha-list-item";
|
||||
@@ -121,19 +122,19 @@ export class SystemLogCard extends LitElement {
|
||||
.label=${this.hass.localize("ui.common.refresh")}
|
||||
></ha-icon-button>
|
||||
|
||||
<ha-button-menu @action=${this._handleOverflowAction}>
|
||||
<ha-icon-button slot="trigger" .path=${mdiDotsVertical}>
|
||||
</ha-icon-button>
|
||||
<ha-list-item graphic="icon">
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiText}
|
||||
></ha-svg-icon>
|
||||
<ha-dropdown @wa-select=${this._handleOverflowAction}>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.path=${mdiDotsVertical}
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
></ha-icon-button>
|
||||
<ha-dropdown-item value="show-full-logs">
|
||||
<ha-svg-icon slot="icon" .path=${mdiText}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.logs.show_full_logs"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
${this._items.length === 0
|
||||
@@ -221,9 +222,11 @@ export class SystemLogCard extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _handleOverflowAction() {
|
||||
// @ts-ignore
|
||||
fireEvent(this, "switch-log-view");
|
||||
private _handleOverflowAction(ev: CustomEvent<{ item: { value: string } }>) {
|
||||
if (ev.detail.item.value === "show-full-logs") {
|
||||
// @ts-ignore
|
||||
fireEvent(this, "switch-log-view");
|
||||
}
|
||||
}
|
||||
|
||||
private async _downloadLogs() {
|
||||
|
||||
Reference in New Issue
Block a user