Love: move create card element to component, improve error card (#1328)

* Love: move create card element to component, improve error card

* Remove whenDefined

* Fix config check

* Allow enity_id only card config

* Feedback

* Fix conflicts

* Add import

* Lint

* Lint

* Lint -.-"
This commit is contained in:
c727 2018-06-26 16:50:51 +02:00 committed by Paulus Schoutsen
parent 748b5a8e41
commit 9fd1db0493
6 changed files with 108 additions and 100 deletions

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,17 +1,9 @@
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import './hui-camera-preview-card.js';
import './hui-entities-card.js';
import './hui-entity-filter-card.js';
import './hui-glance-card';
import './hui-history-graph-card.js';
import './hui-media-control-card.js';
import './hui-picture-glance-card';
import './hui-plant-status-card.js';
import './hui-weather-forecast-card';
import './hui-error-card';
import computeStateDomain from '../../../common/entity/compute_state_domain.js';
import computeCardElement from '../common/compute-card-element.js';
import createCardElement from '../common/create-card-element';
class HuiEntitiesCard extends PolymerElement {
static get properties() {
@ -30,6 +22,7 @@ class HuiEntitiesCard extends PolymerElement {
constructor() {
super();
this._whenDefined = {};
this.elementNotDefinedCallback = this.elementNotDefinedCallback.bind(this);
}
getCardSize() {
@ -72,48 +65,49 @@ class HuiEntitiesCard extends PolymerElement {
if (this.lastChild) {
this.removeChild(this.lastChild);
}
let error = null;
let cardConfig;
let tag = config.card ? computeCardElement(config.card) : 'hui-entities-card';
let error;
let element;
if (tag === null) {
error = `Unknown card type encountered: "${config.card}".`;
} else if (!customElements.get(tag)) {
error = `Custom element doesn't exist: "${tag}".`;
if (!(tag in this._whenDefined)) {
this._whenDefined[tag] = customElements.whenDefined(tag)
.then(() => this._configChanged(this.config));
}
} else if (!config.filter || !Array.isArray(config.filter)) {
error = 'No or incorrect filter.';
if (!config.filter || !Array.isArray(config.filter)) {
error = 'Incorrect filter config.';
} else if (!config.card) {
config.card = { type: 'entities' };
} else if (!config.card.type) {
config.card.type = 'entities';
}
if (error) {
tag = 'hui-error-card';
cardConfig = { error };
element = createCardElement(config, this.elementNotDefinedCallback, error);
} else {
cardConfig = this._computeCardConfig(config);
element = createCardElement(config.card, this.elementNotDefinedCallback, null);
element.config = this._computeCardConfig(config);
element.hass = this.hass;
}
const element = document.createElement(tag);
element.config = cardConfig;
element.hass = this.hass;
this.appendChild(element);
}
_hassChanged(hass) {
const element = this.lastChild;
if (element) {
element.hass = hass;
element.config = this._computeCardConfig(this.config);
}
if (!element || element.tagName === 'HUI-ERROR-CARD') return;
element.hass = hass;
element.config = this._computeCardConfig(this.config);
}
_computeCardConfig(config) {
return Object.assign(
{},
config.card_config,
config.card,
{ entities: this._getEntities(this.hass, config.filter) }
);
}
elementNotDefinedCallback(tag) {
if (!(tag in this._whenDefined)) {
this._whenDefined[tag] = customElements.whenDefined(tag)
.then(() => this._configChanged(this.config));
}
}
}
customElements.define('hui-entity-filter-card', HuiEntitiesCard);

View File

@ -9,23 +9,28 @@ class HuiErrorCard extends PolymerElement {
display: block;
background-color: red;
color: white;
text-align: center;
padding: 8px;
}
</style>
[[config.error]]
[[error]]
<pre>[[_toStr(config)]]</pre>
`;
}
static get properties() {
return {
config: Object
config: Object,
error: String
};
}
getCardSize() {
return 1;
}
_toStr(obj) {
return JSON.stringify(obj, null, 2);
}
}
customElements.define('hui-error-card', HuiErrorCard);

View File

@ -1,38 +0,0 @@
import '../cards/hui-camera-preview-card.js';
import '../cards/hui-entities-card.js';
import '../cards/hui-entity-filter-card.js';
import '../cards/hui-glance-card';
import '../cards/hui-history-graph-card.js';
import '../cards/hui-markdown-card.js';
import '../cards/hui-media-control-card.js';
import '../cards/hui-entity-picture-card.js';
import '../cards/hui-picture-glance-card';
import '../cards/hui-plant-status-card.js';
import '../cards/hui-weather-forecast-card';
import '../cards/hui-error-card.js';
import '../cards/hui-iframe-card.js';
const CARD_TYPES = [
'camera-preview',
'entities',
'entity-filter',
'entity-picture',
'glance',
'history-graph',
'iframe',
'markdown',
'media-control',
'picture-glance',
'plant-status',
'weather-forecast'
];
const CUSTOM_TYPE_PREFIX = 'custom:';
export default function computeCardElement(type) {
if (CARD_TYPES.includes(type)) {
return `hui-${type}-card`;
} else if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
return type.substr(CUSTOM_TYPE_PREFIX.length);
}
return null;
}

View File

@ -0,0 +1,61 @@
import '../cards/hui-camera-preview-card.js';
import '../cards/hui-entities-card.js';
import '../cards/hui-entity-filter-card.js';
import '../cards/hui-glance-card';
import '../cards/hui-history-graph-card.js';
import '../cards/hui-iframe-card.js';
import '../cards/hui-markdown-card.js';
import '../cards/hui-media-control-card.js';
import '../cards/hui-entity-picture-card.js';
import '../cards/hui-picture-glance-card';
import '../cards/hui-plant-status-card.js';
import '../cards/hui-weather-forecast-card';
import '../cards/hui-error-card.js';
const CARD_TYPES = [
'camera-preview',
'entities',
'entity-filter',
'entity-picture',
'glance',
'history-graph',
'iframe',
'markdown',
'media-control',
'picture-glance',
'plant-status',
'weather-forecast'
];
const CUSTOM_TYPE_PREFIX = 'custom:';
export default function
createCardElement(config, elementNotDefinedCallback = null, invalidConfig = null) {
let error = invalidConfig;
let tag;
if (!error && config && typeof config === 'object' && config.type) {
if (CARD_TYPES.includes(config.type)) {
tag = `hui-${config.type}-card`;
} else if (config.type.startsWith(CUSTOM_TYPE_PREFIX)) {
tag = config.type.substr(CUSTOM_TYPE_PREFIX.length);
}
if (tag) {
if (!customElements.get(tag)) {
error = 'Custom element doesn\'t exist.';
if (elementNotDefinedCallback) elementNotDefinedCallback(tag);
}
} else {
error = 'Unknown card type encountered.';
}
} else {
error = 'No card type configured.';
}
if (error) tag = 'hui-error-card';
const element = document.createElement(tag);
if (error) element.error = error;
element.config = config;
return element;
}

View File

@ -2,7 +2,7 @@ import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import applyThemesOnElement from '../../common/dom/apply_themes_on_element.js';
import computeCardElement from './common/compute-card-element.js';
import createCardElement from './common/create-card-element';
class HUIView extends PolymerElement {
static get template() {
@ -77,35 +77,14 @@ class HUIView extends PolymerElement {
super();
this._elements = [];
this._whenDefined = {};
this.elementNotDefinedCallback = this.elementNotDefinedCallback.bind(this);
}
_getElements(cards) {
const elements = [];
for (let i = 0; i < cards.length; i++) {
let error = null;
let cardConfig = cards[i];
let tag;
if (!cardConfig.type) {
error = 'Card type not configured.';
} else {
tag = computeCardElement(cardConfig.type);
if (tag === null) {
error = `Unknown card type encountered: "${cardConfig.type}".`;
} else if (!customElements.get(tag)) {
error = `Custom element doesn't exist: "${tag}".`;
if (!(tag in this._whenDefined)) {
this._whenDefined[tag] = customElements.whenDefined(tag)
.then(() => this._configChanged());
}
}
}
if (error) {
tag = 'hui-error-card';
cardConfig = { error };
}
const element = document.createElement(tag);
element.config = cardConfig;
const element = createCardElement(cards[i], this.elementNotDefinedCallback, null);
element.hass = this.hass;
elements.push(element);
}
@ -180,6 +159,13 @@ class HUIView extends PolymerElement {
this._elements[i].hass = hass;
}
}
elementNotDefinedCallback(tag) {
if (!(tag in this._whenDefined)) {
this._whenDefined[tag] = customElements.whenDefined(tag)
.then(() => this._configChanged());
}
}
}
customElements.define('hui-view', HUIView);