mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 07:16:39 +00:00
Refactor create element (#4509)
* Refactor create element * Move things around * Fix reference in gallery
This commit is contained in:
parent
fbe4550c78
commit
62654ec598
@ -2,7 +2,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import { safeLoad } from "js-yaml";
|
import { safeLoad } from "js-yaml";
|
||||||
|
|
||||||
import { createCardElement } from "../../../src/panels/lovelace/common/create-card-element";
|
import { createCardElement } from "../../../src/panels/lovelace/create-element/create-card-element";
|
||||||
|
|
||||||
class DemoCard extends PolymerElement {
|
class DemoCard extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { createBadgeElement } from "../common/create-badge-element";
|
import { createBadgeElement } from "../create-element/create-badge-element";
|
||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { LovelaceBadge } from "../types";
|
import { LovelaceBadge } from "../types";
|
||||||
import { EntityFilterEntityConfig } from "../entity-rows/types";
|
import { EntityFilterEntityConfig } from "../entity-rows/types";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { createCardElement } from "../common/create-card-element";
|
import { createCardElement } from "../create-element/create-card-element";
|
||||||
import { computeCardSize } from "../common/compute-card-size";
|
import { computeCardSize } from "../common/compute-card-size";
|
||||||
import {
|
import {
|
||||||
checkConditionsMet,
|
checkConditionsMet,
|
||||||
|
@ -16,7 +16,7 @@ import { HomeAssistant } from "../../../types";
|
|||||||
import { EntityRow } from "../entity-rows/types";
|
import { EntityRow } from "../entity-rows/types";
|
||||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { createRowElement } from "../common/create-row-element";
|
import { createRowElement } from "../create-element/create-row-element";
|
||||||
import { EntitiesCardConfig, EntitiesCardEntityConfig } from "./types";
|
import { EntitiesCardConfig, EntitiesCardEntityConfig } from "./types";
|
||||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { createCardElement } from "../common/create-card-element";
|
import { createCardElement } from "../create-element/create-card-element";
|
||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { LovelaceCard } from "../types";
|
import { LovelaceCard } from "../types";
|
||||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { html, LitElement, TemplateResult, CSSResult, css } from "lit-element";
|
import { html, LitElement, TemplateResult, CSSResult, css } from "lit-element";
|
||||||
|
|
||||||
import { createCardElement } from "../common/create-card-element";
|
import { createCardElement } from "../create-element/create-card-element";
|
||||||
import { LovelaceCard } from "../types";
|
import { LovelaceCard } from "../types";
|
||||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { LovelaceElement, LovelaceElementConfig } from "../../elements/types";
|
import { LovelaceElement, LovelaceElementConfig } from "../../elements/types";
|
||||||
import { createHuiElement } from "../../common/create-hui-element";
|
import { createHuiElement } from "../../create-element/create-hui-element";
|
||||||
|
|
||||||
export function createStyledHuiElement(
|
export function createStyledHuiElement(
|
||||||
elementConfig: LovelaceElementConfig
|
elementConfig: LovelaceElementConfig
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
import "../badges/hui-entity-filter-badge";
|
|
||||||
import "../badges/hui-state-label-badge";
|
|
||||||
|
|
||||||
import {
|
|
||||||
createErrorBadgeElement,
|
|
||||||
createErrorBadgeConfig,
|
|
||||||
HuiErrorBadge,
|
|
||||||
} from "../badges/hui-error-badge";
|
|
||||||
import { LovelaceBadge } from "../types";
|
|
||||||
import { LovelaceBadgeConfig } from "../../../data/lovelace";
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
|
||||||
|
|
||||||
const BADGE_TYPES = new Set(["entity-filter", "error", "state-label"]);
|
|
||||||
const CUSTOM_TYPE_PREFIX = "custom:";
|
|
||||||
const TIMEOUT = 2000;
|
|
||||||
|
|
||||||
const _createElement = (
|
|
||||||
tag: string,
|
|
||||||
config: LovelaceBadgeConfig
|
|
||||||
): LovelaceBadge => {
|
|
||||||
const element = document.createElement(tag) as LovelaceBadge;
|
|
||||||
try {
|
|
||||||
element.setConfig(config);
|
|
||||||
} catch (err) {
|
|
||||||
// tslint:disable-next-line
|
|
||||||
console.error(tag, err);
|
|
||||||
return _createErrorElement(err.message);
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
const _createErrorElement = (error: string): HuiErrorBadge =>
|
|
||||||
createErrorBadgeElement(createErrorBadgeConfig(error));
|
|
||||||
|
|
||||||
export const createBadgeElement = (
|
|
||||||
config: LovelaceBadgeConfig
|
|
||||||
): LovelaceBadge => {
|
|
||||||
if (!config || typeof config !== "object") {
|
|
||||||
return _createErrorElement("No config");
|
|
||||||
}
|
|
||||||
|
|
||||||
let type = config.type;
|
|
||||||
|
|
||||||
if (!type) {
|
|
||||||
type = "state-label";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
|
||||||
const tag = type.substr(CUSTOM_TYPE_PREFIX.length);
|
|
||||||
|
|
||||||
if (customElements.get(tag)) {
|
|
||||||
return _createElement(tag, config);
|
|
||||||
}
|
|
||||||
const element = _createErrorElement(`Type doesn't exist: ${tag}`);
|
|
||||||
element.style.display = "None";
|
|
||||||
const timer = window.setTimeout(() => {
|
|
||||||
element.style.display = "";
|
|
||||||
}, TIMEOUT);
|
|
||||||
|
|
||||||
customElements.whenDefined(tag).then(() => {
|
|
||||||
clearTimeout(timer);
|
|
||||||
fireEvent(element, "ll-badge-rebuild");
|
|
||||||
});
|
|
||||||
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!BADGE_TYPES.has(type)) {
|
|
||||||
return _createErrorElement(`Unknown type: ${type}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _createElement(`hui-${type}-badge`, config);
|
|
||||||
};
|
|
@ -1,125 +0,0 @@
|
|||||||
import deepClone from "deep-clone-simple";
|
|
||||||
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
|
||||||
|
|
||||||
import "../cards/hui-alarm-panel-card";
|
|
||||||
import "../cards/hui-conditional-card";
|
|
||||||
import "../cards/hui-entities-card";
|
|
||||||
import "../cards/hui-entity-button-card";
|
|
||||||
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";
|
|
||||||
import "../cards/hui-horizontal-stack-card";
|
|
||||||
import "../cards/hui-iframe-card";
|
|
||||||
import "../cards/hui-light-card";
|
|
||||||
import "../cards/hui-map-card";
|
|
||||||
import "../cards/hui-markdown-card";
|
|
||||||
import "../cards/hui-media-control-card";
|
|
||||||
import "../cards/hui-picture-card";
|
|
||||||
import "../cards/hui-picture-elements-card";
|
|
||||||
import "../cards/hui-picture-entity-card";
|
|
||||||
import "../cards/hui-picture-glance-card";
|
|
||||||
import "../cards/hui-plant-status-card";
|
|
||||||
import "../cards/hui-sensor-card";
|
|
||||||
import "../cards/hui-vertical-stack-card";
|
|
||||||
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",
|
|
||||||
"conditional",
|
|
||||||
"entities",
|
|
||||||
"entity-button",
|
|
||||||
"entity-filter",
|
|
||||||
"error",
|
|
||||||
"gauge",
|
|
||||||
"glance",
|
|
||||||
"history-graph",
|
|
||||||
"horizontal-stack",
|
|
||||||
"iframe",
|
|
||||||
"light",
|
|
||||||
"map",
|
|
||||||
"markdown",
|
|
||||||
"media-control",
|
|
||||||
"picture",
|
|
||||||
"picture-elements",
|
|
||||||
"picture-entity",
|
|
||||||
"picture-glance",
|
|
||||||
"plant-status",
|
|
||||||
"sensor",
|
|
||||||
"shopping-list",
|
|
||||||
"thermostat",
|
|
||||||
"vertical-stack",
|
|
||||||
"weather-forecast",
|
|
||||||
]);
|
|
||||||
const CUSTOM_TYPE_PREFIX = "custom:";
|
|
||||||
const TIMEOUT = 2000;
|
|
||||||
|
|
||||||
const _createElement = (
|
|
||||||
tag: string,
|
|
||||||
config: LovelaceCardConfig
|
|
||||||
): LovelaceCard | HuiErrorCard => {
|
|
||||||
const element = document.createElement(tag) as LovelaceCard;
|
|
||||||
try {
|
|
||||||
element.setConfig(deepClone(config));
|
|
||||||
} catch (err) {
|
|
||||||
// tslint:disable-next-line
|
|
||||||
console.error(tag, err);
|
|
||||||
return _createErrorElement(err.message, config);
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
const _createErrorElement = (
|
|
||||||
error: string,
|
|
||||||
config: LovelaceCardConfig
|
|
||||||
): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config));
|
|
||||||
|
|
||||||
export const createCardElement = (
|
|
||||||
config: LovelaceCardConfig
|
|
||||||
): LovelaceCard | HuiErrorCard => {
|
|
||||||
if (!config || typeof config !== "object" || !config.type) {
|
|
||||||
return _createErrorElement("No card type configured.", config);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
|
||||||
const tag = config.type.substr(CUSTOM_TYPE_PREFIX.length);
|
|
||||||
|
|
||||||
if (customElements.get(tag)) {
|
|
||||||
return _createElement(tag, config);
|
|
||||||
}
|
|
||||||
const element = _createErrorElement(
|
|
||||||
`Custom element doesn't exist: ${tag}.`,
|
|
||||||
config
|
|
||||||
);
|
|
||||||
element.style.display = "None";
|
|
||||||
const timer = window.setTimeout(() => {
|
|
||||||
element.style.display = "";
|
|
||||||
}, TIMEOUT);
|
|
||||||
|
|
||||||
customElements.whenDefined(tag).then(() => {
|
|
||||||
clearTimeout(timer);
|
|
||||||
fireEvent(element, "ll-rebuild");
|
|
||||||
});
|
|
||||||
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CARD_TYPES.has(config.type)) {
|
|
||||||
return _createErrorElement(
|
|
||||||
`Unknown card type encountered: ${config.type}.`,
|
|
||||||
config
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _createElement(`hui-${config.type}-card`, config);
|
|
||||||
};
|
|
@ -1,93 +0,0 @@
|
|||||||
import deepClone from "deep-clone-simple";
|
|
||||||
|
|
||||||
import "../elements/hui-conditional-element";
|
|
||||||
import "../elements/hui-icon-element";
|
|
||||||
import "../elements/hui-image-element";
|
|
||||||
import "../elements/hui-service-button-element";
|
|
||||||
import "../elements/hui-state-badge-element";
|
|
||||||
import "../elements/hui-state-icon-element";
|
|
||||||
import "../elements/hui-state-label-element";
|
|
||||||
|
|
||||||
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([
|
|
||||||
"conditional",
|
|
||||||
"icon",
|
|
||||||
"image",
|
|
||||||
"service-button",
|
|
||||||
"state-badge",
|
|
||||||
"state-icon",
|
|
||||||
"state-label",
|
|
||||||
]);
|
|
||||||
const TIMEOUT = 2000;
|
|
||||||
|
|
||||||
const _createElement = (
|
|
||||||
tag: string,
|
|
||||||
config: LovelaceElementConfig
|
|
||||||
): LovelaceElement | HuiErrorCard => {
|
|
||||||
const element = document.createElement(tag) as LovelaceElement;
|
|
||||||
try {
|
|
||||||
element.setConfig(deepClone(config));
|
|
||||||
} catch (err) {
|
|
||||||
// tslint:disable-next-line
|
|
||||||
console.error(tag, err);
|
|
||||||
return _createErrorElement(err.message, config);
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
const _createErrorElement = (
|
|
||||||
error: string,
|
|
||||||
config: LovelaceElementConfig
|
|
||||||
): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config));
|
|
||||||
|
|
||||||
function _hideErrorElement(element) {
|
|
||||||
element.style.display = "None";
|
|
||||||
return window.setTimeout(() => {
|
|
||||||
element.style.display = "";
|
|
||||||
}, TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createHuiElement = (
|
|
||||||
config: LovelaceElementConfig
|
|
||||||
): LovelaceElement | HuiErrorCard => {
|
|
||||||
if (!config || typeof config !== "object" || !config.type) {
|
|
||||||
return _createErrorElement("No element type configured.", config);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
|
||||||
const tag = config.type.substr(CUSTOM_TYPE_PREFIX.length);
|
|
||||||
|
|
||||||
if (customElements.get(tag)) {
|
|
||||||
return _createElement(tag, config);
|
|
||||||
}
|
|
||||||
const element = _createErrorElement(
|
|
||||||
`Custom element doesn't exist: ${tag}.`,
|
|
||||||
config
|
|
||||||
);
|
|
||||||
const timer = _hideErrorElement(element);
|
|
||||||
|
|
||||||
customElements.whenDefined(tag).then(() => {
|
|
||||||
clearTimeout(timer);
|
|
||||||
fireEvent(element, "ll-rebuild");
|
|
||||||
});
|
|
||||||
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ELEMENT_TYPES.has(config.type)) {
|
|
||||||
return _createErrorElement(
|
|
||||||
`Unknown element type encountered: ${config.type}.`,
|
|
||||||
config
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _createElement(`hui-${config.type}-element`, config);
|
|
||||||
};
|
|
@ -1,143 +0,0 @@
|
|||||||
import deepClone from "deep-clone-simple";
|
|
||||||
|
|
||||||
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";
|
|
||||||
import "../entity-rows/hui-group-entity-row";
|
|
||||||
import "../entity-rows/hui-input-datetime-entity-row";
|
|
||||||
import "../entity-rows/hui-input-number-entity-row";
|
|
||||||
import "../entity-rows/hui-input-select-entity-row";
|
|
||||||
import "../entity-rows/hui-input-text-entity-row";
|
|
||||||
import "../entity-rows/hui-lock-entity-row";
|
|
||||||
import "../entity-rows/hui-media-player-entity-row";
|
|
||||||
import "../entity-rows/hui-scene-entity-row";
|
|
||||||
import "../entity-rows/hui-script-entity-row";
|
|
||||||
import "../entity-rows/hui-sensor-entity-row";
|
|
||||||
import "../entity-rows/hui-text-entity-row";
|
|
||||||
import "../entity-rows/hui-timer-entity-row";
|
|
||||||
import "../entity-rows/hui-toggle-entity-row";
|
|
||||||
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 "../special-rows/hui-cast-row";
|
|
||||||
import { EntityConfig, EntityRow } from "../entity-rows/types";
|
|
||||||
|
|
||||||
const CUSTOM_TYPE_PREFIX = "custom:";
|
|
||||||
const SPECIAL_TYPES = new Set([
|
|
||||||
"call-service",
|
|
||||||
"divider",
|
|
||||||
"section",
|
|
||||||
"weblink",
|
|
||||||
"cast",
|
|
||||||
"select",
|
|
||||||
]);
|
|
||||||
const DOMAIN_TO_ELEMENT_TYPE = {
|
|
||||||
alert: "toggle",
|
|
||||||
automation: "toggle",
|
|
||||||
climate: "climate",
|
|
||||||
cover: "cover",
|
|
||||||
fan: "toggle",
|
|
||||||
group: "group",
|
|
||||||
input_boolean: "toggle",
|
|
||||||
input_number: "input-number",
|
|
||||||
input_select: "input-select",
|
|
||||||
input_text: "input-text",
|
|
||||||
light: "toggle",
|
|
||||||
lock: "lock",
|
|
||||||
media_player: "media-player",
|
|
||||||
remote: "toggle",
|
|
||||||
scene: "scene",
|
|
||||||
script: "script",
|
|
||||||
sensor: "sensor",
|
|
||||||
timer: "timer",
|
|
||||||
switch: "toggle",
|
|
||||||
vacuum: "toggle",
|
|
||||||
// Temporary. Once climate is rewritten,
|
|
||||||
// water heater should get it's own row.
|
|
||||||
water_heater: "climate",
|
|
||||||
input_datetime: "input-datetime",
|
|
||||||
};
|
|
||||||
const TIMEOUT = 2000;
|
|
||||||
|
|
||||||
const _createElement = (
|
|
||||||
tag: string,
|
|
||||||
config: EntityConfig
|
|
||||||
): EntityRow | HuiErrorCard => {
|
|
||||||
const element = document.createElement(tag) as EntityRow;
|
|
||||||
try {
|
|
||||||
element.setConfig(deepClone(config));
|
|
||||||
} catch (err) {
|
|
||||||
// tslint:disable-next-line
|
|
||||||
console.error(tag, err);
|
|
||||||
return _createErrorElement(err.message, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
const _createErrorElement = (
|
|
||||||
error: string,
|
|
||||||
config: EntityConfig
|
|
||||||
): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config));
|
|
||||||
|
|
||||||
const _hideErrorElement = (element) => {
|
|
||||||
element.style.display = "None";
|
|
||||||
return window.setTimeout(() => {
|
|
||||||
element.style.display = "";
|
|
||||||
}, TIMEOUT);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createRowElement = (
|
|
||||||
config: EntityConfig
|
|
||||||
): EntityRow | HuiErrorCard => {
|
|
||||||
let tag;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!config ||
|
|
||||||
typeof config !== "object" ||
|
|
||||||
(!config.entity && !config.type)
|
|
||||||
) {
|
|
||||||
return _createErrorElement("Invalid config given.", config);
|
|
||||||
}
|
|
||||||
|
|
||||||
const type = config.type || "default";
|
|
||||||
if (SPECIAL_TYPES.has(type)) {
|
|
||||||
return _createElement(`hui-${type}-row`, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
|
||||||
tag = type.substr(CUSTOM_TYPE_PREFIX.length);
|
|
||||||
|
|
||||||
if (customElements.get(tag)) {
|
|
||||||
return _createElement(tag, config);
|
|
||||||
}
|
|
||||||
const element = _createErrorElement(
|
|
||||||
`Custom element doesn't exist: ${tag}.`,
|
|
||||||
config
|
|
||||||
);
|
|
||||||
const timer = _hideErrorElement(element);
|
|
||||||
|
|
||||||
customElements.whenDefined(tag).then(() => {
|
|
||||||
clearTimeout(timer);
|
|
||||||
fireEvent(element, "ll-rebuild");
|
|
||||||
});
|
|
||||||
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.entity) {
|
|
||||||
return _createErrorElement("Invalid config given.", config);
|
|
||||||
}
|
|
||||||
|
|
||||||
const domain = config.entity.split(".", 1)[0];
|
|
||||||
tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || "text"}-entity-row`;
|
|
||||||
|
|
||||||
return _createElement(tag, config);
|
|
||||||
};
|
|
10
src/panels/lovelace/create-element/create-badge-element.ts
Normal file
10
src/panels/lovelace/create-element/create-badge-element.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import "../badges/hui-entity-filter-badge";
|
||||||
|
import "../badges/hui-state-label-badge";
|
||||||
|
|
||||||
|
import { LovelaceBadgeConfig } from "../../../data/lovelace";
|
||||||
|
import { createLovelaceElement } from "./create-element-base";
|
||||||
|
|
||||||
|
const BADGE_TYPES = new Set(["entity-filter", "error", "state-label"]);
|
||||||
|
|
||||||
|
export const createBadgeElement = (config: LovelaceBadgeConfig) =>
|
||||||
|
createLovelaceElement("badge", config, BADGE_TYPES, undefined, "state-label");
|
57
src/panels/lovelace/create-element/create-card-element.ts
Normal file
57
src/panels/lovelace/create-element/create-card-element.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import "../cards/hui-alarm-panel-card";
|
||||||
|
import "../cards/hui-conditional-card";
|
||||||
|
import "../cards/hui-entities-card";
|
||||||
|
import "../cards/hui-entity-button-card";
|
||||||
|
import "../cards/hui-entity-filter-card";
|
||||||
|
import "../cards/hui-glance-card";
|
||||||
|
import "../cards/hui-history-graph-card";
|
||||||
|
import "../cards/hui-horizontal-stack-card";
|
||||||
|
import "../cards/hui-iframe-card";
|
||||||
|
import "../cards/hui-light-card";
|
||||||
|
import "../cards/hui-map-card";
|
||||||
|
import "../cards/hui-markdown-card";
|
||||||
|
import "../cards/hui-media-control-card";
|
||||||
|
import "../cards/hui-picture-card";
|
||||||
|
import "../cards/hui-picture-elements-card";
|
||||||
|
import "../cards/hui-picture-entity-card";
|
||||||
|
import "../cards/hui-picture-glance-card";
|
||||||
|
import "../cards/hui-plant-status-card";
|
||||||
|
import "../cards/hui-sensor-card";
|
||||||
|
import "../cards/hui-vertical-stack-card";
|
||||||
|
import "../cards/hui-shopping-list-card";
|
||||||
|
import "../cards/hui-thermostat-card";
|
||||||
|
import "../cards/hui-weather-forecast-card";
|
||||||
|
import "../cards/hui-gauge-card";
|
||||||
|
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||||
|
import { createLovelaceElement } from "./create-element-base";
|
||||||
|
|
||||||
|
const CARD_TYPES = new Set([
|
||||||
|
"alarm-panel",
|
||||||
|
"conditional",
|
||||||
|
"entities",
|
||||||
|
"entity-button",
|
||||||
|
"entity-filter",
|
||||||
|
"error",
|
||||||
|
"gauge",
|
||||||
|
"glance",
|
||||||
|
"history-graph",
|
||||||
|
"horizontal-stack",
|
||||||
|
"iframe",
|
||||||
|
"light",
|
||||||
|
"map",
|
||||||
|
"markdown",
|
||||||
|
"media-control",
|
||||||
|
"picture",
|
||||||
|
"picture-elements",
|
||||||
|
"picture-entity",
|
||||||
|
"picture-glance",
|
||||||
|
"plant-status",
|
||||||
|
"sensor",
|
||||||
|
"shopping-list",
|
||||||
|
"thermostat",
|
||||||
|
"vertical-stack",
|
||||||
|
"weather-forecast",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const createCardElement = (config: LovelaceCardConfig) =>
|
||||||
|
createLovelaceElement("card", config, CARD_TYPES);
|
110
src/panels/lovelace/create-element/create-element-base.ts
Normal file
110
src/panels/lovelace/create-element/create-element-base.ts
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import {
|
||||||
|
LovelaceCardConfig,
|
||||||
|
LovelaceBadgeConfig,
|
||||||
|
} from "../../../data/lovelace";
|
||||||
|
import {
|
||||||
|
HuiErrorCard,
|
||||||
|
createErrorCardElement,
|
||||||
|
createErrorCardConfig,
|
||||||
|
} from "../cards/hui-error-card";
|
||||||
|
import { LovelaceCard, LovelaceBadge } from "../types";
|
||||||
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
|
import { LovelaceElementConfig, LovelaceElement } from "../elements/types";
|
||||||
|
import { EntityRow, EntityRowConfig } from "../entity-rows/types";
|
||||||
|
|
||||||
|
const CUSTOM_TYPE_PREFIX = "custom:";
|
||||||
|
const TIMEOUT = 2000;
|
||||||
|
|
||||||
|
interface CreateElementConfigTypes {
|
||||||
|
card: { config: LovelaceCardConfig; element: LovelaceCard };
|
||||||
|
badge: { config: LovelaceBadgeConfig; element: LovelaceBadge };
|
||||||
|
element: { config: LovelaceElementConfig; element: LovelaceElement };
|
||||||
|
row: { config: EntityRowConfig; element: EntityRow };
|
||||||
|
}
|
||||||
|
|
||||||
|
const _createElement = <T extends keyof CreateElementConfigTypes>(
|
||||||
|
tag: string,
|
||||||
|
config: CreateElementConfigTypes[T]["config"]
|
||||||
|
): CreateElementConfigTypes[T]["element"] | HuiErrorCard => {
|
||||||
|
const element = document.createElement(
|
||||||
|
tag
|
||||||
|
) as CreateElementConfigTypes[T]["element"];
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
element.setConfig(config);
|
||||||
|
} catch (err) {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
console.error(tag, err);
|
||||||
|
return _createErrorElement(err.message, config);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
|
const _createErrorElement = <T extends keyof CreateElementConfigTypes>(
|
||||||
|
error: string,
|
||||||
|
config: CreateElementConfigTypes[T]["config"]
|
||||||
|
): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config));
|
||||||
|
|
||||||
|
export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
|
||||||
|
tagSuffix: T,
|
||||||
|
config: CreateElementConfigTypes[T]["config"],
|
||||||
|
elementTypes: Set<string>,
|
||||||
|
// Allow looking at "entity" in config and mapping that to a type
|
||||||
|
domainTypes?: { _domain_not_found: string; [domain: string]: string },
|
||||||
|
// Default type if no type given. If given, entity types will not work.
|
||||||
|
defaultType?: string
|
||||||
|
): CreateElementConfigTypes[T]["element"] | HuiErrorCard => {
|
||||||
|
if (!config || typeof config !== "object") {
|
||||||
|
return _createErrorElement("Config is not an object", config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!config.type &&
|
||||||
|
!defaultType &&
|
||||||
|
// If domain types is given, we can derive a type from "entity"
|
||||||
|
(!domainTypes || !("entity" in config))
|
||||||
|
) {
|
||||||
|
return _createErrorElement("No card type configured.", config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.type && config.type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
||||||
|
const tag = config.type.substr(CUSTOM_TYPE_PREFIX.length);
|
||||||
|
|
||||||
|
if (customElements.get(tag)) {
|
||||||
|
return _createElement(tag, config);
|
||||||
|
}
|
||||||
|
const element = _createErrorElement(
|
||||||
|
`Custom element doesn't exist: ${tag}.`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
element.style.display = "None";
|
||||||
|
const timer = window.setTimeout(() => {
|
||||||
|
element.style.display = "";
|
||||||
|
}, TIMEOUT);
|
||||||
|
|
||||||
|
customElements.whenDefined(tag).then(() => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
fireEvent(element, "ll-rebuild");
|
||||||
|
});
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
// config.type has priority over config.entity, but defaultType has not.
|
||||||
|
// @ts-ignore
|
||||||
|
if (domainTypes && !config.type && config.entity) {
|
||||||
|
// @ts-ignore
|
||||||
|
const domain = config.entity.split(".", 1)[0];
|
||||||
|
return _createElement(
|
||||||
|
`hui-${domainTypes![domain] ||
|
||||||
|
domainTypes!._domain_not_found}-entity-${tagSuffix}`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = config.type || defaultType;
|
||||||
|
|
||||||
|
return type !== undefined && elementTypes.has(type)
|
||||||
|
? _createElement(`hui-${type}-${tagSuffix}`, config)
|
||||||
|
: _createErrorElement(`Unknown type encountered: ${type}.`, config);
|
||||||
|
};
|
23
src/panels/lovelace/create-element/create-hui-element.ts
Normal file
23
src/panels/lovelace/create-element/create-hui-element.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import "../elements/hui-conditional-element";
|
||||||
|
import "../elements/hui-icon-element";
|
||||||
|
import "../elements/hui-image-element";
|
||||||
|
import "../elements/hui-service-button-element";
|
||||||
|
import "../elements/hui-state-badge-element";
|
||||||
|
import "../elements/hui-state-icon-element";
|
||||||
|
import "../elements/hui-state-label-element";
|
||||||
|
|
||||||
|
import { LovelaceElementConfig } from "../elements/types";
|
||||||
|
import { createLovelaceElement } from "./create-element-base";
|
||||||
|
|
||||||
|
const ELEMENT_TYPES = new Set([
|
||||||
|
"conditional",
|
||||||
|
"icon",
|
||||||
|
"image",
|
||||||
|
"service-button",
|
||||||
|
"state-badge",
|
||||||
|
"state-icon",
|
||||||
|
"state-label",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const createHuiElement = (config: LovelaceElementConfig) =>
|
||||||
|
createLovelaceElement("element", config, ELEMENT_TYPES);
|
61
src/panels/lovelace/create-element/create-row-element.ts
Normal file
61
src/panels/lovelace/create-element/create-row-element.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import "../entity-rows/hui-climate-entity-row";
|
||||||
|
import "../entity-rows/hui-cover-entity-row";
|
||||||
|
import "../entity-rows/hui-group-entity-row";
|
||||||
|
import "../entity-rows/hui-input-datetime-entity-row";
|
||||||
|
import "../entity-rows/hui-input-number-entity-row";
|
||||||
|
import "../entity-rows/hui-input-select-entity-row";
|
||||||
|
import "../entity-rows/hui-input-text-entity-row";
|
||||||
|
import "../entity-rows/hui-lock-entity-row";
|
||||||
|
import "../entity-rows/hui-media-player-entity-row";
|
||||||
|
import "../entity-rows/hui-scene-entity-row";
|
||||||
|
import "../entity-rows/hui-script-entity-row";
|
||||||
|
import "../entity-rows/hui-sensor-entity-row";
|
||||||
|
import "../entity-rows/hui-text-entity-row";
|
||||||
|
import "../entity-rows/hui-timer-entity-row";
|
||||||
|
import "../entity-rows/hui-toggle-entity-row";
|
||||||
|
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 "../special-rows/hui-cast-row";
|
||||||
|
import { EntityConfig } from "../entity-rows/types";
|
||||||
|
import { createLovelaceElement } from "./create-element-base";
|
||||||
|
|
||||||
|
const SPECIAL_TYPES = new Set([
|
||||||
|
"call-service",
|
||||||
|
"divider",
|
||||||
|
"section",
|
||||||
|
"weblink",
|
||||||
|
"cast",
|
||||||
|
"select",
|
||||||
|
]);
|
||||||
|
const DOMAIN_TO_ELEMENT_TYPE = {
|
||||||
|
_domain_not_found: "text",
|
||||||
|
alert: "toggle",
|
||||||
|
automation: "toggle",
|
||||||
|
climate: "climate",
|
||||||
|
cover: "cover",
|
||||||
|
fan: "toggle",
|
||||||
|
group: "group",
|
||||||
|
input_boolean: "toggle",
|
||||||
|
input_number: "input-number",
|
||||||
|
input_select: "input-select",
|
||||||
|
input_text: "input-text",
|
||||||
|
light: "toggle",
|
||||||
|
lock: "lock",
|
||||||
|
media_player: "media-player",
|
||||||
|
remote: "toggle",
|
||||||
|
scene: "scene",
|
||||||
|
script: "script",
|
||||||
|
sensor: "sensor",
|
||||||
|
timer: "timer",
|
||||||
|
switch: "toggle",
|
||||||
|
vacuum: "toggle",
|
||||||
|
// Temporary. Once climate is rewritten,
|
||||||
|
// water heater should get it's own row.
|
||||||
|
water_heater: "climate",
|
||||||
|
input_datetime: "input-datetime",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createRowElement = (config: EntityConfig) =>
|
||||||
|
createLovelaceElement("row", config, SPECIAL_TYPES, DOMAIN_TO_ELEMENT_TYPE);
|
@ -2,7 +2,7 @@ import "@polymer/paper-input/paper-textarea";
|
|||||||
|
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
|
|
||||||
import { createCardElement } from "../../common/create-card-element";
|
import { createCardElement } from "../../create-element/create-card-element";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import { LovelaceCardConfig } from "../../../../data/lovelace";
|
import { LovelaceCardConfig } from "../../../../data/lovelace";
|
||||||
import { LovelaceCard } from "../../types";
|
import { LovelaceCard } from "../../types";
|
||||||
|
@ -9,7 +9,7 @@ import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_elemen
|
|||||||
|
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { LovelaceCard } from "../types";
|
import { LovelaceCard } from "../types";
|
||||||
import { createCardElement } from "../common/create-card-element";
|
import { createCardElement } from "../create-element/create-card-element";
|
||||||
import { LovelaceViewConfig } from "../../../data/lovelace";
|
import { LovelaceViewConfig } from "../../../data/lovelace";
|
||||||
|
|
||||||
@customElement("hui-panel-view")
|
@customElement("hui-panel-view")
|
||||||
|
@ -19,12 +19,12 @@ import {
|
|||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import { Lovelace, LovelaceCard, LovelaceBadge } from "../types";
|
import { Lovelace, LovelaceCard, LovelaceBadge } from "../types";
|
||||||
import { createCardElement } from "../common/create-card-element";
|
import { createCardElement } from "../create-element/create-card-element";
|
||||||
import { computeCardSize } from "../common/compute-card-size";
|
import { computeCardSize } from "../common/compute-card-size";
|
||||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||||
import { HuiErrorCard } from "../cards/hui-error-card";
|
import { HuiErrorCard } from "../cards/hui-error-card";
|
||||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||||
import { createBadgeElement } from "../common/create-badge-element";
|
import { createBadgeElement } from "../create-element/create-badge-element";
|
||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
|
|
||||||
let editCodeLoaded = false;
|
let editCodeLoaded = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user