Update Automation Picker Table (#13405)

This commit is contained in:
Zack Barett 2022-08-23 08:47:15 -05:00 committed by GitHub
parent ab14cf9e9b
commit c82782fa1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 139 deletions

View File

@ -1,7 +1,7 @@
import memoizeOne from "memoize-one";
import { FrontendLocaleData } from "../../data/translation";
import { useAmPm } from "./use_am_pm";
import { polyfillsLoaded } from "../translations/localize";
import { useAmPm } from "./use_am_pm";
if (__BUILD__ === "latest" && polyfillsLoaded) {
await polyfillsLoaded;
@ -28,6 +28,28 @@ const formatDateTimeMem = memoizeOne(
)
);
// Aug 9, 8:23 AM
export const formatShortDateTime = (
dateObj: Date,
locale: FrontendLocaleData
) => formatShortDateTimeMem(locale).format(dateObj);
const formatShortDateTimeMem = memoizeOne(
(locale: FrontendLocaleData) =>
new Intl.DateTimeFormat(
locale.language === "en" && !useAmPm(locale)
? "en-u-hc-h23"
: locale.language,
{
month: "short",
day: "numeric",
hour: useAmPm(locale) ? "numeric" : "2-digit",
minute: "2-digit",
hour12: useAmPm(locale),
}
)
);
// August 9, 2021, 8:23:15 AM
export const formatDateTimeWithSeconds = (
dateObj: Date,

View File

@ -1,32 +1,22 @@
import {
mdiHelpCircle,
mdiHistory,
mdiInformationOutline,
mdiPencil,
mdiPencilOff,
mdiPlayCircleOutline,
mdiPlus,
} from "@mdi/js";
import { mdiHelpCircle, mdiInformationOutline, mdiPlus } from "@mdi/js";
import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { formatDateTime } from "../../../common/datetime/format_date_time";
import { fireEvent } from "../../../common/dom/fire_event";
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
import { relativeTime } from "../../../common/datetime/relative_time";
import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { navigate } from "../../../common/navigate";
import { DataTableColumnContainer } from "../../../components/data-table/ha-data-table";
import "../../../components/entity/ha-entity-toggle";
import type {
DataTableColumnContainer,
RowClickedEvent,
} from "../../../components/data-table/ha-data-table";
import "../../../components/ha-button-related-filter-menu";
import "../../../components/ha-fab";
import "../../../components/ha-icon-button";
import "../../../components/ha-svg-icon";
import "../../../components/ha-icon-overflow-menu";
import {
AutomationEntity,
triggerAutomationActions,
} from "../../../data/automation";
import { UNAVAILABLE_STATES } from "../../../data/entity";
import type { AutomationEntity } from "../../../data/automation";
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
import "../../../layouts/hass-tabs-subpage-data-table";
import { haStyle } from "../../../resources/styles";
@ -35,6 +25,8 @@ import { documentationUrl } from "../../../util/documentation-url";
import { configSections } from "../ha-panel-config";
import { showNewAutomationDialog } from "./show-dialog-new-automation";
const DAY_IN_MILLISECONDS = 86400000;
@customElement("ha-automation-picker")
class HaAutomationPicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -78,20 +70,6 @@ class HaAutomationPicker extends LitElement {
private _columns = memoizeOne(
(narrow: boolean, _locale): DataTableColumnContainer => {
const columns: DataTableColumnContainer = {
toggle: {
title: "",
label: this.hass.localize(
"ui.panel.config.automation.picker.headers.toggle"
),
type: "icon",
template: (_toggle, automation: any) =>
html`
<ha-entity-toggle
.hass=${this.hass}
.stateObj=${automation}
></ha-entity-toggle>
`,
},
name: {
title: this.hass.localize(
"ui.panel.config.automation.picker.headers.name"
@ -101,19 +79,25 @@ class HaAutomationPicker extends LitElement {
direction: "asc",
grows: true,
template: narrow
? (name, automation: any) =>
html`
? (name, automation: any) => {
const date = new Date(automation.attributes.last_triggered);
const now = new Date();
const diff = now.getTime() - date.getTime();
const dayDiff = diff / DAY_IN_MILLISECONDS;
return html`
${name}
<div class="secondary">
${this.hass.localize("ui.card.automation.last_triggered")}:
${automation.attributes.last_triggered
? formatDateTime(
new Date(automation.attributes.last_triggered),
this.hass.locale
)
? dayDiff > 3
? formatShortDateTime(date, this.hass.locale)
: relativeTime(date, this.hass.locale)
: this.hass.localize("ui.components.relative_time.never")}
</div>
`
`;
}
: undefined,
},
};
@ -122,31 +106,21 @@ class HaAutomationPicker extends LitElement {
sortable: true,
width: "20%",
title: this.hass.localize("ui.card.automation.last_triggered"),
template: (last_triggered) => html`
template: (last_triggered) => {
const date = new Date(last_triggered);
const now = new Date();
const diff = now.getTime() - date.getTime();
const dayDiff = diff / DAY_IN_MILLISECONDS;
return html`
${last_triggered
? formatDateTime(new Date(last_triggered), this.hass.locale)
? dayDiff > 3
? formatShortDateTime(date, this.hass.locale)
: relativeTime(date, this.hass.locale)
: this.hass.localize("ui.components.relative_time.never")}
`,
};
columns.trigger = {
label: this.hass.localize(
"ui.panel.config.automation.picker.headers.trigger"
),
title: html`
<mwc-button style="visibility: hidden">
${this.hass.localize("ui.card.automation.trigger")}
</mwc-button>
`,
width: "20%",
template: (_info, automation: any) => html`
<mwc-button
.automation=${automation}
@click=${this._triggerRunActions}
.disabled=${UNAVAILABLE_STATES.includes(automation.state)}
>
${this.hass.localize("ui.card.automation.trigger")}
</mwc-button>
`,
`;
},
};
}
columns.actions = {
@ -154,71 +128,16 @@ class HaAutomationPicker extends LitElement {
label: this.hass.localize(
"ui.panel.config.automation.picker.headers.actions"
),
type: "overflow-menu",
type: "icon-button",
template: (_info, automation: any) => html`
<ha-icon-overflow-menu
.hass=${this.hass}
.narrow=${this.narrow}
.items=${[
// Info Button
{
path: mdiInformationOutline,
label: this.hass.localize(
"ui.panel.config.automation.picker.show_info_automation"
),
action: () => this._showInfo(automation),
},
// Trigger Button
{
path: mdiPlayCircleOutline,
label: this.hass.localize("ui.card.automation.trigger"),
narrowOnly: true,
action: () => this._runActions(automation),
},
// Trace Button
{
path: mdiHistory,
disabled: !automation.attributes.id,
label: this.hass.localize(
"ui.panel.config.automation.picker.dev_automation"
),
tooltip: !automation.attributes.id
? this.hass.localize(
"ui.panel.config.automation.picker.dev_only_editable"
)
: "",
action: () => {
if (automation.attributes.id) {
navigate(
`/config/automation/trace/${automation.attributes.id}`
);
}
},
},
// Edit Button
{
path: automation.attributes.id ? mdiPencil : mdiPencilOff,
disabled: !automation.attributes.id,
label: this.hass.localize(
"ui.panel.config.automation.picker.edit_automation"
),
tooltip: !automation.attributes.id
? this.hass.localize(
"ui.panel.config.automation.picker.dev_only_editable"
)
: "",
action: () => {
if (automation.attributes.id) {
navigate(
`/config/automation/edit/${automation.attributes.id}`
);
}
},
},
]}
style="color: var(--secondary-text-color)"
>
</ha-icon-overflow-menu>
<ha-icon-button
.automation=${automation}
.label=${this.hass.localize(
"ui.panel.config.automation.picker.headers.actions"
)}
.path=${mdiInformationOutline}
@click=${this._showInfo}
></ha-icon-button>
`,
};
return columns;
@ -237,11 +156,13 @@ class HaAutomationPicker extends LitElement {
.activeFilters=${this._activeFilters}
.columns=${this._columns(this.narrow, this.hass.locale)}
.data=${this._automations(this.automations, this._filteredAutomations)}
@row-click=${this._handleRowClicked}
.noDataText=${this.hass.localize(
"ui.panel.config.automation.picker.no_automations"
)}
@clear-filter=${this._clearFilter}
hasFab
clickable
>
<ha-icon-button
slot="toolbar-icon"
@ -289,9 +210,10 @@ class HaAutomationPicker extends LitElement {
this._filterValue = undefined;
}
private _showInfo(automation: AutomationEntity) {
const entityId = automation.entity_id;
fireEvent(this, "hass-more-info", { entityId });
private _showInfo(ev) {
ev.stopPropagation();
const automation = ev.currentTarget.automation;
fireEvent(this, "hass-more-info", { entityId: automation.entity_id });
}
private _showHelp() {
@ -314,13 +236,15 @@ class HaAutomationPicker extends LitElement {
});
}
private _triggerRunActions = (ev) => {
this._runActions(ev.currentTarget.automation);
};
private _handleRowClicked(ev: HASSDomEvent<RowClickedEvent>) {
const automation = this.automations.find(
(a) => a.entity_id === ev.detail.id
);
private _runActions = (automation: AutomationEntity) => {
triggerAutomationActions(this.hass, automation.entity_id);
};
if (automation?.attributes.id) {
navigate(`/config/automation/edit/${automation?.attributes.id}`);
}
}
private _createNew() {
if (isComponentLoaded(this.hass, "blueprint")) {