mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Don't set hass to undefined in lovelace cards. (#21189)
* Wait for hass and config before building the card * Don't use setter * Improve code readability * Use hasupdated * Rename build to load
This commit is contained in:
parent
7aa005e0ce
commit
7603fa3aa8
@ -1,4 +1,4 @@
|
|||||||
import { PropertyValueMap, PropertyValues, ReactiveElement } from "lit";
|
import { PropertyValues, ReactiveElement } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { MediaQueriesListener } from "../../../common/dom/media_query";
|
import { MediaQueriesListener } from "../../../common/dom/media_query";
|
||||||
@ -23,30 +23,21 @@ declare global {
|
|||||||
|
|
||||||
@customElement("hui-card")
|
@customElement("hui-card")
|
||||||
export class HuiCard extends ReactiveElement {
|
export class HuiCard extends ReactiveElement {
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public preview = false;
|
@property({ type: Boolean }) public preview = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) public isPanel = false;
|
@property({ type: Boolean }) public isPanel = false;
|
||||||
|
|
||||||
set config(config: LovelaceCardConfig | undefined) {
|
@property({ attribute: false }) public config?: LovelaceCardConfig;
|
||||||
if (!config) return;
|
|
||||||
if (config.type !== this._config?.type) {
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
this._buildElement(config);
|
|
||||||
} else if (config !== this.config) {
|
public load() {
|
||||||
this._element?.setConfig(config);
|
if (!this.config) {
|
||||||
fireEvent(this, "card-updated");
|
throw new Error("Cannot build card without config");
|
||||||
}
|
}
|
||||||
this._config = config;
|
this._loadElement(this.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
public get config() {
|
|
||||||
return this._config;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _config?: LovelaceCardConfig;
|
|
||||||
|
|
||||||
private _element?: LovelaceCard;
|
private _element?: LovelaceCard;
|
||||||
|
|
||||||
private _listeners: MediaQueriesListener[] = [];
|
private _listeners: MediaQueriesListener[] = [];
|
||||||
@ -90,57 +81,76 @@ export class HuiCard extends ReactiveElement {
|
|||||||
return this._element?.getLayoutOptions?.() ?? {};
|
return this._element?.getLayoutOptions?.() ?? {};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createElement(config: LovelaceCardConfig) {
|
private _loadElement(config: LovelaceCardConfig) {
|
||||||
const element = createCardElement(config);
|
this._element = createCardElement(config);
|
||||||
element.hass = this.hass;
|
if (this.hass) {
|
||||||
element.preview = this.preview;
|
this._element.hass = this.hass;
|
||||||
|
}
|
||||||
|
this._element.preview = this.preview;
|
||||||
// For backwards compatibility
|
// For backwards compatibility
|
||||||
(element as any).editMode = this.preview;
|
(this._element as any).editMode = this.preview;
|
||||||
// Update element when the visibility of the card changes (e.g. conditional card or filter card)
|
// Update element when the visibility of the card changes (e.g. conditional card or filter card)
|
||||||
element.addEventListener("card-visibility-changed", (ev: Event) => {
|
this._element.addEventListener("card-visibility-changed", (ev: Event) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
});
|
});
|
||||||
element.addEventListener(
|
this._element.addEventListener(
|
||||||
"ll-upgrade",
|
"ll-upgrade",
|
||||||
(ev: Event) => {
|
(ev: Event) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
element.hass = this.hass;
|
if (this.hass) {
|
||||||
element.preview = this.preview;
|
this._element!.hass = this.hass;
|
||||||
|
}
|
||||||
fireEvent(this, "card-updated");
|
fireEvent(this, "card-updated");
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true }
|
||||||
);
|
);
|
||||||
element.addEventListener(
|
this._element.addEventListener(
|
||||||
"ll-rebuild",
|
"ll-rebuild",
|
||||||
(ev: Event) => {
|
(ev: Event) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this._buildElement(config);
|
this._loadElement(config);
|
||||||
fireEvent(this, "card-updated");
|
fireEvent(this, "card-updated");
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true }
|
||||||
);
|
);
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _buildElement(config: LovelaceCardConfig) {
|
|
||||||
this._element = this._createElement(config);
|
|
||||||
|
|
||||||
while (this.lastChild) {
|
while (this.lastChild) {
|
||||||
this.removeChild(this.lastChild);
|
this.removeChild(this.lastChild);
|
||||||
}
|
}
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected willUpdate(changedProps: PropertyValues<typeof this>): void {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
|
|
||||||
|
if (!this._element) {
|
||||||
|
this.load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected update(changedProps: PropertyValues<typeof this>) {
|
protected update(changedProps: PropertyValues<typeof this>) {
|
||||||
super.update(changedProps);
|
super.update(changedProps);
|
||||||
|
|
||||||
if (this._element) {
|
if (this._element) {
|
||||||
|
if (changedProps.has("config") && this.hasUpdated) {
|
||||||
|
const oldConfig = changedProps.get("config");
|
||||||
|
if (this.config !== oldConfig && this.config) {
|
||||||
|
const typeChanged = this.config?.type !== oldConfig?.type;
|
||||||
|
if (typeChanged) {
|
||||||
|
this._loadElement(this.config);
|
||||||
|
} else {
|
||||||
|
this._element?.setConfig(this.config);
|
||||||
|
fireEvent(this, "card-updated");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (changedProps.has("hass")) {
|
if (changedProps.has("hass")) {
|
||||||
try {
|
try {
|
||||||
this._element.hass = this.hass;
|
if (this.hass) {
|
||||||
|
this._element.hass = this.hass;
|
||||||
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this._buildElement(createErrorCardConfig(e.message, null));
|
this._loadElement(createErrorCardConfig(e.message, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changedProps.has("preview")) {
|
if (changedProps.has("preview")) {
|
||||||
@ -149,18 +159,14 @@ export class HuiCard extends ReactiveElement {
|
|||||||
// For backwards compatibility
|
// For backwards compatibility
|
||||||
(this._element as any).editMode = this.preview;
|
(this._element as any).editMode = this.preview;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this._buildElement(createErrorCardConfig(e.message, null));
|
this._loadElement(createErrorCardConfig(e.message, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changedProps.has("isPanel")) {
|
if (changedProps.has("isPanel")) {
|
||||||
this._element.isPanel = this.isPanel;
|
this._element.isPanel = this.isPanel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected willUpdate(
|
|
||||||
changedProps: PropertyValueMap<any> | Map<PropertyKey, unknown>
|
|
||||||
): void {
|
|
||||||
if (changedProps.has("hass") || changedProps.has("preview")) {
|
if (changedProps.has("hass") || changedProps.has("preview")) {
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ class HuiConditionalCard extends HuiConditionalBase implements LovelaceCard {
|
|||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
element.preview = this.preview;
|
element.preview = this.preview;
|
||||||
element.config = cardConfig;
|
element.config = cardConfig;
|
||||||
|
element.load();
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +249,7 @@ export class HuiEntityFilterCard
|
|||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
element.preview = this.preview;
|
element.preview = this.preview;
|
||||||
element.config = cardConfig;
|
element.config = cardConfig;
|
||||||
|
element.load();
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||||||
card.hass = this.hass;
|
card.hass = this.hass;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (changedProperties.has("editMode")) {
|
if (changedProperties.has("preview")) {
|
||||||
this._cards.forEach((card) => {
|
this._cards.forEach((card) => {
|
||||||
card.preview = this.preview;
|
card.preview = this.preview;
|
||||||
});
|
});
|
||||||
@ -69,6 +69,7 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
element.preview = this.preview;
|
element.preview = this.preview;
|
||||||
element.config = cardConfig;
|
element.config = cardConfig;
|
||||||
|
element.load();
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +146,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
this._defaultLayoutOptions =
|
this._defaultLayoutOptions =
|
||||||
this._cardElement?.getElementLayoutOptions();
|
this._cardElement?.getElementLayoutOptions();
|
||||||
});
|
});
|
||||||
|
this._cardElement.load();
|
||||||
this._defaultLayoutOptions = this._cardElement.getElementLayoutOptions();
|
this._defaultLayoutOptions = this._cardElement.getElementLayoutOptions();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
@ -64,6 +64,7 @@ export class HuiSection extends ReactiveElement {
|
|||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this._cards = [...this._cards];
|
this._cards = [...this._cards];
|
||||||
});
|
});
|
||||||
|
element.load();
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ export class HUIView extends ReactiveElement {
|
|||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this._cards = [...this._cards];
|
this._cards = [...this._cards];
|
||||||
});
|
});
|
||||||
|
element.load();
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user