mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +00:00
Lovelace: Add picture-glance card (#1309)
* Lovelace: Add glance-toggle card * Update * Option to force dialog * Fix box height * Rename const * Change name, separate sensors * Lint * Lint
This commit is contained in:
parent
63b123fc8f
commit
f8b38ced26
@ -60,6 +60,14 @@ export const DOMAINS_MORE_INFO_NO_HISTORY = [
|
||||
'scene',
|
||||
];
|
||||
|
||||
/** States that we consider "on". */
|
||||
export const STATES_ON = [
|
||||
'home',
|
||||
'locked',
|
||||
'on',
|
||||
'open',
|
||||
];
|
||||
|
||||
/** States that we consider "off". */
|
||||
export const STATES_OFF = [
|
||||
'closed',
|
||||
|
188
src/panels/lovelace/hui-picture-glance-card.js
Normal file
188
src/panels/lovelace/hui-picture-glance-card.js
Normal file
@ -0,0 +1,188 @@
|
||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||
|
||||
import '../../components/ha-card.js';
|
||||
|
||||
import { STATES_ON } from '../../common/const.js';
|
||||
import computeDomain from '../../common/entity/compute_domain.js';
|
||||
import computeStateDisplay from '../../common/entity/compute_state_display.js';
|
||||
import computeStateName from '../../common/entity/compute_state_name.js';
|
||||
import stateIcon from '../../common/entity/state_icon.js';
|
||||
|
||||
import EventsMixin from '../../mixins/events-mixin.js';
|
||||
import LocalizeMixin from '../../mixins/localize-mixin.js';
|
||||
|
||||
const DOMAINS_FORCE_DIALOG = ['binary_sensor', 'device_tracker', 'sensor'];
|
||||
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
class HuiPictureGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
ha-card {
|
||||
position: relative;
|
||||
min-height: 48px;
|
||||
line-height: 0;
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.box {
|
||||
@apply --paper-font-common-nowrap;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
padding: 4px 16px;
|
||||
font-size: 16px;
|
||||
line-height: 40px;
|
||||
color: white;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.box .title {
|
||||
font-weight: 500;
|
||||
}
|
||||
paper-icon-button, iron-icon {
|
||||
color: #A9A9A9;
|
||||
}
|
||||
paper-icon-button.state-on, iron-icon.state-on {
|
||||
color: white;
|
||||
}
|
||||
iron-icon {
|
||||
padding: 8px;
|
||||
}
|
||||
.error {
|
||||
background-color: red;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-card>
|
||||
<img src="[[config.image]]">
|
||||
<div class="box">
|
||||
<div class="title">[[config.title]]</div>
|
||||
<div>
|
||||
<template is="dom-repeat" items="[[_entitiesDialog]]">
|
||||
<template is="dom-if" if="[[_showEntity(item, hass.states)]]">
|
||||
<paper-icon-button
|
||||
on-click="_openDialog"
|
||||
class$="[[_computeClass(item, hass.states)]]"
|
||||
icon="[[_computeIcon(item, hass.states)]]"
|
||||
title="[[_computeTooltip(item, hass.states)]]"
|
||||
></paper-icon-button>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<template is="dom-repeat" items="[[_entitiesService]]">
|
||||
<template is="dom-if" if="[[_showEntity(item, hass.states)]]">
|
||||
<paper-icon-button
|
||||
on-click="_callService"
|
||||
class$="[[_computeClass(item, hass.states)]]"
|
||||
icon="[[_computeIcon(item, hass.states)]]"
|
||||
title="[[_computeTooltip(item, hass.states)]]"
|
||||
></paper-icon-button>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<template is="dom-if" if="[[_error]]">
|
||||
<div class="error">[[_error]]</div>
|
||||
</template>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
config: {
|
||||
type: Object,
|
||||
observer: '_configChanged'
|
||||
},
|
||||
_entitiesDialog: Array,
|
||||
_entitiesService: Array,
|
||||
_error: String
|
||||
};
|
||||
}
|
||||
|
||||
getCardSize() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
_configChanged(config) {
|
||||
let dialog = [];
|
||||
let service = [];
|
||||
let _error = null;
|
||||
if (config && config.entities && Array.isArray(config.entities) && config.image) {
|
||||
if (config.force_dialog) {
|
||||
dialog = config.entities;
|
||||
} else {
|
||||
dialog = config.entities
|
||||
.filter(entity => DOMAINS_FORCE_DIALOG.includes(computeDomain(entity)));
|
||||
service = config.entities.filter(entity => !dialog.includes(entity));
|
||||
}
|
||||
} else {
|
||||
_error = 'Error in card configuration.';
|
||||
}
|
||||
this.setProperties({
|
||||
_entitiesDialog: dialog,
|
||||
_entitiesService: service,
|
||||
_error
|
||||
});
|
||||
}
|
||||
|
||||
_showEntity(entityId, states) {
|
||||
return entityId in states;
|
||||
}
|
||||
|
||||
_computeIcon(entityId, states) {
|
||||
return stateIcon(states[entityId]);
|
||||
}
|
||||
|
||||
_computeClass(entityId, states) {
|
||||
return STATES_ON.includes(states[entityId].state) ? 'state-on' : '';
|
||||
}
|
||||
|
||||
_computeTooltip(entityId, states) {
|
||||
return `${computeStateName(states[entityId])}: ${computeStateDisplay(this.localize, states[entityId])}`;
|
||||
}
|
||||
|
||||
_openDialog(ev) {
|
||||
this.fire('hass-more-info', { entityId: ev.model.item });
|
||||
}
|
||||
|
||||
_callService(ev) {
|
||||
const entityId = ev.model.item;
|
||||
const domain = computeDomain(entityId);
|
||||
const isOn = STATES_ON.includes(this.hass.states[entityId].state);
|
||||
let service;
|
||||
switch (domain) {
|
||||
case 'lock':
|
||||
service = isOn ? 'unlock' : 'lock';
|
||||
break;
|
||||
case 'cover':
|
||||
service = isOn ? 'close' : 'open';
|
||||
break;
|
||||
case 'scene':
|
||||
service = 'turn_on';
|
||||
break;
|
||||
default:
|
||||
service = isOn ? 'turn_off' : 'turn_on';
|
||||
}
|
||||
this.hass.callService(domain, service, { entity_id: entityId });
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('hui-picture-glance-card', HuiPictureGlanceCard);
|
@ -7,6 +7,7 @@ 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 './hui-error-card.js';
|
||||
@ -20,6 +21,7 @@ const VALID_TYPES = [
|
||||
'glance',
|
||||
'history-graph',
|
||||
'media-control',
|
||||
'picture-glance',
|
||||
'plant-status',
|
||||
'weather-forecast'
|
||||
];
|
||||
|
Loading…
x
Reference in New Issue
Block a user