diff --git a/demo/src/configs/teachingbirds/lovelace.ts b/demo/src/configs/teachingbirds/lovelace.ts index 76fb7f959a..f7684fde6d 100644 --- a/demo/src/configs/teachingbirds/lovelace.ts +++ b/demo/src/configs/teachingbirds/lovelace.ts @@ -63,7 +63,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ elements: [ { style: { - "--mdc-icon-size": "100px", + "--mdc-icon-size": "100%", top: "50%", left: "50%", }, diff --git a/src/panels/lovelace/cards/hui-entity-filter-card.ts b/src/panels/lovelace/cards/hui-entity-filter-card.ts index 16e141e058..cc6dcc82f7 100644 --- a/src/panels/lovelace/cards/hui-entity-filter-card.ts +++ b/src/panels/lovelace/cards/hui-entity-filter-card.ts @@ -6,26 +6,28 @@ import { createCardElement } from "../create-element/create-card-element"; import { EntityFilterEntityConfig } from "../entity-rows/types"; import { LovelaceCard } from "../types"; import { EntityFilterCardConfig } from "./types"; +import { property, PropertyValues, UpdatingElement } from "lit-element"; +import { computeCardSize } from "../common/compute-card-size"; -class EntityFilterCard extends HTMLElement implements LovelaceCard { - public isPanel?: boolean; +class EntityFilterCard extends UpdatingElement implements LovelaceCard { + @property() public hass?: HomeAssistant; - private _editMode = false; + @property() public isPanel = false; + + @property() public editMode = false; + + @property() private _config?: EntityFilterCardConfig; private _element?: LovelaceCard; - private _config?: EntityFilterCardConfig; - private _configEntities?: EntityFilterEntityConfig[]; private _baseCardConfig?: LovelaceCardConfig; - private _hass?: HomeAssistant; - private _oldEntities?: EntityFilterEntityConfig[]; public getCardSize(): number { - return this._element ? this._element.getCardSize() : 1; + return this._element ? computeCardSize(this._element) : 1; } public setConfig(config: EntityFilterCardConfig): void { @@ -45,8 +47,8 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard { throw new Error("Incorrect filter config."); } + this._configEntities = processConfigEntities(config.entities); this._config = config; - this._configEntities = undefined; this._baseCardConfig = { type: "entities", entities: [], @@ -59,32 +61,32 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard { } } - set editMode(editMode: boolean) { - this._editMode = editMode; - if (!this._element) { - return; + protected shouldUpdate(changedProps: PropertyValues): boolean { + if (this._element) { + this._element.hass = this.hass; + this._element.editMode = this.editMode; + this._element.isPanel = this.isPanel; } - this._element.editMode = editMode; + + if (changedProps.has("_config")) { + return true; + } + if (changedProps.has("hass")) { + return this._haveEntitiesChanged( + changedProps.get("hass") as HomeAssistant | null + ); + } + return false; } - set hass(hass: HomeAssistant) { - if (!hass || !this._config) { + protected update(changedProps: PropertyValues) { + super.update(changedProps); + if (!this.hass || !this._config || !this._configEntities) { return; } - if (!this.haveEntitiesChanged(hass)) { - this._hass = hass; - return; - } - - this._hass = hass; - - if (!this._configEntities) { - this._configEntities = processConfigEntities(this._config.entities); - } - const entitiesList = this._configEntities.filter((entityConf) => { - const stateObj = hass.states[entityConf.entity]; + const stateObj = this.hass!.states[entityConf.entity]; if (!stateObj) { return false; @@ -112,13 +114,13 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard { return; } - const element = this._cardElement(); - - if (!element) { - return; - } - - if (element.tagName !== "HUI-ERROR-CARD") { + if (!this._element) { + this._element = this._createCardElement({ + ...this._baseCardConfig!, + entities: entitiesList, + }); + this._oldEntities = entitiesList; + } else if (this._element.tagName !== "HUI-ERROR-CARD") { const isSame = this._oldEntities && entitiesList.length === this._oldEntities.length && @@ -126,24 +128,23 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard { if (!isSame) { this._oldEntities = entitiesList; - element.setConfig({ ...this._baseCardConfig!, entities: entitiesList }); + this._element.setConfig({ + ...this._baseCardConfig!, + entities: entitiesList, + }); } - - element.isPanel = this.isPanel; - element.editMode = this._editMode; - element.hass = hass; } // Attach element if it has never been attached. if (!this.lastChild) { - this.appendChild(element); + this.appendChild(this._element); } this.style.display = "block"; } - private haveEntitiesChanged(hass: HomeAssistant): boolean { - if (!this._hass) { + private _haveEntitiesChanged(oldHass: HomeAssistant | null): boolean { + if (!this.hass || !oldHass) { return true; } @@ -151,11 +152,12 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard { return true; } + if (this.hass.localize !== oldHass.localize) { + return true; + } + for (const config of this._configEntities) { - if ( - this._hass.states[config.entity] !== hass.states[config.entity] || - this._hass.localize !== hass.localize - ) { + if (this.hass.states[config.entity] !== oldHass.states[config.entity]) { return true; } } @@ -163,13 +165,33 @@ class EntityFilterCard extends HTMLElement implements LovelaceCard { return false; } - private _cardElement(): LovelaceCard | undefined { - if (!this._element && this._config) { - const element = createCardElement(this._baseCardConfig!); - this._element = element; + private _createCardElement(cardConfig: LovelaceCardConfig) { + const element = createCardElement(cardConfig) as LovelaceCard; + if (this.hass) { + element.hass = this.hass; } + element.isPanel = this.isPanel; + element.editMode = this.editMode; + element.addEventListener( + "ll-rebuild", + (ev) => { + ev.stopPropagation(); + this._rebuildCard(element, cardConfig); + }, + { once: true } + ); + return element; + } - return this._element; + private _rebuildCard( + cardElToReplace: LovelaceCard, + config: LovelaceCardConfig + ): void { + const newCardEl = this._createCardElement(config); + if (cardElToReplace.parentElement) { + cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace); + } + this._element = newCardEl; } } customElements.define("hui-entity-filter-card", EntityFilterCard);