Use collections for registries (#3168)

* Use collections

* Fix bugs

* Lint
This commit is contained in:
Paulus Schoutsen 2019-05-07 20:57:23 -07:00 committed by GitHub
parent 289611363e
commit fa13b95498
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 237 additions and 109 deletions

View File

@ -1,4 +1,7 @@
import { createCollection } from "home-assistant-js-websocket";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import { compare } from "../common/string/compare";
import { debounce } from "../common/util/debounce";
export interface AreaRegistryEntry { export interface AreaRegistryEntry {
area_id: string; area_id: string;
@ -9,9 +12,6 @@ export interface AreaRegistryEntryMutableParams {
name: string; name: string;
} }
export const fetchAreaRegistry = (hass: HomeAssistant) =>
hass.callWS<AreaRegistryEntry[]>({ type: "config/area_registry/list" });
export const createAreaRegistryEntry = ( export const createAreaRegistryEntry = (
hass: HomeAssistant, hass: HomeAssistant,
values: AreaRegistryEntryMutableParams values: AreaRegistryEntryMutableParams
@ -37,3 +37,33 @@ export const deleteAreaRegistryEntry = (hass: HomeAssistant, areaId: string) =>
type: "config/area_registry/delete", type: "config/area_registry/delete",
area_id: areaId, area_id: areaId,
}); });
const fetchAreaRegistry = (conn) =>
conn
.sendMessagePromise({
type: "config/area_registry/list",
})
.then((areas) => areas.sort((ent1, ent2) => compare(ent1.name, ent2.name)));
const subscribeAreaRegistryUpdates = (conn, store) =>
conn.subscribeEvents(
debounce(
() =>
fetchAreaRegistry(conn).then((areas) => store.setState(areas, true)),
500,
true
),
"area_registry_updated"
);
export const subscribeAreaRegistry = (
hass: HomeAssistant,
onChange: (areas: AreaRegistryEntry[]) => void
) =>
createCollection<AreaRegistryEntry[]>(
"_areaRegistry",
fetchAreaRegistry,
subscribeAreaRegistryUpdates,
hass.connection,
onChange
);

View File

@ -1,4 +1,6 @@
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import { createCollection } from "home-assistant-js-websocket";
import { debounce } from "../common/util/debounce";
export interface FieldSchema { export interface FieldSchema {
name: string; name: string;
@ -74,3 +76,33 @@ export const getConfigFlowsInProgress = (hass: HomeAssistant) =>
export const getConfigFlowHandlers = (hass: HomeAssistant) => export const getConfigFlowHandlers = (hass: HomeAssistant) =>
hass.callApi<string[]>("GET", "config/config_entries/flow_handlers"); hass.callApi<string[]>("GET", "config/config_entries/flow_handlers");
const fetchConfigFlowInProgress = (conn) =>
conn.sendMessagePromise({
type: "config/entity_registry/list",
});
const subscribeConfigFlowInProgressUpdates = (conn, store) =>
debounce(
conn.subscribeEvents(
() =>
fetchConfigFlowInProgress(conn).then((flows) =>
store.setState(flows, true)
),
500,
true
),
"config_entry_discovered"
);
export const subscribeConfigFlowInProgress = (
hass: HomeAssistant,
onChange: (flows: ConfigFlowProgress[]) => void
) =>
createCollection<ConfigFlowProgress[]>(
"_configFlowProgress",
fetchConfigFlowInProgress,
subscribeConfigFlowInProgressUpdates,
hass.connection,
onChange
);

View File

@ -1,4 +1,6 @@
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import { createCollection } from "home-assistant-js-websocket";
import { debounce } from "../common/util/debounce";
export interface DeviceRegistryEntry { export interface DeviceRegistryEntry {
id: string; id: string;
@ -18,9 +20,6 @@ export interface DeviceRegistryEntryMutableParams {
name_by_user?: string; name_by_user?: string;
} }
export const fetchDeviceRegistry = (hass: HomeAssistant) =>
hass.callWS<DeviceRegistryEntry[]>({ type: "config/device_registry/list" });
export const updateDeviceRegistryEntry = ( export const updateDeviceRegistryEntry = (
hass: HomeAssistant, hass: HomeAssistant,
deviceId: string, deviceId: string,
@ -31,3 +30,33 @@ export const updateDeviceRegistryEntry = (
device_id: deviceId, device_id: deviceId,
...updates, ...updates,
}); });
const fetchDeviceRegistry = (conn) =>
conn.sendMessagePromise({
type: "config/device_registry/list",
});
const subscribeDeviceRegistryUpdates = (conn, store) =>
conn.subscribeEvents(
debounce(
() =>
fetchDeviceRegistry(conn).then((devices) =>
store.setState(devices, true)
),
500,
true
),
"device_registry_updated"
);
export const subscribeDeviceRegistry = (
hass: HomeAssistant,
onChange: (devices: DeviceRegistryEntry[]) => void
) =>
createCollection<DeviceRegistryEntry[]>(
"_dr",
fetchDeviceRegistry,
subscribeDeviceRegistryUpdates,
hass.connection,
onChange
);

View File

@ -1,5 +1,7 @@
import { createCollection } from "home-assistant-js-websocket";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import computeStateName from "../common/entity/compute_state_name"; import computeStateName from "../common/entity/compute_state_name";
import { debounce } from "../common/util/debounce";
export interface EntityRegistryEntry { export interface EntityRegistryEntry {
entity_id: string; entity_id: string;
@ -26,11 +28,6 @@ export const computeEntityRegistryName = (
return state ? computeStateName(state) : null; return state ? computeStateName(state) : null;
}; };
export const fetchEntityRegistry = (
hass: HomeAssistant
): Promise<EntityRegistryEntry[]> =>
hass.callWS<EntityRegistryEntry[]>({ type: "config/entity_registry/list" });
export const updateEntityRegistryEntry = ( export const updateEntityRegistryEntry = (
hass: HomeAssistant, hass: HomeAssistant,
entityId: string, entityId: string,
@ -50,3 +47,33 @@ export const removeEntityRegistryEntry = (
type: "config/entity_registry/remove", type: "config/entity_registry/remove",
entity_id: entityId, entity_id: entityId,
}); });
const fetchEntityRegistry = (conn) =>
conn.sendMessagePromise({
type: "config/entity_registry/list",
});
const subscribeEntityRegistryUpdates = (conn, store) =>
conn.subscribeEvents(
debounce(
() =>
fetchEntityRegistry(conn).then((entities) =>
store.setState(entities, true)
),
500,
true
),
"entity_registry_updated"
);
export const subscribeEntityRegistry = (
hass: HomeAssistant,
onChange: (entities: EntityRegistryEntry[]) => void
) =>
createCollection<EntityRegistryEntry[]>(
"_entityRegistry",
fetchEntityRegistry,
subscribeEntityRegistryUpdates,
hass.connection,
onChange
);

View File

@ -37,10 +37,14 @@ import "./step-flow-abort";
import "./step-flow-create-entry"; import "./step-flow-create-entry";
import { import {
DeviceRegistryEntry, DeviceRegistryEntry,
fetchDeviceRegistry, subscribeDeviceRegistry,
} from "../../data/device_registry"; } from "../../data/device_registry";
import { AreaRegistryEntry, fetchAreaRegistry } from "../../data/area_registry"; import {
AreaRegistryEntry,
subscribeAreaRegistry,
} from "../../data/area_registry";
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
let instance = 0; let instance = 0;
@ -57,30 +61,19 @@ declare global {
@customElement("dialog-config-flow") @customElement("dialog-config-flow")
class ConfigFlowDialog extends LitElement { class ConfigFlowDialog extends LitElement {
public hass!: HomeAssistant; public hass!: HomeAssistant;
@property() private _params?: HaConfigFlowParams;
@property() @property() private _loading = true;
private _params?: HaConfigFlowParams;
@property()
private _loading = true;
private _instance = instance; private _instance = instance;
@property() private _step:
@property()
private _step:
| ConfigFlowStep | ConfigFlowStep
| undefined | undefined
// Null means we need to pick a config flow // Null means we need to pick a config flow
| null; | null;
@property() private _devices?: DeviceRegistryEntry[];
@property() @property() private _areas?: AreaRegistryEntry[];
private _devices?: DeviceRegistryEntry[]; @property() private _handlers?: string[];
private _unsubAreas?: UnsubscribeFunc;
@property() private _unsubDevices?: UnsubscribeFunc;
private _areas?: AreaRegistryEntry[];
@property()
private _handlers?: string[];
public async showDialog(params: HaConfigFlowParams): Promise<void> { public async showDialog(params: HaConfigFlowParams): Promise<void> {
this._params = params; this._params = params;
@ -196,6 +189,10 @@ class ConfigFlowDialog extends LitElement {
this._fetchDevices(this._step.result); this._fetchDevices(this._step.result);
this._fetchAreas(); this._fetchAreas();
} }
if (changedProps.has("_devices") && this._dialog) {
this._scheduleCenterDialog();
}
} }
private _scheduleCenterDialog() { private _scheduleCenterDialog() {
@ -207,16 +204,17 @@ class ConfigFlowDialog extends LitElement {
} }
private async _fetchDevices(configEntryId) { private async _fetchDevices(configEntryId) {
// Wait 5 seconds to give integrations time to find devices this._unsubDevices = subscribeDeviceRegistry(this.hass, (devices) => {
await new Promise((resolve) => setTimeout(resolve, 5000)); this._devices = devices.filter((device) =>
const devices = await fetchDeviceRegistry(this.hass); device.config_entries.includes(configEntryId)
this._devices = devices.filter((device) => );
device.config_entries.includes(configEntryId) });
);
} }
private async _fetchAreas() { private async _fetchAreas() {
this._areas = await fetchAreaRegistry(this.hass); this._unsubAreas = subscribeAreaRegistry(this.hass, (areas) => {
this._areas = areas;
});
} }
private async _processStep( private async _processStep(
@ -261,6 +259,14 @@ class ConfigFlowDialog extends LitElement {
this._step = undefined; this._step = undefined;
this._params = undefined; this._params = undefined;
this._devices = undefined; this._devices = undefined;
if (this._unsubAreas) {
this._unsubAreas();
this._unsubAreas = undefined;
}
if (this._unsubDevices) {
this._unsubDevices();
this._unsubDevices = undefined;
}
} }
private _openedChanged(ev: PolymerChangedEvent<boolean>): void { private _openedChanged(ev: PolymerChangedEvent<boolean>): void {

View File

@ -4,7 +4,7 @@ import {
html, html,
css, css,
CSSResult, CSSResult,
PropertyDeclarations, property,
} from "lit-element"; } from "lit-element";
import "@polymer/paper-item/paper-item"; import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body"; import "@polymer/paper-item/paper-item-body";
@ -13,15 +13,14 @@ import "@polymer/paper-fab/paper-fab";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { import {
AreaRegistryEntry, AreaRegistryEntry,
fetchAreaRegistry,
updateAreaRegistryEntry, updateAreaRegistryEntry,
deleteAreaRegistryEntry, deleteAreaRegistryEntry,
createAreaRegistryEntry, createAreaRegistryEntry,
subscribeAreaRegistry,
} from "../../../data/area_registry"; } from "../../../data/area_registry";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../layouts/hass-subpage"; import "../../../layouts/hass-subpage";
import "../../../layouts/hass-loading-screen"; import "../../../layouts/hass-loading-screen";
import { compare } from "../../../common/string/compare";
import "../ha-config-section"; import "../ha-config-section";
import { import {
showAreaRegistryDetailDialog, showAreaRegistryDetailDialog,
@ -29,22 +28,23 @@ import {
} from "./show-dialog-area-registry-detail"; } from "./show-dialog-area-registry-detail";
import { classMap } from "lit-html/directives/class-map"; import { classMap } from "lit-html/directives/class-map";
import { computeRTL } from "../../../common/util/compute_rtl"; import { computeRTL } from "../../../common/util/compute_rtl";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
class HaConfigAreaRegistry extends LitElement { class HaConfigAreaRegistry extends LitElement {
public hass?: HomeAssistant; @property() public hass!: HomeAssistant;
public isWide?: boolean; @property() public isWide?: boolean;
private _items?: AreaRegistryEntry[]; @property() private _areas?: AreaRegistryEntry[];
private _unsubAreas?: UnsubscribeFunc;
static get properties(): PropertyDeclarations { public disconnectedCallback() {
return { super.disconnectedCallback();
hass: {}, if (this._unsubAreas) {
isWide: {}, this._unsubAreas();
_items: {}, }
};
} }
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
if (!this.hass || this._items === undefined) { if (!this.hass || this._areas === undefined) {
return html` return html`
<hass-loading-screen></hass-loading-screen> <hass-loading-screen></hass-loading-screen>
`; `;
@ -73,7 +73,7 @@ class HaConfigAreaRegistry extends LitElement {
</a> </a>
</span> </span>
<ha-card> <ha-card>
${this._items.map((entry) => { ${this._areas.map((entry) => {
return html` return html`
<paper-item @click=${this._openEditEntry} .entry=${entry}> <paper-item @click=${this._openEditEntry} .entry=${entry}>
<paper-item-body> <paper-item-body>
@ -82,7 +82,7 @@ class HaConfigAreaRegistry extends LitElement {
</paper-item> </paper-item>
`; `;
})} })}
${this._items.length === 0 ${this._areas.length === 0
? html` ? html`
<div class="empty"> <div class="empty">
${this.hass.localize( ${this.hass.localize(
@ -116,14 +116,16 @@ class HaConfigAreaRegistry extends LitElement {
protected firstUpdated(changedProps) { protected firstUpdated(changedProps) {
super.firstUpdated(changedProps); super.firstUpdated(changedProps);
this._fetchData();
loadAreaRegistryDetailDialog(); loadAreaRegistryDetailDialog();
} }
private async _fetchData() { protected updated(changedProps) {
this._items = (await fetchAreaRegistry(this.hass!)).sort((ent1, ent2) => super.updated(changedProps);
compare(ent1.name, ent2.name) if (!this._unsubAreas) {
); this._unsubAreas = subscribeAreaRegistry(this.hass, (areas) => {
this._areas = areas;
});
}
} }
private _createArea() { private _createArea() {
@ -137,22 +139,10 @@ class HaConfigAreaRegistry extends LitElement {
private _openDialog(entry?: AreaRegistryEntry) { private _openDialog(entry?: AreaRegistryEntry) {
showAreaRegistryDetailDialog(this, { showAreaRegistryDetailDialog(this, {
entry, entry,
createEntry: async (values) => { createEntry: async (values) =>
const created = await createAreaRegistryEntry(this.hass!, values); createAreaRegistryEntry(this.hass!, values),
this._items = this._items!.concat(created).sort((ent1, ent2) => updateEntry: async (values) =>
compare(ent1.name, ent2.name) updateAreaRegistryEntry(this.hass!, entry!.area_id, values),
);
},
updateEntry: async (values) => {
const updated = await updateAreaRegistryEntry(
this.hass!,
entry!.area_id,
values
);
this._items = this._items!.map((ent) =>
ent === entry ? updated : ent
);
},
removeEntry: async () => { removeEntry: async () => {
if ( if (
!confirm(`Are you sure you want to delete this area? !confirm(`Are you sure you want to delete this area?
@ -164,7 +154,6 @@ All devices in this area will become unassigned.`)
try { try {
await deleteAreaRegistryEntry(this.hass!, entry!.area_id); await deleteAreaRegistryEntry(this.hass!, entry!.area_id);
this._items = this._items!.filter((ent) => ent !== entry);
return true; return true;
} catch (err) { } catch (err) {
return false; return false;

View File

@ -4,7 +4,7 @@ import {
html, html,
css, css,
CSSResult, CSSResult,
PropertyDeclarations, property,
} from "lit-element"; } from "lit-element";
import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-item/paper-item-body"; import "@polymer/paper-item/paper-item-body";
@ -12,16 +12,15 @@ import "@polymer/paper-item/paper-item-body";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { import {
EntityRegistryEntry, EntityRegistryEntry,
fetchEntityRegistry,
computeEntityRegistryName, computeEntityRegistryName,
updateEntityRegistryEntry, updateEntityRegistryEntry,
removeEntityRegistryEntry, removeEntityRegistryEntry,
subscribeEntityRegistry,
} from "../../../data/entity_registry"; } from "../../../data/entity_registry";
import "../../../layouts/hass-subpage"; import "../../../layouts/hass-subpage";
import "../../../layouts/hass-loading-screen"; import "../../../layouts/hass-loading-screen";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../components/ha-icon"; import "../../../components/ha-icon";
import { compare } from "../../../common/string/compare";
import domainIcon from "../../../common/entity/domain_icon"; import domainIcon from "../../../common/entity/domain_icon";
import stateIcon from "../../../common/entity/state_icon"; import stateIcon from "../../../common/entity/state_icon";
import computeDomain from "../../../common/entity/compute_domain"; import computeDomain from "../../../common/entity/compute_domain";
@ -30,22 +29,24 @@ import {
showEntityRegistryDetailDialog, showEntityRegistryDetailDialog,
loadEntityRegistryDetailDialog, loadEntityRegistryDetailDialog,
} from "./show-dialog-entity-registry-detail"; } from "./show-dialog-entity-registry-detail";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { compare } from "../../../common/string/compare";
class HaConfigEntityRegistry extends LitElement { class HaConfigEntityRegistry extends LitElement {
public hass?: HomeAssistant; @property() public hass!: HomeAssistant;
public isWide?: boolean; @property() public isWide?: boolean;
private _items?: EntityRegistryEntry[]; @property() private _entities?: EntityRegistryEntry[];
private _unsubEntities?: UnsubscribeFunc;
static get properties(): PropertyDeclarations { public disconnectedCallback() {
return { super.disconnectedCallback();
hass: {}, if (this._unsubEntities) {
isWide: {}, this._unsubEntities();
_items: {}, }
};
} }
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
if (!this.hass || this._items === undefined) { if (!this.hass || this._entities === undefined) {
return html` return html`
<hass-loading-screen></hass-loading-screen> <hass-loading-screen></hass-loading-screen>
`; `;
@ -78,7 +79,7 @@ class HaConfigEntityRegistry extends LitElement {
</a> </a>
</span> </span>
<ha-card> <ha-card>
${this._items.map((entry) => { ${this._entities.map((entry) => {
const state = this.hass!.states[entry.entity_id]; const state = this.hass!.states[entry.entity_id];
return html` return html`
<paper-icon-item @click=${this._openEditEntry} .entry=${entry}> <paper-icon-item @click=${this._openEditEntry} .entry=${entry}>
@ -111,14 +112,18 @@ class HaConfigEntityRegistry extends LitElement {
protected firstUpdated(changedProps): void { protected firstUpdated(changedProps): void {
super.firstUpdated(changedProps); super.firstUpdated(changedProps);
this._fetchData();
loadEntityRegistryDetailDialog(); loadEntityRegistryDetailDialog();
} }
private async _fetchData(): Promise<void> { protected updated(changedProps) {
this._items = (await fetchEntityRegistry(this.hass!)).sort((ent1, ent2) => super.updated(changedProps);
compare(ent1.entity_id, ent2.entity_id) if (!this._unsubEntities) {
); this._unsubEntities = subscribeEntityRegistry(this.hass, (entities) => {
this._entities = entities.sort((ent1, ent2) =>
compare(ent1.entity_id, ent2.entity_id)
);
});
}
} }
private _openEditEntry(ev: MouseEvent): void { private _openEditEntry(ev: MouseEvent): void {
@ -131,7 +136,7 @@ class HaConfigEntityRegistry extends LitElement {
entry.entity_id, entry.entity_id,
updates updates
); );
this._items = this._items!.map((ent) => this._entities = this._entities!.map((ent) =>
ent === entry ? updated : ent ent === entry ? updated : ent
); );
}, },
@ -148,7 +153,7 @@ Deleting an entry will not remove the entity from Home Assistant. To do this, yo
try { try {
await removeEntityRegistryEntry(this.hass!, entry.entity_id); await removeEntityRegistryEntry(this.hass!, entry.entity_id);
this._items = this._items!.filter((ent) => ent !== entry); this._entities = this._entities!.filter((ent) => ent !== entry);
return true; return true;
} catch (err) { } catch (err) {
return false; return false;

View File

@ -8,7 +8,7 @@ import "./ha-config-entries-dashboard";
import "./ha-config-entry-page"; import "./ha-config-entry-page";
import NavigateMixin from "../../../mixins/navigate-mixin"; import NavigateMixin from "../../../mixins/navigate-mixin";
import { compare } from "../../../common/string/compare"; import { compare } from "../../../common/string/compare";
import { fetchAreaRegistry } from "../../../data/area_registry"; import { subscribeAreaRegistry } from "../../../data/area_registry";
class HaConfigIntegrations extends NavigateMixin(PolymerElement) { class HaConfigIntegrations extends NavigateMixin(PolymerElement) {
static get template() { static get template() {
@ -96,6 +96,9 @@ class HaConfigIntegrations extends NavigateMixin(PolymerElement) {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this._loadData(); this._loadData();
this._unsubAreas = subscribeAreaRegistry(this.hass, (areas) => {
this._areas = areas;
});
this.hass.connection this.hass.connection
.subscribeEvents(() => { .subscribeEvents(() => {
@ -113,6 +116,7 @@ class HaConfigIntegrations extends NavigateMixin(PolymerElement) {
disconnectedCallback() { disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback();
if (this._unsubEvents) this._unsubEvents(); if (this._unsubEvents) this._unsubEvents();
if (this._unsubAreas) this._unsubAreas();
} }
_loadData() { _loadData() {
@ -143,10 +147,6 @@ class HaConfigIntegrations extends NavigateMixin(PolymerElement) {
.then((devices) => { .then((devices) => {
this._devices = devices; this._devices = devices;
}); });
fetchAreaRegistry(this.hass).then((areas) => {
this._areas = areas.sort((a, b) => compare(a.name, b.name));
});
} }
_computeConfigEntry(routeData, entries) { _computeConfigEntry(routeData, entries) {

View File

@ -22,10 +22,9 @@ import {
} from "lit-element"; } from "lit-element";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { compare } from "../../../common/string/compare";
import { import {
AreaRegistryEntry, AreaRegistryEntry,
fetchAreaRegistry, subscribeAreaRegistry,
} from "../../../data/area_registry"; } from "../../../data/area_registry";
import { import {
DeviceRegistryEntryMutableParams, DeviceRegistryEntryMutableParams,
@ -36,6 +35,7 @@ import { haStyle } from "../../../resources/styles";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { ItemSelectedEvent, NodeServiceData } from "./types"; import { ItemSelectedEvent, NodeServiceData } from "./types";
import { navigate } from "../../../common/navigate"; import { navigate } from "../../../common/navigate";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
declare global { declare global {
// for fire event // for fire event
@ -48,7 +48,7 @@ declare global {
@customElement("zha-device-card") @customElement("zha-device-card")
class ZHADeviceCard extends LitElement { class ZHADeviceCard extends LitElement {
@property() public hass?: HomeAssistant; @property() public hass!: HomeAssistant;
@property() public narrow?: boolean; @property() public narrow?: boolean;
@property() public device?: ZHADevice; @property() public device?: ZHADevice;
@property() public showHelp: boolean = false; @property() public showHelp: boolean = false;
@ -58,8 +58,16 @@ class ZHADeviceCard extends LitElement {
@property() private _areas: AreaRegistryEntry[] = []; @property() private _areas: AreaRegistryEntry[] = [];
@property() private _selectedAreaIndex: number = -1; @property() private _selectedAreaIndex: number = -1;
@property() private _userGivenName?: string; @property() private _userGivenName?: string;
private _unsubAreas?: UnsubscribeFunc;
public firstUpdated(changedProperties: PropertyValues): void { public disconnectedCallback() {
super.disconnectedCallback();
if (this._unsubAreas) {
this._unsubAreas();
}
}
protected firstUpdated(changedProperties: PropertyValues): void {
super.firstUpdated(changedProperties); super.firstUpdated(changedProperties);
this.addEventListener("hass-service-called", (ev) => this.addEventListener("hass-service-called", (ev) =>
this.serviceCalled(ev) this.serviceCalled(ev)
@ -67,9 +75,6 @@ class ZHADeviceCard extends LitElement {
this._serviceData = { this._serviceData = {
ieee_address: this.device!.ieee, ieee_address: this.device!.ieee,
}; };
fetchAreaRegistry(this.hass!).then((areas) => {
this._areas = areas.sort((a, b) => compare(a.name, b.name));
});
} }
protected updated(changedProperties: PropertyValues): void { protected updated(changedProperties: PropertyValues): void {
@ -84,6 +89,11 @@ class ZHADeviceCard extends LitElement {
} }
this._userGivenName = this.device!.user_given_name; this._userGivenName = this.device!.user_given_name;
} }
if (!this._unsubAreas) {
this._unsubAreas = subscribeAreaRegistry(this.hass, (areas) => {
this._areas = areas;
});
}
super.update(changedProperties); super.update(changedProperties);
} }