TS create element functions (#2276)

* TS create element functions

* Name chunk
This commit is contained in:
Paulus Schoutsen 2018-12-12 14:21:34 +01:00 committed by GitHub
parent 8c61624a9c
commit 6a9cfbfa1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 144 additions and 87 deletions

View File

@ -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() {

View File

@ -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 {

View File

@ -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";

View File

@ -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";

View File

@ -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) {

View File

@ -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() {

View File

@ -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";

View File

@ -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";

View File

@ -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();
}

View File

@ -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();
};

View File

@ -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);
}
};

View File

@ -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);
}
};

View File

@ -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);
}
};

View File

@ -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";

View File

@ -29,7 +29,7 @@ export type EntityRowConfig =
| WeblinkConfig
| CallServiceConfig;
export interface EntityRow {
export interface EntityRow extends HTMLElement {
hass?: HomeAssistant;
setConfig(config: EntityRowConfig);
}

View File

@ -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;

View File

@ -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",

View File

@ -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";