From 58ad949bc871a47a608139d0944b7817fc95d85f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sun, 12 Jan 2020 13:00:26 +0100 Subject: [PATCH] Virtualize logbook (#4450) * Virtualize logbook * Clean * Update ha-logbook.ts --- package.json | 1 + src/data/logbook.ts | 7 ++ src/panels/logbook/ha-logbook.js | 137 ---------------------- src/panels/logbook/ha-logbook.ts | 156 +++++++++++++++++++++++++ src/panels/logbook/ha-panel-logbook.js | 31 ++++- yarn.lock | 23 +++- 6 files changed, 213 insertions(+), 142 deletions(-) create mode 100644 src/data/logbook.ts delete mode 100644 src/panels/logbook/ha-logbook.js create mode 100644 src/panels/logbook/ha-logbook.ts diff --git a/package.json b/package.json index 17670b2b1b..873013d82f 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "leaflet": "^1.4.0", "lit-element": "^2.2.1", "lit-html": "^1.1.0", + "lit-virtualizer": "^0.4.2", "marked": "^0.6.1", "mdn-polyfills": "^5.16.0", "memoize-one": "^5.0.2", diff --git a/src/data/logbook.ts b/src/data/logbook.ts new file mode 100644 index 0000000000..be4ab3166e --- /dev/null +++ b/src/data/logbook.ts @@ -0,0 +1,7 @@ +export interface LogbookEntry { + when: string; + name: string; + message: string; + entity_id?: string; + domain: string; +} diff --git a/src/panels/logbook/ha-logbook.js b/src/panels/logbook/ha-logbook.js deleted file mode 100644 index 3faa6be64f..0000000000 --- a/src/panels/logbook/ha-logbook.js +++ /dev/null @@ -1,137 +0,0 @@ -import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import "@polymer/iron-icon/iron-icon"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import formatTime from "../../common/datetime/format_time"; -import formatDate from "../../common/datetime/format_date"; -import { EventsMixin } from "../../mixins/events-mixin"; -import LocalizeMixin from "../../mixins/localize-mixin"; -import { domainIcon } from "../../common/entity/domain_icon"; -import { computeRTL } from "../../common/util/compute_rtl"; - -/* - * @appliesMixin EventsMixin - */ -class HaLogbook extends LocalizeMixin(EventsMixin(PolymerElement)) { - static get template() { - return html` - - - - - - - `; - } - - static get properties() { - return { - hass: { - type: Object, - }, - - entries: { - type: Array, - value: [], - }, - rtl: { - type: Boolean, - reflectToAttribute: true, - computed: "_computeRTL(hass)", - }, - }; - } - - _formatTime(date) { - return formatTime(new Date(date), this.hass.language); - } - - _formatDate(date) { - return formatDate(new Date(date), this.hass.language); - } - - _needHeader(change, index) { - if (!index) return true; - const current = this.get("when", change.base[index]); - const previous = this.get("when", change.base[index - 1]); - return ( - current && - previous && - new Date(current).toDateString() !== new Date(previous).toDateString() - ); - } - - _computeIcon(domain) { - return domainIcon(domain); - } - - _computeRTL(hass) { - return computeRTL(hass); - } - - entityClicked(ev) { - ev.preventDefault(); - this.fire("hass-more-info", { entityId: ev.model.item.entity_id }); - } -} - -customElements.define("ha-logbook", HaLogbook); diff --git a/src/panels/logbook/ha-logbook.ts b/src/panels/logbook/ha-logbook.ts new file mode 100644 index 0000000000..158211b045 --- /dev/null +++ b/src/panels/logbook/ha-logbook.ts @@ -0,0 +1,156 @@ +import "@polymer/iron-icon/iron-icon"; + +import formatTime from "../../common/datetime/format_time"; +import formatDate from "../../common/datetime/format_date"; +import { domainIcon } from "../../common/entity/domain_icon"; +import { computeRTL } from "../../common/util/compute_rtl"; +import { + LitElement, + html, + property, + TemplateResult, + CSSResult, + css, + PropertyValues, +} from "lit-element"; +import { HomeAssistant } from "../../types"; +import { fireEvent } from "../../common/dom/fire_event"; +import "lit-virtualizer"; +import { LogbookEntry } from "../../data/logbook"; + +class HaLogbook extends LitElement { + @property() public hass!: HomeAssistant; + @property() public entries: LogbookEntry[] = []; + @property({ attribute: "rtl", type: Boolean, reflect: true }) + // @ts-ignore + private _rtl = false; + + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); + if (!changedProps.has("hass")) { + return; + } + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (oldHass && oldHass.language !== this.hass.language) { + this._rtl = computeRTL(this.hass); + } + } + + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + this._rtl = computeRTL(this.hass); + } + + protected render(): TemplateResult | void { + if (!this.entries?.length) { + return html` + ${this.hass.localize("ui.panel.logbook.entries_not_found")} + `; + } + + return html` + + this._renderLogbookItem(item, index)} + style="height: 100%;" + > + `; + } + + private _renderLogbookItem( + item: LogbookEntry, + index: number + ): TemplateResult { + const previous = this.entries[index - 1]; + return html` +
+ ${index === 0 || + (item?.when && + previous?.when && + new Date(item.when).toDateString() !== + new Date(previous.when).toDateString()) + ? html` +

+ ${formatDate(new Date(item.when), this.hass.language)} +

+ ` + : html``} + +
+
+ ${formatTime(new Date(item.when), this.hass.language)} +
+ +
+ ${!item.entity_id + ? html` + ${item.name} + ` + : html` + + ${item.name} + + `} + ${item.message} +
+
+
+ `; + } + + private _entityClicked(ev: Event) { + ev.preventDefault(); + fireEvent(this, "hass-more-info", { + entityId: (ev.target as any).entityId, + }); + } + + static get styles(): CSSResult { + return css` + :host { + display: block; + height: 100%; + } + + :host([rtl]) { + direction: ltr; + } + + .entry { + display: flex; + line-height: 2em; + } + + .time { + width: 55px; + font-size: 0.8em; + color: var(--secondary-text-color); + } + + :host([rtl]) .date { + direction: rtl; + } + + iron-icon { + margin: 0 8px 0 16px; + color: var(--primary-text-color); + } + + .message { + color: var(--primary-text-color); + } + + a { + color: var(--primary-color); + } + `; + } +} + +customElements.define("ha-logbook", HaLogbook); diff --git a/src/panels/logbook/ha-panel-logbook.js b/src/panels/logbook/ha-panel-logbook.js index 7e46b66979..1f72e8ccba 100644 --- a/src/panels/logbook/ha-panel-logbook.js +++ b/src/panels/logbook/ha-panel-logbook.js @@ -28,7 +28,15 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) { return html`