Add conditional card for Lovelace (#1524)

* Add conditional card for Lovelace

* Make it work

* Fix cardSize

* Lint

* Check if visible in cardSize

* Fix

* Add demo, remove visible in cardSize

* Check if undefined
This commit is contained in:
c727 2018-07-27 08:37:09 +02:00 committed by Paulus Schoutsen
parent be7fb50f8c
commit 7ca7d3e12c
3 changed files with 167 additions and 3 deletions

View File

@ -0,0 +1,84 @@
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import getEntity from '../data/entity.js';
import provideHass from '../data/provide_hass.js';
import '../components/demo-cards.js';
const ENTITIES = [
getEntity('light', 'controller_1', 'on', {
friendly_name: 'Controller 1'
}),
getEntity('light', 'controller_2', 'on', {
friendly_name: 'Controller 2'
}),
getEntity('light', 'floor', 'off', {
friendly_name: 'Floor light'
}),
getEntity('light', 'kitchen', 'on', {
friendly_name: 'Kitchen light'
}),
];
const CONFIGS = [
{
heading: 'Controller',
config: `
- type: entities
entities:
- light.controller_1
- light.controller_2
- type: divider
- light.floor
- light.kitchen
`
},
{
heading: 'Demo',
config: `
- type: conditional
conditions:
- entity: light.controller_1
state: "on"
- entity: light.controller_2
state_not: "off"
card:
type: entities
entities:
- light.controller_1
- light.controller_2
- light.floor
- light.kitchen
`
},
];
class DemoConditional extends PolymerElement {
static get template() {
return html`
<demo-cards
id='demos'
hass='[[hass]]'
configs="[[_configs]]"
></demo-cards>
`;
}
static get properties() {
return {
_configs: {
type: Object,
value: CONFIGS
},
hass: Object,
};
}
ready() {
super.ready();
const hass = provideHass(this.$.demos);
hass.addEntities(ENTITIES);
}
}
customElements.define('demo-hui-conditional-card', DemoConditional);

View File

@ -0,0 +1,78 @@
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import computeCardSize from '../common/compute-card-size.js';
import createCardElement from '../common/create-card-element.js';
class HuiConditionalCard extends PolymerElement {
static get template() {
return html`
<style>
.hidden {
display: none;
}
</style>
<div id="card"></div>
`;
}
static get properties() {
return {
hass: {
type: Object,
observer: '_hassChanged',
},
_config: Object
};
}
ready() {
super.ready();
if (this._config) this._buildConfig();
}
setConfig(config) {
if (!config || !config.card || !Array.isArray(config.conditions) ||
!config.conditions.every(c => c.entity && (c.state || c.state_not))) {
throw new Error('Error in card configuration.');
}
this._config = config;
if (this.$) this._buildConfig();
}
_buildConfig() {
const config = this._config;
const root = this.$.card;
while (root.lastChild) {
root.removeChild(root.lastChild);
}
const element = createCardElement(config.card);
element.hass = this.hass;
root.appendChild(element);
}
getCardSize() {
const el = this.$.card && this.$.card.lastChild;
return el ? computeCardSize(el) : 1;
}
_hassChanged(hass) {
const root = this.$.card;
if (!root || !root.lastChild) return;
root.lastChild.hass = hass;
const conditions = this._config.conditions;
const visible = conditions.every((c) => {
if (c.entity in hass.states) {
if (c.state) return hass.states[c.entity].state === c.state;
return hass.states[c.entity].state !== c.state_not;
}
return false;
});
root.classList.toggle('hidden', !visible);
}
}
customElements.define('hui-conditional-card', HuiConditionalCard);

View File

@ -1,5 +1,6 @@
import fireEvent from '../../../common/dom/fire_event.js';
import '../cards/hui-conditional-card.js';
import '../cards/hui-entities-card.js';
import '../cards/hui-entity-filter-card.js';
import '../cards/hui-error-card.js';
@ -20,7 +21,8 @@ import '../cards/hui-weather-forecast-card';
import createErrorCardConfig from './create-error-card-config.js';
const CARD_TYPES = [
const CARD_TYPES = new Set([
'conditional',
'entities',
'entity-filter',
'error',
@ -38,7 +40,7 @@ const CARD_TYPES = [
'plant-status',
'vertical-stack',
'weather-forecast'
];
]);
const CUSTOM_TYPE_PREFIX = 'custom:';
@ -81,7 +83,7 @@ export default function createCardElement(config) {
return element;
}
if (!CARD_TYPES.includes(config.type)) {
if (!CARD_TYPES.has(config.type)) {
return _createErrorElement(`Unknown card type encountered: ${config.type}.`, config);
}