Add lovelace template extension points (#1653)

This commit is contained in:
cdce8p 2018-09-10 23:15:29 +02:00 committed by Paulus Schoutsen
parent 8505750958
commit 76161329b6
15 changed files with 323 additions and 179 deletions

View File

@ -9,6 +9,24 @@ import computeStateName from '../../../common/entity/compute_state_name.js';
class HuiGenericEntityRow extends PolymerElement {
static get template() {
return html`
${this.styleTemplate}
<template is="dom-if" if="[[_stateObj]]">
${this.stateBadgeTemplate}
<div class="flex">
${this.infoTemplate}
<slot></slot>
</div>
</template>
<template is="dom-if" if="[[!_stateObj]]">
<div class="not-found">
Entity not available: [[config.entity]]
</div>
</template>
`;
}
static get styleTemplate() {
return html`
<style>
:host {
@ -50,36 +68,36 @@ class HuiGenericEntityRow extends PolymerElement {
flex: 0 0 40px;
}
</style>
<template is="dom-if" if="[[_stateObj]]">
<state-badge
state-obj="[[_stateObj]]"
override-icon="[[config.icon]]"
></state-badge>
<div class="flex">
<div class="info">
[[_computeName(config.name, _stateObj)]]
<template is="dom-if" if="[[config.secondary_info]]">
<template is="dom-if" if="[[_equals(config.secondary_info, 'entity-id')]]">
<div class="secondary">
[[_stateObj.entity_id]]
</div>
</template>
<template is="dom-if" if="[[_equals(config.secondary_info, 'last-changed')]]">
<ha-relative-time
hass="[[hass]]"
datetime="[[_stateObj.last_changed]]"
></ha-relative-time>
</template>
</template>
</div>
<slot></slot>
</div>
</template>
<template is="dom-if" if="[[!_stateObj]]">
<div class="not-found">
Entity not available: [[config.entity]]
</div>
</template>
`;
}
static get stateBadgeTemplate() {
return html`
<state-badge
state-obj="[[_stateObj]]"
override-icon="[[config.icon]]"
></state-badge>
`;
}
static get infoTemplate() {
return html`
<div class="info">
[[_computeName(config.name, _stateObj)]]
<template is="dom-if" if="[[config.secondary_info]]">
<template is="dom-if" if="[[_equals(config.secondary_info, 'entity-id')]]">
<div class="secondary">
[[_stateObj.entity_id]]
</div>
</template>
<template is="dom-if" if="[[_equals(config.secondary_info, 'last-changed')]]">
<ha-relative-time
hass="[[hass]]"
datetime="[[_stateObj.last_changed]]"
></ha-relative-time>
</template>
</template>
</div>
`;
}

View File

@ -6,21 +6,33 @@ import '../components/hui-generic-entity-row.js';
class HuiClimateEntityRow extends PolymerElement {
static get template() {
return html`
${this.styleTemplate}
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
${this.climateControlTemplate}
</hui-generic-entity-row>
`;
}
static get styleTemplate() {
return html`
<style>
ha-climate-state {
text-align: right;
}
</style>
<hui-generic-entity-row
`;
}
static get climateControlTemplate() {
return html`
<ha-climate-state
hass="[[hass]]"
config="[[_config]]"
>
<ha-climate-state
hass="[[hass]]"
state-obj="[[_stateObj]]"
></ha-climate-state>
</hui-generic-entity-row>
state-obj="[[_stateObj]]"
></ha-climate-state>
`;
}

View File

@ -8,6 +8,18 @@ import CoverEntity from '../../../util/cover-model.js';
class HuiCoverEntityRow extends PolymerElement {
static get template() {
return html`
${this.styleTemplate}
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
${this.coverControlTemplate}
</hui-generic-entity-row>
`;
}
static get styleTemplate() {
return html`
<style>
ha-cover-controls,
@ -15,17 +27,17 @@ class HuiCoverEntityRow extends PolymerElement {
margin-right: -.57em;
}
</style>
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
<template is="dom-if" if="[[!_entityObj.isTiltOnly]]">
<ha-cover-controls hass="[[hass]]" state-obj="[[_stateObj]]"></ha-cover-controls>
</template>
<template is="dom-if" if="[[_entityObj.isTiltOnly]]">
<ha-cover-tilt-controls hass="[[hass]]" state-obj="[[_stateObj]]"></ha-cover-tilt-controls>
</template>
</hui-generic-entity-row>
`;
}
static get coverControlTemplate() {
return html`
<template is="dom-if" if="[[!_entityObj.isTiltOnly]]">
<ha-cover-controls hass="[[hass]]" state-obj="[[_stateObj]]"></ha-cover-controls>
</template>
<template is="dom-if" if="[[_entityObj.isTiltOnly]]">
<ha-cover-tilt-controls hass="[[hass]]" state-obj="[[_stateObj]]"></ha-cover-tilt-controls>
</template>
`;
}

View File

@ -18,21 +18,27 @@ class HuiGroupEntityRow extends LocalizeMixin(PolymerElement) {
hass="[[hass]]"
config="[[_config]]"
>
<template is="dom-if" if="[[_canToggle]]">
<ha-entity-toggle
hass="[[hass]]"
state-obj="[[_stateObj]]"
></ha-entity-toggle>
</template>
<template is="dom-if" if="[[!_canToggle]]">
<div>
[[_computeState(_stateObj)]]
</div>
</template>
${this.groupControlTemplate}
</hui-generic-entity-row>
`;
}
static get groupControlTemplate() {
return html`
<template is="dom-if" if="[[_canToggle]]">
<ha-entity-toggle
hass="[[hass]]"
state-obj="[[_stateObj]]"
></ha-entity-toggle>
</template>
<template is="dom-if" if="[[!_canToggle]]">
<div>
[[_computeState(_stateObj)]]
</div>
</template>
`;
}
static get properties() {
return {
hass: Object,

View File

@ -9,6 +9,19 @@ import '../components/hui-generic-entity-row.js';
class HuiInputNumberEntityRow extends mixinBehaviors([IronResizableBehavior], PolymerElement) {
static get template() {
return html`
${this.styleTemplate}
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
id="input_number_card"
>
${this.inputNumberControlTemplate}
</hui-generic-entity-row>
`;
}
static get styleTemplate() {
return html`
<style>
.flex {
@ -23,41 +36,40 @@ class HuiInputNumberEntityRow extends mixinBehaviors([IronResizableBehavior], Po
text-align: right;
}
</style>
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
id="input_number_card"
>
<div>
<template is="dom-if" if="[[_equals(_stateObj.attributes.mode, 'slider')]]">
<div class="flex">
<paper-slider
min="[[_min]]"
max="[[_max]]"
value="{{_value}}"
step="[[_step]]"
pin
on-change="_selectedValueChanged"
ignore-bar-touch
></paper-slider>
<span class="state">[[_value]] [[_stateObj.attributes.unit_of_measurement]]</span>
</div>
</template>
<template is="dom-if" if="[[_equals(_stateObj.attributes.mode, 'box')]]">
<paper-input
no-label-float
auto-validate
pattern="[0-9]+([\\.][0-9]+)?"
step="[[_step]]"
`;
}
static get inputNumberControlTemplate() {
return html`
<div>
<template is="dom-if" if="[[_equals(_stateObj.attributes.mode, 'slider')]]">
<div class="flex">
<paper-slider
min="[[_min]]"
max="[[_max]]"
value="{{_value}}"
type="number"
step="[[_step]]"
pin
on-change="_selectedValueChanged"
></paper-input>
</template>
</div>
</hui-generic-entity-row>
ignore-bar-touch
></paper-slider>
<span class="state">[[_value]] [[_stateObj.attributes.unit_of_measurement]]</span>
</div>
</template>
<template is="dom-if" if="[[_equals(_stateObj.attributes.mode, 'box')]]">
<paper-input
no-label-float
auto-validate
pattern="[0-9]+([\\.][0-9]+)?"
step="[[_step]]"
min="[[_min]]"
max="[[_max]]"
value="{{_value}}"
type="number"
on-change="_selectedValueChanged"
></paper-input>
</template>
</div>
`;
}

View File

@ -16,21 +16,7 @@ import EventsMixin from '../../../mixins/events-mixin.js';
class HuiInputSelectEntityRow extends EventsMixin(PolymerElement) {
static get template() {
return html`
<style>
:host {
display: flex;
align-items: center;
}
paper-dropdown-menu {
margin-left: 16px;
flex: 1;
}
.not-found {
flex: 1;
background-color: yellow;
padding: 8px;
}
</style>
${this.styleTemplate}
<template is="dom-if" if="[[_stateObj]]">
<state-badge state-obj="[[_stateObj]]"></state-badge>
<paper-dropdown-menu on-click="_stopPropagation" selected-item-label="{{_selected}}" label="[[_computeName(_config.name, _stateObj)]]">
@ -49,6 +35,26 @@ class HuiInputSelectEntityRow extends EventsMixin(PolymerElement) {
`;
}
static get styleTemplate() {
return html`
<style>
:host {
display: flex;
align-items: center;
}
paper-dropdown-menu {
margin-left: 16px;
flex: 1;
}
.not-found {
flex: 1;
background-color: yellow;
padding: 8px;
}
</style>
`;
}
static get properties() {
return {
hass: Object,

View File

@ -11,21 +11,27 @@ class HuiInputTextEntityRow extends PolymerElement {
hass="[[hass]]"
config="[[_config]]"
>
<paper-input
no-label-float
minlength="[[_stateObj.attributes.min]]"
maxlength="[[_stateObj.attributes.max]]"
value="{{_value}}"
auto-validate="[[_stateObj.attributes.pattern]]"
pattern="[[_stateObj.attributes.pattern]]"
type="[[_stateObj.attributes.mode]]"
on-change="_selectedValueChanged"
placeholder="(empty value)"
></paper-input>
${this.inputTextControlTemplate}
</hui-generic-entity-row>
`;
}
static get inputTextControlTemplate() {
return html`
<paper-input
no-label-float
minlength="[[_stateObj.attributes.min]]"
maxlength="[[_stateObj.attributes.max]]"
value="{{_value}}"
auto-validate="[[_stateObj.attributes.pattern]]"
pattern="[[_stateObj.attributes.pattern]]"
type="[[_stateObj.attributes.mode]]"
on-change="_selectedValueChanged"
placeholder="(empty value)"
></paper-input>
`;
}
static get properties() {
return {
hass: Object,

View File

@ -11,6 +11,18 @@ import LocalizeMixin from '../../../mixins/localize-mixin.js';
*/
class HuiLockEntityRow extends LocalizeMixin(PolymerElement) {
static get template() {
return html`
${this.styleTemplate}
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
${this.lockControlTemplate}
</hui-generic-entity-row>
`;
}
static get styleTemplate() {
return html`
<style>
paper-button {
@ -19,14 +31,14 @@ class HuiLockEntityRow extends LocalizeMixin(PolymerElement) {
margin-right: -.57em;
}
</style>
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
<paper-button on-click="_callService">
[[_computeButtonTitle(_stateObj.state)]]
</paper-button>
</hui-generic-entity-row>
`;
}
static get lockControlTemplate() {
return html`
<paper-button on-click="_callService">
[[_computeButtonTitle(_stateObj.state)]]
</paper-button>
`;
}

View File

@ -11,6 +11,18 @@ import LocalizeMixin from '../../../mixins/localize-mixin.js';
*/
class HuiSceneEntityRow extends LocalizeMixin(PolymerElement) {
static get template() {
return html`
${this.styleTemplate}
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
${this.sceneControlTemplate}
</hui-generic-entity-row>
`;
}
static get styleTemplate() {
return html`
<style>
paper-button {
@ -19,14 +31,14 @@ class HuiSceneEntityRow extends LocalizeMixin(PolymerElement) {
margin-right: -.57em;
}
</style>
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
<paper-button on-click="_callService">
[[localize('ui.card.scene.activate')]]
</paper-button>
</hui-generic-entity-row>
`;
}
static get sceneControlTemplate() {
return html`
<paper-button on-click="_callService">
[[localize('ui.card.scene.activate')]]
</paper-button>
`;
}

View File

@ -12,6 +12,18 @@ import LocalizeMixin from '../../../mixins/localize-mixin.js';
*/
class HuiScriptEntityRow extends LocalizeMixin(PolymerElement) {
static get template() {
return html`
${this.styleTemplate}
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
${this.scriptControlTemplate}
</hui-generic-entity-row>
`;
}
static get styleTemplate() {
return html`
<style>
paper-button {
@ -20,17 +32,17 @@ class HuiScriptEntityRow extends LocalizeMixin(PolymerElement) {
margin-right: -.57em;
}
</style>
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
<template is="dom-if" if="[[_stateObj.attributes.can_cancel]]">
<ha-entity-toggle state-obj="[[_stateObj]]" hass="[[hass]]"></ha-entity-toggle>
</template>
<template is="dom-if" if="[[!_stateObj.attributes.can_cancel]]">
<paper-button on-click="_callService">[[localize('ui.card.script.execute')]]</paper-button>
</template>
</hui-generic-entity-row>
`;
}
static get scriptControlTemplate() {
return html`
<template is="dom-if" if="[[_stateObj.attributes.can_cancel]]">
<ha-entity-toggle state-obj="[[_stateObj]]" hass="[[hass]]"></ha-entity-toggle>
</template>
<template is="dom-if" if="[[!_stateObj.attributes.can_cancel]]">
<paper-button on-click="_callService">[[localize('ui.card.script.execute')]]</paper-button>
</template>
`;
}

View File

@ -12,20 +12,32 @@ import LocalizeMixin from '../../../mixins/localize-mixin.js';
*/
class HuiTextEntityRow extends LocalizeMixin(PolymerElement) {
static get template() {
return html`
${this.styleTemplate}
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
${this.textControlTemplate}
</hui-generic-entity-row>
`;
}
static get styleTemplate() {
return html`
<style>
div {
text-align: right;
}
</style>
<hui-generic-entity-row
hass="[[hass]]"
config="[[_config]]"
>
<div>
[[_computeState(_stateObj)]]
</div>
</hui-generic-entity-row>
`;
}
static get textControlTemplate() {
return html`
<div>
[[_computeState(_stateObj)]]
</div>
`;
}

View File

@ -13,13 +13,19 @@ class HuiTimerEntityRow extends PolymerElement {
hass="[[hass]]"
config="[[_config]]"
>
<div>
[[_computeDisplay(_stateObj, _timeRemaining)]]
</div>
${this.timerControlTemplate}
</hui-generic-entity-row>
`;
}
static get timerControlTemplate() {
return html`
<div>
[[_computeDisplay(_stateObj, _timeRemaining)]]
</div>
`;
}
static get properties() {
return {
hass: Object,

View File

@ -18,21 +18,27 @@ class HuiToggleEntityRow extends LocalizeMixin(PolymerElement) {
hass="[[hass]]"
config="[[_config]]"
>
<template is="dom-if" if="[[_canToggle]]">
<ha-entity-toggle
hass="[[hass]]"
state-obj="[[_stateObj]]"
></ha-entity-toggle>
</template>
<template is="dom-if" if="[[!_canToggle]]">
<div>
[[_computeState(_stateObj)]]
</div>
</template>
${this.toggleControlTemplate}
</hui-generic-entity-row>
`;
}
static get toggleControlTemplate() {
return html`
<template is="dom-if" if="[[_canToggle]]">
<ha-entity-toggle
hass="[[hass]]"
state-obj="[[_stateObj]]"
></ha-entity-toggle>
</template>
<template is="dom-if" if="[[!_canToggle]]">
<div>
[[_computeState(_stateObj)]]
</div>
</template>
`;
}
static get properties() {
return {
hass: Object,

View File

@ -7,6 +7,19 @@ import callService from '../common/call-service.js';
class HuiCallServiceRow extends PolymerElement {
static get template() {
return html`
${this.styleTemplate}
<ha-icon icon="[[_config.icon]]"></ha-icon>
<div class="flex">
<div>
[[_config.name]]
</div>
<paper-button on-click="_callService">[[_config.action_name]]</paper-button>
</div>
`;
}
static get styleTemplate() {
return html`
<style>
:host {
@ -36,13 +49,6 @@ class HuiCallServiceRow extends PolymerElement {
margin-right: -.57em;
}
</style>
<ha-icon icon="[[_config.icon]]"></ha-icon>
<div class="flex">
<div>
[[_config.name]]
</div>
<paper-button on-click="_callService">[[_config.action_name]]</paper-button>
</div>
`;
}

View File

@ -5,6 +5,18 @@ import '../../../components/ha-icon.js';
class HuiWeblinkRow extends PolymerElement {
static get template() {
return html`
${this.styleTemplate}
<a href="[[_config.url]]">
<ha-icon icon="[[_config.icon]]"></ha-icon>
<div>
[[_config.name]]
</div>
</a>
`;
}
static get styleTemplate() {
return html`
<style>
a {
@ -24,12 +36,6 @@ class HuiWeblinkRow extends PolymerElement {
margin-left: 16px;
}
</style>
<a href="[[_config.url]]">
<ha-icon icon="[[_config.icon]]"></ha-icon>
<div>
[[_config.name]]
</div>
</a>
`;
}