mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Multiple entities on history panel bugfix and additional improvements (#13045)
Co-authored-by: Zack Barett <zackbarett@hey.com>
This commit is contained in:
parent
8fd5f53f96
commit
6cd38472cd
@ -186,6 +186,7 @@ class StateHistoryCharts extends LitElement {
|
|||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-height: var(--history-max-height);
|
max-height: var(--history-max-height);
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ import "./entity/ha-entity-picker";
|
|||||||
import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
|
import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
|
||||||
import "./ha-area-picker";
|
import "./ha-area-picker";
|
||||||
import "./ha-icon-button";
|
import "./ha-icon-button";
|
||||||
import "./ha-svg-icon";
|
|
||||||
import "./ha-input-helper-text";
|
import "./ha-input-helper-text";
|
||||||
|
import "./ha-svg-icon";
|
||||||
|
|
||||||
@customElement("ha-target-picker")
|
@customElement("ha-target-picker")
|
||||||
export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
||||||
@ -119,55 +119,68 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
|||||||
if (!this._areas || !this._devices || !this._entities) {
|
if (!this._areas || !this._devices || !this._entities) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
return html`<div class=${this.horizontal ? "horizontal-container" : ""}>
|
return html`
|
||||||
${this.horizontal ? this._renderChips() : this._renderItems()}
|
${this.horizontal
|
||||||
${this._renderPicker()}
|
? html`
|
||||||
${this.horizontal ? this._renderItems() : this._renderChips()}
|
<div class="horizontal-container">
|
||||||
</div>`;
|
${this._renderChips()} ${this._renderPicker()}
|
||||||
|
</div>
|
||||||
|
${this._renderItems()}
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<div>
|
||||||
|
${this._renderItems()} ${this._renderPicker()}
|
||||||
|
${this._renderChips()}
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderItems() {
|
private _renderItems() {
|
||||||
return html`<div class="mdc-chip-set items">
|
return html`
|
||||||
${this.value?.area_id
|
<div class="mdc-chip-set items">
|
||||||
? ensureArray(this.value.area_id).map((area_id) => {
|
${this.value?.area_id
|
||||||
const area = this._areas![area_id];
|
? ensureArray(this.value.area_id).map((area_id) => {
|
||||||
return this._renderChip(
|
const area = this._areas![area_id];
|
||||||
"area_id",
|
return this._renderChip(
|
||||||
area_id,
|
"area_id",
|
||||||
area?.name || area_id,
|
area_id,
|
||||||
undefined,
|
area?.name || area_id,
|
||||||
mdiSofa
|
undefined,
|
||||||
);
|
mdiSofa
|
||||||
})
|
);
|
||||||
: ""}
|
})
|
||||||
${this.value?.device_id
|
: ""}
|
||||||
? ensureArray(this.value.device_id).map((device_id) => {
|
${this.value?.device_id
|
||||||
const device = this._devices![device_id];
|
? ensureArray(this.value.device_id).map((device_id) => {
|
||||||
return this._renderChip(
|
const device = this._devices![device_id];
|
||||||
"device_id",
|
return this._renderChip(
|
||||||
device_id,
|
"device_id",
|
||||||
device ? computeDeviceName(device, this.hass) : device_id,
|
device_id,
|
||||||
undefined,
|
device ? computeDeviceName(device, this.hass) : device_id,
|
||||||
mdiDevices
|
undefined,
|
||||||
);
|
mdiDevices
|
||||||
})
|
);
|
||||||
: ""}
|
})
|
||||||
${this.value?.entity_id
|
: ""}
|
||||||
? ensureArray(this.value.entity_id).map((entity_id) => {
|
${this.value?.entity_id
|
||||||
const entity = this.hass.states[entity_id];
|
? ensureArray(this.value.entity_id).map((entity_id) => {
|
||||||
return this._renderChip(
|
const entity = this.hass.states[entity_id];
|
||||||
"entity_id",
|
return this._renderChip(
|
||||||
entity_id,
|
"entity_id",
|
||||||
entity ? computeStateName(entity) : entity_id,
|
entity_id,
|
||||||
entity
|
entity ? computeStateName(entity) : entity_id,
|
||||||
);
|
entity
|
||||||
})
|
);
|
||||||
: ""}
|
})
|
||||||
</div>`;
|
: ""}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderChips() {
|
private _renderChips() {
|
||||||
return html`<div class="mdc-chip-set">
|
return html`
|
||||||
|
<div class="mdc-chip-set">
|
||||||
<div
|
<div
|
||||||
class="mdc-chip area_id add"
|
class="mdc-chip area_id add"
|
||||||
.type=${"area_id"}
|
.type=${"area_id"}
|
||||||
@ -231,7 +244,8 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
|||||||
</div>
|
</div>
|
||||||
${this.helper
|
${this.helper
|
||||||
? html`<ha-input-helper-text>${this.helper}</ha-input-helper-text>`
|
? html`<ha-input-helper-text>${this.helper}</ha-input-helper-text>`
|
||||||
: ""} `;
|
: ""}
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _showPicker(ev) {
|
private async _showPicker(ev) {
|
||||||
@ -320,51 +334,54 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
|||||||
private _renderPicker() {
|
private _renderPicker() {
|
||||||
switch (this._addMode) {
|
switch (this._addMode) {
|
||||||
case "area_id":
|
case "area_id":
|
||||||
return html`<ha-area-picker
|
return html`
|
||||||
.hass=${this.hass}
|
<ha-area-picker
|
||||||
id="input"
|
.hass=${this.hass}
|
||||||
.type=${"area_id"}
|
id="input"
|
||||||
.label=${this.hass.localize(
|
.type=${"area_id"}
|
||||||
"ui.components.target-picker.add_area_id"
|
.label=${this.hass.localize(
|
||||||
)}
|
"ui.components.target-picker.add_area_id"
|
||||||
no-add
|
)}
|
||||||
.deviceFilter=${this.deviceFilter}
|
no-add
|
||||||
.entityFilter=${this.entityRegFilter}
|
.deviceFilter=${this.deviceFilter}
|
||||||
.includeDeviceClasses=${this.includeDeviceClasses}
|
.entityFilter=${this.entityRegFilter}
|
||||||
.includeDomains=${this.includeDomains}
|
.includeDeviceClasses=${this.includeDeviceClasses}
|
||||||
class=${this.horizontal ? "hidden-picker" : ""}
|
.includeDomains=${this.includeDomains}
|
||||||
@value-changed=${this._targetPicked}
|
@value-changed=${this._targetPicked}
|
||||||
></ha-area-picker>`;
|
></ha-area-picker>
|
||||||
|
`;
|
||||||
case "device_id":
|
case "device_id":
|
||||||
return html`<ha-device-picker
|
return html`
|
||||||
.hass=${this.hass}
|
<ha-device-picker
|
||||||
id="input"
|
.hass=${this.hass}
|
||||||
.type=${"device_id"}
|
id="input"
|
||||||
.label=${this.hass.localize(
|
.type=${"device_id"}
|
||||||
"ui.components.target-picker.add_device_id"
|
.label=${this.hass.localize(
|
||||||
)}
|
"ui.components.target-picker.add_device_id"
|
||||||
.deviceFilter=${this.deviceFilter}
|
)}
|
||||||
.entityFilter=${this.entityRegFilter}
|
.deviceFilter=${this.deviceFilter}
|
||||||
.includeDeviceClasses=${this.includeDeviceClasses}
|
.entityFilter=${this.entityRegFilter}
|
||||||
.includeDomains=${this.includeDomains}
|
.includeDeviceClasses=${this.includeDeviceClasses}
|
||||||
class=${this.horizontal ? "hidden-picker" : ""}
|
.includeDomains=${this.includeDomains}
|
||||||
@value-changed=${this._targetPicked}
|
@value-changed=${this._targetPicked}
|
||||||
></ha-device-picker>`;
|
></ha-device-picker>
|
||||||
|
`;
|
||||||
case "entity_id":
|
case "entity_id":
|
||||||
return html`<ha-entity-picker
|
return html`
|
||||||
.hass=${this.hass}
|
<ha-entity-picker
|
||||||
id="input"
|
.hass=${this.hass}
|
||||||
.type=${"entity_id"}
|
id="input"
|
||||||
.label=${this.hass.localize(
|
.type=${"entity_id"}
|
||||||
"ui.components.target-picker.add_entity_id"
|
.label=${this.hass.localize(
|
||||||
)}
|
"ui.components.target-picker.add_entity_id"
|
||||||
.entityFilter=${this.entityFilter}
|
)}
|
||||||
.includeDeviceClasses=${this.includeDeviceClasses}
|
.entityFilter=${this.entityFilter}
|
||||||
.includeDomains=${this.includeDomains}
|
.includeDeviceClasses=${this.includeDeviceClasses}
|
||||||
class=${this.horizontal ? "hidden-picker" : ""}
|
.includeDomains=${this.includeDomains}
|
||||||
@value-changed=${this._targetPicked}
|
@value-changed=${this._targetPicked}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>`;
|
></ha-entity-picker>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
@ -553,12 +570,6 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
|||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
${unsafeCSS(chipStyles)}
|
${unsafeCSS(chipStyles)}
|
||||||
.hidden-picker {
|
|
||||||
height: 0px;
|
|
||||||
display: inline-block;
|
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.horizontal-container {
|
.horizontal-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { mdiRefresh } from "@mdi/js";
|
import { mdiCollapseAll, mdiRefresh } from "@mdi/js";
|
||||||
import "@polymer/app-layout/app-header/app-header";
|
import "@polymer/app-layout/app-header/app-header";
|
||||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||||
import {
|
import {
|
||||||
@ -34,6 +34,10 @@ import {
|
|||||||
EntityRegistryEntry,
|
EntityRegistryEntry,
|
||||||
subscribeEntityRegistry,
|
subscribeEntityRegistry,
|
||||||
} from "../../data/entity_registry";
|
} from "../../data/entity_registry";
|
||||||
|
import {
|
||||||
|
DeviceRegistryEntry,
|
||||||
|
subscribeDeviceRegistry,
|
||||||
|
} from "../../data/device_registry";
|
||||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||||
import { computeDomain } from "../../common/entity/compute_domain";
|
import { computeDomain } from "../../common/entity/compute_domain";
|
||||||
@ -57,9 +61,23 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _ranges?: DateRangePickerRanges;
|
@state() private _ranges?: DateRangePickerRanges;
|
||||||
|
|
||||||
@state() private _entities?: EntityRegistryEntry[];
|
@state() private _devices?: { [deviceId: string]: DeviceRegistryEntry };
|
||||||
|
|
||||||
@state() private _stateEntities?: EntityRegistryEntry[];
|
@state() private _entities?: { [entityId: string]: EntityRegistryEntry };
|
||||||
|
|
||||||
|
@state() private _stateEntities?: { [entityId: string]: EntityRegistryEntry };
|
||||||
|
|
||||||
|
@state() private _deviceIdToEntities?: {
|
||||||
|
[deviceId: string]: EntityRegistryEntry[];
|
||||||
|
};
|
||||||
|
|
||||||
|
@state() private _areaIdToEntities?: {
|
||||||
|
[areaId: string]: EntityRegistryEntry[];
|
||||||
|
};
|
||||||
|
|
||||||
|
@state() private _areaIdToDevices?: {
|
||||||
|
[areaId: string]: DeviceRegistryEntry[];
|
||||||
|
};
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
@ -76,7 +94,52 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
public hassSubscribe(): UnsubscribeFunc[] {
|
public hassSubscribe(): UnsubscribeFunc[] {
|
||||||
return [
|
return [
|
||||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||||
this._entities = entities;
|
this._entities = entities.reduce((accumulator, current) => {
|
||||||
|
accumulator[current.entity_id] = current;
|
||||||
|
return accumulator;
|
||||||
|
}, {});
|
||||||
|
this._deviceIdToEntities = entities.reduce((accumulator, current) => {
|
||||||
|
if (!current.device_id) {
|
||||||
|
return accumulator;
|
||||||
|
}
|
||||||
|
let found = accumulator[current.device_id];
|
||||||
|
if (found === undefined) {
|
||||||
|
found = [];
|
||||||
|
accumulator[current.device_id] = found;
|
||||||
|
}
|
||||||
|
found.push(current);
|
||||||
|
return accumulator;
|
||||||
|
}, {});
|
||||||
|
this._areaIdToEntities = entities.reduce((accumulator, current) => {
|
||||||
|
if (!current.area_id) {
|
||||||
|
return accumulator;
|
||||||
|
}
|
||||||
|
let found = accumulator[current.area_id];
|
||||||
|
if (found === undefined) {
|
||||||
|
found = [];
|
||||||
|
accumulator[current.area_id] = found;
|
||||||
|
}
|
||||||
|
found.push(current);
|
||||||
|
return accumulator;
|
||||||
|
}, {});
|
||||||
|
}),
|
||||||
|
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
|
||||||
|
this._devices = devices.reduce((accumulator, current) => {
|
||||||
|
accumulator[current.id] = current;
|
||||||
|
return accumulator;
|
||||||
|
}, {});
|
||||||
|
this._areaIdToDevices = devices.reduce((accumulator, current) => {
|
||||||
|
if (!current.area_id) {
|
||||||
|
return accumulator;
|
||||||
|
}
|
||||||
|
let found = accumulator[current.area_id];
|
||||||
|
if (found === undefined) {
|
||||||
|
found = [];
|
||||||
|
accumulator[current.area_id] = found;
|
||||||
|
}
|
||||||
|
found.push(current);
|
||||||
|
return accumulator;
|
||||||
|
}, {});
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -91,6 +154,12 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
></ha-menu-button>
|
></ha-menu-button>
|
||||||
<div main-title>${this.hass.localize("panel.history")}</div>
|
<div main-title>${this.hass.localize("panel.history")}</div>
|
||||||
|
<ha-icon-button
|
||||||
|
@click=${this._removeAll}
|
||||||
|
.disabled=${this._isLoading}
|
||||||
|
.path=${mdiCollapseAll}
|
||||||
|
.label=${this.hass.localize("ui.panel.history.remove_all")}
|
||||||
|
></ha-icon-button>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
@click=${this._refreshHistory}
|
@click=${this._refreshHistory}
|
||||||
.disabled=${this._isLoading}
|
.disabled=${this._isLoading}
|
||||||
@ -125,6 +194,10 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
alt=${this.hass.localize("ui.common.loading")}
|
alt=${this.hass.localize("ui.common.loading")}
|
||||||
></ha-circular-progress>
|
></ha-circular-progress>
|
||||||
</div>`
|
</div>`
|
||||||
|
: !this._targetPickerValue
|
||||||
|
? html`<div class="start-search">
|
||||||
|
${this.hass.localize("ui.panel.history.start_search")}
|
||||||
|
</div>`
|
||||||
: html`
|
: html`
|
||||||
<state-history-charts
|
<state-history-charts
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -135,24 +208,6 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
</state-history-charts>
|
</state-history-charts>
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
${this._isLoading
|
|
||||||
? html`<div class="progress-wrapper">
|
|
||||||
<ha-circular-progress
|
|
||||||
active
|
|
||||||
alt=${this.hass.localize("ui.common.loading")}
|
|
||||||
></ha-circular-progress>
|
|
||||||
</div>`
|
|
||||||
: html`
|
|
||||||
<state-history-charts
|
|
||||||
virtualize
|
|
||||||
.hass=${this.hass}
|
|
||||||
.historyData=${this._stateHistory}
|
|
||||||
.endTime=${this._endDate}
|
|
||||||
.narrow=${this.narrow}
|
|
||||||
no-single
|
|
||||||
>
|
|
||||||
</state-history-charts>
|
|
||||||
`}
|
|
||||||
</ha-app-layout>
|
</ha-app-layout>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -199,8 +254,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
if (
|
if (
|
||||||
changedProps.has("_startDate") ||
|
changedProps.has("_startDate") ||
|
||||||
changedProps.has("_endDate") ||
|
changedProps.has("_endDate") ||
|
||||||
changedProps.has("_targetPickerValue") ||
|
changedProps.has("_targetPickerValue")
|
||||||
changedProps.has("_entities")
|
|
||||||
) {
|
) {
|
||||||
this._getHistory();
|
this._getHistory();
|
||||||
}
|
}
|
||||||
@ -211,15 +265,13 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
this.rtl = computeRTL(this.hass);
|
this.rtl = computeRTL(this.hass);
|
||||||
}
|
}
|
||||||
if (this._entities) {
|
if (this._entities) {
|
||||||
const stateEntities: EntityRegistryEntry[] = [];
|
const stateEntities: { [entityId: string]: EntityRegistryEntry } = {};
|
||||||
const regEntityIds = new Set(
|
const regEntityIds = new Set(Object.keys(this._entities));
|
||||||
this._entities.map((entity) => entity.entity_id)
|
|
||||||
);
|
|
||||||
for (const entityId of Object.keys(this.hass.states)) {
|
for (const entityId of Object.keys(this.hass.states)) {
|
||||||
if (regEntityIds.has(entityId)) {
|
if (regEntityIds.has(entityId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
stateEntities.push({
|
stateEntities[entityId] = {
|
||||||
name: computeStateName(this.hass.states[entityId]),
|
name: computeStateName(this.hass.states[entityId]),
|
||||||
entity_id: entityId,
|
entity_id: entityId,
|
||||||
platform: computeDomain(entityId),
|
platform: computeDomain(entityId),
|
||||||
@ -230,17 +282,27 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
device_id: null,
|
device_id: null,
|
||||||
icon: null,
|
icon: null,
|
||||||
entity_category: null,
|
entity_category: null,
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
this._stateEntities = stateEntities;
|
this._stateEntities = stateEntities;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _removeAll() {
|
||||||
|
this._targetPickerValue = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private _refreshHistory() {
|
private _refreshHistory() {
|
||||||
this._getHistory();
|
this._getHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _shouldShowEntityByLargerSelection(
|
||||||
|
entity: EntityRegistryEntry
|
||||||
|
): boolean {
|
||||||
|
return entity.entity_category === null;
|
||||||
|
}
|
||||||
|
|
||||||
private async _getHistory() {
|
private async _getHistory() {
|
||||||
this._isLoading = true;
|
this._isLoading = true;
|
||||||
const entityIds = this._getEntityIds();
|
const entityIds = this._getEntityIds();
|
||||||
@ -261,50 +323,79 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
this._isLoading = false;
|
this._isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _filterEntity(entity: EntityRegistryEntry): boolean {
|
|
||||||
const { area_id, device_id, entity_id } = this._targetPickerValue;
|
|
||||||
if (area_id !== undefined) {
|
|
||||||
if (typeof area_id === "string" && area_id === entity.area_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Array.isArray(area_id) && area_id.includes(entity.area_id)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (device_id !== undefined) {
|
|
||||||
if (typeof device_id === "string" && device_id === entity.device_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Array.isArray(device_id) && device_id.includes(entity.device_id)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entity_id !== undefined) {
|
|
||||||
if (typeof entity_id === "string" && entity_id === entity.entity_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Array.isArray(entity_id) && entity_id.includes(entity.entity_id)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getEntityIds(): string[] {
|
private _getEntityIds(): string[] {
|
||||||
if (
|
if (
|
||||||
this._targetPickerValue === undefined ||
|
this._targetPickerValue === undefined ||
|
||||||
this._entities === undefined ||
|
this._entities === undefined ||
|
||||||
this._stateEntities === undefined
|
this._stateEntities === undefined ||
|
||||||
|
this._devices === undefined ||
|
||||||
|
this._deviceIdToEntities === undefined ||
|
||||||
|
this._areaIdToEntities === undefined ||
|
||||||
|
this._areaIdToDevices === undefined
|
||||||
) {
|
) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const entityIds = this._entities
|
const entityIds = new Set<string>();
|
||||||
.filter((entity) => this._filterEntity(entity))
|
let {
|
||||||
.map((entity) => entity.entity_id);
|
area_id: searchingAreaId,
|
||||||
const stateEntityIds = this._stateEntities
|
device_id: searchingDeviceId,
|
||||||
.filter((entity) => this._filterEntity(entity))
|
entity_id: searchingEntityId,
|
||||||
.map((entity) => entity.entity_id);
|
} = this._targetPickerValue;
|
||||||
return [...entityIds, ...stateEntityIds];
|
if (searchingAreaId !== undefined) {
|
||||||
|
if (typeof searchingAreaId === "string") {
|
||||||
|
searchingAreaId = [searchingAreaId];
|
||||||
|
}
|
||||||
|
for (const singleSearchingAreaId of searchingAreaId) {
|
||||||
|
const foundEntities = this._areaIdToEntities[singleSearchingAreaId];
|
||||||
|
if (foundEntities !== undefined) {
|
||||||
|
for (const foundEntity of foundEntities) {
|
||||||
|
if (this._shouldShowEntityByLargerSelection(foundEntity)) {
|
||||||
|
entityIds.add(foundEntity.entity_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const foundDevices = this._areaIdToDevices[singleSearchingAreaId];
|
||||||
|
if (foundDevices !== undefined) {
|
||||||
|
for (const foundDevice of foundDevices) {
|
||||||
|
const foundDeviceEntities =
|
||||||
|
this._deviceIdToEntities[foundDevice.id];
|
||||||
|
for (const foundDeviceEntity of foundDeviceEntities) {
|
||||||
|
if (
|
||||||
|
(!foundDeviceEntity.area_id ||
|
||||||
|
foundDeviceEntity.area_id === singleSearchingAreaId) &&
|
||||||
|
this._shouldShowEntityByLargerSelection(foundDeviceEntity)
|
||||||
|
) {
|
||||||
|
entityIds.add(foundDeviceEntity.entity_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (searchingDeviceId !== undefined) {
|
||||||
|
if (typeof searchingDeviceId === "string") {
|
||||||
|
searchingDeviceId = [searchingDeviceId];
|
||||||
|
}
|
||||||
|
for (const singleSearchingDeviceId of searchingDeviceId) {
|
||||||
|
const foundEntities = this._deviceIdToEntities[singleSearchingDeviceId];
|
||||||
|
if (foundEntities !== undefined) {
|
||||||
|
for (const foundEntity of foundEntities) {
|
||||||
|
if (this._shouldShowEntityByLargerSelection(foundEntity)) {
|
||||||
|
entityIds.add(foundEntity.entity_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (searchingEntityId !== undefined) {
|
||||||
|
if (typeof searchingEntityId === "string") {
|
||||||
|
searchingEntityId = [searchingEntityId];
|
||||||
|
}
|
||||||
|
for (const singleSearchingEntityId of searchingEntityId) {
|
||||||
|
entityIds.add(singleSearchingEntityId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...entityIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
private _dateRangeChanged(ev) {
|
private _dateRangeChanged(ev) {
|
||||||
@ -389,7 +480,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
.filters {
|
.filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-start;
|
||||||
padding: 8px 16px 0;
|
padding: 8px 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,6 +520,12 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
|||||||
max-width: none;
|
max-width: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.start-search {
|
||||||
|
padding-top: 16px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -4559,6 +4559,11 @@
|
|||||||
"energy_sources_table_title": "Sources",
|
"energy_sources_table_title": "Sources",
|
||||||
"energy_devices_graph_title": "Monitor individual devices"
|
"energy_devices_graph_title": "Monitor individual devices"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"history": {
|
||||||
|
"start_search": "Start by selecting an area, device or entity above",
|
||||||
|
"add_all": "Add all entities",
|
||||||
|
"remove_all": "Remove all selections"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tips": {
|
"tips": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user