Clean up HUI-VIEW (#8967)

This commit is contained in:
Paulus Schoutsen 2021-04-22 09:46:15 -07:00 committed by GitHub
parent e8d1318a5b
commit 0b8d356865
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 101 additions and 95 deletions

View File

@ -613,7 +613,7 @@ class HUIRoot extends LitElement {
} }
if (!force && huiView) { if (!force && huiView) {
huiView.lovelace = this.lovelace; huiView.lovelace = this.lovelace!;
} }
} }

View File

@ -101,6 +101,11 @@ export class PanelView extends LitElement implements LovelaceViewElement {
} }
private _createCard(): void { private _createCard(): void {
if (this.cards.length === 0) {
this._card = undefined;
return;
}
const card: LovelaceCard = this.cards[0]; const card: LovelaceCard = this.cards[0];
card.isPanel = true; card.isPanel = true;

View File

@ -39,13 +39,13 @@ declare global {
@customElement("hui-view") @customElement("hui-view")
export class HUIView extends UpdatingElement { export class HUIView extends UpdatingElement {
@property({ attribute: false }) public hass?: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public lovelace?: Lovelace; @property({ attribute: false }) public lovelace!: Lovelace;
@property({ type: Boolean }) public narrow!: boolean; @property({ type: Boolean }) public narrow!: boolean;
@property({ type: Number }) public index?: number; @property({ type: Number }) public index!: number;
@internalProperty() private _cards: Array<LovelaceCard | HuiErrorCard> = []; @internalProperty() private _cards: Array<LovelaceCard | HuiErrorCard> = [];
@ -89,49 +89,116 @@ export class HUIView extends UpdatingElement {
protected updated(changedProperties: PropertyValues): void { protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties); super.updated(changedProperties);
const hass = this.hass!; /*
const lovelace = this.lovelace!; We need to handle the following use cases:
- initialization: create layout element, populate
- config changed to view with same layout element
- config changed to view with different layout element
- forwarded properties hass/narrow/lovelace/cards/badges change
- cards/badges change if one is rebuild when it was loaded later
- lovelace changes if edit mode is enabled or config has changed
*/
const hassChanged = changedProperties.has("hass"); const oldLovelace = changedProperties.get("lovelace") as this["lovelace"];
const oldLovelace = changedProperties.get("lovelace") as Lovelace; const configChanged =
changedProperties.has("index") ||
let editModeChanged = false; (changedProperties.has("lovelace") &&
let configChanged = false; (!oldLovelace ||
this.lovelace.config.views[this.index] !==
if (changedProperties.has("index")) { oldLovelace.config.views[this.index]));
configChanged = true;
} else if (changedProperties.has("lovelace")) {
editModeChanged =
oldLovelace && lovelace.editMode !== oldLovelace.editMode;
configChanged = !oldLovelace || lovelace.config !== oldLovelace.config;
}
let viewConfig: LovelaceViewConfig | undefined;
// If config has changed, create element if necessary and set all values.
if (configChanged) { if (configChanged) {
viewConfig = lovelace.config.views[this.index!]; let viewConfig = this.lovelace.config.views[this.index];
viewConfig = { viewConfig = {
...viewConfig, ...viewConfig,
type: viewConfig.panel type: viewConfig.panel
? PANEL_VIEW_LAYOUT ? PANEL_VIEW_LAYOUT
: viewConfig.type || DEFAULT_VIEW_LAYOUT, : viewConfig.type || DEFAULT_VIEW_LAYOUT,
}; };
}
let replace = false; this._createBadges(viewConfig!);
this._createCards(viewConfig!);
// Create a new layout element if necessary.
let addLayoutElement = false;
if ( if (
configChanged && !this._layoutElement ||
(!this._layoutElement || this._layoutElementType !== viewConfig!.type) this._layoutElementType !== viewConfig!.type
) { ) {
replace = true; addLayoutElement = true;
this._layoutElement = createViewElement(viewConfig!); this._createLayoutElement(viewConfig!);
this._layoutElementType = viewConfig!.type; }
this._layoutElement!.hass = this.hass;
this._layoutElement!.narrow = this.narrow;
this._layoutElement!.lovelace = this.lovelace;
this._layoutElement!.index = this.index;
this._layoutElement!.cards = this._cards;
this._layoutElement!.badges = this._badges;
if (addLayoutElement) {
while (this.lastChild) {
this.removeChild(this.lastChild);
}
this.appendChild(this._layoutElement!);
}
} else {
// Config has not changed. Just props
if (changedProperties.has("hass")) {
this._badges.forEach((badge) => {
badge.hass = this.hass;
});
this._cards.forEach((element) => {
element.hass = this.hass;
});
this._layoutElement!.hass = this.hass;
}
if (changedProperties.has("narrow")) {
this._layoutElement!.narrow = this.narrow;
}
if (changedProperties.has("lovelace")) {
this._layoutElement!.lovelace = this.lovelace;
}
if (changedProperties.has("_cards")) {
this._layoutElement!.cards = this._cards;
}
if (changedProperties.has("_badges")) {
this._layoutElement!.badges = this._badges;
}
}
const oldHass = changedProperties.get("hass") as this["hass"] | undefined;
// Update theme if necessary:
// - If config changed, the theme could have changed
// - if hass themes preferences have changed
if (
configChanged ||
(changedProperties.has("hass") &&
(!oldHass ||
this.hass.themes !== oldHass.themes ||
this.hass.selectedTheme !== oldHass.selectedTheme))
) {
applyThemesOnElement(
this,
this.hass.themes,
this.lovelace.config.views[this.index].theme
);
}
}
private _createLayoutElement(config: LovelaceViewConfig): void {
this._layoutElement = createViewElement(config);
this._layoutElementType = config.type;
this._layoutElement.addEventListener("ll-create-card", () => { this._layoutElement.addEventListener("ll-create-card", () => {
showCreateCardDialog(this, { showCreateCardDialog(this, {
lovelaceConfig: this.lovelace!.config, lovelaceConfig: this.lovelace!.config,
saveConfig: this.lovelace!.saveConfig, saveConfig: this.lovelace!.saveConfig,
path: [this.index!], path: [this.index],
}); });
}); });
this._layoutElement.addEventListener("ll-edit-card", (ev) => { this._layoutElement.addEventListener("ll-edit-card", (ev) => {
@ -146,72 +213,6 @@ export class HUIView extends UpdatingElement {
}); });
} }
if (configChanged) {
this._createBadges(viewConfig!);
this._createCards(viewConfig!);
this._layoutElement!.hass = this.hass;
this._layoutElement!.narrow = this.narrow;
this._layoutElement!.lovelace = lovelace;
this._layoutElement!.index = this.index;
}
if (hassChanged) {
this._badges.forEach((badge) => {
badge.hass = hass;
});
this._cards.forEach((element) => {
element.hass = hass;
});
this._layoutElement!.hass = this.hass;
}
if (changedProperties.has("narrow")) {
this._layoutElement!.narrow = this.narrow;
}
if (editModeChanged) {
this._layoutElement!.lovelace = lovelace;
}
if (
configChanged ||
hassChanged ||
editModeChanged ||
changedProperties.has("_cards") ||
changedProperties.has("_badges")
) {
this._layoutElement!.cards = this._cards;
this._layoutElement!.badges = this._badges;
}
const oldHass = changedProperties.get("hass") as this["hass"] | undefined;
if (
configChanged ||
editModeChanged ||
(hassChanged &&
oldHass &&
(hass.themes !== oldHass.themes ||
hass.selectedTheme !== oldHass.selectedTheme))
) {
applyThemesOnElement(
this,
hass.themes,
lovelace.config.views[this.index!].theme
);
}
if (this._layoutElement && replace) {
while (this.lastChild) {
this.removeChild(this.lastChild);
}
this.appendChild(this._layoutElement);
}
}
private _createBadges(config: LovelaceViewConfig): void { private _createBadges(config: LovelaceViewConfig): void {
if (!config || !config.badges || !Array.isArray(config.badges)) { if (!config || !config.badges || !Array.isArray(config.badges)) {
this._badges = []; this._badges = [];