mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Love: Pimp filter card (#1314)
* Love: Pimp filter card * Make it work * Update * getCardSize * Import elements * Lint * Lint * Remove this._cardSize
This commit is contained in:
parent
75502bac6e
commit
8cebddcccc
21
src/panels/lovelace/common/compute-card-element.js
Normal file
21
src/panels/lovelace/common/compute-card-element.js
Normal file
@ -0,0 +1,21 @@
|
||||
const CARD_TYPES = [
|
||||
'camera-preview',
|
||||
'entities',
|
||||
'entity-filter',
|
||||
'glance',
|
||||
'history-graph',
|
||||
'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;
|
||||
}
|
@ -1,55 +1,113 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
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 computeStateDomain from '../../common/entity/compute_state_domain.js';
|
||||
import computeCardElement from './common/compute-card-element.js';
|
||||
|
||||
class HuiEntitiesCard extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<hui-entities-card
|
||||
hass='[[hass]]'
|
||||
config='[[_computeCardConfig(hass, config)]]'
|
||||
></hui-entities-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
config: Object,
|
||||
hass: {
|
||||
type: Object,
|
||||
observer: '_hassChanged'
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
observer: '_configChanged'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getCardSize() {
|
||||
// +1 for the header
|
||||
return 1 + this._getEntities(this.hass, this.config.filter).length;
|
||||
return this.lastChild ? this.lastChild.getCardSize() : 1;
|
||||
}
|
||||
|
||||
// Return a list of entities based on a filter.
|
||||
_getEntities(hass, filter) {
|
||||
const filters = [];
|
||||
// Return a list of entities based on filters.
|
||||
_getEntities(hass, filterList) {
|
||||
const entities = new Set();
|
||||
filterList.forEach((filter) => {
|
||||
const filters = [];
|
||||
if (filter.domain) {
|
||||
filters.push(stateObj => computeStateDomain(stateObj) === filter.domain);
|
||||
}
|
||||
if (filter.entity_id) {
|
||||
filters.push(stateObj => this._filterEntityId(stateObj, filter.entity_id));
|
||||
}
|
||||
if (filter.state) {
|
||||
filters.push(stateObj => stateObj.state === filter.state);
|
||||
}
|
||||
|
||||
if (filter.domain) {
|
||||
const domain = filter.domain;
|
||||
filters.push(stateObj => computeStateDomain(stateObj) === domain);
|
||||
}
|
||||
|
||||
if (filter.state) {
|
||||
const state = filter.state;
|
||||
filters.push(stateObj => stateObj.state === state);
|
||||
}
|
||||
|
||||
return Object.values(hass.states)
|
||||
.filter(stateObj => filters.every(filterFunc => filterFunc(stateObj)))
|
||||
.map(stateObj => stateObj.entity_id);
|
||||
}
|
||||
|
||||
_computeCardConfig(hass, config) {
|
||||
return Object.assign({}, config.card_config || {}, {
|
||||
entities: this._getEntities(hass, config.filter),
|
||||
Object.values(hass.states).forEach((stateObj) => {
|
||||
if (filters.every(filterFunc => filterFunc(stateObj))) {
|
||||
entities.add(stateObj.entity_id);
|
||||
}
|
||||
});
|
||||
});
|
||||
return Array.from(entities);
|
||||
}
|
||||
|
||||
_filterEntityId(stateObj, pattern) {
|
||||
if (pattern.indexOf('*') === -1) {
|
||||
return stateObj.entity_id === pattern;
|
||||
}
|
||||
const regEx = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`);
|
||||
return stateObj.entity_id.search(regEx) === 0;
|
||||
}
|
||||
|
||||
_configChanged(config) {
|
||||
if (this.lastChild) {
|
||||
this.removeChild(this.lastChild);
|
||||
}
|
||||
let error = null;
|
||||
let cardConfig;
|
||||
let tag = config.card ? computeCardElement(config.card) : 'hui-entities-card';
|
||||
|
||||
if (tag === null) {
|
||||
error = `Unknown card type encountered: "${config.card}".`;
|
||||
} else if (!customElements.get(tag)) {
|
||||
error = `Custom element doesn't exist: "${tag}".`;
|
||||
} else if (!config.filter || !Array.isArray(config.filter)) {
|
||||
error = 'No or incorrect filter.';
|
||||
}
|
||||
if (error) {
|
||||
tag = 'hui-error-card';
|
||||
cardConfig = { error };
|
||||
} else {
|
||||
cardConfig = this._computeCardConfig(config);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
_computeCardConfig(config) {
|
||||
const cardConfig = Object.assign(
|
||||
{},
|
||||
config,
|
||||
{ entities: this._getEntities(this.hass, config.filter) }
|
||||
);
|
||||
delete cardConfig.card;
|
||||
delete cardConfig.filter;
|
||||
return cardConfig;
|
||||
}
|
||||
}
|
||||
customElements.define('hui-entity-filter-card', HuiEntitiesCard);
|
||||
|
@ -14,29 +14,7 @@ import './hui-weather-forecast-card';
|
||||
import './hui-error-card.js';
|
||||
|
||||
import applyThemesOnElement from '../../common/dom/apply_themes_on_element.js';
|
||||
|
||||
const VALID_TYPES = [
|
||||
'camera-preview',
|
||||
'entities',
|
||||
'entity-filter',
|
||||
'glance',
|
||||
'history-graph',
|
||||
'media-control',
|
||||
'picture',
|
||||
'picture-glance',
|
||||
'plant-status',
|
||||
'weather-forecast'
|
||||
];
|
||||
const CUSTOM_TYPE_PREFIX = 'custom:';
|
||||
|
||||
function cardElement(type) {
|
||||
if (VALID_TYPES.includes(type)) {
|
||||
return `hui-${type}-card`;
|
||||
} else if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
||||
return type.substr(CUSTOM_TYPE_PREFIX.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
import computeCardElement from './common/compute-card-element.js';
|
||||
|
||||
class HUIView extends PolymerElement {
|
||||
static get template() {
|
||||
@ -123,7 +101,7 @@ class HUIView extends PolymerElement {
|
||||
if (!cardConfig.type) {
|
||||
error = 'Card type not configured.';
|
||||
} else {
|
||||
tag = cardElement(cardConfig.type);
|
||||
tag = computeCardElement(cardConfig.type);
|
||||
if (tag === null) {
|
||||
error = `Unknown card type encountered: "${cardConfig.type}".`;
|
||||
} else if (!customElements.get(tag)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user