mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 19:56:42 +00:00
Fix and optimize automation overflow (#20293)
* WIP fix and optimize automation overflow * finish * Prettier --------- Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
This commit is contained in:
parent
2e58d6656c
commit
4fb42d3545
@ -627,9 +627,13 @@ export class HaDataTable extends LitElement {
|
|||||||
ev
|
ev
|
||||||
.composedPath()
|
.composedPath()
|
||||||
.find((el) =>
|
.find((el) =>
|
||||||
["ha-checkbox", "mwc-button", "ha-button", "ha-assist-chip"].includes(
|
[
|
||||||
(el as HTMLElement).localName
|
"ha-checkbox",
|
||||||
)
|
"mwc-button",
|
||||||
|
"ha-button",
|
||||||
|
"ha-icon-button",
|
||||||
|
"ha-assist-chip",
|
||||||
|
].includes((el as HTMLElement).localName)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
@ -556,7 +556,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
|
|||||||
></ha-svg-icon
|
></ha-svg-icon
|
||||||
><ha-svg-icon slot="end" .path=${mdiPlus}></ha-svg-icon>
|
><ha-svg-icon slot="end" .path=${mdiPlus}></ha-svg-icon>
|
||||||
</ha-list-item-new>
|
</ha-list-item-new>
|
||||||
<md-divider></md-divider>`
|
<md-divider role="separator" tabindex="-1"></md-divider>`
|
||||||
: ""}
|
: ""}
|
||||||
${repeat(
|
${repeat(
|
||||||
items,
|
items,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { consume } from "@lit-labs/context";
|
import { consume } from "@lit-labs/context";
|
||||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
||||||
|
import "@material/web/divider/divider";
|
||||||
import {
|
import {
|
||||||
mdiChevronRight,
|
mdiChevronRight,
|
||||||
mdiCog,
|
mdiCog,
|
||||||
@ -30,7 +31,7 @@ import {
|
|||||||
html,
|
html,
|
||||||
nothing,
|
nothing,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { computeCssColor } from "../../../common/color/compute-color";
|
import { computeCssColor } from "../../../common/color/compute-color";
|
||||||
@ -58,6 +59,7 @@ import "../../../components/ha-filter-floor-areas";
|
|||||||
import "../../../components/ha-filter-labels";
|
import "../../../components/ha-filter-labels";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-icon-overflow-menu";
|
import "../../../components/ha-icon-overflow-menu";
|
||||||
|
import "../../../components/ha-menu";
|
||||||
import "../../../components/ha-menu-item";
|
import "../../../components/ha-menu-item";
|
||||||
import "../../../components/ha-sub-menu";
|
import "../../../components/ha-sub-menu";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
@ -99,6 +101,7 @@ import { turnOnOffEntity } from "../../lovelace/common/entity/turn-on-off-entity
|
|||||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import { showNewAutomationDialog } from "./show-dialog-new-automation";
|
import { showNewAutomationDialog } from "./show-dialog-new-automation";
|
||||||
|
import type { HaMenu } from "../../../components/ha-menu";
|
||||||
|
|
||||||
type AutomationItem = AutomationEntity & {
|
type AutomationItem = AutomationEntity & {
|
||||||
name: string;
|
name: string;
|
||||||
@ -143,6 +146,10 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
_entityReg!: EntityRegistryEntry[];
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
|
@state() private _overflowAutomation?: AutomationItem;
|
||||||
|
|
||||||
|
@query("#overflow-menu") private _overflowMenu!: HaMenu;
|
||||||
|
|
||||||
private _automations = memoizeOne(
|
private _automations = memoizeOne(
|
||||||
(
|
(
|
||||||
automations: AutomationEntity[],
|
automations: AutomationEntity[],
|
||||||
@ -291,89 +298,33 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
columns.actions = {
|
columns.actions = {
|
||||||
title: "",
|
title: "",
|
||||||
width: "64px",
|
width: "64px",
|
||||||
type: "overflow-menu",
|
type: "icon-button",
|
||||||
template: (automation) => html`
|
template: (automation) => html`
|
||||||
<ha-icon-overflow-menu
|
<ha-icon-button
|
||||||
.hass=${this.hass}
|
.automation=${automation}
|
||||||
narrow
|
.label=${this.hass.localize("ui.common.overflow_menu")}
|
||||||
.items=${[
|
.path=${mdiDotsVertical}
|
||||||
{
|
@click=${this._showOverflowMenu}
|
||||||
path: mdiInformationOutline,
|
></ha-icon-button>
|
||||||
label: this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.show_info"
|
|
||||||
),
|
|
||||||
action: () => this._showInfo(automation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: mdiCog,
|
|
||||||
label: this.hass.localize(
|
|
||||||
"ui.panel.config.automation.picker.show_settings"
|
|
||||||
),
|
|
||||||
action: () => this._showSettings(automation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: mdiTag,
|
|
||||||
label: this.hass.localize(
|
|
||||||
`ui.panel.config.automation.picker.${automation.category ? "edit_category" : "assign_category"}`
|
|
||||||
),
|
|
||||||
action: () => this._editCategory(automation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: mdiPlay,
|
|
||||||
label: this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.run"
|
|
||||||
),
|
|
||||||
action: () => this._runActions(automation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: mdiTransitConnection,
|
|
||||||
label: this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.show_trace"
|
|
||||||
),
|
|
||||||
action: () => this._showTrace(automation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
divider: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: mdiContentDuplicate,
|
|
||||||
label: this.hass.localize(
|
|
||||||
"ui.panel.config.automation.picker.duplicate"
|
|
||||||
),
|
|
||||||
action: () => this.duplicate(automation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path:
|
|
||||||
automation.state === "off"
|
|
||||||
? mdiPlayCircleOutline
|
|
||||||
: mdiStopCircleOutline,
|
|
||||||
label:
|
|
||||||
automation.state === "off"
|
|
||||||
? this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.enable"
|
|
||||||
)
|
|
||||||
: this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.disable"
|
|
||||||
),
|
|
||||||
action: () => this._toggle(automation),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.hass.localize(
|
|
||||||
"ui.panel.config.automation.picker.delete"
|
|
||||||
),
|
|
||||||
path: mdiDelete,
|
|
||||||
action: () => this._deleteConfirm(automation),
|
|
||||||
warning: true,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
</ha-icon-overflow-menu>
|
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private _showOverflowMenu = (ev) => {
|
||||||
|
if (
|
||||||
|
this._overflowMenu.open &&
|
||||||
|
ev.target === this._overflowMenu.anchorElement
|
||||||
|
) {
|
||||||
|
this._overflowMenu.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._overflowAutomation = ev.target.automation;
|
||||||
|
this._overflowMenu.anchorElement = ev.target;
|
||||||
|
this._overflowMenu.show();
|
||||||
|
};
|
||||||
|
|
||||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
||||||
return [
|
return [
|
||||||
subscribeCategoryRegistry(
|
subscribeCategoryRegistry(
|
||||||
@ -689,6 +640,80 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||||
</ha-fab>
|
</ha-fab>
|
||||||
</hass-tabs-subpage-data-table>
|
</hass-tabs-subpage-data-table>
|
||||||
|
<ha-menu id="overflow-menu" positioning="fixed">
|
||||||
|
<ha-menu-item @click=${this._showInfo}>
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiInformationOutline}
|
||||||
|
slot="start"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div slot="headline">
|
||||||
|
${this.hass.localize("ui.panel.config.automation.editor.show_info")}
|
||||||
|
</div>
|
||||||
|
</ha-menu-item>
|
||||||
|
|
||||||
|
<ha-menu-item @click=${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-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-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-svg-icon .path=${mdiTransitConnection} slot="start"></ha-svg-icon>
|
||||||
|
<div slot="headline">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.show_trace"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ha-menu-item>
|
||||||
|
<md-divider role="separator" tabindex="-1"></md-divider>
|
||||||
|
<ha-menu-item @click=${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-svg-icon
|
||||||
|
.path=${
|
||||||
|
this._overflowAutomation?.state === "off"
|
||||||
|
? mdiPlayCircleOutline
|
||||||
|
: mdiStopCircleOutline
|
||||||
|
}
|
||||||
|
slot="start"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div slot="headline">
|
||||||
|
${
|
||||||
|
this._overflowAutomation?.state === "off"
|
||||||
|
? this.hass.localize("ui.panel.config.automation.editor.enable")
|
||||||
|
: this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.disable"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</ha-menu-item>
|
||||||
|
<ha-menu-item @click=${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")}
|
||||||
|
</div>
|
||||||
|
</ha-menu-item>
|
||||||
|
</ha-menu>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,22 +840,29 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
this._applyFilters();
|
this._applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showInfo(automation: any) {
|
private _showInfo(ev) {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
||||||
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
|
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showSettings(automation: any) {
|
private _showSettings(ev) {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.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(automation: any) {
|
private _runActions(ev) {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
||||||
|
|
||||||
triggerAutomationActions(this.hass, automation.entity_id);
|
triggerAutomationActions(this.hass, automation.entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _editCategory(automation: any) {
|
private _editCategory(ev) {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.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
|
||||||
);
|
);
|
||||||
@ -851,7 +883,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showTrace(automation: any) {
|
private _showTrace(ev) {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
||||||
|
|
||||||
if (!automation.attributes.id) {
|
if (!automation.attributes.id) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
text: this.hass.localize(
|
text: this.hass.localize(
|
||||||
@ -865,14 +899,18 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _toggle(automation): Promise<void> {
|
private async _toggle(ev): Promise<void> {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.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(automation) {
|
private async _deleteConfirm(ev) {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
||||||
|
|
||||||
showConfirmationDialog(this, {
|
showConfirmationDialog(this, {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
"ui.panel.config.automation.picker.delete_confirm_title"
|
"ui.panel.config.automation.picker.delete_confirm_title"
|
||||||
@ -906,7 +944,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async duplicate(automation) {
|
private async _duplicate(ev) {
|
||||||
|
const automation = ev.currentTarget.parentElement.anchorElement.automation;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const config = await fetchAutomationFileConfig(
|
const config = await fetchAutomationFileConfig(
|
||||||
this.hass,
|
this.hass,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user