Skip to content

Commit

Permalink
Fix automation picker overflow menu for keyboard (#21048)
Browse files Browse the repository at this point in the history
* Fix automation picker overflow menu for keyboard

* some updates from review

* typing

* no removeEventListener

* updates from review
  • Loading branch information
karwosts authored Jul 3, 2024
1 parent 97c4cf9 commit e332364
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 33 deletions.
4 changes: 3 additions & 1 deletion src/components/ha-menu-item.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { MdMenuItem } from "@material/web/menu/menu-item";
import { css } from "lit";
import { customElement } from "lit/decorators";
import { customElement, property } from "lit/decorators";

@customElement("ha-menu-item")
export class HaMenuItem extends MdMenuItem {
@property({ attribute: false }) clickAction?: (item?: HTMLElement) => void;

static override styles = [
...super.styles,
css`
Expand Down
25 changes: 25 additions & 0 deletions src/components/ha-menu.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
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 { customElement } from "lit/decorators";
import type { HaMenuItem } from "./ha-menu-item";

@customElement("ha-menu")
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 = [
...super.styles,
css`
Expand All @@ -18,4 +39,8 @@ declare global {
interface HTMLElementTagNameMap {
"ha-menu": HaMenu;
}

interface HTMLElementEventMap {
"close-menu": CloseMenuEvent;
}
}
73 changes: 41 additions & 32 deletions src/panels/config/automation/ha-automation-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import "../../../components/ha-icon-overflow-menu";
import "../../../components/ha-menu";
import type { HaMenu } from "../../../components/ha-menu";
import "../../../components/ha-menu-item";
import type { HaMenuItem } from "../../../components/ha-menu-item";
import "../../../components/ha-sub-menu";
import "../../../components/ha-svg-icon";
import { createAreaRegistryEntry } from "../../../data/area_registry";
Expand Down Expand Up @@ -826,7 +827,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
</ha-fab>
</hass-tabs-subpage-data-table>
<ha-menu id="overflow-menu" positioning="fixed">
<ha-menu-item @click=${this._showInfo}>
<ha-menu-item .clickAction=${this._showInfo}>
<ha-svg-icon
.path=${mdiInformationOutline}
slot="start"
Expand All @@ -836,29 +837,29 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
</div>
</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>
<div slot="headline">
${this.hass.localize(
"ui.panel.config.automation.picker.show_settings"
)}
</div>
</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>
<div slot="headline">
${this.hass.localize(
`ui.panel.config.automation.picker.${this._overflowAutomation?.category ? "edit_category" : "assign_category"}`
)}
</div>
</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>
<div slot="headline">
${this.hass.localize("ui.panel.config.automation.editor.run")}
</div>
</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>
<div slot="headline">
${this.hass.localize(
Expand All @@ -867,13 +868,13 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
</div>
</ha-menu-item>
<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>
<div slot="headline">
${this.hass.localize("ui.panel.config.automation.picker.duplicate")}
</div>
</ha-menu-item>
<ha-menu-item @click=${this._toggle}>
<ha-menu-item .clickAction=${this._toggle}>
<ha-svg-icon
.path=${
this._overflowAutomation?.state === "off"
Expand All @@ -892,7 +893,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
}
</div>
</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>
<div slot="headline">
${this.hass.localize("ui.panel.config.automation.picker.delete")}
Expand Down Expand Up @@ -1055,28 +1056,32 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
this._applyFilters();
}

private _showInfo(ev) {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _showInfo = (item: HaMenuItem) => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
}
};

private _showSettings(ev) {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _showSettings = (item: HaMenuItem) => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;

fireEvent(this, "hass-more-info", {
entityId: automation.entity_id,
view: "settings",
});
}
};

private _runActions(ev) {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _runActions = (item: HaMenuItem) => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;

triggerAutomationActions(this.hass, automation.entity_id);
}
};

private _editCategory(ev) {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _editCategory = (item: HaMenuItem) => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;

const entityReg = this._entityReg.find(
(reg) => reg.entity_id === automation.entity_id
Expand All @@ -1096,10 +1101,11 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
scope: "automation",
entityReg,
});
}
};

private _showTrace(ev) {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _showTrace = (item: HaMenuItem) => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;

if (!automation.attributes.id) {
showAlertDialog(this, {
Expand All @@ -1112,19 +1118,21 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
navigate(
`/config/automation/trace/${encodeURIComponent(automation.attributes.id)}`
);
}
};

private async _toggle(ev): Promise<void> {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _toggle = async (item: HaMenuItem): Promise<void> => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;

const service = automation.state === "off" ? "turn_on" : "turn_off";
await this.hass.callService("automation", service, {
entity_id: automation.entity_id,
});
}
};

private async _deleteConfirm(ev) {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _deleteConfirm = async (item: HaMenuItem) => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;

showConfirmationDialog(this, {
title: this.hass.localize(
Expand All @@ -1139,7 +1147,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
confirm: () => this._delete(automation),
destructive: true,
});
}
};

private async _delete(automation) {
try {
Expand All @@ -1159,8 +1167,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
}
}

private async _duplicate(ev) {
const automation = ev.currentTarget.parentElement.anchorElement.automation;
private _duplicate = async (item: HaMenuItem) => {
const automation = ((item.parentElement as HaMenu)!.anchorElement as any)!
.automation;

try {
const config = await fetchAutomationFileConfig(
Expand All @@ -1184,7 +1193,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
),
});
}
}
};

private _showHelp() {
showAlertDialog(this, {
Expand Down

0 comments on commit e332364

Please sign in to comment.