mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 07:16:39 +00:00
Integration filter for Area Selector (#12682)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
97663aef42
commit
2dec8e70ec
@ -1,15 +1,24 @@
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ConfigEntry, getConfigEntries } from "../../data/config_entries";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import { EntityRegistryEntry } from "../../data/entity_registry";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../data/entity_registry";
|
||||
import {
|
||||
EntitySources,
|
||||
fetchEntitySourcesWithCache,
|
||||
} from "../../data/entity_sources";
|
||||
import { AreaSelector } from "../../data/selector";
|
||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "../ha-area-picker";
|
||||
import "../ha-areas-picker";
|
||||
|
||||
@customElement("ha-selector-area")
|
||||
export class HaAreaSelector extends LitElement {
|
||||
export class HaAreaSelector extends SubscribeMixin(LitElement) {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@property() public selector!: AreaSelector;
|
||||
@ -20,29 +29,44 @@ export class HaAreaSelector extends LitElement {
|
||||
|
||||
@property() public helper?: string;
|
||||
|
||||
@state() public _configEntries?: ConfigEntry[];
|
||||
@state() private _entitySources?: EntitySources;
|
||||
|
||||
@state() private _entities?: EntityRegistryEntry[];
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@property({ type: Boolean }) public required = true;
|
||||
|
||||
protected updated(changedProperties) {
|
||||
if (changedProperties.has("selector")) {
|
||||
const oldSelector = changedProperties.get("selector");
|
||||
if (
|
||||
oldSelector !== this.selector &&
|
||||
this.selector.area.device?.integration
|
||||
) {
|
||||
getConfigEntries(this.hass, {
|
||||
domain: this.selector.area.device.integration,
|
||||
}).then((entries) => {
|
||||
this._configEntries = entries;
|
||||
});
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||
this._entities = entities.filter((entity) => entity.device_id !== null);
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected updated(changedProperties) {
|
||||
if (
|
||||
changedProperties.has("selector") &&
|
||||
(this.selector.area.device?.integration ||
|
||||
this.selector.area.entity?.integration) &&
|
||||
!this._entitySources
|
||||
) {
|
||||
fetchEntitySourcesWithCache(this.hass).then((sources) => {
|
||||
this._entitySources = sources;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (
|
||||
(this.selector.area.device?.integration ||
|
||||
this.selector.area.entity?.integration) &&
|
||||
!this._entitySources
|
||||
) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
if (!this.selector.area.multiple) {
|
||||
return html`
|
||||
<ha-area-picker
|
||||
@ -87,39 +111,62 @@ export class HaAreaSelector extends LitElement {
|
||||
}
|
||||
|
||||
private _filterEntities = (entity: EntityRegistryEntry): boolean => {
|
||||
if (this.selector.area.entity?.integration) {
|
||||
if (entity.platform !== this.selector.area.entity.integration) {
|
||||
const filterIntegration = this.selector.area.entity?.integration;
|
||||
if (
|
||||
filterIntegration &&
|
||||
this._entitySources?.[entity.entity_id]?.domain !== filterIntegration
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
private _filterDevices = (device: DeviceRegistryEntry): boolean => {
|
||||
if (!this.selector.area.device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const {
|
||||
manufacturer: filterManufacturer,
|
||||
model: filterModel,
|
||||
integration: filterIntegration,
|
||||
} = this.selector.area.device;
|
||||
|
||||
if (filterManufacturer && device.manufacturer !== filterManufacturer) {
|
||||
return false;
|
||||
}
|
||||
if (filterModel && device.model !== filterModel) {
|
||||
return false;
|
||||
}
|
||||
if (filterIntegration && this._entitySources && this._entities) {
|
||||
const deviceIntegrations = this._deviceIntegrations(
|
||||
this._entitySources,
|
||||
this._entities
|
||||
);
|
||||
if (!deviceIntegrations?.[device.id]?.includes(filterIntegration)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
private _filterDevices = (device: DeviceRegistryEntry): boolean => {
|
||||
if (
|
||||
this.selector.area.device?.manufacturer &&
|
||||
device.manufacturer !== this.selector.area.device.manufacturer
|
||||
) {
|
||||
return false;
|
||||
private _deviceIntegrations = memoizeOne(
|
||||
(entitySources: EntitySources, entities: EntityRegistryEntry[]) => {
|
||||
const deviceIntegrations: Record<string, string[]> = {};
|
||||
|
||||
for (const entity of entities) {
|
||||
const source = entitySources[entity.entity_id];
|
||||
if (!source?.domain) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
this.selector.area.device?.model &&
|
||||
device.model !== this.selector.area.device.model
|
||||
) {
|
||||
return false;
|
||||
if (!deviceIntegrations[entity.device_id!]) {
|
||||
deviceIntegrations[entity.device_id!] = [];
|
||||
}
|
||||
if (this.selector.area.device?.integration) {
|
||||
if (
|
||||
this._configEntries &&
|
||||
!this._configEntries.some((entry) =>
|
||||
device.config_entries.includes(entry.entry_id)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
deviceIntegrations[entity.device_id!].push(source.domain);
|
||||
}
|
||||
return deviceIntegrations;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
Loading…
x
Reference in New Issue
Block a user