From e48286c2a0de54b7863f104f7542dddf4b125d23 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 3 Jun 2024 18:23:30 +0200 Subject: [PATCH] Fix conditional card visiblity inside section (#20966) * Fix conditional card visiblity inside section * Remove _ from protected method --- src/panels/lovelace/cards/hui-card.ts | 18 ++++++++++++++++ .../lovelace/cards/hui-conditional-card.ts | 10 +++++++++ .../lovelace/cards/hui-entity-filter-card.ts | 15 ++++++++++--- .../components/hui-conditional-base.ts | 21 ++++++++++++------- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/panels/lovelace/cards/hui-card.ts b/src/panels/lovelace/cards/hui-card.ts index 19c6f08ee3..7d931632c2 100644 --- a/src/panels/lovelace/cards/hui-card.ts +++ b/src/panels/lovelace/cards/hui-card.ts @@ -12,6 +12,12 @@ import { import { createCardElement } from "../create-element/create-card-element"; import type { Lovelace, LovelaceCard, LovelaceLayoutOptions } from "../types"; +declare global { + interface HASSDomEvents { + "card-visibility-changed": { value: boolean }; + } +} + @customElement("hui-card") export class HuiCard extends ReactiveElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -66,6 +72,11 @@ export class HuiCard extends ReactiveElement { const element = createCardElement(config) as LovelaceCard; element.hass = this.hass; element.editMode = this.lovelace?.editMode; + // Update element when the visibility of the card changes (e.g. conditional card or filter card) + element.addEventListener("card-visibility-changed", (ev) => { + ev.stopPropagation(); + this._updateElement(); + }); return element; } @@ -129,6 +140,13 @@ export class HuiCard extends ReactiveElement { if (!this._element) { return; } + + if (this._element.hidden) { + this.style.setProperty("display", "none"); + this.toggleAttribute("hidden", true); + return; + } + const visible = forceVisible || this.lovelace?.editMode || diff --git a/src/panels/lovelace/cards/hui-conditional-card.ts b/src/panels/lovelace/cards/hui-conditional-card.ts index 96d3120ead..b39d24e7bf 100644 --- a/src/panels/lovelace/cards/hui-conditional-card.ts +++ b/src/panels/lovelace/cards/hui-conditional-card.ts @@ -1,4 +1,5 @@ import { customElement } from "lit/decorators"; +import { fireEvent } from "../../../common/dom/fire_event"; import { LovelaceCardConfig } from "../../../data/lovelace/config/card"; import { computeCardSize } from "../common/compute-card-size"; import { HuiConditionalBase } from "../components/hui-conditional-base"; @@ -58,6 +59,15 @@ class HuiConditionalCard extends HuiConditionalBase implements LovelaceCard { this.replaceChild(this._element, this.lastChild); } } + + protected setVisibility(conditionMet: boolean): void { + const visible = this.editMode || conditionMet; + const previouslyHidden = this.hidden; + super.setVisibility(conditionMet); + if (previouslyHidden !== this.hidden) { + fireEvent(this, "card-visibility-changed", { value: visible }); + } + } } declare global { diff --git a/src/panels/lovelace/cards/hui-entity-filter-card.ts b/src/panels/lovelace/cards/hui-entity-filter-card.ts index ab6fb943b2..efa3d9730a 100644 --- a/src/panels/lovelace/cards/hui-entity-filter-card.ts +++ b/src/panels/lovelace/cards/hui-entity-filter-card.ts @@ -15,6 +15,7 @@ import { createCardElement } from "../create-element/create-card-element"; import { EntityFilterEntityConfig } from "../entity-rows/types"; import { LovelaceCard } from "../types"; import { EntityFilterCardConfig } from "./types"; +import { fireEvent } from "../../../common/dom/fire_event"; @customElement("hui-entity-filter-card") export class HuiEntityFilterCard @@ -162,9 +163,14 @@ export class HuiEntityFilterCard return false; }); - if (entitiesList.length === 0 && this._config.show_empty === false) { + if ( + entitiesList.length === 0 && + this._config.show_empty === false && + !this.hidden + ) { this.style.display = "none"; this.toggleAttribute("hidden", true); + fireEvent(this, "card-visibility-changed", { value: false }); return; } @@ -194,8 +200,11 @@ export class HuiEntityFilterCard this.appendChild(this._element); } - this.style.display = "block"; - this.toggleAttribute("hidden", false); + if (this.hidden) { + this.style.display = "block"; + this.toggleAttribute("hidden", false); + fireEvent(this, "card-visibility-changed", { value: true }); + } } private _haveEntitiesChanged(oldHass: HomeAssistant | null): boolean { diff --git a/src/panels/lovelace/components/hui-conditional-base.ts b/src/panels/lovelace/components/hui-conditional-base.ts index 764481047d..f392fc5c80 100644 --- a/src/panels/lovelace/components/hui-conditional-base.ts +++ b/src/panels/lovelace/components/hui-conditional-base.ts @@ -6,14 +6,20 @@ import { HomeAssistant } from "../../../types"; import { ConditionalCardConfig } from "../cards/types"; import { Condition, - checkConditionsMet, attachConditionMediaQueriesListeners, + checkConditionsMet, extractMediaQueries, validateConditionalConfig, } from "../common/validate-condition"; import { ConditionalRowConfig, LovelaceRow } from "../entity-rows/types"; import { LovelaceCard } from "../types"; +declare global { + interface HASSDomEvents { + "visibility-changed": { value: boolean }; + } +} + @customElement("hui-conditional-base") export class HuiConditionalBase extends ReactiveElement { @property({ attribute: false }) public hass?: HomeAssistant; @@ -95,7 +101,7 @@ export class HuiConditionalBase extends ReactiveElement { supportedConditions, (matches) => { if (hasOnlyMediaQuery) { - this._setVisibility(matches); + this.setVisibility(matches); return; } this._updateVisibility(); @@ -129,17 +135,18 @@ export class HuiConditionalBase extends ReactiveElement { this.hass! ); - this._setVisibility(conditionMet); + this.setVisibility(conditionMet); } - private _setVisibility(conditionMet: boolean) { + protected setVisibility(conditionMet: boolean) { if (!this._element || !this.hass) { return; } const visible = this.editMode || conditionMet; - this.toggleAttribute("hidden", !visible); - this.style.setProperty("display", visible ? "" : "none"); - + if (this.hidden !== !visible) { + this.toggleAttribute("hidden", !visible); + this.style.setProperty("display", visible ? "" : "none"); + } if (visible) { this._element.hass = this.hass; if (!this._element!.parentElement) {