From 6a9cfbfa1c017c1994b457efd9a9d8afe01b8d71 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 12 Dec 2018 14:21:34 +0100 Subject: [PATCH] TS create element functions (#2276) * TS create element functions * Name chunk --- gallery/src/components/demo-card.js | 2 +- src/data/lovelace.ts | 1 + .../lovelace/cards/hui-conditional-card.ts | 2 +- .../lovelace/cards/hui-entities-card.ts | 2 +- .../lovelace/cards/hui-entity-filter-card.js | 2 +- src/panels/lovelace/cards/hui-error-card.ts | 4 +- .../cards/hui-picture-elements-card.ts | 2 +- src/panels/lovelace/cards/hui-stack-card.ts | 2 +- .../common/compute-unused-entities.js | 38 ------------- .../common/compute-unused-entities.ts | 54 +++++++++++++++++++ ...card-element.js => create-card-element.ts} | 27 ++++++---- ...e-hui-element.js => create-hui-element.ts} | 24 ++++++--- ...e-row-element.js => create-row-element.ts} | 26 +++++---- ...{is-valid-object.js => is-valid-object.ts} | 0 .../editor/card-editor/hui-card-preview.ts | 2 +- src/panels/lovelace/entity-rows/types.ts | 2 +- src/panels/lovelace/hui-root.ts | 25 +++++++-- src/panels/lovelace/hui-unused-entities.ts | 14 +++-- src/panels/lovelace/hui-view.ts | 2 +- 19 files changed, 144 insertions(+), 87 deletions(-) delete mode 100644 src/panels/lovelace/common/compute-unused-entities.js create mode 100644 src/panels/lovelace/common/compute-unused-entities.ts rename src/panels/lovelace/common/{create-card-element.js => create-card-element.ts} (82%) rename src/panels/lovelace/common/{create-hui-element.js => create-hui-element.ts} (75%) rename src/panels/lovelace/common/{create-row-element.js => create-row-element.ts} (84%) rename src/panels/lovelace/common/{is-valid-object.js => is-valid-object.ts} (100%) diff --git a/gallery/src/components/demo-card.js b/gallery/src/components/demo-card.js index 703f24c346..e63ad1eecd 100644 --- a/gallery/src/components/demo-card.js +++ b/gallery/src/components/demo-card.js @@ -7,7 +7,7 @@ import { demoConfig } from "../data/demo_config"; import { demoServices } from "../data/demo_services"; import demoResources from "../data/demo_resources"; import demoStates from "../data/demo_states"; -import createCardElement from "../../../src/panels/lovelace/common/create-card-element"; +import { createCardElement } from "../../../src/panels/lovelace/common/create-card-element"; class DemoCard extends PolymerElement { static get template() { diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts index 994227b87c..84edaa0472 100644 --- a/src/data/lovelace.ts +++ b/src/data/lovelace.ts @@ -5,6 +5,7 @@ export interface LovelaceConfig { views: LovelaceViewConfig[]; background?: string; resources?: Array<{ type: "css" | "js" | "module" | "html"; url: string }>; + excluded_entities?: string[]; } export interface LovelaceViewConfig { diff --git a/src/panels/lovelace/cards/hui-conditional-card.ts b/src/panels/lovelace/cards/hui-conditional-card.ts index 0f2e6329cc..51cdb07a3e 100644 --- a/src/panels/lovelace/cards/hui-conditional-card.ts +++ b/src/panels/lovelace/cards/hui-conditional-card.ts @@ -1,4 +1,4 @@ -import createCardElement from "../common/create-card-element"; +import { createCardElement } from "../common/create-card-element"; import { computeCardSize } from "../common/compute-card-size"; import { HomeAssistant } from "../../../types"; import { LovelaceCard } from "../types"; diff --git a/src/panels/lovelace/cards/hui-entities-card.ts b/src/panels/lovelace/cards/hui-entities-card.ts index 188c8a15ae..2e1e2e1dd2 100644 --- a/src/panels/lovelace/cards/hui-entities-card.ts +++ b/src/panels/lovelace/cards/hui-entities-card.ts @@ -17,7 +17,7 @@ import { EntityConfig, EntityRow } from "../entity-rows/types"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { LovelaceCardConfig } from "../../../data/lovelace"; import { processConfigEntities } from "../common/process-config-entities"; -import createRowElement from "../common/create-row-element"; +import { createRowElement } from "../common/create-row-element"; import computeDomain from "../../../common/entity/compute_domain"; import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; diff --git a/src/panels/lovelace/cards/hui-entity-filter-card.js b/src/panels/lovelace/cards/hui-entity-filter-card.js index 841dfaa0c5..7b854b9e5b 100644 --- a/src/panels/lovelace/cards/hui-entity-filter-card.js +++ b/src/panels/lovelace/cards/hui-entity-filter-card.js @@ -1,6 +1,6 @@ import { PolymerElement } from "@polymer/polymer/polymer-element"; -import createCardElement from "../common/create-card-element"; +import { createCardElement } from "../common/create-card-element"; import { processConfigEntities } from "../common/process-config-entities"; function getEntities(hass, filterState, entities) { diff --git a/src/panels/lovelace/cards/hui-error-card.ts b/src/panels/lovelace/cards/hui-error-card.ts index 65c7fe0ddf..59981fc7fb 100644 --- a/src/panels/lovelace/cards/hui-error-card.ts +++ b/src/panels/lovelace/cards/hui-error-card.ts @@ -3,6 +3,7 @@ import { html, LitElement } from "@polymer/lit-element"; import { LovelaceCard } from "../types"; import { LovelaceCardConfig } from "../../../data/lovelace"; import { TemplateResult } from "lit-html"; +import { HomeAssistant } from "../../../types"; interface Config extends LovelaceCardConfig { error: string; @@ -21,7 +22,8 @@ export const createErrorCardConfig = (error, origConfig) => ({ origConfig, }); -class HuiErrorCard extends LitElement implements LovelaceCard { +export class HuiErrorCard extends LitElement implements LovelaceCard { + public hass?: HomeAssistant; private _config?: Config; static get properties() { diff --git a/src/panels/lovelace/cards/hui-picture-elements-card.ts b/src/panels/lovelace/cards/hui-picture-elements-card.ts index 072215f318..02f669b612 100644 --- a/src/panels/lovelace/cards/hui-picture-elements-card.ts +++ b/src/panels/lovelace/cards/hui-picture-elements-card.ts @@ -1,7 +1,7 @@ import { html, LitElement } from "@polymer/lit-element"; import { TemplateResult } from "lit-html"; -import createHuiElement from "../common/create-hui-element"; +import { createHuiElement } from "../common/create-hui-element"; import { LovelaceCard } from "../types"; import { LovelaceCardConfig } from "../../../data/lovelace"; diff --git a/src/panels/lovelace/cards/hui-stack-card.ts b/src/panels/lovelace/cards/hui-stack-card.ts index f246ed8c74..d5f13689c7 100644 --- a/src/panels/lovelace/cards/hui-stack-card.ts +++ b/src/panels/lovelace/cards/hui-stack-card.ts @@ -1,7 +1,7 @@ import { html, LitElement } from "@polymer/lit-element"; import { TemplateResult } from "lit-html"; -import createCardElement from "../common/create-card-element"; +import { createCardElement } from "../common/create-card-element"; import { LovelaceCard } from "../types"; import { LovelaceCardConfig } from "../../../data/lovelace"; diff --git a/src/panels/lovelace/common/compute-unused-entities.js b/src/panels/lovelace/common/compute-unused-entities.js deleted file mode 100644 index faaedcc3a7..0000000000 --- a/src/panels/lovelace/common/compute-unused-entities.js +++ /dev/null @@ -1,38 +0,0 @@ -const EXCLUDED_DOMAINS = ["zone"]; - -function computeUsedEntities(config) { - const entities = new Set(); - - function addEntityId(entity) { - if (typeof entity === "string") { - entities.add(entity); - } else if (entity.entity) { - entities.add(entity.entity); - } - } - - function addEntities(obj) { - if (obj.entity) addEntityId(obj.entity); - if (obj.entities) obj.entities.forEach((entity) => addEntityId(entity)); - if (obj.card) addEntities(obj.card); - if (obj.cards) obj.cards.forEach((card) => addEntities(card)); - if (obj.badges) obj.badges.forEach((badge) => addEntityId(badge)); - } - - config.views.forEach((view) => addEntities(view)); - return entities; -} - -export default function computeUnusedEntities(hass, config) { - const usedEntities = computeUsedEntities(config); - return Object.keys(hass.states) - .filter( - (entity) => - !usedEntities.has(entity) && - !( - config.excluded_entities && config.excluded_entities.includes(entity) - ) && - !EXCLUDED_DOMAINS.includes(entity.split(".", 1)[0]) - ) - .sort(); -} diff --git a/src/panels/lovelace/common/compute-unused-entities.ts b/src/panels/lovelace/common/compute-unused-entities.ts new file mode 100644 index 0000000000..0c4fd0c331 --- /dev/null +++ b/src/panels/lovelace/common/compute-unused-entities.ts @@ -0,0 +1,54 @@ +import { LovelaceConfig } from "../../../data/lovelace"; +import { HomeAssistant } from "../../../types"; + +const EXCLUDED_DOMAINS = ["zone"]; + +const computeUsedEntities = (config) => { + const entities = new Set(); + + const addEntityId = (entity) => { + if (typeof entity === "string") { + entities.add(entity); + } else if (entity.entity) { + entities.add(entity.entity); + } + }; + + const addEntities = (obj) => { + if (obj.entity) { + addEntityId(obj.entity); + } + if (obj.entities) { + obj.entities.forEach((entity) => addEntityId(entity)); + } + if (obj.card) { + addEntities(obj.card); + } + if (obj.cards) { + obj.cards.forEach((card) => addEntities(card)); + } + if (obj.badges) { + obj.badges.forEach((badge) => addEntityId(badge)); + } + }; + + config.views.forEach((view) => addEntities(view)); + return entities; +}; + +export const computeUnusedEntities = ( + hass: HomeAssistant, + config: LovelaceConfig +): string[] => { + const usedEntities = computeUsedEntities(config); + return Object.keys(hass.states) + .filter( + (entity) => + !usedEntities.has(entity) && + !( + config.excluded_entities && config.excluded_entities.includes(entity) + ) && + !EXCLUDED_DOMAINS.includes(entity.split(".", 1)[0]) + ) + .sort(); +}; diff --git a/src/panels/lovelace/common/create-card-element.js b/src/panels/lovelace/common/create-card-element.ts similarity index 82% rename from src/panels/lovelace/common/create-card-element.js rename to src/panels/lovelace/common/create-card-element.ts index c33bd394eb..0b7c18a562 100644 --- a/src/panels/lovelace/common/create-card-element.js +++ b/src/panels/lovelace/common/create-card-element.ts @@ -8,6 +8,7 @@ import "../cards/hui-entity-filter-card"; import { createErrorCardElement, createErrorCardConfig, + HuiErrorCard, } from "../cards/hui-error-card"; import "../cards/hui-glance-card"; import "../cards/hui-history-graph-card"; @@ -28,6 +29,8 @@ import "../cards/hui-shopping-list-card"; import "../cards/hui-thermostat-card"; import "../cards/hui-weather-forecast-card"; import "../cards/hui-gauge-card"; +import { LovelaceCard } from "../types"; +import { LovelaceCardConfig } from "../../../data/lovelace"; const CARD_TYPES = new Set([ "alarm-panel", @@ -59,23 +62,29 @@ const CARD_TYPES = new Set([ const CUSTOM_TYPE_PREFIX = "custom:"; const TIMEOUT = 2000; -function _createElement(tag, config) { - const element = document.createElement(tag); +const _createElement = ( + tag: string, + config: LovelaceCardConfig +): LovelaceCard | HuiErrorCard => { + const element = document.createElement(tag) as LovelaceCard; try { element.setConfig(config); } catch (err) { - // eslint-disable-next-line + // tslint:disable-next-line console.error(tag, err); - // eslint-disable-next-line return _createErrorElement(err.message, config); } return element; -} +}; -const _createErrorElement = (error, config) => - createErrorCardElement(createErrorCardConfig(error, config)); +const _createErrorElement = ( + error: string, + config: LovelaceCardConfig +): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config)); -export default function createCardElement(config) { +export const createCardElement = ( + config: LovelaceCardConfig +): LovelaceCard | HuiErrorCard => { if (!config || typeof config !== "object" || !config.type) { return _createErrorElement("No card type configured.", config); } @@ -111,4 +120,4 @@ export default function createCardElement(config) { } return _createElement(`hui-${config.type}-card`, config); -} +}; diff --git a/src/panels/lovelace/common/create-hui-element.js b/src/panels/lovelace/common/create-hui-element.ts similarity index 75% rename from src/panels/lovelace/common/create-hui-element.js rename to src/panels/lovelace/common/create-hui-element.ts index 520ca4f3d5..eac2082a3d 100644 --- a/src/panels/lovelace/common/create-hui-element.js +++ b/src/panels/lovelace/common/create-hui-element.ts @@ -9,7 +9,9 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { createErrorCardElement, createErrorCardConfig, + HuiErrorCard, } from "../cards/hui-error-card"; +import { LovelaceElementConfig, LovelaceElement } from "../elements/types"; const CUSTOM_TYPE_PREFIX = "custom:"; const ELEMENT_TYPES = new Set([ @@ -22,21 +24,25 @@ const ELEMENT_TYPES = new Set([ ]); const TIMEOUT = 2000; -const _createElement = (tag, config) => { - const element = document.createElement(tag); +const _createElement = ( + tag: string, + config: LovelaceElementConfig +): LovelaceElement | HuiErrorCard => { + const element = document.createElement(tag) as LovelaceElement; try { element.setConfig(config); } catch (err) { - // eslint-disable-next-line + // tslint:disable-next-line console.error(tag, err); - // eslint-disable-next-line return _createErrorElement(err.message, config); } return element; }; -const _createErrorElement = (error, config) => - createErrorCardElement(createErrorCardConfig(error, config)); +const _createErrorElement = ( + error: string, + config: LovelaceElementConfig +): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config)); function _hideErrorElement(element) { element.style.display = "None"; @@ -45,7 +51,9 @@ function _hideErrorElement(element) { }, TIMEOUT); } -export default function createHuiElement(config) { +export const createHuiElement = ( + config: LovelaceElementConfig +): LovelaceElement | HuiErrorCard => { if (!config || typeof config !== "object" || !config.type) { return _createErrorElement("No element type configured.", config); } @@ -78,4 +86,4 @@ export default function createHuiElement(config) { } return _createElement(`hui-${config.type}-element`, config); -} +}; diff --git a/src/panels/lovelace/common/create-row-element.js b/src/panels/lovelace/common/create-row-element.ts similarity index 84% rename from src/panels/lovelace/common/create-row-element.js rename to src/panels/lovelace/common/create-row-element.ts index 140e58a3f2..a2bc40f8d0 100644 --- a/src/panels/lovelace/common/create-row-element.js +++ b/src/panels/lovelace/common/create-row-element.ts @@ -3,6 +3,7 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { createErrorCardElement, createErrorCardConfig, + HuiErrorCard, } from "../cards/hui-error-card"; import "../entity-rows/hui-climate-entity-row"; import "../entity-rows/hui-cover-entity-row"; @@ -22,6 +23,7 @@ import "../special-rows/hui-call-service-row"; import "../special-rows/hui-divider-row"; import "../special-rows/hui-section-row"; import "../special-rows/hui-weblink-row"; +import { EntityConfig, EntityRow } from "../entity-rows/types"; const CUSTOM_TYPE_PREFIX = "custom:"; const SPECIAL_TYPES = new Set([ @@ -53,22 +55,26 @@ const DOMAIN_TO_ELEMENT_TYPE = { }; const TIMEOUT = 2000; -const _createElement = (tag, config) => { - const element = document.createElement(tag); +const _createElement = ( + tag: string, + config: EntityConfig +): EntityRow | HuiErrorCard => { + const element = document.createElement(tag) as EntityRow; try { - if ("setConfig" in element) element.setConfig(config); + element.setConfig(config); } catch (err) { - // eslint-disable-next-line + // tslint:disable-next-line console.error(tag, err); - // eslint-disable-next-line return _createErrorElement(err.message, config); } return element; }; -const _createErrorElement = (error, config) => - createErrorCardElement(createErrorCardConfig(error, config)); +const _createErrorElement = ( + error: string, + config: EntityConfig +): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config)); const _hideErrorElement = (element) => { element.style.display = "None"; @@ -77,7 +83,9 @@ const _hideErrorElement = (element) => { }, TIMEOUT); }; -export default function createRowElement(config) { +export const createRowElement = ( + config: EntityConfig +): EntityRow | HuiErrorCard => { let tag; if ( @@ -117,4 +125,4 @@ export default function createRowElement(config) { tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || "text"}-entity-row`; return _createElement(tag, config); -} +}; diff --git a/src/panels/lovelace/common/is-valid-object.js b/src/panels/lovelace/common/is-valid-object.ts similarity index 100% rename from src/panels/lovelace/common/is-valid-object.js rename to src/panels/lovelace/common/is-valid-object.ts diff --git a/src/panels/lovelace/editor/card-editor/hui-card-preview.ts b/src/panels/lovelace/editor/card-editor/hui-card-preview.ts index 39c49b2400..7f037282df 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-preview.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-preview.ts @@ -1,6 +1,6 @@ import "@polymer/paper-input/paper-textarea"; -import createCardElement from "../../common/create-card-element"; +import { createCardElement } from "../../common/create-card-element"; import { HomeAssistant } from "../../../../types"; import { LovelaceCardConfig } from "../../../../data/lovelace"; import { LovelaceCard } from "../../types"; diff --git a/src/panels/lovelace/entity-rows/types.ts b/src/panels/lovelace/entity-rows/types.ts index 88e983bc69..c73cf9ef50 100644 --- a/src/panels/lovelace/entity-rows/types.ts +++ b/src/panels/lovelace/entity-rows/types.ts @@ -29,7 +29,7 @@ export type EntityRowConfig = | WeblinkConfig | CallServiceConfig; -export interface EntityRow { +export interface EntityRow extends HTMLElement { hass?: HomeAssistant; setConfig(config: EntityRowConfig); } diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 066c9536b6..b814c049bc 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -36,12 +36,11 @@ import { fireEvent } from "../../common/dom/fire_event"; import { computeNotifications } from "./common/compute-notifications"; import "./components/notifications/hui-notification-drawer"; import "./components/notifications/hui-notifications-button"; -import "./hui-unused-entities"; import "./hui-view"; // Not a duplicate import, this one is for type // tslint:disable-next-line import { HUIView } from "./hui-view"; -import createCardElement from "./common/create-card-element"; +import { createCardElement } from "./common/create-card-element"; import { showEditViewDialog } from "./editor/view-editor/show-edit-view-dialog"; import { showEditLovelaceDialog } from "./editor/lovelace-editor/show-edit-lovelace-dialog"; import { Lovelace } from "./types"; @@ -51,6 +50,15 @@ import { afterNextRender } from "../../common/util/render-status"; const CSS_CACHE = {}; const JS_CACHE = {}; +declare global { + // tslint:disable-next-line + interface HASSDomEvents { + "rebuild-view": {}; + } +} + +let loadedUnusedEntities = false; + class HUIRoot extends hassLocalizeLitMixin(LitElement) { public narrow?: boolean; public showMenu?: boolean; @@ -59,7 +67,7 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) { public columns?: number; public route?: { path: string; prefix: string }; private _routeData?: { view: string }; - private _curView?: number | "unused"; + private _curView?: number | "hass-unused-entities"; private notificationsOpen?: boolean; private _persistentNotifications?: Notification[]; private _haStyle?: DocumentFragment; @@ -394,6 +402,8 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) { views ) { navigate(this, `/lovelace/${views[0].path || 0}`, true); + } else if (this._routeData!.view === "hass-unused-entities") { + newSelectView = "hass-unused-entities"; } else if (this._routeData!.view) { const selectedView = this._routeData!.view; const selectedViewInt = parseInt(selectedView, 10); @@ -478,7 +488,7 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) { } private _handleUnusedEntities(): void { - this._selectView("unused", false); + navigate(this, `/lovelace/hass-unused-entities`); } private _deselect(ev): void { @@ -556,9 +566,14 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) { root.removeChild(root.lastChild); } - if (viewIndex === "unused") { + if (viewIndex === "hass-unused-entities") { + if (!loadedUnusedEntities) { + loadedUnusedEntities = true; + await import(/* webpackChunkName: "hui-unused-entities" */ "./hui-unused-entities"); + } const unusedEntities = document.createElement("hui-unused-entities"); unusedEntities.setConfig(this.config); + unusedEntities.hass = this.hass!; root.style.background = this.config.background || ""; root.appendChild(unusedEntities); return; diff --git a/src/panels/lovelace/hui-unused-entities.ts b/src/panels/lovelace/hui-unused-entities.ts index 9548c44bec..ec3970b9ae 100644 --- a/src/panels/lovelace/hui-unused-entities.ts +++ b/src/panels/lovelace/hui-unused-entities.ts @@ -2,15 +2,16 @@ import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element"; import "./cards/hui-entities-card"; -import computeUnusedEntities from "./common/compute-unused-entities"; -import createCardElement from "./common/create-card-element"; +import { computeUnusedEntities } from "./common/compute-unused-entities"; +import { createCardElement } from "./common/create-card-element"; import { HomeAssistant } from "../../types"; import { TemplateResult } from "lit-html"; import { LovelaceCard } from "./types"; +import { LovelaceConfig } from "../../data/lovelace"; export class HuiUnusedEntities extends LitElement { private _hass?: HomeAssistant; - private _config?: object; + private _config?: LovelaceConfig; private _element?: LovelaceCard; static get properties(): PropertyDeclarations { @@ -29,10 +30,7 @@ export class HuiUnusedEntities extends LitElement { this._element.hass = this._hass; } - public setConfig(config: object): void { - if (!config) { - throw new Error("Card config incorrect"); - } + public setConfig(config: LovelaceConfig): void { this._config = config; this._createElement(); } @@ -62,7 +60,7 @@ export class HuiUnusedEntities extends LitElement { private _createElement(): void { if (this._hass) { - const entities = computeUnusedEntities(this._hass, this._config).map( + const entities = computeUnusedEntities(this._hass, this._config!).map( (entity) => ({ entity, secondary_info: "entity-id", diff --git a/src/panels/lovelace/hui-view.ts b/src/panels/lovelace/hui-view.ts index 4bbe6b3b15..471e917c1e 100644 --- a/src/panels/lovelace/hui-view.ts +++ b/src/panels/lovelace/hui-view.ts @@ -18,7 +18,7 @@ import { LovelaceViewConfig } from "../../data/lovelace"; import { HomeAssistant } from "../../types"; import { Lovelace, LovelaceCard } from "./types"; -import createCardElement from "./common/create-card-element"; +import { createCardElement } from "./common/create-card-element"; import { computeCardSize } from "./common/compute-card-size"; import { showEditCardDialog } from "./editor/card-editor/show-edit-card-dialog";