mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-26 06:17:20 +00:00
Add overflow menu to automation picker (#13569)
This commit is contained in:
parent
ffad6f340f
commit
ec257710ff
@ -3,6 +3,8 @@ import { mdiDotsVertical } from "@mdi/js";
|
|||||||
import "@polymer/paper-tooltip/paper-tooltip";
|
import "@polymer/paper-tooltip/paper-tooltip";
|
||||||
import { css, html, LitElement, TemplateResult } from "lit";
|
import { css, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
|
import { haStyle } from "../resources/styles";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import "./ha-button-menu";
|
import "./ha-button-menu";
|
||||||
import "./ha-icon-button";
|
import "./ha-icon-button";
|
||||||
@ -16,6 +18,7 @@ export interface IconOverflowMenuItem {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
onClick: CallableFunction;
|
onClick: CallableFunction;
|
||||||
|
warning?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@customElement("ha-icon-overflow-menu")
|
@customElement("ha-icon-overflow-menu")
|
||||||
@ -49,9 +52,13 @@ export class HaIconOverflowMenu extends LitElement {
|
|||||||
graphic="icon"
|
graphic="icon"
|
||||||
.disabled=${item.disabled}
|
.disabled=${item.disabled}
|
||||||
@click=${item.action}
|
@click=${item.action}
|
||||||
|
class=${classMap({ warning: Boolean(item.warning) })}
|
||||||
>
|
>
|
||||||
<div slot="graphic">
|
<div slot="graphic">
|
||||||
<ha-svg-icon .path=${item.path}></ha-svg-icon>
|
<ha-svg-icon
|
||||||
|
class=${classMap({ warning: Boolean(item.warning) })}
|
||||||
|
.path=${item.path}
|
||||||
|
></ha-svg-icon>
|
||||||
</div>
|
</div>
|
||||||
${item.label}
|
${item.label}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
@ -81,7 +88,8 @@ export class HaIconOverflowMenu extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _handleIconOverflowMenuOpened() {
|
protected _handleIconOverflowMenuOpened(e) {
|
||||||
|
e.stopPropagation();
|
||||||
// If this component is used inside a data table, the z-index of the row
|
// If this component is used inside a data table, the z-index of the row
|
||||||
// needs to be increased. Otherwise the ha-button-menu would be displayed
|
// needs to be increased. Otherwise the ha-button-menu would be displayed
|
||||||
// underneath the next row in the table.
|
// underneath the next row in the table.
|
||||||
@ -99,12 +107,15 @@ export class HaIconOverflowMenu extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [
|
||||||
:host {
|
haStyle,
|
||||||
display: flex;
|
css`
|
||||||
justify-content: flex-end;
|
:host {
|
||||||
}
|
display: flex;
|
||||||
`;
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,16 @@
|
|||||||
import { mdiHelpCircle, mdiInformationOutline, mdiPlus } from "@mdi/js";
|
import {
|
||||||
|
mdiCancel,
|
||||||
|
mdiContentDuplicate,
|
||||||
|
mdiDelete,
|
||||||
|
mdiHelpCircle,
|
||||||
|
mdiInformationOutline,
|
||||||
|
mdiPlay,
|
||||||
|
mdiPlayCircleOutline,
|
||||||
|
mdiPlus,
|
||||||
|
mdiStopCircleOutline,
|
||||||
|
mdiTransitConnection,
|
||||||
|
} from "@mdi/js";
|
||||||
|
import "@polymer/paper-tooltip/paper-tooltip";
|
||||||
import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
@ -13,11 +25,22 @@ import type {
|
|||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/ha-button-related-filter-menu";
|
import "../../../components/ha-button-related-filter-menu";
|
||||||
|
import "../../../components/ha-chip";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
|
import "../../../components/ha-icon-overflow-menu";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import type { AutomationEntity } from "../../../data/automation";
|
import {
|
||||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
AutomationEntity,
|
||||||
|
deleteAutomation,
|
||||||
|
getAutomationConfig,
|
||||||
|
showAutomationEditor,
|
||||||
|
triggerAutomationActions,
|
||||||
|
} from "../../../data/automation";
|
||||||
|
import {
|
||||||
|
showAlertDialog,
|
||||||
|
showConfirmationDialog,
|
||||||
|
} from "../../../dialogs/generic/show-dialog-box";
|
||||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant, Route } from "../../../types";
|
import { HomeAssistant, Route } from "../../../types";
|
||||||
@ -63,6 +86,7 @@ class HaAutomationPicker extends LitElement {
|
|||||||
...automation,
|
...automation,
|
||||||
name: computeStateName(automation),
|
name: computeStateName(automation),
|
||||||
last_triggered: automation.attributes.last_triggered || undefined,
|
last_triggered: automation.attributes.last_triggered || undefined,
|
||||||
|
disabled: automation.state === "off",
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -123,22 +147,105 @@ class HaAutomationPicker extends LitElement {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
columns.disabled = this.narrow
|
||||||
|
? {
|
||||||
|
title: "",
|
||||||
|
template: (disabled: boolean) =>
|
||||||
|
disabled
|
||||||
|
? html`
|
||||||
|
<paper-tooltip animation-delay="0" position="left">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.disabled"
|
||||||
|
)}
|
||||||
|
</paper-tooltip>
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCancel}
|
||||||
|
style="color: var(--secondary-text-color)"
|
||||||
|
></ha-svg-icon>
|
||||||
|
`
|
||||||
|
: "",
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
width: "20%",
|
||||||
|
title: "",
|
||||||
|
template: (disabled: boolean) =>
|
||||||
|
disabled
|
||||||
|
? html`
|
||||||
|
<ha-chip>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.disabled"
|
||||||
|
)}
|
||||||
|
</ha-chip>
|
||||||
|
`
|
||||||
|
: "",
|
||||||
|
};
|
||||||
|
|
||||||
columns.actions = {
|
columns.actions = {
|
||||||
title: "",
|
title: "",
|
||||||
label: this.hass.localize(
|
width: this.narrow ? undefined : "10%",
|
||||||
"ui.panel.config.automation.picker.headers.actions"
|
type: "overflow-menu",
|
||||||
),
|
template: (_: string, automation: any) =>
|
||||||
type: "icon-button",
|
html`
|
||||||
template: (_info, automation: any) => html`
|
<ha-icon-overflow-menu
|
||||||
<ha-icon-button
|
.hass=${this.hass}
|
||||||
.automation=${automation}
|
narrow
|
||||||
.label=${this.hass.localize(
|
.items=${[
|
||||||
"ui.panel.config.automation.picker.headers.actions"
|
{
|
||||||
)}
|
path: mdiInformationOutline,
|
||||||
.path=${mdiInformationOutline}
|
label: this.hass.localize(
|
||||||
@click=${this._showInfo}
|
"ui.panel.config.automation.editor.show_info"
|
||||||
></ha-icon-button>
|
),
|
||||||
`,
|
action: () => this._showInfo(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),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@ -210,12 +317,52 @@ class HaAutomationPicker extends LitElement {
|
|||||||
this._filterValue = undefined;
|
this._filterValue = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showInfo(ev) {
|
private _showInfo(automation: any) {
|
||||||
ev.stopPropagation();
|
|
||||||
const automation = ev.currentTarget.automation;
|
|
||||||
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
|
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _runActions(automation: any) {
|
||||||
|
triggerAutomationActions(this.hass, automation.entity_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _showTrace(automation: any) {
|
||||||
|
navigate(`/config/automation/trace/${automation.attributes.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _toggle(automation): Promise<void> {
|
||||||
|
const service = automation.state === "off" ? "turn_on" : "turn_off";
|
||||||
|
await this.hass.callService("automation", service, {
|
||||||
|
entity_id: automation.entity_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _deleteConfirm(automation) {
|
||||||
|
showConfirmationDialog(this, {
|
||||||
|
text: this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.delete_confirm"
|
||||||
|
),
|
||||||
|
confirmText: this.hass!.localize("ui.common.delete"),
|
||||||
|
dismissText: this.hass!.localize("ui.common.cancel"),
|
||||||
|
confirm: () => this._delete(automation),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _delete(automation) {
|
||||||
|
await deleteAutomation(this.hass, automation.attributes.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async duplicate(automation) {
|
||||||
|
const config = await getAutomationConfig(
|
||||||
|
this.hass,
|
||||||
|
automation.attributes.id
|
||||||
|
);
|
||||||
|
showAutomationEditor({
|
||||||
|
...config,
|
||||||
|
id: undefined,
|
||||||
|
alias: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _showHelp() {
|
private _showHelp() {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: this.hass.localize("ui.panel.config.automation.caption"),
|
title: this.hass.localize("ui.panel.config.automation.caption"),
|
||||||
|
@ -1793,6 +1793,7 @@
|
|||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"delete_confirm": "Are you sure you want to delete this automation?",
|
"delete_confirm": "Are you sure you want to delete this automation?",
|
||||||
"duplicate": "Duplicate",
|
"duplicate": "Duplicate",
|
||||||
|
"disabled": "Disabled",
|
||||||
"headers": {
|
"headers": {
|
||||||
"toggle": "Enable/disable",
|
"toggle": "Enable/disable",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
@ -1822,6 +1823,7 @@
|
|||||||
"run": "[%key:ui::panel::config::automation::editor::actions::run%]",
|
"run": "[%key:ui::panel::config::automation::editor::actions::run%]",
|
||||||
"rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]",
|
"rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]",
|
||||||
"show_trace": "Traces",
|
"show_trace": "Traces",
|
||||||
|
"show_info": "Information",
|
||||||
"introduction": "Use automations to bring your home to life.",
|
"introduction": "Use automations to bring your home to life.",
|
||||||
"default_name": "New Automation",
|
"default_name": "New Automation",
|
||||||
"missing_name": "Cannot save automation without a name",
|
"missing_name": "Cannot save automation without a name",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user