mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-18 14:56:37 +00:00
Fix broken cards being able to crash entire view (#11440)
This commit is contained in:
parent
94953ddf6c
commit
a8c365edc8
@ -1,4 +1,4 @@
|
|||||||
export const promiseTimeout = (ms: number, promise: Promise<any>) => {
|
export const promiseTimeout = (ms: number, promise: Promise<any> | any) => {
|
||||||
const timeout = new Promise((_resolve, reject) => {
|
const timeout = new Promise((_resolve, reject) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
reject(`Timed out in ${ms} ms.`);
|
reject(`Timed out in ${ms} ms.`);
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
|
import { promiseTimeout } from "../../../common/util/promise-timeout";
|
||||||
import { LovelaceCard, LovelaceHeaderFooter } from "../types";
|
import { LovelaceCard, LovelaceHeaderFooter } from "../types";
|
||||||
|
|
||||||
export const computeCardSize = (
|
export const computeCardSize = (
|
||||||
card: LovelaceCard | LovelaceHeaderFooter
|
card: LovelaceCard | LovelaceHeaderFooter
|
||||||
): number | Promise<number> => {
|
): number | Promise<number> => {
|
||||||
if (typeof card.getCardSize === "function") {
|
if (typeof card.getCardSize === "function") {
|
||||||
return card.getCardSize();
|
try {
|
||||||
|
return promiseTimeout(500, card.getCardSize()).catch(
|
||||||
|
() => 1
|
||||||
|
) as Promise<number>;
|
||||||
|
} catch (_e: any) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (customElements.get(card.localName)) {
|
if (customElements.get(card.localName)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -10,10 +10,18 @@ import type {
|
|||||||
LovelaceViewElement,
|
LovelaceViewElement,
|
||||||
} from "../../../data/lovelace";
|
} from "../../../data/lovelace";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
|
import {
|
||||||
|
createErrorBadgeConfig,
|
||||||
|
createErrorBadgeElement,
|
||||||
|
} from "../badges/hui-error-badge";
|
||||||
import type { HuiErrorCard } from "../cards/hui-error-card";
|
import type { HuiErrorCard } from "../cards/hui-error-card";
|
||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { createBadgeElement } from "../create-element/create-badge-element";
|
import { createBadgeElement } from "../create-element/create-badge-element";
|
||||||
import { createCardElement } from "../create-element/create-card-element";
|
import { createCardElement } from "../create-element/create-card-element";
|
||||||
|
import {
|
||||||
|
createErrorCardConfig,
|
||||||
|
createErrorCardElement,
|
||||||
|
} from "../create-element/create-element-base";
|
||||||
import { createViewElement } from "../create-element/create-view-element";
|
import { createViewElement } from "../create-element/create-view-element";
|
||||||
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
|
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
|
||||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||||
@ -54,7 +62,13 @@ export class HUIView extends ReactiveElement {
|
|||||||
// Public to make demo happy
|
// Public to make demo happy
|
||||||
public createCardElement(cardConfig: LovelaceCardConfig) {
|
public createCardElement(cardConfig: LovelaceCardConfig) {
|
||||||
const element = createCardElement(cardConfig) as LovelaceCard;
|
const element = createCardElement(cardConfig) as LovelaceCard;
|
||||||
|
try {
|
||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
return createErrorCardElement(
|
||||||
|
createErrorCardConfig(e.message, cardConfig)
|
||||||
|
);
|
||||||
|
}
|
||||||
element.addEventListener(
|
element.addEventListener(
|
||||||
"ll-rebuild",
|
"ll-rebuild",
|
||||||
(ev: Event) => {
|
(ev: Event) => {
|
||||||
@ -71,7 +85,11 @@ export class HUIView extends ReactiveElement {
|
|||||||
|
|
||||||
public createBadgeElement(badgeConfig: LovelaceBadgeConfig) {
|
public createBadgeElement(badgeConfig: LovelaceBadgeConfig) {
|
||||||
const element = createBadgeElement(badgeConfig) as LovelaceBadge;
|
const element = createBadgeElement(badgeConfig) as LovelaceBadge;
|
||||||
|
try {
|
||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
return createErrorBadgeElement(createErrorBadgeConfig(e.message));
|
||||||
|
}
|
||||||
element.addEventListener(
|
element.addEventListener(
|
||||||
"ll-badge-rebuild",
|
"ll-badge-rebuild",
|
||||||
() => {
|
() => {
|
||||||
@ -121,11 +139,19 @@ export class HUIView extends ReactiveElement {
|
|||||||
// Config has not changed. Just props
|
// Config has not changed. Just props
|
||||||
if (changedProperties.has("hass")) {
|
if (changedProperties.has("hass")) {
|
||||||
this._badges.forEach((badge) => {
|
this._badges.forEach((badge) => {
|
||||||
|
try {
|
||||||
badge.hass = this.hass;
|
badge.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
this._rebuildBadge(badge, createErrorBadgeConfig(e.message));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._cards.forEach((element) => {
|
this._cards.forEach((element) => {
|
||||||
|
try {
|
||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
this._rebuildCard(element, createErrorCardConfig(e.message, null));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._layoutElement.hass = this.hass;
|
this._layoutElement.hass = this.hass;
|
||||||
@ -238,7 +264,11 @@ export class HUIView extends ReactiveElement {
|
|||||||
const badges = processConfigEntities(config.badges as any);
|
const badges = processConfigEntities(config.badges as any);
|
||||||
this._badges = badges.map((badge) => {
|
this._badges = badges.map((badge) => {
|
||||||
const element = createBadgeElement(badge);
|
const element = createBadgeElement(badge);
|
||||||
|
try {
|
||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
return createErrorBadgeElement(createErrorBadgeConfig(e.message));
|
||||||
|
}
|
||||||
return element;
|
return element;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -251,7 +281,13 @@ export class HUIView extends ReactiveElement {
|
|||||||
|
|
||||||
this._cards = config.cards.map((cardConfig) => {
|
this._cards = config.cards.map((cardConfig) => {
|
||||||
const element = this.createCardElement(cardConfig);
|
const element = this.createCardElement(cardConfig);
|
||||||
|
try {
|
||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
return createErrorCardElement(
|
||||||
|
createErrorCardConfig(e.message, cardConfig)
|
||||||
|
);
|
||||||
|
}
|
||||||
return element;
|
return element;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -260,8 +296,14 @@ export class HUIView extends ReactiveElement {
|
|||||||
cardElToReplace: LovelaceCard,
|
cardElToReplace: LovelaceCard,
|
||||||
config: LovelaceCardConfig
|
config: LovelaceCardConfig
|
||||||
): void {
|
): void {
|
||||||
const newCardEl = this.createCardElement(config);
|
let newCardEl = this.createCardElement(config);
|
||||||
|
try {
|
||||||
newCardEl.hass = this.hass;
|
newCardEl.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
newCardEl = createErrorCardElement(
|
||||||
|
createErrorCardConfig(e.message, config)
|
||||||
|
);
|
||||||
|
}
|
||||||
if (cardElToReplace.parentElement) {
|
if (cardElToReplace.parentElement) {
|
||||||
cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace);
|
cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace);
|
||||||
}
|
}
|
||||||
@ -274,8 +316,12 @@ export class HUIView extends ReactiveElement {
|
|||||||
badgeElToReplace: LovelaceBadge,
|
badgeElToReplace: LovelaceBadge,
|
||||||
config: LovelaceBadgeConfig
|
config: LovelaceBadgeConfig
|
||||||
): void {
|
): void {
|
||||||
const newBadgeEl = this.createBadgeElement(config);
|
let newBadgeEl = this.createBadgeElement(config);
|
||||||
|
try {
|
||||||
newBadgeEl.hass = this.hass;
|
newBadgeEl.hass = this.hass;
|
||||||
|
} catch (e: any) {
|
||||||
|
newBadgeEl = createErrorBadgeElement(createErrorBadgeConfig(e.message));
|
||||||
|
}
|
||||||
if (badgeElToReplace.parentElement) {
|
if (badgeElToReplace.parentElement) {
|
||||||
badgeElToReplace.parentElement!.replaceChild(
|
badgeElToReplace.parentElement!.replaceChild(
|
||||||
newBadgeEl,
|
newBadgeEl,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user