mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 01:36:49 +00:00
Lazy load more info content, split logbook and history (#6936)
This commit is contained in:
parent
8a998369d6
commit
99d0a0a6fd
@ -2,8 +2,8 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/dialogs/more-info/more-info-content";
|
||||
import "../../../src/state-summary/state-card-content";
|
||||
import "./more-info-content";
|
||||
|
||||
class DemoMoreInfo extends PolymerElement {
|
||||
static get template() {
|
||||
|
73
gallery/src/components/more-info-content.ts
Normal file
73
gallery/src/components/more-info-content.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { property, PropertyValues, UpdatingElement } from "lit-element";
|
||||
import dynamicContentUpdater from "../../../src/common/dom/dynamic_content_updater";
|
||||
import { stateMoreInfoType } from "../../../src/common/entity/state_more_info_type";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-alarm_control_panel";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-automation";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-camera";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-climate";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-configurator";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-counter";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-cover";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-default";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-fan";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-group";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-humidifier";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-input_datetime";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-light";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-lock";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-media_player";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-person";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-script";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-sun";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-timer";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-vacuum";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-water_heater";
|
||||
import "../../../src/dialogs/more-info/controls/more-info-weather";
|
||||
import { HomeAssistant } from "../../../src/types";
|
||||
|
||||
class MoreInfoContent extends UpdatingElement {
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property() public stateObj?: HassEntity;
|
||||
|
||||
private _detachedChild?: ChildNode;
|
||||
|
||||
protected firstUpdated(): void {
|
||||
this.style.position = "relative";
|
||||
this.style.display = "block";
|
||||
}
|
||||
|
||||
// This is not a lit element, but an updating element, so we implement update
|
||||
protected update(changedProps: PropertyValues): void {
|
||||
super.update(changedProps);
|
||||
const stateObj = this.stateObj;
|
||||
const hass = this.hass;
|
||||
|
||||
if (!stateObj || !hass) {
|
||||
if (this.lastChild) {
|
||||
this._detachedChild = this.lastChild;
|
||||
// Detach child to prevent it from doing work.
|
||||
this.removeChild(this.lastChild);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._detachedChild) {
|
||||
this.appendChild(this._detachedChild);
|
||||
this._detachedChild = undefined;
|
||||
}
|
||||
|
||||
const moreInfoType =
|
||||
stateObj.attributes && "custom_ui_more_info" in stateObj.attributes
|
||||
? stateObj.attributes.custom_ui_more_info
|
||||
: "more-info-" + stateMoreInfoType(stateObj);
|
||||
|
||||
dynamicContentUpdater(this, moreInfoType.toUpperCase(), {
|
||||
hass,
|
||||
stateObj,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("more-info-content", MoreInfoContent);
|
@ -3,10 +3,10 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import "../../../src/components/ha-card";
|
||||
import { SUPPORT_BRIGHTNESS } from "../../../src/data/light";
|
||||
import "../../../src/dialogs/more-info/more-info-content";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-more-infos";
|
||||
import "../components/more-info-content";
|
||||
|
||||
const ENTITIES = [
|
||||
getEntity("light", "bed_light", "on", {
|
||||
|
@ -44,7 +44,6 @@ export const DOMAINS_WITH_MORE_INFO = [
|
||||
"script",
|
||||
"sun",
|
||||
"timer",
|
||||
"updater",
|
||||
"vacuum",
|
||||
"water_heater",
|
||||
"weather",
|
||||
|
50
src/common/util/throttle.ts
Normal file
50
src/common/util/throttle.ts
Normal file
@ -0,0 +1,50 @@
|
||||
// From: underscore.js https://github.com/jashkenas/underscore/blob/master/underscore.js
|
||||
|
||||
// Returns a function, that, when invoked, will only be triggered at most once
|
||||
// during a given window of time. Normally, the throttled function will run
|
||||
// as much as it can, without ever going more than once per `wait` duration;
|
||||
// but if you'd like to disable the execution on the leading edge, pass
|
||||
// `false for leading`. To disable execution on the trailing edge, ditto.
|
||||
export const throttle = <T extends Function>(
|
||||
func: T,
|
||||
wait: number,
|
||||
leading = true,
|
||||
trailing = true
|
||||
): T => {
|
||||
let timeout: number | undefined;
|
||||
let previous = 0;
|
||||
let context: any;
|
||||
let args: any;
|
||||
const later = () => {
|
||||
previous = leading === false ? 0 : Date.now();
|
||||
timeout = undefined;
|
||||
func.apply(context, args);
|
||||
if (!timeout) {
|
||||
context = null;
|
||||
args = null;
|
||||
}
|
||||
};
|
||||
// @ts-ignore
|
||||
return function (...argmnts) {
|
||||
// @ts-ignore
|
||||
// @typescript-eslint/no-this-alias
|
||||
context = this;
|
||||
args = argmnts;
|
||||
|
||||
const now = Date.now();
|
||||
if (!previous && leading === false) {
|
||||
previous = now;
|
||||
}
|
||||
const remaining = wait - (now - previous);
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = undefined;
|
||||
}
|
||||
previous = now;
|
||||
func.apply(context, args);
|
||||
} else if (!timeout && trailing !== false) {
|
||||
timeout = window.setTimeout(later, remaining);
|
||||
}
|
||||
};
|
||||
};
|
@ -13,10 +13,15 @@ import {
|
||||
} from "lit-element";
|
||||
import { cache } from "lit-html/directives/cache";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { DOMAINS_MORE_INFO_NO_HISTORY } from "../../common/const";
|
||||
import {
|
||||
DOMAINS_MORE_INFO_NO_HISTORY,
|
||||
DOMAINS_WITH_MORE_INFO,
|
||||
} from "../../common/const";
|
||||
import { dynamicElement } from "../../common/dom/dynamic-element-directive";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { stateMoreInfoType } from "../../common/entity/state_more_info_type";
|
||||
import { navigate } from "../../common/navigate";
|
||||
import "../../components/ha-dialog";
|
||||
import "../../components/ha-header-bar";
|
||||
@ -30,21 +35,38 @@ import "../../state-summary/state-card-content";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { showConfirmationDialog } from "../generic/show-dialog-box";
|
||||
import "./ha-more-info-history";
|
||||
import "./more-info-content";
|
||||
import "./ha-more-info-logbook";
|
||||
|
||||
const DOMAINS_NO_INFO = ["camera", "configurator"];
|
||||
const CONTROL_DOMAINS = [
|
||||
"light",
|
||||
"media_player",
|
||||
"vacuum",
|
||||
"alarm_control_panel",
|
||||
"climate",
|
||||
"humidifier",
|
||||
"weather",
|
||||
];
|
||||
const EDITABLE_DOMAINS_WITH_ID = ["scene", "automation"];
|
||||
const EDITABLE_DOMAINS = ["script"];
|
||||
|
||||
const MORE_INFO_CONTROL_IMPORT = {
|
||||
alarm_control_panel: () => import("./controls/more-info-alarm_control_panel"),
|
||||
automation: () => import("./controls/more-info-automation"),
|
||||
camera: () => import("./controls/more-info-camera"),
|
||||
climate: () => import("./controls/more-info-climate"),
|
||||
configurator: () => import("./controls/more-info-configurator"),
|
||||
counter: () => import("./controls/more-info-counter"),
|
||||
cover: () => import("./controls/more-info-cover"),
|
||||
fan: () => import("./controls/more-info-fan"),
|
||||
group: () => import("./controls/more-info-group"),
|
||||
humidifier: () => import("./controls/more-info-humidifier"),
|
||||
input_datetime: () => import("./controls/more-info-input_datetime"),
|
||||
light: () => import("./controls/more-info-light"),
|
||||
lock: () => import("./controls/more-info-lock"),
|
||||
media_player: () => import("./controls/more-info-media_player"),
|
||||
person: () => import("./controls/more-info-person"),
|
||||
script: () => import("./controls/more-info-script"),
|
||||
sun: () => import("./controls/more-info-sun"),
|
||||
timer: () => import("./controls/more-info-timer"),
|
||||
vacuum: () => import("./controls/more-info-vacuum"),
|
||||
water_heater: () => import("./controls/more-info-water_heater"),
|
||||
weather: () => import("./controls/more-info-weather"),
|
||||
hidden: () => {},
|
||||
default: () => import("./controls/more-info-default"),
|
||||
};
|
||||
|
||||
export interface MoreInfoDialogParams {
|
||||
entityId: string | null;
|
||||
}
|
||||
@ -57,6 +79,8 @@ export class MoreInfoDialog extends LitElement {
|
||||
|
||||
@internalProperty() private _entityId?: string | null;
|
||||
|
||||
@internalProperty() private _moreInfoType?: string;
|
||||
|
||||
@internalProperty() private _currTabIndex = 0;
|
||||
|
||||
public showDialog(params: MoreInfoDialogParams) {
|
||||
@ -73,6 +97,23 @@ export class MoreInfoDialog extends LitElement {
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected updated(changedProperties) {
|
||||
if (!this.hass || !this._entityId || !changedProperties.has("_entityId")) {
|
||||
return;
|
||||
}
|
||||
const stateObj = this.hass.states[this._entityId];
|
||||
if (!stateObj) {
|
||||
return;
|
||||
}
|
||||
if (stateObj.attributes && "custom_ui_more_info" in stateObj.attributes) {
|
||||
this._moreInfoType = stateObj.attributes.custom_ui_more_info;
|
||||
} else {
|
||||
const type = stateMoreInfoType(stateObj);
|
||||
this._moreInfoType = `more-info-${type}`;
|
||||
MORE_INFO_CONTROL_IMPORT[type]();
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._entityId) {
|
||||
return html``;
|
||||
@ -137,7 +178,7 @@ export class MoreInfoDialog extends LitElement {
|
||||
`
|
||||
: ""}
|
||||
</ha-header-bar>
|
||||
${CONTROL_DOMAINS.includes(domain) &&
|
||||
${DOMAINS_WITH_MORE_INFO.includes(domain) &&
|
||||
this._computeShowHistoryComponent(entityId)
|
||||
? html`
|
||||
<mwc-tab-bar
|
||||
@ -171,17 +212,23 @@ export class MoreInfoDialog extends LitElement {
|
||||
.hass=${this.hass}
|
||||
></state-card-content>
|
||||
`}
|
||||
<more-info-content
|
||||
.stateObj=${stateObj}
|
||||
.hass=${this.hass}
|
||||
></more-info-content>
|
||||
${CONTROL_DOMAINS.includes(domain) ||
|
||||
${DOMAINS_WITH_MORE_INFO.includes(domain) ||
|
||||
!this._computeShowHistoryComponent(entityId)
|
||||
? ""
|
||||
: html`<ha-more-info-history
|
||||
.hass=${this.hass}
|
||||
.entityId=${this._entityId}
|
||||
></ha-more-info-history>`}
|
||||
.hass=${this.hass}
|
||||
.entityId=${this._entityId}
|
||||
></ha-more-info-history>
|
||||
<ha-more-info-logbook
|
||||
.hass=${this.hass}
|
||||
.entityId=${this._entityId}
|
||||
></ha-more-info-logbook>`}
|
||||
${this._moreInfoType
|
||||
? dynamicElement(this._moreInfoType, {
|
||||
hass: this.hass,
|
||||
stateObj,
|
||||
})
|
||||
: ""}
|
||||
${stateObj.attributes.restored
|
||||
? html`
|
||||
<p>
|
||||
@ -210,6 +257,10 @@ export class MoreInfoDialog extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.entityId=${this._entityId}
|
||||
></ha-more-info-history>
|
||||
<ha-more-info-logbook
|
||||
.hass=${this.hass}
|
||||
.entityId=${this._entityId}
|
||||
></ha-more-info-logbook>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
|
@ -9,14 +9,11 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||
import "../../components/ha-circular-progress";
|
||||
import { throttle } from "../../common/util/throttle";
|
||||
import "../../components/state-history-charts";
|
||||
import { getRecentWithCache } from "../../data/cached-history";
|
||||
import { HistoryResult } from "../../data/history";
|
||||
import { getLogbookData, LogbookEntry } from "../../data/logbook";
|
||||
import "../../panels/logbook/ha-logbook";
|
||||
import { haStyle, haStyleScrollbar } from "../../resources/styles";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
|
||||
@customElement("ha-more-info-history")
|
||||
@ -27,21 +24,14 @@ export class MoreInfoHistory extends LitElement {
|
||||
|
||||
@internalProperty() private _stateHistory?: HistoryResult;
|
||||
|
||||
@internalProperty() private _entries?: LogbookEntry[];
|
||||
|
||||
@internalProperty() private _persons = {};
|
||||
|
||||
private _historyRefreshInterval?: number;
|
||||
private _throttleGetStateHistory = throttle(() => {
|
||||
this._getStateHistory();
|
||||
}, 10000);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.entityId) {
|
||||
return html``;
|
||||
}
|
||||
const stateObj = this.hass.states[this.entityId];
|
||||
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`${isComponentLoaded(this.hass, "history")
|
||||
? html`<state-history-charts
|
||||
@ -50,54 +40,35 @@ export class MoreInfoHistory extends LitElement {
|
||||
.historyData=${this._stateHistory}
|
||||
.isLoadingData=${!this._stateHistory}
|
||||
></state-history-charts>`
|
||||
: ""}
|
||||
${isComponentLoaded(this.hass, "logbook")
|
||||
? !this._entries
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt=${this.hass.localize("ui.common.loading")}
|
||||
></ha-circular-progress>
|
||||
`
|
||||
: this._entries.length
|
||||
? html`
|
||||
<ha-logbook
|
||||
class="ha-scrollbar"
|
||||
narrow
|
||||
no-icon
|
||||
no-name
|
||||
.hass=${this.hass}
|
||||
.entries=${this._entries}
|
||||
.userIdToName=${this._persons}
|
||||
></ha-logbook>
|
||||
`
|
||||
: html`<div class="no-entries">
|
||||
${this.hass.localize("ui.components.logbook.entries_not_found")}
|
||||
</div>`
|
||||
: ""} `;
|
||||
}
|
||||
|
||||
protected firstUpdated(): void {
|
||||
this._fetchPersonNames();
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
super.updated(changedProps);
|
||||
if (!this.entityId) {
|
||||
clearInterval(this._historyRefreshInterval);
|
||||
}
|
||||
|
||||
if (changedProps.has("entityId")) {
|
||||
this._stateHistory = undefined;
|
||||
this._entries = undefined;
|
||||
|
||||
this._getStateHistory();
|
||||
this._getLogBookData();
|
||||
if (!this.entityId) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval(this._historyRefreshInterval);
|
||||
this._historyRefreshInterval = window.setInterval(() => {
|
||||
this._getStateHistory();
|
||||
}, 60 * 1000);
|
||||
this._throttleGetStateHistory();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.entityId || !changedProps.has("hass")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
|
||||
if (
|
||||
oldHass &&
|
||||
this.hass.states[this.entityId] !== oldHass?.states[this.entityId]
|
||||
) {
|
||||
// wait for commit of data (we only account for the default setting of 1 sec)
|
||||
setTimeout(this._throttleGetStateHistory, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,55 +89,14 @@ export class MoreInfoHistory extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private async _getLogBookData() {
|
||||
if (!isComponentLoaded(this.hass, "logbook")) {
|
||||
return;
|
||||
}
|
||||
const yesterday = new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
|
||||
const now = new Date();
|
||||
this._entries = await getLogbookData(
|
||||
this.hass,
|
||||
yesterday.toISOString(),
|
||||
now.toISOString(),
|
||||
this.entityId,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchPersonNames() {
|
||||
Object.values(this.hass.states).forEach((entity) => {
|
||||
if (
|
||||
entity.attributes.user_id &&
|
||||
computeStateDomain(entity) === "person"
|
||||
) {
|
||||
this._persons[entity.attributes.user_id] =
|
||||
entity.attributes.friendly_name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleScrollbar,
|
||||
css`
|
||||
state-history-charts {
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.no-entries {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
ha-logbook {
|
||||
max-height: 250px;
|
||||
overflow: auto;
|
||||
}
|
||||
ha-circular-progress {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
171
src/dialogs/more-info/ha-more-info-logbook.ts
Normal file
171
src/dialogs/more-info/ha-more-info-logbook.ts
Normal file
@ -0,0 +1,171 @@
|
||||
import {
|
||||
css,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||
import { throttle } from "../../common/util/throttle";
|
||||
import "../../components/ha-circular-progress";
|
||||
import "../../components/state-history-charts";
|
||||
import { getLogbookData, LogbookEntry } from "../../data/logbook";
|
||||
import "../../panels/logbook/ha-logbook";
|
||||
import { haStyle, haStyleScrollbar } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
|
||||
@customElement("ha-more-info-logbook")
|
||||
export class MoreInfoLogbook extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public entityId!: string;
|
||||
|
||||
@internalProperty() private _logbookEntries?: LogbookEntry[];
|
||||
|
||||
@internalProperty() private _persons = {};
|
||||
|
||||
private _lastLogbookDate?: Date;
|
||||
|
||||
private _throttleGetLogbookEntries = throttle(() => {
|
||||
this._getLogBookData();
|
||||
}, 10000);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.entityId) {
|
||||
return html``;
|
||||
}
|
||||
const stateObj = this.hass.states[this.entityId];
|
||||
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
${isComponentLoaded(this.hass, "logbook")
|
||||
? !this._logbookEntries
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt=${this.hass.localize("ui.common.loading")}
|
||||
></ha-circular-progress>
|
||||
`
|
||||
: this._logbookEntries.length
|
||||
? html`
|
||||
<ha-logbook
|
||||
class="ha-scrollbar"
|
||||
narrow
|
||||
no-icon
|
||||
no-name
|
||||
.hass=${this.hass}
|
||||
.entries=${this._logbookEntries}
|
||||
.userIdToName=${this._persons}
|
||||
></ha-logbook>
|
||||
`
|
||||
: html`<div class="no-entries">
|
||||
${this.hass.localize("ui.components.logbook.entries_not_found")}
|
||||
</div>`
|
||||
: ""}
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated(): void {
|
||||
this._fetchPersonNames();
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
super.updated(changedProps);
|
||||
|
||||
if (changedProps.has("entityId")) {
|
||||
this._lastLogbookDate = undefined;
|
||||
this._logbookEntries = undefined;
|
||||
|
||||
if (!this.entityId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._throttleGetLogbookEntries();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.entityId || !changedProps.has("hass")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
|
||||
if (
|
||||
oldHass &&
|
||||
this.hass.states[this.entityId] !== oldHass?.states[this.entityId]
|
||||
) {
|
||||
// wait for commit of data (we only account for the default setting of 1 sec)
|
||||
setTimeout(this._throttleGetLogbookEntries, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private async _getLogBookData() {
|
||||
if (!isComponentLoaded(this.hass, "logbook")) {
|
||||
return;
|
||||
}
|
||||
const lastDate =
|
||||
this._lastLogbookDate ||
|
||||
new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
|
||||
const now = new Date();
|
||||
const newEntries = await getLogbookData(
|
||||
this.hass,
|
||||
lastDate.toISOString(),
|
||||
now.toISOString(),
|
||||
this.entityId,
|
||||
true
|
||||
);
|
||||
this._logbookEntries = this._logbookEntries
|
||||
? [...newEntries, ...this._logbookEntries]
|
||||
: newEntries;
|
||||
this._lastLogbookDate = now;
|
||||
}
|
||||
|
||||
private _fetchPersonNames() {
|
||||
Object.values(this.hass.states).forEach((entity) => {
|
||||
if (
|
||||
entity.attributes.user_id &&
|
||||
computeStateDomain(entity) === "person"
|
||||
) {
|
||||
this._persons[entity.attributes.user_id] =
|
||||
entity.attributes.friendly_name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleScrollbar,
|
||||
css`
|
||||
.no-entries {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
ha-logbook {
|
||||
max-height: 250px;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
margin-top: 16px;
|
||||
}
|
||||
ha-circular-progress {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-more-info-logbook": MoreInfoLogbook;
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { property, PropertyValues, UpdatingElement } from "lit-element";
|
||||
import dynamicContentUpdater from "../../common/dom/dynamic_content_updater";
|
||||
import { stateMoreInfoType } from "../../common/entity/state_more_info_type";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "./controls/more-info-alarm_control_panel";
|
||||
import "./controls/more-info-automation";
|
||||
import "./controls/more-info-camera";
|
||||
import "./controls/more-info-climate";
|
||||
import "./controls/more-info-configurator";
|
||||
import "./controls/more-info-counter";
|
||||
import "./controls/more-info-cover";
|
||||
import "./controls/more-info-default";
|
||||
import "./controls/more-info-fan";
|
||||
import "./controls/more-info-group";
|
||||
import "./controls/more-info-humidifier";
|
||||
import "./controls/more-info-input_datetime";
|
||||
import "./controls/more-info-light";
|
||||
import "./controls/more-info-lock";
|
||||
import "./controls/more-info-media_player";
|
||||
import "./controls/more-info-person";
|
||||
import "./controls/more-info-script";
|
||||
import "./controls/more-info-sun";
|
||||
import "./controls/more-info-timer";
|
||||
import "./controls/more-info-vacuum";
|
||||
import "./controls/more-info-water_heater";
|
||||
import "./controls/more-info-weather";
|
||||
|
||||
class MoreInfoContent extends UpdatingElement {
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property() public stateObj?: HassEntity;
|
||||
|
||||
private _detachedChild?: ChildNode;
|
||||
|
||||
protected firstUpdated(): void {
|
||||
this.style.position = "relative";
|
||||
this.style.display = "block";
|
||||
}
|
||||
|
||||
// This is not a lit element, but an updating element, so we implement update
|
||||
protected update(changedProps: PropertyValues): void {
|
||||
super.update(changedProps);
|
||||
const stateObj = this.stateObj;
|
||||
const hass = this.hass;
|
||||
|
||||
if (!stateObj || !hass) {
|
||||
if (this.lastChild) {
|
||||
this._detachedChild = this.lastChild;
|
||||
// Detach child to prevent it from doing work.
|
||||
this.removeChild(this.lastChild);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._detachedChild) {
|
||||
this.appendChild(this._detachedChild);
|
||||
this._detachedChild = undefined;
|
||||
}
|
||||
|
||||
const moreInfoType =
|
||||
stateObj.attributes && "custom_ui_more_info" in stateObj.attributes
|
||||
? stateObj.attributes.custom_ui_more_info
|
||||
: "more-info-" + stateMoreInfoType(stateObj);
|
||||
|
||||
dynamicContentUpdater(this, moreInfoType.toUpperCase(), {
|
||||
hass,
|
||||
stateObj,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("more-info-content", MoreInfoContent);
|
Loading…
x
Reference in New Issue
Block a user