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);