From c82782fa1b3dbda3af3a14cadb749ea327833498 Mon Sep 17 00:00:00 2001 From: Zack Barett Date: Tue, 23 Aug 2022 08:47:15 -0500 Subject: [PATCH] Update Automation Picker Table (#13405) --- src/common/datetime/format_date_time.ts | 24 ++- .../config/automation/ha-automation-picker.ts | 200 ++++++------------ 2 files changed, 85 insertions(+), 139 deletions(-) diff --git a/src/common/datetime/format_date_time.ts b/src/common/datetime/format_date_time.ts index 3310de0291..9aef50e2c8 100644 --- a/src/common/datetime/format_date_time.ts +++ b/src/common/datetime/format_date_time.ts @@ -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, diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index 7c637b4dc7..aba85d255b 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -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` - - `, - }, 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}
${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")}
- ` + `; + } : 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` - ${last_triggered - ? formatDateTime(new Date(last_triggered), 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` - - ${this.hass.localize("ui.card.automation.trigger")} - - `, - width: "20%", - template: (_info, automation: any) => html` - - ${this.hass.localize("ui.card.automation.trigger")} - - `, + 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 + ? dayDiff > 3 + ? formatShortDateTime(date, this.hass.locale) + : relativeTime(date, this.hass.locale) + : this.hass.localize("ui.components.relative_time.never")} + `; + }, }; } 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` - 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)" - > - + `, }; 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 > { - this._runActions(ev.currentTarget.automation); - }; + private _handleRowClicked(ev: HASSDomEvent) { + 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")) {