diff --git a/gallery/src/demos/demo-hui-entities-card.js b/gallery/src/demos/demo-hui-entities-card.js index f473b01bb9..44f38fa4f5 100644 --- a/gallery/src/demos/demo-hui-entities-card.js +++ b/gallery/src/demos/demo-hui-entities-card.js @@ -112,6 +112,17 @@ const CONFIGS = [ show_header_toggle: false ` }, + { + heading: 'Special rows', + config: ` +- type: entities + entities: + - type: weblink + url: http://google.com/ + icon: mdi:google + name: Google + ` + }, ]; class DemoEntities extends PolymerElement { diff --git a/src/components/entity/ha-entity-toggle.js b/src/components/entity/ha-entity-toggle.js index f79bdd3a17..0308999f98 100644 --- a/src/components/entity/ha-entity-toggle.js +++ b/src/components/entity/ha-entity-toggle.js @@ -4,7 +4,7 @@ import { html } from '@polymer/polymer/lib/utils/html-tag.js'; import { PolymerElement } from '@polymer/polymer/polymer-element.js'; import { STATES_OFF } from '../../common/const.js'; -import computeStateDomain from '../../common/entity/compute_state_domain'; +import computeStateDomain from '../../common/entity/compute_state_domain.js'; class HaEntityToggle extends PolymerElement { static get template() { diff --git a/src/panels/lovelace/cards/hui-entities-card.js b/src/panels/lovelace/cards/hui-entities-card.js index e7a1952370..38cd7af859 100644 --- a/src/panels/lovelace/cards/hui-entities-card.js +++ b/src/panels/lovelace/cards/hui-entities-card.js @@ -5,8 +5,7 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js'; import '../../../components/ha-card.js'; import '../components/hui-entities-toggle.js'; -import createEntityRowElement from '../common/create-entity-row-element.js'; -import processConfigEntities from '../common/process-config-entities.js'; +import createRowElement from '../common/create-row-element.js'; import computeDomain from '../../../common/entity/compute_domain.js'; import { DOMAINS_HIDE_MORE_INFO } from '../../../common/const.js'; @@ -101,13 +100,12 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) { setConfig(config) { this._config = config; - this._configEntities = processConfigEntities(config.entities); + this._rows = config.entities.map(item => (typeof item === 'string' ? { entity: item } : item)); if (this.$) this._buildConfig(); } _buildConfig() { const root = this.$.states; - const entities = this._configEntities; while (root.lastChild) { root.removeChild(root.lastChild); @@ -115,9 +113,9 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) { this._elements = []; - for (const entity of entities) { - const entityId = entity.entity; - const element = createEntityRowElement(entity); + for (const row of this._rows) { + const entityId = row.entity; + const element = createRowElement(row); if (entityId && !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityId))) { element.classList.add('state-card-dialog'); element.addEventListener('click', () => this.fire('hass-more-info', { entityId })); diff --git a/src/panels/lovelace/cards/hui-picture-entity-card.js b/src/panels/lovelace/cards/hui-picture-entity-card.js index aabcfc7fca..f6d23fc1ba 100644 --- a/src/panels/lovelace/cards/hui-picture-entity-card.js +++ b/src/panels/lovelace/cards/hui-picture-entity-card.js @@ -57,7 +57,7 @@ class HuiPictureEntityCard extends EventsMixin(LocalizeMixin(PolymerElement)) { hass="[[hass]]" image="[[_config.image]]" state-image="[[_config.state_image]]" - camera-image="[[_getCameraImage(_config)]]" + camera-image="[[_getCameraImage(_config)]]" entity="[[_config.entity]]" >
@@ -148,19 +148,15 @@ class HuiPictureEntityCard extends EventsMixin(LocalizeMixin(PolymerElement)) { } _cardClicked() { - const entityId = this._config && this._config.entity; + const config = this._config; + const entityId = config.entity; - if (!entityId || !(entityId in this.hass.states)) return; + if (!(entityId in this.hass.states)) return; - if (this._config.tap_action !== 'toggle') { - this.fire('hass-more-info', { entityId }); - return; - } - - if (this._entityDomain === 'weblink') { - window.open(this.hass.states[entityId].state); - } else { + if (config.tap_action === 'toggle') { toggleEntity(this.hass, entityId); + } else { + this.fire('hass-more-info', { entityId }); } } diff --git a/src/panels/lovelace/common/compute-unused-entities.js b/src/panels/lovelace/common/compute-unused-entities.js index ceb0b0782c..86a27ed90b 100644 --- a/src/panels/lovelace/common/compute-unused-entities.js +++ b/src/panels/lovelace/common/compute-unused-entities.js @@ -1,5 +1,4 @@ const EXCLUDED_DOMAINS = [ - 'group', 'zone' ]; @@ -7,7 +6,11 @@ function computeUsedEntities(config) { const entities = new Set(); function addEntityId(entity) { - entities.add(typeof entity === 'string' ? entity : entity.entity); + if (typeof entity === 'string') { + entities.add(entity); + } else if (entity.entity) { + entities.add(entity.entity); + } } function addEntities(obj) { diff --git a/src/panels/lovelace/common/create-entity-row-element.js b/src/panels/lovelace/common/create-row-element.js similarity index 87% rename from src/panels/lovelace/common/create-entity-row-element.js rename to src/panels/lovelace/common/create-row-element.js index 1f31090a79..1621edaa5a 100644 --- a/src/panels/lovelace/common/create-entity-row-element.js +++ b/src/panels/lovelace/common/create-row-element.js @@ -11,9 +11,14 @@ import '../entity-rows/hui-text-entity-row.js'; import '../entity-rows/hui-timer-entity-row.js'; import '../entity-rows/hui-toggle-entity-row.js'; +import '../special-rows/hui-weblink-row.js'; + import createErrorCardConfig from './create-error-card-config.js'; const CUSTOM_TYPE_PREFIX = 'custom:'; +const SPECIAL_TYPES = new Set([ + 'weblink' +]); const DOMAIN_TO_ELEMENT_TYPE = { automation: 'toggle', cover: 'cover', @@ -50,14 +55,18 @@ function _createErrorElement(error, config) { return _createElement('hui-error-card', createErrorCardConfig(error, config)); } -export default function createEntityRowElement(config) { +export default function createRowElement(config) { let tag; - if (!config || typeof config !== 'object' || !config.entity) { + 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); diff --git a/src/panels/lovelace/common/process-config-entities.js b/src/panels/lovelace/common/process-config-entities.js index c1036b8fd4..ae3e15a743 100644 --- a/src/panels/lovelace/common/process-config-entities.js +++ b/src/panels/lovelace/common/process-config-entities.js @@ -7,6 +7,10 @@ export default function processConfigEntities(entities) { } return entities.map((entityConf, index) => { + if (typeof entityConf === 'object' && !Array.isArray(entityConf) && entityConf.type) { + return entityConf; + } + if (typeof entityConf === 'string') { entityConf = { entity: entityConf }; } else if (typeof entityConf === 'object' && !Array.isArray(entityConf)) { diff --git a/src/panels/lovelace/special-rows/hui-weblink-row.js b/src/panels/lovelace/special-rows/hui-weblink-row.js new file mode 100644 index 0000000000..76a62822d5 --- /dev/null +++ b/src/panels/lovelace/special-rows/hui-weblink-row.js @@ -0,0 +1,40 @@ +import { html } from '@polymer/polymer/lib/utils/html-tag.js'; +import { PolymerElement } from '@polymer/polymer/polymer-element.js'; + +import '../../../components/ha-icon.js'; + +class HuiWeblinkRow extends PolymerElement { + static get template() { + return html` + + + [[_config.name]] + + `; + } + + static get properties() { + return { + _config: Object + }; + } + + setConfig(config) { + if (!config || !config.icon || !config.name || !config.url) { + throw new Error('Error in card configuration.'); + } + this._config = config; + } +} +customElements.define('hui-weblink-row', HuiWeblinkRow);