1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-15 07:25:54 +00:00

Migrate button-menu to ha-dropdown 8 files (#29102)

This commit is contained in:
Wendelin
2026-01-21 10:35:25 +01:00
committed by GitHub
parent 5795b8787d
commit 54b72ce2b8
8 changed files with 250 additions and 193 deletions

View File

@@ -1,15 +1,15 @@
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import "@home-assistant/webawesome/dist/components/divider/divider";
import { mdiCog, mdiContentCopy } from "@mdi/js";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { PropertyValues } from "lit";
import { css, html, LitElement } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { slugify } from "../../../../../common/string/slugify";
import { copyToClipboard } from "../../../../../common/util/copy-clipboard";
import { stopPropagation } from "../../../../../common/dom/stop_propagation";
import "../../../../../components/ha-button-menu";
import "../../../../../components/ha-check-list-item";
import "../../../../../components/ha-dropdown";
import "../../../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../../../components/ha-dropdown-item";
import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-textfield";
import type { HaTextField } from "../../../../../components/ha-textfield";
@@ -125,7 +125,11 @@ export class HaWebhookTrigger extends LitElement {
.path=${mdiContentCopy}
></ha-icon-button>
</ha-textfield>
<ha-button-menu multi @closed=${stopPropagation} fixed>
<ha-dropdown
@wa-select=${this._handleDropdownSelect}
placement="bottom-end"
distance="-24"
>
<ha-icon-button
slot="trigger"
.label=${this.hass!.localize(
@@ -135,27 +139,29 @@ export class HaWebhookTrigger extends LitElement {
></ha-icon-button>
${SUPPORTED_METHODS.map(
(method) => html`
<ha-check-list-item
left
<ha-dropdown-item
.value=${method}
type="checkbox"
@request-selected=${this._allowedMethodsChanged}
.selected=${allowedMethods!.includes(method)}
.checked=${allowedMethods!.includes(method)}
>
${method}
</ha-check-list-item>
</ha-dropdown-item>
`
)}
<li divider role="separator"></li>
<ha-check-list-item
left
@request-selected=${this._localOnlyChanged}
.selected=${localOnly!}
${SUPPORTED_METHODS.length
? html`<wa-divider></wa-divider>`
: nothing}
<ha-dropdown-item
type="checkbox"
.checked=${localOnly!}
value="local_only"
>
${this.hass!.localize(
"ui.panel.config.automation.editor.triggers.type.webhook.local_only"
)}
</ha-check-list-item>
</ha-button-menu>
</ha-dropdown-item>
</ha-dropdown>
</div>
`;
}
@@ -164,23 +170,18 @@ export class HaWebhookTrigger extends LitElement {
handleChangeEvent(this, ev);
}
private _localOnlyChanged(ev: CustomEvent<RequestSelectedDetail>): void {
ev.stopPropagation();
if (this.trigger.local_only === ev.detail.selected) {
private _localOnlyChanged(local_only: boolean): void {
if (this.trigger.local_only === local_only) {
return;
}
const newTrigger = {
...this.trigger,
local_only: ev.detail.selected,
local_only,
};
fireEvent(this, "value-changed", { value: newTrigger });
}
private _allowedMethodsChanged(ev: CustomEvent<RequestSelectedDetail>): void {
ev.stopPropagation();
const method = (ev.target as any).value;
const selected = ev.detail.selected;
private _allowedMethodsChanged(method: string, selected: boolean): void {
if (selected === this.trigger.allowed_methods?.includes(method)) {
return;
}
@@ -207,6 +208,22 @@ export class HaWebhookTrigger extends LitElement {
});
}
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
ev.preventDefault(); // don't close the dropdown to select multiple options
const action = ev.detail?.item?.value;
if (!action) {
return;
}
if (action === "local_only") {
this._localOnlyChanged(ev.detail.item.checked);
return;
}
this._allowedMethodsChanged(ev.detail.item.value, ev.detail.item.checked);
}
static styles = css`
.flex {
display: flex;
@@ -222,7 +239,7 @@ export class HaWebhookTrigger extends LitElement {
color: var(--secondary-text-color);
}
ha-button-menu {
ha-dropdown ha-icon-button {
padding-top: 4px;
}
`;

View File

@@ -16,7 +16,6 @@ import { relativeTime } from "../../../common/datetime/relative_time";
import { storage } from "../../../common/decorators/storage";
import { fireEvent, type HASSDomEvent } from "../../../common/dom/fire_event";
import { computeDomain } from "../../../common/entity/compute_domain";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import { navigate } from "../../../common/navigate";
import type { LocalizeFunc } from "../../../common/translations/localize";
import type {
@@ -26,14 +25,18 @@ import type {
SelectionChangedEvent,
} from "../../../components/data-table/ha-data-table";
import "../../../components/ha-button";
import "../../../components/ha-button-menu";
import "../../../components/ha-spinner";
import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import "../../../components/ha-fab";
import "../../../components/ha-filter-states";
import "../../../components/ha-icon";
import "../../../components/ha-icon-next";
import "../../../components/ha-icon-overflow-menu";
import "../../../components/ha-list-item";
import "../../../components/ha-md-menu";
import type { HaMdMenu } from "../../../components/ha-md-menu";
import "../../../components/ha-md-menu-item";
import "../../../components/ha-spinner";
import "../../../components/ha-svg-icon";
import type {
BackupAgent,
@@ -71,9 +74,6 @@ import { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup"
import { showNewBackupDialog } from "./dialogs/show-dialog-new-backup";
import { showUploadBackupDialog } from "./dialogs/show-dialog-upload-backup";
import { downloadBackup } from "./helper/download_backup";
import type { HaMdMenu } from "../../../components/ha-md-menu";
import "../../../components/ha-md-menu";
import "../../../components/ha-md-menu-item";
interface BackupRow extends DataTableRowData, BackupContent {
formatted_type: string;
@@ -401,22 +401,22 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
)}
>
<div slot="toolbar-icon">
<ha-button-menu>
<ha-dropdown
@wa-select=${this._handleDropdownSelect}
placement="bottom-end"
>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-list-item
graphic="icon"
@request-selected=${this._uploadBackup}
>
<ha-svg-icon slot="graphic" .path=${mdiUpload}></ha-svg-icon>
<ha-dropdown-item value="upload_backup">
<ha-svg-icon slot="icon" .path=${mdiUpload}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.backup.backups.menu.upload_backup"
)}
</ha-list-item>
</ha-button-menu>
</ha-dropdown-item>
</ha-dropdown>
</div>
<div slot="selection-bar">
@@ -447,7 +447,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
<ha-filter-states
.hass=${this.hass}
.label=${this.hass.localize("ui.panel.config.backup.backup_type")}
.value=${this._filters["ha-filter-states"]}
.value="${this._filters["ha-filter-states"]}q"
.states=${this._states(this.hass.localize, isHassio)}
@data-table-filter-changed=${this._filterChanged}
slot="filter-pane"
@@ -519,13 +519,9 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
return !this.config?.automatic_backups_configured;
}
private async _uploadBackup(ev) {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
private _uploadBackup = async () => {
await showUploadBackupDialog(this, {});
}
};
private async _newBackup(): Promise<void> {
const config = this.config!;
@@ -635,6 +631,14 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
this._dataTable.clearSelection();
}
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
const action = ev.detail?.item.value;
if (action === "upload_backup") {
this._uploadBackup();
}
}
static get styles(): CSSResultGroup {
return [
haStyle,

View File

@@ -3,16 +3,16 @@ import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
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-spinner";
import "../../../components/ha-icon";
import "../../../components/ha-icon-next";
import "../../../components/ha-icon-overflow-menu";
import "../../../components/ha-list-item";
import "../../../components/ha-spinner";
import "../../../components/ha-svg-icon";
import type {
BackupAgent,
@@ -63,13 +63,9 @@ class HaConfigBackupOverview extends LitElement {
@property({ attribute: false }) public agents: BackupAgent[] = [];
private async _uploadBackup(ev) {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
private _uploadBackup = async () => {
await showUploadBackupDialog(this, {});
}
};
private _handleOnboardingButtonClick(ev) {
ev.stopPropagation();
@@ -143,19 +139,23 @@ class HaConfigBackupOverview extends LitElement {
.narrow=${this.narrow}
.header=${this.hass.localize("ui.panel.config.backup.overview.header")}
>
<ha-button-menu slot="toolbar-icon">
<ha-dropdown
slot="toolbar-icon"
placement="bottom-end"
@wa-select=${this._handleDropdownSelect}
>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-list-item graphic="icon" @request-selected=${this._uploadBackup}>
<ha-svg-icon slot="graphic" .path=${mdiUpload}></ha-svg-icon>
<ha-dropdown-item value="upload_backup">
<ha-svg-icon slot="icon" .path=${mdiUpload}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.backup.overview.menu.upload_backup"
)}
</ha-list-item>
</ha-button-menu>
</ha-dropdown-item>
</ha-dropdown>
<div class="content">
${this.info && Object.keys(this.info.agent_errors).length
? html`${Object.entries(this.info.agent_errors).map(
@@ -240,6 +240,14 @@ class HaConfigBackupOverview extends LitElement {
`;
}
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
const action = ev.detail?.item.value;
if (action === "upload_backup") {
this._uploadBackup();
}
}
static get styles(): CSSResultGroup {
return [
haStyle,

View File

@@ -4,16 +4,16 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { fireEvent } from "../../../common/dom/fire_event";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import { debounce } from "../../../common/util/debounce";
import { nextRender } from "../../../common/util/render-status";
import "../../../components/ha-alert";
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-icon-button";
import "../../../components/ha-icon-next";
import "../../../components/ha-list-item";
import "../../../components/ha-password-field";
import "../../../components/ha-svg-icon";
import type { BackupAgent, BackupConfig } from "../../../data/backup";
@@ -26,6 +26,7 @@ import {
} from "../../../data/supervisor/update";
import "../../../layouts/hass-subpage";
import type { HomeAssistant } from "../../../types";
import { brandsUrl } from "../../../util/brands-url";
import { documentationUrl } from "../../../util/documentation-url";
import "./components/config/ha-backup-config-addon";
import "./components/config/ha-backup-config-agents";
@@ -35,7 +36,6 @@ import "./components/config/ha-backup-config-encryption-key";
import "./components/config/ha-backup-config-schedule";
import type { BackupConfigSchedule } from "./components/config/ha-backup-config-schedule";
import { showLocalBackupLocationDialog } from "./dialogs/show-dialog-local-backup-location";
import { brandsUrl } from "../../../util/brands-url";
@customElement("ha-config-backup-settings")
class HaConfigBackupSettings extends LitElement {
@@ -140,25 +140,22 @@ class HaConfigBackupSettings extends LitElement {
>
${supervisor
? html`
<ha-button-menu slot="toolbar-icon">
<ha-dropdown
slot="toolbar-icon"
@wa-select=${this._handleDropdownSelect}
>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-list-item
graphic="icon"
@request-selected=${this._changeLocalLocation}
>
<ha-svg-icon
slot="graphic"
.path=${mdiHarddisk}
></ha-svg-icon>
<ha-dropdown-item value="change_local_location">
<ha-svg-icon slot="icon" .path=${mdiHarddisk}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.backup.settings.menu.change_default_location"
)}
</ha-list-item>
</ha-button-menu>
</ha-dropdown-item>
</ha-dropdown>
`
: nothing}
@@ -372,13 +369,9 @@ class HaConfigBackupSettings extends LitElement {
`;
}
private async _changeLocalLocation(ev) {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
private _changeLocalLocation = () => {
showLocalBackupLocationDialog(this, {});
}
};
private async _supervisorUpdateConfigChanged(ev) {
const config = ev.detail.value as SupervisorUpdateConfig;
@@ -499,6 +492,14 @@ class HaConfigBackupSettings extends LitElement {
fireEvent(this, "ha-refresh-backup-config");
}
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
const action = ev.detail?.item?.value;
if (action === "change_local_location") {
this._changeLocalLocation();
}
}
static styles = css`
ha-card {
scroll-margin-top: 16px;

View File

@@ -6,13 +6,14 @@ import {
mdiOpenInNew,
} from "@mdi/js";
import type { TemplateResult } from "lit";
import { LitElement, css, html } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-button";
import "../../../components/ha-button-menu";
import "../../../components/ha-list-item";
import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import {
deleteApplicationCredential,
fetchApplicationCredentialsConfigEntry,
@@ -53,7 +54,7 @@ export class HaConfigFlowCard extends LitElement {
.hass=${this.hass}
.manifest=${this.manifest}
.domain=${this.flow.handler}
.label=${this.flow.localized_title}
.label=${this.flow.localized_title ?? ""}
>
${DISCOVERY_SOURCES.includes(this.flow.context.source) &&
this.flow.context.unique_id
@@ -62,7 +63,7 @@ export class HaConfigFlowCard extends LitElement {
"ui.panel.config.integrations.ignore.ignore"
)}</ha-button
>`
: ""}
: nothing}
<ha-button
@click=${this._continueFlow}
variant=${attention ? "danger" : "brand"}
@@ -75,7 +76,11 @@ export class HaConfigFlowCard extends LitElement {
)}
</ha-button>
${this.flow.context.configuration_url || this.manifest || attention
? html`<ha-button-menu slot="header-button">
? html`<ha-dropdown
slot="header-button"
placement="bottom-end"
@wa-select=${this._handleDropdownSelect}
>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
@@ -94,18 +99,18 @@ export class HaConfigFlowCard extends LitElement {
? "_self"
: "_blank"}
>
<ha-list-item graphic="icon" hasMeta>
<ha-dropdown-item>
${this.hass.localize(
"ui.panel.config.integrations.config_entry.open_configuration_url"
)}
<ha-svg-icon slot="graphic" .path=${mdiCog}></ha-svg-icon>
<ha-svg-icon slot="icon" .path=${mdiCog}></ha-svg-icon>
<ha-svg-icon
slot="meta"
slot="details"
.path=${mdiOpenInNew}
></ha-svg-icon>
</ha-list-item>
</ha-dropdown-item>
</a>`
: ""}
: nothing}
${this.manifest
? html`<a
href=${this.manifest.is_built_in
@@ -117,39 +122,31 @@ export class HaConfigFlowCard extends LitElement {
rel="noreferrer"
target="_blank"
>
<ha-list-item graphic="icon" hasMeta>
<ha-dropdown-item>
${this.hass.localize(
"ui.panel.config.integrations.config_entry.documentation"
)}
<ha-svg-icon
slot="graphic"
slot="icon"
.path=${mdiBookshelf}
></ha-svg-icon>
<ha-svg-icon
slot="meta"
slot="details"
.path=${mdiOpenInNew}
></ha-svg-icon>
</ha-list-item>
</ha-dropdown-item>
</a>`
: ""}
: nothing}
${attention
? html`<ha-list-item
class="warning"
graphic="icon"
@click=${this._handleDelete}
>
<ha-svg-icon
class="warning"
slot="graphic"
.path=${mdiDelete}
></ha-svg-icon>
? html`<ha-dropdown-item variant="danger" value="delete">
<ha-svg-icon slot="icon" .path=${mdiDelete}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.integrations.config_entry.delete"
)}
</ha-list-item>`
: ""}
</ha-button-menu>`
: ""}
</ha-dropdown-item>`
: nothing}
</ha-dropdown>`
: nothing}
</ha-integration-action-card>
`;
}
@@ -263,7 +260,7 @@ export class HaConfigFlowCard extends LitElement {
}
}
private async _handleDelete() {
private _handleDelete = async () => {
const entryId = this.flow.context.entry_id;
if (!entryId) {
@@ -306,6 +303,14 @@ export class HaConfigFlowCard extends LitElement {
}
this._handleFlowUpdated();
};
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
const action = ev.detail?.item?.value;
if (action === "delete") {
this._handleDelete();
}
}
static styles = css`
@@ -313,7 +318,7 @@ export class HaConfigFlowCard extends LitElement {
text-decoration: none;
color: var(--primary-color);
}
ha-button-menu {
ha-dropdown {
color: var(--secondary-text-color);
}
ha-svg-icon[slot="meta"] {
@@ -324,9 +329,6 @@ export class HaConfigFlowCard extends LitElement {
--mdc-theme-primary: var(--error-color);
--ha-card-border-color: var(--error-color);
}
.warning {
--mdc-theme-text-primary-on-background: var(--error-color);
}
`;
}

View File

@@ -4,8 +4,10 @@ import { customElement, property, state } from "lit/decorators";
import { cache } from "lit/directives/cache";
import "../../../components/ha-alert";
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-expansion-panel";
import "../../../components/ha-formfield";
import "../../../components/ha-icon-button";
@@ -476,9 +478,9 @@ export class HassioNetwork extends LitElement {
<div class="address-row">
<ha-textfield
id="nameserver"
.label=${this.hass.localize(
.label=${`${this.hass.localize(
"ui.panel.config.network.supervisor.dns_server"
)}
)}${this._getPredefinedDnsName(nameserver, version)}`}
.version=${version}
.value=${nameserver}
.index=${index}
@@ -500,13 +502,12 @@ export class HassioNetwork extends LitElement {
`
)}
</div>
<ha-button-menu
@opened=${this._handleDNSMenuOpened}
@closed=${this._handleDNSMenuClosed}
<ha-dropdown
@wa-show=${this._handleDNSMenuOpened}
@wa-hide=${this._handleDNSMenuClosed}
.version=${version}
@wa-select=${this._handleDropdownSelect}
class="add-nameserver"
appearance="filled"
size="small"
>
<ha-button appearance="filled" size="small" slot="trigger">
${this.hass.localize(
@@ -519,27 +520,38 @@ export class HassioNetwork extends LitElement {
</ha-button>
${Object.entries(PREDEFINED_DNS[version]).map(
([name, addresses]) => html`
<ha-list-item
@click=${this._addPredefinedDNS}
<ha-dropdown-item
value="add_predefined"
.version=${version}
.addresses=${addresses}
>
${name}
</ha-list-item>
</ha-dropdown-item>
`
)}
<ha-list-item @click=${this._addCustomDNS} .version=${version}>
<ha-dropdown-item value="add_custom" .version=${version}>
${this.hass.localize(
"ui.panel.config.network.supervisor.custom_dns"
)}
</ha-list-item>
</ha-button-menu>
</ha-dropdown-item>
</ha-dropdown>
`
: nothing}
</ha-expansion-panel>
`;
}
private _getPredefinedDnsName(nameserver: string, version: string) {
for (const [name, addresses] of Object.entries(
PREDEFINED_DNS[version as "ipv4" | "ipv6"]
)) {
if (addresses.includes(nameserver)) {
return ` - ${name}`;
}
}
return "";
}
private async _updateNetwork() {
this._processing = true;
let interfaceOptions: Partial<NetworkInterface> = {};
@@ -747,10 +759,7 @@ export class HassioNetwork extends LitElement {
this._dnsMenuOpen = false;
}
private _addPredefinedDNS(ev: Event) {
const source = ev.target as any;
const version = source.version as "ipv4" | "ipv6";
const addresses = source.addresses as string[];
private _addPredefinedDNS(version: "ipv4" | "ipv6", addresses: string[]) {
if (!this._interface![version]!.nameservers) {
this._interface![version]!.nameservers = [];
}
@@ -759,9 +768,7 @@ export class HassioNetwork extends LitElement {
this.requestUpdate("_interface");
}
private _addCustomDNS(ev: Event) {
const source = ev.target as any;
const version = source.version as "ipv4" | "ipv6";
private _addCustomDNS(version: "ipv4" | "ipv6") {
if (!this._interface![version]!.nameservers) {
this._interface![version]!.nameservers = [];
}
@@ -779,6 +786,22 @@ export class HassioNetwork extends LitElement {
this.requestUpdate("_interface");
}
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
const action = ev.detail?.item?.value;
if (action === "add_predefined") {
this._addPredefinedDNS(
(ev.detail.item as any).version,
(ev.detail.item as any).addresses
);
return;
}
if (action === "add_custom") {
this._addCustomDNS((ev.detail.item as any).version);
}
}
static get styles(): CSSResultGroup {
return [
css`
@@ -817,6 +840,10 @@ export class HassioNetwork extends LitElement {
--mdc-icon-button-size: 36px;
margin-top: 16px;
}
ha-dropdown {
display: block;
}
.add-address,
.add-nameserver {
margin-top: 16px;

View File

@@ -1,17 +1,17 @@
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item-base";
import "@home-assistant/webawesome/dist/components/divider/divider";
import { mdiDotsVertical } from "@mdi/js";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { TemplateResult } from "lit";
import { css, html, LitElement } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import { navigate } from "../../../common/navigate";
import { extractSearchParam } from "../../../common/url/search-params";
import "../../../components/ha-card";
import "../../../components/ha-check-list-item";
import "../../../components/ha-list-item";
import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import type { RepairsIssue } from "../../../data/repairs";
import {
severitySort,
@@ -81,40 +81,36 @@ class HaConfigRepairsDashboard extends SubscribeMixin(LitElement) {
.header=${this.hass.localize("ui.panel.config.repairs.caption")}
>
<div slot="toolbar-icon">
<ha-button-menu multi>
<ha-dropdown @wa-select=${this._handleDropdownSelect}>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-check-list-item
left
@request-selected=${this._toggleIgnored}
.selected=${this._showIgnored}
<ha-dropdown-item
type="checkbox"
value="toggle_ignored"
.checked=${this._showIgnored}
>
${this.hass.localize("ui.panel.config.repairs.show_ignored")}
</ha-check-list-item>
<li divider role="separator"></li>
</ha-dropdown-item>
<wa-divider></wa-divider>
${isComponentLoaded(this.hass, "system_health") ||
isComponentLoaded(this.hass, "hassio")
? html`
<ha-list-item
@request-selected=${this._showSystemInformationDialog}
>
<ha-dropdown-item value="system_information">
${this.hass.localize(
"ui.panel.config.repairs.system_information"
)}
</ha-list-item>
</ha-dropdown-item>
`
: ""}
<ha-list-item
@request-selected=${this._showIntegrationStartupDialog}
>
: nothing}
<ha-dropdown-item value="integration_startup_time">
${this.hass.localize(
"ui.panel.config.repairs.integration_startup_time"
)}
</ha-list-item>
</ha-button-menu>
</ha-dropdown-item>
</ha-dropdown>
</div>
<div class="content">
<ha-card outlined>
@@ -141,34 +137,34 @@ class HaConfigRepairsDashboard extends SubscribeMixin(LitElement) {
`;
}
private _showSystemInformationDialog(
ev: CustomEvent<RequestSelectedDetail>
): void {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
private _showSystemInformationDialog(): void {
showSystemInformationDialog(this);
}
private _showIntegrationStartupDialog(
ev: CustomEvent<RequestSelectedDetail>
): void {
if (!shouldHandleRequestSelectedEvent(ev)) {
return;
}
private _showIntegrationStartupDialog(): void {
showIntegrationStartupDialog(this);
}
private _toggleIgnored(ev: CustomEvent<RequestSelectedDetail>): void {
if (ev.detail.source !== "property") {
return;
}
private _toggleIgnored(): void {
this._showIgnored = !this._showIgnored;
}
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
const action = ev.detail?.item?.value;
switch (action) {
case "toggle_ignored":
this._toggleIgnored();
break;
case "system_information":
this._showSystemInformationDialog();
break;
case "integration_startup_time":
this._showIntegrationStartupDialog();
break;
}
}
static styles = css`
.content {
padding: 28px 20px 0;

View File

@@ -4,12 +4,12 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../common/dom/fire_event";
import { stopPropagation } from "../../../common/dom/stop_propagation";
import { computeDomain } from "../../../common/entity/compute_domain";
import "../../../components/ha-button";
import "../../../components/ha-dialog-header";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import "../../../components/ha-form/ha-form";
import "../../../components/ha-list-item";
import type {
AssistPipeline,
AssistPipelineMutableParams,
@@ -152,22 +152,20 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement {
this._params.hideWakeWord ||
!this._hasWakeWorkEntities(this.hass.states)
? nothing
: html`<ha-button-menu
: html`<ha-dropdown
slot="actionItems"
@action=${this._handleShowWakeWord}
@closed=${stopPropagation}
menu-corner="END"
corner="BOTTOM_END"
@wa-select=${this._handleDropdownSelect}
placement="bottom-end"
>
<ha-icon-button
.path=${mdiDotsVertical}
slot="trigger"
></ha-icon-button>
<ha-list-item>
<ha-dropdown-item value="show_wake_word">
${this.hass.localize(
"ui.panel.config.voice_assistants.assistants.pipeline.detail.add_streaming_wake_word"
)}
</ha-list-item></ha-button-menu
</ha-dropdown-item></ha-dropdown
>`}
</ha-dialog-header>
<div class="content">
@@ -243,8 +241,12 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement {
`;
}
private _handleShowWakeWord() {
this._hideWakeWord = false;
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
const action = ev.detail?.item?.value;
if (action === "show_wake_word") {
this._hideWakeWord = false;
}
}
private _valueChanged(ev: CustomEvent) {