Fix area filtering logic in RegistryFilter

Method `whereAreaId()` filtered out entries without a device.
Those entries are now kept:
When areaId is `undisclosed`, the entry's area_id must match, and the
entry's device `area_id` must match, only if it is defined.
This commit is contained in:
DigiLive
2025-05-02 09:37:24 +02:00
parent eed47c6d55
commit 5ee0500f08

View File

@@ -70,25 +70,36 @@ class RegistryFilter<T extends RegistryEntry, K extends keyof T = keyof T> {
* Filters entries **strictly** by their `area_id`.
*
* - Entries with a matching `area_id` are kept.
* - If `expandToDevice` is `true`, the device's `area_id` is evaluated if the entry's area_id doesn't match.
* - If `areaId` is `undefined` (or omitted), entries without an `area_id` property are kept.
* - If `expandToDevice` is `true` and the entry's `area_id` is `undisclosed`, the device's `area_id` is used.
*
* @param {string | undefined} areaId - The area id to match.
* @param {boolean} [expandToDevice=true] - Whether to use the device's `area_id` if the entry has none.
* @param {boolean} [expandToDevice=true] - Whether to use the device's `area_id` if the entry's doesn't match.
*
* @remarks
* For area id `undisclosed`, the `area_id` of the entry's device may be `undisclosed` or `undefined`.
*/
whereAreaId(areaId?: string, expandToDevice: boolean = true): this {
const predicate = (entry: T) => {
let deviceAreaId: string | null | undefined = undefined;
const entryObject = entry as EntityRegistryEntry;
// Retrieve the device area ID only if expandToDevice is true
if (expandToDevice && entryObject.device_id) {
deviceAreaId = Registry.devices.find((device) => device.id === entryObject.device_id)?.area_id;
}
if (areaId === 'undisclosed' || areaId === undefined) {
return entry.area_id === areaId && (!expandToDevice || deviceAreaId === areaId);
// Logic for 'undisclosed' areaId
if (areaId === 'undisclosed') {
return entry.area_id === areaId && (deviceAreaId === areaId || deviceAreaId === undefined);
}
// Logic for undefined areaId
if (areaId === undefined) {
return entry.area_id === undefined && (!expandToDevice || deviceAreaId === undefined);
}
// Logic for any other areaId
return entry.area_id === areaId || (expandToDevice && deviceAreaId === areaId);
};