mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Fix automation picker overflow menu for keyboard (#21048)
* Fix automation picker overflow menu for keyboard * some updates from review * typing * no removeEventListener * updates from review
This commit is contained in:
parent
97c4cf9391
commit
e332364ec0
@ -1,9 +1,11 @@
|
|||||||
import { MdMenuItem } from "@material/web/menu/menu-item";
|
import { MdMenuItem } from "@material/web/menu/menu-item";
|
||||||
import { css } from "lit";
|
import { css } from "lit";
|
||||||
import { customElement } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
|
||||||
@customElement("ha-menu-item")
|
@customElement("ha-menu-item")
|
||||||
export class HaMenuItem extends MdMenuItem {
|
export class HaMenuItem extends MdMenuItem {
|
||||||
|
@property({ attribute: false }) clickAction?: (item?: HTMLElement) => void;
|
||||||
|
|
||||||
static override styles = [
|
static override styles = [
|
||||||
...super.styles,
|
...super.styles,
|
||||||
css`
|
css`
|
||||||
|
@ -1,9 +1,30 @@
|
|||||||
import { MdMenu } from "@material/web/menu/menu";
|
import { MdMenu } from "@material/web/menu/menu";
|
||||||
|
import type { CloseMenuEvent } from "@material/web/menu/menu";
|
||||||
|
import {
|
||||||
|
CloseReason,
|
||||||
|
KeydownCloseKey,
|
||||||
|
} from "@material/web/menu/internal/controllers/shared";
|
||||||
import { css } from "lit";
|
import { css } from "lit";
|
||||||
import { customElement } from "lit/decorators";
|
import { customElement } from "lit/decorators";
|
||||||
|
import type { HaMenuItem } from "./ha-menu-item";
|
||||||
|
|
||||||
@customElement("ha-menu")
|
@customElement("ha-menu")
|
||||||
export class HaMenu extends MdMenu {
|
export class HaMenu extends MdMenu {
|
||||||
|
connectedCallback(): void {
|
||||||
|
super.connectedCallback();
|
||||||
|
this.addEventListener("close-menu", this._handleCloseMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCloseMenu(ev: CloseMenuEvent) {
|
||||||
|
if (
|
||||||
|
ev.detail.reason.kind === CloseReason.KEYDOWN &&
|
||||||
|
ev.detail.reason.key === KeydownCloseKey.ESCAPE
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(ev.detail.initiator as HaMenuItem).clickAction?.(ev.detail.initiator);
|
||||||
|
}
|
||||||
|
|
||||||
static override styles = [
|
static override styles = [
|
||||||
...super.styles,
|
...super.styles,
|
||||||
css`
|
css`
|
||||||
@ -18,4 +39,8 @@ declare global {
|
|||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
"ha-menu": HaMenu;
|
"ha-menu": HaMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface HTMLElementEventMap {
|
||||||
|
"close-menu": CloseMenuEvent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ import "../../../components/ha-icon-overflow-menu";
|
|||||||
import "../../../components/ha-menu";
|
import "../../../components/ha-menu";
|
||||||
import type { HaMenu } from "../../../components/ha-menu";
|
import type { HaMenu } from "../../../components/ha-menu";
|
||||||
import "../../../components/ha-menu-item";
|
import "../../../components/ha-menu-item";
|
||||||
|
import type { HaMenuItem } from "../../../components/ha-menu-item";
|
||||||
import "../../../components/ha-sub-menu";
|
import "../../../components/ha-sub-menu";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import { createAreaRegistryEntry } from "../../../data/area_registry";
|
import { createAreaRegistryEntry } from "../../../data/area_registry";
|
||||||
@ -826,7 +827,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
</ha-fab>
|
</ha-fab>
|
||||||
</hass-tabs-subpage-data-table>
|
</hass-tabs-subpage-data-table>
|
||||||
<ha-menu id="overflow-menu" positioning="fixed">
|
<ha-menu id="overflow-menu" positioning="fixed">
|
||||||
<ha-menu-item @click=${this._showInfo}>
|
<ha-menu-item .clickAction=${this._showInfo}>
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
.path=${mdiInformationOutline}
|
.path=${mdiInformationOutline}
|
||||||
slot="start"
|
slot="start"
|
||||||
@ -836,7 +837,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
</div>
|
</div>
|
||||||
</ha-menu-item>
|
</ha-menu-item>
|
||||||
|
|
||||||
<ha-menu-item @click=${this._showSettings}>
|
<ha-menu-item .clickAction=${this._showSettings}>
|
||||||
<ha-svg-icon .path=${mdiCog} slot="start"></ha-svg-icon>
|
<ha-svg-icon .path=${mdiCog} slot="start"></ha-svg-icon>
|
||||||
<div slot="headline">
|
<div slot="headline">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
@ -844,7 +845,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ha-menu-item>
|
</ha-menu-item>
|
||||||
<ha-menu-item @click=${this._editCategory}>
|
<ha-menu-item .clickAction=${this._editCategory}>
|
||||||
<ha-svg-icon .path=${mdiTag} slot="start"></ha-svg-icon>
|
<ha-svg-icon .path=${mdiTag} slot="start"></ha-svg-icon>
|
||||||
<div slot="headline">
|
<div slot="headline">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
@ -852,13 +853,13 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ha-menu-item>
|
</ha-menu-item>
|
||||||
<ha-menu-item @click=${this._runActions}>
|
<ha-menu-item .clickAction=${this._runActions}>
|
||||||
<ha-svg-icon .path=${mdiPlay} slot="start"></ha-svg-icon>
|
<ha-svg-icon .path=${mdiPlay} slot="start"></ha-svg-icon>
|
||||||
<div slot="headline">
|
<div slot="headline">
|
||||||
${this.hass.localize("ui.panel.config.automation.editor.run")}
|
${this.hass.localize("ui.panel.config.automation.editor.run")}
|
||||||
</div>
|
</div>
|
||||||
</ha-menu-item>
|
</ha-menu-item>
|
||||||
<ha-menu-item @click=${this._showTrace}>
|
<ha-menu-item .clickAction=${this._showTrace}>
|
||||||
<ha-svg-icon .path=${mdiTransitConnection} slot="start"></ha-svg-icon>
|
<ha-svg-icon .path=${mdiTransitConnection} slot="start"></ha-svg-icon>
|
||||||
<div slot="headline">
|
<div slot="headline">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
@ -867,13 +868,13 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
</div>
|
</div>
|
||||||
</ha-menu-item>
|
</ha-menu-item>
|
||||||
<md-divider role="separator" tabindex="-1"></md-divider>
|
<md-divider role="separator" tabindex="-1"></md-divider>
|
||||||
<ha-menu-item @click=${this._duplicate}>
|
<ha-menu-item .clickAction=${this._duplicate}>
|
||||||
<ha-svg-icon .path=${mdiContentDuplicate} slot="start"></ha-svg-icon>
|
<ha-svg-icon .path=${mdiContentDuplicate} slot="start"></ha-svg-icon>
|
||||||
<div slot="headline">
|
<div slot="headline">
|
||||||
${this.hass.localize("ui.panel.config.automation.picker.duplicate")}
|
${this.hass.localize("ui.panel.config.automation.picker.duplicate")}
|
||||||
</div>
|
</div>
|
||||||
</ha-menu-item>
|
</ha-menu-item>
|
||||||
<ha-menu-item @click=${this._toggle}>
|
<ha-menu-item .clickAction=${this._toggle}>
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
.path=${
|
.path=${
|
||||||
this._overflowAutomation?.state === "off"
|
this._overflowAutomation?.state === "off"
|
||||||
@ -892,7 +893,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</ha-menu-item>
|
</ha-menu-item>
|
||||||
<ha-menu-item @click=${this._deleteConfirm} class="warning">
|
<ha-menu-item .clickAction=${this._deleteConfirm} class="warning">
|
||||||
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
|
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
|
||||||
<div slot="headline">
|
<div slot="headline">
|
||||||
${this.hass.localize("ui.panel.config.automation.picker.delete")}
|
${this.hass.localize("ui.panel.config.automation.picker.delete")}
|
||||||
@ -1055,28 +1056,32 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
this._applyFilters();
|
this._applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showInfo(ev) {
|
private _showInfo = (item: HaMenuItem) => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
|
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
|
||||||
}
|
};
|
||||||
|
|
||||||
private _showSettings(ev) {
|
private _showSettings = (item: HaMenuItem) => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
|
|
||||||
fireEvent(this, "hass-more-info", {
|
fireEvent(this, "hass-more-info", {
|
||||||
entityId: automation.entity_id,
|
entityId: automation.entity_id,
|
||||||
view: "settings",
|
view: "settings",
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
private _runActions(ev) {
|
private _runActions = (item: HaMenuItem) => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
|
|
||||||
triggerAutomationActions(this.hass, automation.entity_id);
|
triggerAutomationActions(this.hass, automation.entity_id);
|
||||||
}
|
};
|
||||||
|
|
||||||
private _editCategory(ev) {
|
private _editCategory = (item: HaMenuItem) => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
|
|
||||||
const entityReg = this._entityReg.find(
|
const entityReg = this._entityReg.find(
|
||||||
(reg) => reg.entity_id === automation.entity_id
|
(reg) => reg.entity_id === automation.entity_id
|
||||||
@ -1096,10 +1101,11 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
scope: "automation",
|
scope: "automation",
|
||||||
entityReg,
|
entityReg,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
private _showTrace(ev) {
|
private _showTrace = (item: HaMenuItem) => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
|
|
||||||
if (!automation.attributes.id) {
|
if (!automation.attributes.id) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
@ -1112,19 +1118,21 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
navigate(
|
navigate(
|
||||||
`/config/automation/trace/${encodeURIComponent(automation.attributes.id)}`
|
`/config/automation/trace/${encodeURIComponent(automation.attributes.id)}`
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
private async _toggle(ev): Promise<void> {
|
private _toggle = async (item: HaMenuItem): Promise<void> => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
|
|
||||||
const service = automation.state === "off" ? "turn_on" : "turn_off";
|
const service = automation.state === "off" ? "turn_on" : "turn_off";
|
||||||
await this.hass.callService("automation", service, {
|
await this.hass.callService("automation", service, {
|
||||||
entity_id: automation.entity_id,
|
entity_id: automation.entity_id,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
private async _deleteConfirm(ev) {
|
private _deleteConfirm = async (item: HaMenuItem) => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
|
|
||||||
showConfirmationDialog(this, {
|
showConfirmationDialog(this, {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
@ -1139,7 +1147,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
confirm: () => this._delete(automation),
|
confirm: () => this._delete(automation),
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
private async _delete(automation) {
|
private async _delete(automation) {
|
||||||
try {
|
try {
|
||||||
@ -1159,8 +1167,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _duplicate(ev) {
|
private _duplicate = async (item: HaMenuItem) => {
|
||||||
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
|
||||||
|
.automation;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const config = await fetchAutomationFileConfig(
|
const config = await fetchAutomationFileConfig(
|
||||||
@ -1184,7 +1193,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
private _showHelp() {
|
private _showHelp() {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user