mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Add visibility option to dashboard cards (#20840)
* Create hui card * Add compatiblity with helpers * Improve layout options * Fix conditional card * Add missing import * Add visibility option in config * Fix conditions * Fix case with multiple conditions * Remove useless set hass
This commit is contained in:
parent
ce5bcf61f9
commit
13f01492b4
@ -3,17 +3,13 @@ import {
|
||||
getCollection,
|
||||
HassEventBase,
|
||||
} from "home-assistant-js-websocket";
|
||||
import { HuiErrorCard } from "../panels/lovelace/cards/hui-error-card";
|
||||
import {
|
||||
Lovelace,
|
||||
LovelaceBadge,
|
||||
LovelaceCard,
|
||||
} from "../panels/lovelace/types";
|
||||
import type { HuiCard } from "../panels/lovelace/cards/hui-card";
|
||||
import type { HuiSection } from "../panels/lovelace/sections/hui-section";
|
||||
import { Lovelace, LovelaceBadge } from "../panels/lovelace/types";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { LovelaceSectionConfig } from "./lovelace/config/section";
|
||||
import { fetchConfig, LegacyLovelaceConfig } from "./lovelace/config/types";
|
||||
import { LovelaceViewConfig } from "./lovelace/config/view";
|
||||
import { HuiSection } from "../panels/lovelace/sections/hui-section";
|
||||
|
||||
export interface LovelacePanelConfig {
|
||||
mode: "yaml" | "storage";
|
||||
@ -24,7 +20,7 @@ export interface LovelaceViewElement extends HTMLElement {
|
||||
lovelace?: Lovelace;
|
||||
narrow?: boolean;
|
||||
index?: number;
|
||||
cards?: Array<LovelaceCard | HuiErrorCard>;
|
||||
cards?: HuiCard[];
|
||||
badges?: LovelaceBadge[];
|
||||
sections?: HuiSection[];
|
||||
isStrategy: boolean;
|
||||
@ -36,7 +32,7 @@ export interface LovelaceSectionElement extends HTMLElement {
|
||||
lovelace?: Lovelace;
|
||||
viewIndex?: number;
|
||||
index?: number;
|
||||
cards?: Array<LovelaceCard | HuiErrorCard>;
|
||||
cards?: HuiCard[];
|
||||
isStrategy: boolean;
|
||||
setConfig(config: LovelaceSectionConfig): void;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { LovelaceLayoutOptions } from "../../../panels/lovelace/types";
|
||||
import type { Condition } from "../../../panels/lovelace/common/validate-condition";
|
||||
import type { LovelaceLayoutOptions } from "../../../panels/lovelace/types";
|
||||
|
||||
export interface LovelaceCardConfig {
|
||||
index?: number;
|
||||
@ -7,4 +8,5 @@ export interface LovelaceCardConfig {
|
||||
layout_options?: LovelaceLayoutOptions;
|
||||
type: string;
|
||||
[key: string]: any;
|
||||
visibility?: Condition[];
|
||||
}
|
||||
|
141
src/panels/lovelace/cards/hui-card.ts
Normal file
141
src/panels/lovelace/cards/hui-card.ts
Normal file
@ -0,0 +1,141 @@
|
||||
import { PropertyValues, ReactiveElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { MediaQueriesListener } from "../../../common/dom/media_query";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeCardSize } from "../common/compute-card-size";
|
||||
import {
|
||||
attachConditionMediaQueriesListeners,
|
||||
checkConditionsMet,
|
||||
} from "../common/validate-condition";
|
||||
import { createCardElement } from "../create-element/create-card-element";
|
||||
import type { Lovelace, LovelaceCard, LovelaceLayoutOptions } from "../types";
|
||||
|
||||
@customElement("hui-card")
|
||||
export class HuiCard extends ReactiveElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public lovelace!: Lovelace;
|
||||
|
||||
@state() public _config?: LovelaceCardConfig;
|
||||
|
||||
private _element?: LovelaceCard;
|
||||
|
||||
private _listeners: MediaQueriesListener[] = [];
|
||||
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._clearMediaQueries();
|
||||
}
|
||||
|
||||
public connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._listenMediaQueries();
|
||||
this._updateElement();
|
||||
}
|
||||
|
||||
public getCardSize(): number | Promise<number> {
|
||||
if (this._element) {
|
||||
const size = computeCardSize(this._element);
|
||||
return size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public getLayoutOptions(): LovelaceLayoutOptions {
|
||||
const configOptions = this._config?.layout_options ?? {};
|
||||
if (this._element) {
|
||||
const cardOptions = this._element.getLayoutOptions?.() ?? {};
|
||||
return {
|
||||
...cardOptions,
|
||||
...configOptions,
|
||||
};
|
||||
}
|
||||
return configOptions;
|
||||
}
|
||||
|
||||
public setConfig(config: LovelaceCardConfig): void {
|
||||
if (this._config === config) {
|
||||
return;
|
||||
}
|
||||
this._config = config;
|
||||
this._element = createCardElement(config);
|
||||
this._element.hass = this.hass;
|
||||
this._element.editMode = this.lovelace.editMode;
|
||||
|
||||
while (this.lastChild) {
|
||||
this.removeChild(this.lastChild);
|
||||
}
|
||||
this.appendChild(this._element!);
|
||||
}
|
||||
|
||||
protected update(changedProperties: PropertyValues<typeof this>) {
|
||||
super.update(changedProperties);
|
||||
|
||||
if (this._element) {
|
||||
if (changedProperties.has("hass")) {
|
||||
this._element.hass = this.hass;
|
||||
}
|
||||
if (changedProperties.has("lovelace")) {
|
||||
this._element.editMode = this.lovelace.editMode;
|
||||
}
|
||||
if (changedProperties.has("hass") || changedProperties.has("lovelace")) {
|
||||
this._updateElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _clearMediaQueries() {
|
||||
this._listeners.forEach((unsub) => unsub());
|
||||
this._listeners = [];
|
||||
}
|
||||
|
||||
private _listenMediaQueries() {
|
||||
this._clearMediaQueries();
|
||||
if (!this._config?.visibility) {
|
||||
return;
|
||||
}
|
||||
const conditions = this._config.visibility;
|
||||
const hasOnlyMediaQuery =
|
||||
conditions.length === 1 &&
|
||||
conditions[0].condition === "screen" &&
|
||||
!!conditions[0].media_query;
|
||||
|
||||
this._listeners = attachConditionMediaQueriesListeners(
|
||||
this._config.visibility,
|
||||
(matches) => {
|
||||
this._updateElement(hasOnlyMediaQuery && matches);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private _updateElement(forceVisible?: boolean) {
|
||||
if (!this._element) {
|
||||
return;
|
||||
}
|
||||
const visible =
|
||||
forceVisible ||
|
||||
this.lovelace.editMode ||
|
||||
!this._config?.visibility ||
|
||||
checkConditionsMet(this._config.visibility, this.hass);
|
||||
|
||||
this.style.setProperty("display", visible ? "" : "none");
|
||||
this.toggleAttribute("hidden", !visible);
|
||||
if (!visible && this._element.parentElement) {
|
||||
this.removeChild(this._element);
|
||||
} else if (visible && !this._element.parentElement) {
|
||||
this.appendChild(this._element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-card": HuiCard;
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import { promiseTimeout } from "../../../common/util/promise-timeout";
|
||||
import { HuiCard } from "../cards/hui-card";
|
||||
import { LovelaceCard, LovelaceHeaderFooter } from "../types";
|
||||
|
||||
export const computeCardSize = (
|
||||
card: LovelaceCard | LovelaceHeaderFooter
|
||||
card: LovelaceCard | LovelaceHeaderFooter | HuiCard
|
||||
): number | Promise<number> => {
|
||||
if (typeof card.getCardSize === "function") {
|
||||
try {
|
||||
|
@ -327,27 +327,13 @@ export function extractMediaQueries(conditions: Condition[]): string[] {
|
||||
|
||||
export function attachConditionMediaQueriesListeners(
|
||||
conditions: Condition[],
|
||||
hass: HomeAssistant,
|
||||
onChange: (visibility: boolean) => void
|
||||
): MediaQueriesListener[] {
|
||||
// For performance, if there is only one condition and it's a screen condition, set the visibility directly
|
||||
if (
|
||||
conditions.length === 1 &&
|
||||
conditions[0].condition === "screen" &&
|
||||
conditions[0].media_query
|
||||
) {
|
||||
const listener = listenMediaQuery(conditions[0].media_query, (matches) => {
|
||||
onChange(matches);
|
||||
});
|
||||
return [listener];
|
||||
}
|
||||
|
||||
const mediaQueries = extractMediaQueries(conditions);
|
||||
|
||||
const listeners = mediaQueries.map((query) => {
|
||||
const listener = listenMediaQuery(query, () => {
|
||||
const visibility = checkConditionsMet(conditions, hass);
|
||||
onChange(visibility);
|
||||
const listener = listenMediaQuery(query, (matches) => {
|
||||
onChange(matches);
|
||||
});
|
||||
return listener;
|
||||
});
|
||||
|
@ -84,11 +84,21 @@ export class HuiConditionalBase extends ReactiveElement {
|
||||
|
||||
this._clearMediaQueries();
|
||||
|
||||
const conditions = this._config.conditions;
|
||||
const hasOnlyMediaQuery =
|
||||
conditions.length === 1 &&
|
||||
"condition" in conditions[0] &&
|
||||
conditions[0].condition === "screen" &&
|
||||
!!conditions[0].media_query;
|
||||
|
||||
this._listeners = attachConditionMediaQueriesListeners(
|
||||
supportedConditions,
|
||||
this.hass,
|
||||
(visibility) => {
|
||||
this._setVisibility(visibility);
|
||||
(matches) => {
|
||||
if (hasOnlyMediaQuery) {
|
||||
this._setVisibility(matches);
|
||||
return;
|
||||
}
|
||||
this._updateVisibility();
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -99,7 +109,8 @@ export class HuiConditionalBase extends ReactiveElement {
|
||||
if (
|
||||
changed.has("_element") ||
|
||||
changed.has("_config") ||
|
||||
changed.has("hass")
|
||||
changed.has("hass") ||
|
||||
changed.has("editMode")
|
||||
) {
|
||||
this._listenMediaQueries();
|
||||
this._updateVisibility();
|
||||
|
@ -3,13 +3,16 @@ import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-yaml-editor";
|
||||
|
||||
import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
|
||||
import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
||||
import { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||
import { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
import { isStrategyView } from "../../../../data/lovelace/config/view";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { showSaveSuccessToast } from "../../../../util/toast-saved-success";
|
||||
import "../../sections/hui-section";
|
||||
import { addCards, addSection } from "../config-util";
|
||||
import {
|
||||
LovelaceContainerPath,
|
||||
@ -18,7 +21,6 @@ import {
|
||||
import "./hui-card-preview";
|
||||
import { showCreateCardDialog } from "./show-create-card-dialog";
|
||||
import { SuggestCardDialogParams } from "./show-suggest-card-dialog";
|
||||
import { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
|
||||
@customElement("hui-dialog-suggest-card")
|
||||
export class HuiDialogSuggestCard extends LitElement {
|
||||
|
@ -4,4 +4,5 @@ export const baseLovelaceCardConfig = object({
|
||||
type: string(),
|
||||
view_layout: any(),
|
||||
layout_options: any(),
|
||||
visibility: any(),
|
||||
});
|
||||
|
@ -11,10 +11,10 @@ import { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { HuiErrorCard } from "../cards/hui-error-card";
|
||||
import "../components/hui-card-edit-mode";
|
||||
import { moveCard } from "../editor/config-util";
|
||||
import type { Lovelace, LovelaceCard, LovelaceLayoutOptions } from "../types";
|
||||
import type { Lovelace } from "../types";
|
||||
import { HuiCard } from "../cards/hui-card";
|
||||
|
||||
const CARD_SORTABLE_OPTIONS: HaSortableOptions = {
|
||||
delay: 100,
|
||||
@ -34,9 +34,7 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
||||
|
||||
@property({ type: Boolean }) public isStrategy = false;
|
||||
|
||||
@property({ attribute: false }) public cards: Array<
|
||||
LovelaceCard | HuiErrorCard
|
||||
> = [];
|
||||
@property({ attribute: false }) public cards: HuiCard[] = [];
|
||||
|
||||
@state() _config?: LovelaceSectionConfig;
|
||||
|
||||
@ -95,27 +93,16 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
||||
(cardConfig) => this._getKey(cardConfig),
|
||||
(_cardConfig, idx) => {
|
||||
const card = this.cards![idx];
|
||||
(card as any).editMode = editMode;
|
||||
(card as any).lovelace = this.lovelace;
|
||||
|
||||
const configOptions = _cardConfig.layout_options;
|
||||
const cardOptions = (card as any)?.getLayoutOptions?.() as
|
||||
| LovelaceLayoutOptions
|
||||
| undefined;
|
||||
|
||||
const options = {
|
||||
...cardOptions,
|
||||
...configOptions,
|
||||
} as LovelaceLayoutOptions;
|
||||
const layoutOptions = card.getLayoutOptions();
|
||||
|
||||
return html`
|
||||
<div
|
||||
style=${styleMap({
|
||||
"--column-size": options.grid_columns,
|
||||
"--row-size": options.grid_rows,
|
||||
"--column-size": layoutOptions.grid_columns,
|
||||
"--row-size": layoutOptions.grid_rows,
|
||||
})}
|
||||
class="card ${classMap({
|
||||
"fit-rows": typeof options?.grid_rows === "number",
|
||||
"fit-rows": typeof layoutOptions?.grid_rows === "number",
|
||||
})}"
|
||||
>
|
||||
${editMode
|
||||
|
@ -10,16 +10,13 @@ import {
|
||||
isStrategySection,
|
||||
} from "../../../data/lovelace/config/section";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { HuiErrorCard } from "../cards/hui-error-card";
|
||||
import "../cards/hui-card";
|
||||
import type { HuiCard } from "../cards/hui-card";
|
||||
import {
|
||||
checkConditionsMet,
|
||||
attachConditionMediaQueriesListeners,
|
||||
checkConditionsMet,
|
||||
} from "../common/validate-condition";
|
||||
import { createCardElement } from "../create-element/create-card-element";
|
||||
import {
|
||||
createErrorCardConfig,
|
||||
createErrorCardElement,
|
||||
} from "../create-element/create-element-base";
|
||||
import { createErrorCardConfig } from "../create-element/create-element-base";
|
||||
import { createSectionElement } from "../create-element/create-section-element";
|
||||
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
|
||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||
@ -27,7 +24,7 @@ import { deleteCard } from "../editor/config-util";
|
||||
import { confDeleteCard } from "../editor/delete-card";
|
||||
import { parseLovelaceCardPath } from "../editor/lovelace-path";
|
||||
import { generateLovelaceSectionStrategy } from "../strategies/get-strategy";
|
||||
import type { Lovelace, LovelaceCard } from "../types";
|
||||
import type { Lovelace } from "../types";
|
||||
import { DEFAULT_SECTION_LAYOUT } from "./const";
|
||||
|
||||
@customElement("hui-section")
|
||||
@ -42,7 +39,7 @@ export class HuiSection extends ReactiveElement {
|
||||
|
||||
@property({ type: Number }) public viewIndex!: number;
|
||||
|
||||
@state() private _cards: Array<LovelaceCard | HuiErrorCard> = [];
|
||||
@state() private _cards: HuiCard[] = [];
|
||||
|
||||
private _layoutElementType?: string;
|
||||
|
||||
@ -52,14 +49,10 @@ export class HuiSection extends ReactiveElement {
|
||||
|
||||
// Public to make demo happy
|
||||
public createCardElement(cardConfig: LovelaceCardConfig) {
|
||||
const element = createCardElement(cardConfig) as LovelaceCard;
|
||||
try {
|
||||
element.hass = this.hass;
|
||||
} catch (e: any) {
|
||||
return createErrorCardElement(
|
||||
createErrorCardConfig(e.message, cardConfig)
|
||||
);
|
||||
}
|
||||
const element = document.createElement("hui-card");
|
||||
element.hass = this.hass;
|
||||
element.lovelace = this.lovelace;
|
||||
element.setConfig(cardConfig);
|
||||
element.addEventListener(
|
||||
"ll-rebuild",
|
||||
(ev: Event) => {
|
||||
@ -131,6 +124,13 @@ export class HuiSection extends ReactiveElement {
|
||||
}
|
||||
if (changedProperties.has("lovelace")) {
|
||||
this._layoutElement.lovelace = this.lovelace;
|
||||
this._cards.forEach((element) => {
|
||||
try {
|
||||
element.lovelace = this.lovelace;
|
||||
} catch (e: any) {
|
||||
this._rebuildCard(element, createErrorCardConfig(e.message, null));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (changedProperties.has("_cards")) {
|
||||
this._layoutElement.cards = this._cards;
|
||||
@ -147,16 +147,20 @@ export class HuiSection extends ReactiveElement {
|
||||
}
|
||||
|
||||
private _listenMediaQueries() {
|
||||
if (!this.config.visibility) {
|
||||
this._clearMediaQueries();
|
||||
if (!this.config?.visibility) {
|
||||
return;
|
||||
}
|
||||
this._clearMediaQueries();
|
||||
const conditions = this.config.visibility;
|
||||
const hasOnlyMediaQuery =
|
||||
conditions.length === 1 &&
|
||||
conditions[0].condition === "screen" &&
|
||||
conditions[0].media_query != null;
|
||||
|
||||
this._listeners = attachConditionMediaQueriesListeners(
|
||||
this.config.visibility,
|
||||
this.hass,
|
||||
(visibility) => {
|
||||
const visible = visibility || this.lovelace!.editMode;
|
||||
this._updateElement(visible);
|
||||
(matches) => {
|
||||
this._updateElement(hasOnlyMediaQuery && matches);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -210,10 +214,10 @@ export class HuiSection extends ReactiveElement {
|
||||
return;
|
||||
}
|
||||
const visible =
|
||||
forceVisible ??
|
||||
(this.lovelace.editMode ||
|
||||
!this.config.visibility ||
|
||||
checkConditionsMet(this.config.visibility, this.hass));
|
||||
forceVisible ||
|
||||
this.lovelace.editMode ||
|
||||
!this.config.visibility ||
|
||||
checkConditionsMet(this.config.visibility, this.hass);
|
||||
|
||||
this.style.setProperty("display", visible ? "" : "none");
|
||||
this.toggleAttribute("hidden", !visible);
|
||||
@ -267,29 +271,15 @@ export class HuiSection extends ReactiveElement {
|
||||
|
||||
this._cards = config.cards.map((cardConfig) => {
|
||||
const element = this.createCardElement(cardConfig);
|
||||
try {
|
||||
element.hass = this.hass;
|
||||
} catch (e: any) {
|
||||
return createErrorCardElement(
|
||||
createErrorCardConfig(e.message, cardConfig)
|
||||
);
|
||||
}
|
||||
return element;
|
||||
});
|
||||
}
|
||||
|
||||
private _rebuildCard(
|
||||
cardElToReplace: LovelaceCard,
|
||||
cardElToReplace: HuiCard,
|
||||
config: LovelaceCardConfig
|
||||
): void {
|
||||
let newCardEl = this.createCardElement(config);
|
||||
try {
|
||||
newCardEl.hass = this.hass;
|
||||
} catch (e: any) {
|
||||
newCardEl = createErrorCardElement(
|
||||
createErrorCardConfig(e.message, config)
|
||||
);
|
||||
}
|
||||
const newCardEl = this.createCardElement(config);
|
||||
if (cardElToReplace.parentElement) {
|
||||
cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import "../../../components/ha-svg-icon";
|
||||
import type { LovelaceViewElement } from "../../../data/lovelace";
|
||||
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { HuiErrorCard } from "../cards/hui-error-card";
|
||||
import { HuiCard } from "../cards/hui-card";
|
||||
import { computeCardSize } from "../common/compute-card-size";
|
||||
import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types";
|
||||
|
||||
@ -48,9 +48,7 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
|
||||
|
||||
@property({ type: Boolean }) public isStrategy = false;
|
||||
|
||||
@property({ attribute: false }) public cards: Array<
|
||||
LovelaceCard | HuiErrorCard
|
||||
> = [];
|
||||
@property({ attribute: false }) public cards: HuiCard[] = [];
|
||||
|
||||
@property({ attribute: false }) public badges: LovelaceBadge[] = [];
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import type { LovelaceViewElement } from "../../../data/lovelace";
|
||||
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { HuiErrorCard } from "../cards/hui-error-card";
|
||||
import { HuiCard } from "../cards/hui-card";
|
||||
import { HuiCardOptions } from "../components/hui-card-options";
|
||||
import { HuiWarning } from "../components/hui-warning";
|
||||
import type { Lovelace, LovelaceCard } from "../types";
|
||||
@ -30,9 +30,7 @@ export class PanelView extends LitElement implements LovelaceViewElement {
|
||||
|
||||
@property({ type: Boolean }) public isStrategy = false;
|
||||
|
||||
@property({ attribute: false }) public cards: Array<
|
||||
LovelaceCard | HuiErrorCard
|
||||
> = [];
|
||||
@property({ attribute: false }) public cards: HuiCard[] = [];
|
||||
|
||||
@state() private _card?: LovelaceCard | HuiWarning | HuiCardOptions;
|
||||
|
||||
|
@ -12,7 +12,7 @@ import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import type { LovelaceViewElement } from "../../../data/lovelace";
|
||||
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { HuiErrorCard } from "../cards/hui-error-card";
|
||||
import { HuiCard } from "../cards/hui-card";
|
||||
import { HuiCardOptions } from "../components/hui-card-options";
|
||||
import { replaceCard } from "../editor/config-util";
|
||||
import type { Lovelace, LovelaceCard } from "../types";
|
||||
@ -26,9 +26,7 @@ export class SideBarView extends LitElement implements LovelaceViewElement {
|
||||
|
||||
@property({ type: Boolean }) public isStrategy = false;
|
||||
|
||||
@property({ attribute: false }) public cards: Array<
|
||||
LovelaceCard | HuiErrorCard
|
||||
> = [];
|
||||
@property({ attribute: false }) public cards: HuiCard[] = [];
|
||||
|
||||
@state() private _config?: LovelaceViewConfig;
|
||||
|
||||
|
@ -17,14 +17,11 @@ import {
|
||||
createErrorBadgeConfig,
|
||||
createErrorBadgeElement,
|
||||
} from "../badges/hui-error-badge";
|
||||
import type { HuiErrorCard } from "../cards/hui-error-card";
|
||||
import "../cards/hui-card";
|
||||
import type { HuiCard } from "../cards/hui-card";
|
||||
import { processConfigEntities } from "../common/process-config-entities";
|
||||
import { createBadgeElement } from "../create-element/create-badge-element";
|
||||
import { createCardElement } from "../create-element/create-card-element";
|
||||
import {
|
||||
createErrorCardConfig,
|
||||
createErrorCardElement,
|
||||
} from "../create-element/create-element-base";
|
||||
import { createErrorCardConfig } from "../create-element/create-element-base";
|
||||
import { createViewElement } from "../create-element/create-view-element";
|
||||
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
|
||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||
@ -38,7 +35,7 @@ import { createErrorSectionConfig } from "../sections/hui-error-section";
|
||||
import "../sections/hui-section";
|
||||
import type { HuiSection } from "../sections/hui-section";
|
||||
import { generateLovelaceViewStrategy } from "../strategies/get-strategy";
|
||||
import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types";
|
||||
import type { Lovelace, LovelaceBadge } from "../types";
|
||||
import { DEFAULT_VIEW_LAYOUT, PANEL_VIEW_LAYOUT } from "./const";
|
||||
|
||||
declare global {
|
||||
@ -65,7 +62,7 @@ export class HUIView extends ReactiveElement {
|
||||
|
||||
@property({ type: Number }) public index!: number;
|
||||
|
||||
@state() private _cards: Array<LovelaceCard | HuiErrorCard> = [];
|
||||
@state() private _cards: HuiCard[] = [];
|
||||
|
||||
@state() private _badges: LovelaceBadge[] = [];
|
||||
|
||||
@ -79,14 +76,10 @@ export class HUIView extends ReactiveElement {
|
||||
|
||||
// Public to make demo happy
|
||||
public createCardElement(cardConfig: LovelaceCardConfig) {
|
||||
const element = createCardElement(cardConfig) as LovelaceCard;
|
||||
try {
|
||||
element.hass = this.hass;
|
||||
} catch (e: any) {
|
||||
return createErrorCardElement(
|
||||
createErrorCardConfig(e.message, cardConfig)
|
||||
);
|
||||
}
|
||||
const element = document.createElement("hui-card");
|
||||
element.hass = this.hass;
|
||||
element.lovelace = this.lovelace;
|
||||
element.setConfig(cardConfig);
|
||||
element.addEventListener(
|
||||
"ll-rebuild",
|
||||
(ev: Event) => {
|
||||
@ -233,6 +226,14 @@ export class HUIView extends ReactiveElement {
|
||||
this._rebuildSection(element, createErrorSectionConfig(e.message));
|
||||
}
|
||||
});
|
||||
this._cards.forEach((element) => {
|
||||
try {
|
||||
element.hass = this.hass;
|
||||
element.lovelace = this.lovelace;
|
||||
} catch (e: any) {
|
||||
this._rebuildCard(element, createErrorCardConfig(e.message, null));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (changedProperties.has("_cards")) {
|
||||
this._layoutElement.cards = this._cards;
|
||||
@ -371,13 +372,6 @@ export class HUIView extends ReactiveElement {
|
||||
|
||||
this._cards = config.cards.map((cardConfig) => {
|
||||
const element = this.createCardElement(cardConfig);
|
||||
try {
|
||||
element.hass = this.hass;
|
||||
} catch (e: any) {
|
||||
return createErrorCardElement(
|
||||
createErrorCardConfig(e.message, cardConfig)
|
||||
);
|
||||
}
|
||||
return element;
|
||||
});
|
||||
}
|
||||
@ -396,17 +390,10 @@ export class HUIView extends ReactiveElement {
|
||||
}
|
||||
|
||||
private _rebuildCard(
|
||||
cardElToReplace: LovelaceCard,
|
||||
cardElToReplace: HuiCard,
|
||||
config: LovelaceCardConfig
|
||||
): void {
|
||||
let newCardEl = this.createCardElement(config);
|
||||
try {
|
||||
newCardEl.hass = this.hass;
|
||||
} catch (e: any) {
|
||||
newCardEl = createErrorCardElement(
|
||||
createErrorCardConfig(e.message, config)
|
||||
);
|
||||
}
|
||||
const newCardEl = this.createCardElement(config);
|
||||
if (cardElToReplace.parentElement) {
|
||||
cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user