mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 03:06:41 +00:00
Entities card: special row types, weblink (#1493)
* Add special row-cards: weblink * Fix binding * Fix yaml * Lint * Feedback * Fix build * Lint * Lint
This commit is contained in:
parent
af4df647cc
commit
44ab96d590
@ -112,6 +112,17 @@ const CONFIGS = [
|
|||||||
show_header_toggle: false
|
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 {
|
class DemoEntities extends PolymerElement {
|
||||||
|
@ -4,7 +4,7 @@ import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
|||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
import { STATES_OFF } from '../../common/const.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 {
|
class HaEntityToggle extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
|
@ -5,8 +5,7 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|||||||
import '../../../components/ha-card.js';
|
import '../../../components/ha-card.js';
|
||||||
import '../components/hui-entities-toggle.js';
|
import '../components/hui-entities-toggle.js';
|
||||||
|
|
||||||
import createEntityRowElement from '../common/create-entity-row-element.js';
|
import createRowElement from '../common/create-row-element.js';
|
||||||
import processConfigEntities from '../common/process-config-entities.js';
|
|
||||||
import computeDomain from '../../../common/entity/compute_domain.js';
|
import computeDomain from '../../../common/entity/compute_domain.js';
|
||||||
import { DOMAINS_HIDE_MORE_INFO } from '../../../common/const.js';
|
import { DOMAINS_HIDE_MORE_INFO } from '../../../common/const.js';
|
||||||
|
|
||||||
@ -101,13 +100,12 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
setConfig(config) {
|
setConfig(config) {
|
||||||
this._config = 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();
|
if (this.$) this._buildConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildConfig() {
|
_buildConfig() {
|
||||||
const root = this.$.states;
|
const root = this.$.states;
|
||||||
const entities = this._configEntities;
|
|
||||||
|
|
||||||
while (root.lastChild) {
|
while (root.lastChild) {
|
||||||
root.removeChild(root.lastChild);
|
root.removeChild(root.lastChild);
|
||||||
@ -115,9 +113,9 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
this._elements = [];
|
this._elements = [];
|
||||||
|
|
||||||
for (const entity of entities) {
|
for (const row of this._rows) {
|
||||||
const entityId = entity.entity;
|
const entityId = row.entity;
|
||||||
const element = createEntityRowElement(entity);
|
const element = createRowElement(row);
|
||||||
if (entityId && !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityId))) {
|
if (entityId && !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityId))) {
|
||||||
element.classList.add('state-card-dialog');
|
element.classList.add('state-card-dialog');
|
||||||
element.addEventListener('click', () => this.fire('hass-more-info', { entityId }));
|
element.addEventListener('click', () => this.fire('hass-more-info', { entityId }));
|
||||||
|
@ -148,19 +148,15 @@ class HuiPictureEntityCard extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cardClicked() {
|
_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') {
|
if (config.tap_action === 'toggle') {
|
||||||
this.fire('hass-more-info', { entityId });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._entityDomain === 'weblink') {
|
|
||||||
window.open(this.hass.states[entityId].state);
|
|
||||||
} else {
|
|
||||||
toggleEntity(this.hass, entityId);
|
toggleEntity(this.hass, entityId);
|
||||||
|
} else {
|
||||||
|
this.fire('hass-more-info', { entityId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
const EXCLUDED_DOMAINS = [
|
const EXCLUDED_DOMAINS = [
|
||||||
'group',
|
|
||||||
'zone'
|
'zone'
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -7,7 +6,11 @@ function computeUsedEntities(config) {
|
|||||||
const entities = new Set();
|
const entities = new Set();
|
||||||
|
|
||||||
function addEntityId(entity) {
|
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) {
|
function addEntities(obj) {
|
||||||
|
@ -11,9 +11,14 @@ import '../entity-rows/hui-text-entity-row.js';
|
|||||||
import '../entity-rows/hui-timer-entity-row.js';
|
import '../entity-rows/hui-timer-entity-row.js';
|
||||||
import '../entity-rows/hui-toggle-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';
|
import createErrorCardConfig from './create-error-card-config.js';
|
||||||
|
|
||||||
const CUSTOM_TYPE_PREFIX = 'custom:';
|
const CUSTOM_TYPE_PREFIX = 'custom:';
|
||||||
|
const SPECIAL_TYPES = new Set([
|
||||||
|
'weblink'
|
||||||
|
]);
|
||||||
const DOMAIN_TO_ELEMENT_TYPE = {
|
const DOMAIN_TO_ELEMENT_TYPE = {
|
||||||
automation: 'toggle',
|
automation: 'toggle',
|
||||||
cover: 'cover',
|
cover: 'cover',
|
||||||
@ -50,14 +55,18 @@ function _createErrorElement(error, config) {
|
|||||||
return _createElement('hui-error-card', createErrorCardConfig(error, config));
|
return _createElement('hui-error-card', createErrorCardConfig(error, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function createEntityRowElement(config) {
|
export default function createRowElement(config) {
|
||||||
let tag;
|
let tag;
|
||||||
|
|
||||||
if (!config || typeof config !== 'object' || !config.entity) {
|
if (!config || typeof config !== 'object' || (!config.entity && !config.type)) {
|
||||||
return _createErrorElement('Invalid config given.', config);
|
return _createErrorElement('Invalid config given.', config);
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = config.type || 'default';
|
const type = config.type || 'default';
|
||||||
|
if (SPECIAL_TYPES.has(type)) {
|
||||||
|
return _createElement(`hui-${type}-row`, config);
|
||||||
|
}
|
||||||
|
|
||||||
if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
||||||
tag = type.substr(CUSTOM_TYPE_PREFIX.length);
|
tag = type.substr(CUSTOM_TYPE_PREFIX.length);
|
||||||
|
|
@ -7,6 +7,10 @@ export default function processConfigEntities(entities) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return entities.map((entityConf, index) => {
|
return entities.map((entityConf, index) => {
|
||||||
|
if (typeof entityConf === 'object' && !Array.isArray(entityConf) && entityConf.type) {
|
||||||
|
return entityConf;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof entityConf === 'string') {
|
if (typeof entityConf === 'string') {
|
||||||
entityConf = { entity: entityConf };
|
entityConf = { entity: entityConf };
|
||||||
} else if (typeof entityConf === 'object' && !Array.isArray(entityConf)) {
|
} else if (typeof entityConf === 'object' && !Array.isArray(entityConf)) {
|
||||||
|
40
src/panels/lovelace/special-rows/hui-weblink-row.js
Normal file
40
src/panels/lovelace/special-rows/hui-weblink-row.js
Normal file
@ -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`
|
||||||
|
<style>
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
ha-icon {
|
||||||
|
padding: 8px;
|
||||||
|
margin-right: 16px;
|
||||||
|
color: var(--paper-item-icon-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<a href="[[_config.url]]">
|
||||||
|
<ha-icon icon="[[_config.icon]]"></ha-icon>[[_config.name]]
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
Loading…
x
Reference in New Issue
Block a user