mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-26 02:36:37 +00:00
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:
parent
be7fb50f8c
commit
7ca7d3e12c
84
gallery/src/demos/demo-hui-conditional-card.js
Normal file
84
gallery/src/demos/demo-hui-conditional-card.js
Normal 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);
|
78
src/panels/lovelace/cards/hui-conditional-card.js
Normal file
78
src/panels/lovelace/cards/hui-conditional-card.js
Normal 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);
|
@ -1,5 +1,6 @@
|
|||||||
import fireEvent from '../../../common/dom/fire_event.js';
|
import fireEvent from '../../../common/dom/fire_event.js';
|
||||||
|
|
||||||
|
import '../cards/hui-conditional-card.js';
|
||||||
import '../cards/hui-entities-card.js';
|
import '../cards/hui-entities-card.js';
|
||||||
import '../cards/hui-entity-filter-card.js';
|
import '../cards/hui-entity-filter-card.js';
|
||||||
import '../cards/hui-error-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';
|
import createErrorCardConfig from './create-error-card-config.js';
|
||||||
|
|
||||||
const CARD_TYPES = [
|
const CARD_TYPES = new Set([
|
||||||
|
'conditional',
|
||||||
'entities',
|
'entities',
|
||||||
'entity-filter',
|
'entity-filter',
|
||||||
'error',
|
'error',
|
||||||
@ -38,7 +40,7 @@ const CARD_TYPES = [
|
|||||||
'plant-status',
|
'plant-status',
|
||||||
'vertical-stack',
|
'vertical-stack',
|
||||||
'weather-forecast'
|
'weather-forecast'
|
||||||
];
|
]);
|
||||||
|
|
||||||
const CUSTOM_TYPE_PREFIX = 'custom:';
|
const CUSTOM_TYPE_PREFIX = 'custom:';
|
||||||
|
|
||||||
@ -81,7 +83,7 @@ export default function createCardElement(config) {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CARD_TYPES.includes(config.type)) {
|
if (!CARD_TYPES.has(config.type)) {
|
||||||
return _createErrorElement(`Unknown card type encountered: ${config.type}.`, config);
|
return _createErrorElement(`Unknown card type encountered: ${config.type}.`, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user