From 68e22d23f1ecf7e1313e49ed82bc483e2a2817b2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 26 Jun 2025 16:42:11 +0200 Subject: [PATCH] Fix filtering on device in entities config panel (#25948) * Fix filtering on device in entities config panel * fix * set filters from url twice to catch race... --- src/common/decorators/storage.ts | 5 +++-- src/components/ha-filter-blueprints.ts | 14 ++++++------ src/components/ha-filter-devices.ts | 15 ++++++++----- src/components/ha-filter-entities.ts | 14 +++++++----- src/components/ha-filter-floor-areas.ts | 17 ++++++-------- .../config/entities/ha-config-entities.ts | 22 +++++++------------ 6 files changed, 43 insertions(+), 44 deletions(-) diff --git a/src/common/decorators/storage.ts b/src/common/decorators/storage.ts index 03d4176548..80c258b83f 100644 --- a/src/common/decorators/storage.ts +++ b/src/common/decorators/storage.ts @@ -202,7 +202,6 @@ export function storage(options: { // Don't set the initial value if we have a value in localStorage if (this.__initialized || getValue() === undefined) { setValue(this, value); - this.requestUpdate(propertyKey, undefined); } }, configurable: true, @@ -212,11 +211,13 @@ export function storage(options: { const oldSetter = descriptor.set; newDescriptor = { ...descriptor, + get(this: ReactiveStorageElement) { + return getValue(); + }, set(this: ReactiveStorageElement, value) { // Don't set the initial value if we have a value in localStorage if (this.__initialized || getValue() === undefined) { setValue(this, value); - this.requestUpdate(propertyKey, undefined); } oldSetter?.call(this, value); }, diff --git a/src/components/ha-filter-blueprints.ts b/src/components/ha-filter-blueprints.ts index bdb2816ff3..c32d79659a 100644 --- a/src/components/ha-filter-blueprints.ts +++ b/src/components/ha-filter-blueprints.ts @@ -14,6 +14,7 @@ import "./ha-check-list-item"; import "./ha-expansion-panel"; import "./ha-icon-button"; import "./ha-list"; +import { deepEqual } from "../common/util/deep-equal"; @customElement("ha-filter-blueprints") export class HaFilterBlueprints extends LitElement { @@ -34,10 +35,11 @@ export class HaFilterBlueprints extends LitElement { public willUpdate(properties: PropertyValues) { super.willUpdate(properties); - if (!this.hasUpdated) { - if (this.value?.length) { - this._findRelated(); - } + if ( + properties.has("value") && + !deepEqual(this.value, properties.get("value")) + ) { + this._findRelated(); } } @@ -130,17 +132,15 @@ export class HaFilterBlueprints extends LitElement { } this.value = value; - - this._findRelated(); } private async _findRelated() { if (!this.value?.length) { + this.value = []; fireEvent(this, "data-table-filter-changed", { value: [], items: undefined, }); - this.value = []; return; } diff --git a/src/components/ha-filter-devices.ts b/src/components/ha-filter-devices.ts index 7beb3c05ea..17bf421295 100644 --- a/src/components/ha-filter-devices.ts +++ b/src/components/ha-filter-devices.ts @@ -6,6 +6,7 @@ import memoizeOne from "memoize-one"; import { fireEvent } from "../common/dom/fire_event"; import { computeDeviceNameDisplay } from "../common/entity/compute_device_name"; import { stringCompare } from "../common/string/compare"; +import { deepEqual } from "../common/util/deep-equal"; import type { RelatedResult } from "../data/search"; import { findRelated } from "../data/search"; import { haStyleScrollbar } from "../resources/styles"; @@ -37,9 +38,13 @@ export class HaFilterDevices extends LitElement { if (!this.hasUpdated) { loadVirtualizer(); - if (this.value?.length) { - this._findRelated(); - } + } + + if ( + properties.has("value") && + !deepEqual(this.value, properties.get("value")) + ) { + this._findRelated(); } } @@ -110,7 +115,6 @@ export class HaFilterDevices extends LitElement { this.value = [...(this.value || []), value]; } listItem.selected = this.value?.includes(value); - this._findRelated(); } protected updated(changed) { @@ -160,11 +164,11 @@ export class HaFilterDevices extends LitElement { const relatedPromises: Promise[] = []; if (!this.value?.length) { + this.value = []; fireEvent(this, "data-table-filter-changed", { value: [], items: undefined, }); - this.value = []; return; } @@ -176,7 +180,6 @@ export class HaFilterDevices extends LitElement { relatedPromises.push(findRelated(this.hass, "device", deviceId)); } } - this.value = value; const results = await Promise.all(relatedPromises); const items = new Set(); for (const result of results) { diff --git a/src/components/ha-filter-entities.ts b/src/components/ha-filter-entities.ts index 3f078d813c..35da537f86 100644 --- a/src/components/ha-filter-entities.ts +++ b/src/components/ha-filter-entities.ts @@ -17,6 +17,7 @@ import "./ha-expansion-panel"; import "./ha-list"; import "./ha-state-icon"; import "./search-input-outlined"; +import { deepEqual } from "../common/util/deep-equal"; @customElement("ha-filter-entities") export class HaFilterEntities extends LitElement { @@ -39,9 +40,13 @@ export class HaFilterEntities extends LitElement { if (!this.hasUpdated) { loadVirtualizer(); - if (this.value?.length) { - this._findRelated(); - } + } + + if ( + properties.has("value") && + !deepEqual(this.value, properties.get("value")) + ) { + this._findRelated(); } } @@ -131,7 +136,6 @@ export class HaFilterEntities extends LitElement { this.value = [...(this.value || []), value]; } listItem.selected = this.value?.includes(value); - this._findRelated(); } private _expandedWillChange(ev) { @@ -178,11 +182,11 @@ export class HaFilterEntities extends LitElement { const relatedPromises: Promise[] = []; if (!this.value?.length) { + this.value = []; fireEvent(this, "data-table-filter-changed", { value: [], items: undefined, }); - this.value = []; return; } diff --git a/src/components/ha-filter-floor-areas.ts b/src/components/ha-filter-floor-areas.ts index 5f4e811b4f..38ee414683 100644 --- a/src/components/ha-filter-floor-areas.ts +++ b/src/components/ha-filter-floor-areas.ts @@ -20,6 +20,7 @@ import "./ha-icon-button"; import "./ha-list"; import "./ha-svg-icon"; import "./ha-tree-indicator"; +import { deepEqual } from "../common/util/deep-equal"; @customElement("ha-filter-floor-areas") export class HaFilterFloorAreas extends LitElement { @@ -41,10 +42,11 @@ export class HaFilterFloorAreas extends LitElement { public willUpdate(properties: PropertyValues) { super.willUpdate(properties); - if (!this.hasUpdated) { - if (this.value?.floors?.length || this.value?.areas?.length) { - this._findRelated(); - } + if ( + properties.has("value") && + !deepEqual(this.value, properties.get("value")) + ) { + this._findRelated(); } } @@ -174,8 +176,6 @@ export class HaFilterFloorAreas extends LitElement { } listItem.selected = this.value[type]?.includes(value); - - this._findRelated(); } protected updated(changed) { @@ -188,10 +188,6 @@ export class HaFilterFloorAreas extends LitElement { } } - protected firstUpdated() { - this._findRelated(); - } - private _expandedWillChange(ev) { this._shouldRender = ev.detail.expanded; } @@ -226,6 +222,7 @@ export class HaFilterFloorAreas extends LitElement { !this.value || (!this.value.areas?.length && !this.value.floors?.length) ) { + this.value = {}; fireEvent(this, "data-table-filter-changed", { value: {}, items: undefined, diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index e1607485cb..106a6fb8f3 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -1099,10 +1099,10 @@ ${ } protected firstUpdated() { + this._setFiltersFromUrl(); fetchEntitySourcesWithCache(this.hass).then((sources) => { this._entitySources = sources; }); - this._setFiltersFromUrl(); if (Object.keys(this._filters).length) { return; } @@ -1116,7 +1116,7 @@ ${ const configEntry = this._searchParms.get("config_entry"); const subEntry = this._searchParms.get("sub_entry"); const device = this._searchParms.get("device"); - const label = this._searchParms.has("label"); + const label = this._searchParms.get("label"); if (!domain && !configEntry && !label && !device) { return; @@ -1128,21 +1128,10 @@ ${ "ha-filter-states": [], "ha-filter-integrations": domain ? [domain] : [], "ha-filter-devices": device ? [device] : [], + "ha-filter-labels": label ? [label] : [], config_entry: configEntry ? [configEntry] : [], sub_entry: subEntry ? [subEntry] : [], }; - this._filterLabel(); - } - - private _filterLabel() { - const label = this._searchParms.get("label"); - if (!label) { - return; - } - this._filters = { - ...this._filters, - "ha-filter-labels": [label], - }; } private _clearFilter() { @@ -1152,6 +1141,11 @@ ${ public willUpdate(changedProps: PropertyValues): void { super.willUpdate(changedProps); + + if (!this.hasUpdated) { + this._setFiltersFromUrl(); + } + const oldHass = changedProps.get("hass"); let changed = false; if (!this.hass || !this._entities) {