Convert card elements to ES6 classes (#465)

* Convert cards to ES6 classes

* Bonus bugfix debugging card functionality

* Properly scope UPDATE_INTERVAL

* Condense simple property declarations
This commit is contained in:
Adam Mills 2017-10-17 01:09:55 -04:00 committed by Paulus Schoutsen
parent de64c766f6
commit 9c0845d595
10 changed files with 236 additions and 261 deletions

View File

@ -1,4 +1,4 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel='import' href='../components/entity/ha-state-label-badge.html'> <link rel='import' href='../components/entity/ha-state-label-badge.html'>
@ -17,17 +17,14 @@
</dom-module> </dom-module>
<script> <script>
Polymer({ class HaBadgesCard extends Polymer.Element {
is: 'ha-badges-card', static get is() { return 'ha-badges-card'; }
static get properties() {
properties: { return {
hass: { hass: Object,
type: Object, states: Array,
}, };
}
states: { }
type: Array, customElements.define(HaBadgesCard.is, HaBadgesCard);
},
},
});
</script> </script>

View File

@ -1,6 +1,8 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel="import" href="../../bower_components/paper-material/paper-material.html"> <link rel="import" href="../../bower_components/paper-material/paper-material.html">
<link rel='import' href='../util/hass-mixins.html'>
<dom-module id='ha-camera-card'> <dom-module id='ha-camera-card'>
<template> <template>
<style include="paper-material"> <style include="paper-material">
@ -49,29 +51,23 @@
</dom-module> </dom-module>
<script> <script>
Polymer({ {
is: 'ha-camera-card', const UPDATE_INTERVAL = 10000; // ms
UPDATE_INTERVAL: 10000, // ms
properties: {
hass: {
type: Object,
},
class HaCameraCard extends window.hassMixins.EventsMixin(Polymer.Element) {
static get is() { return 'ha-camera-card'; }
static get properties() {
return {
hass: Object,
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'updateCameraFeedSrc', observer: 'updateCameraFeedSrc',
}, },
cameraFeedSrc: String,
cameraFeedSrc: {
type: String,
},
imageLoaded: { imageLoaded: {
type: Boolean, type: Boolean,
value: true, value: true,
}, },
/** /**
* The z-depth of the card, from 0-5. * The z-depth of the card, from 0-5.
*/ */
@ -80,45 +76,46 @@ Polymer({
value: 1, value: 1,
reflectToAttribute: true, reflectToAttribute: true,
}, },
}, };
}
listeners: { ready() {
tap: 'cardTapped', super.ready();
}, this.addEventListener('tap', () => this.cardTapped());
}
attached: function () { connectedCallback() {
this.timer = setInterval( super.connectedCallback();
function () { this.timer = setInterval(() => this.updateCameraFeedSrc(), UPDATE_INTERVAL);
this.updateCameraFeedSrc(this.stateObj); }
}.bind(this),
this.UPDATE_INTERVAL
);
},
detached: function () { disconnectedCallback() {
super.disconnectedCallback();
clearInterval(this.timer); clearInterval(this.timer);
}, }
cardTapped: function () { cardTapped() {
this.fire('hass-more-info', { entityId: this.stateObj.entity_id }); this.fire('hass-more-info', { entityId: this.stateObj.entity_id });
}, }
updateCameraFeedSrc: function (stateObj) { updateCameraFeedSrc() {
var attr = stateObj.attributes; var attr = this.stateObj.attributes;
var time = (new Date()).getTime(); var time = (new Date()).getTime();
this.cameraFeedSrc = attr.entity_picture + '&time=' + time; this.cameraFeedSrc = attr.entity_picture + '&time=' + time;
}, }
imageLoadSuccess: function () { imageLoadSuccess() {
this.imageLoaded = true; this.imageLoaded = true;
}, }
imageLoadFail: function () { imageLoadFail() {
this.imageLoaded = false; this.imageLoaded = false;
}, }
computeStateName: function (stateObj) { computeStateName(stateObj) {
return window.hassUtil.computeStateName(stateObj); return window.hassUtil.computeStateName(stateObj);
}, }
}); }
customElements.define(HaCameraCard.is, HaCameraCard);
}
</script> </script>

View File

@ -1,4 +1,4 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel='import' href='./ha-camera-card.html'> <link rel='import' href='./ha-camera-card.html'>
<link rel='import' href='./ha-entities-card.html'> <link rel='import' href='./ha-entities-card.html'>
@ -9,23 +9,25 @@
<link rel='import' href='./ha-persistent_notification-card.html'> <link rel='import' href='./ha-persistent_notification-card.html'>
<script> <script>
Polymer({ class HaCardChooser extends Polymer.Element {
is: 'ha-card-chooser', static get is() { return 'ha-card-chooser'; }
static get properties() {
properties: { return {
cardData: { cardData: {
type: Object, type: Object,
observer: 'cardDataChanged', observer: 'cardDataChanged',
}, },
}, };
}
cardDataChanged: function (newData) { cardDataChanged(newData) {
if (!newData) return; if (!newData) return;
window.hassUtil.dynamicContentUpdater( window.hassUtil.dynamicContentUpdater(
this, 'HA-' + newData.cardType.toUpperCase() + '-CARD', this, 'HA-' + newData.cardType.toUpperCase() + '-CARD',
newData newData
); );
}, }
}); }
customElements.define(HaCardChooser.is, HaCardChooser);
</script> </script>

View File

@ -1,10 +1,11 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel='import' href='../components/ha-card.html'> <link rel='import' href='../components/ha-card.html'>
<link rel='import' href='../components/entity/ha-entity-toggle.html'> <link rel='import' href='../components/entity/ha-entity-toggle.html'>
<link rel='import' href='../state-summary/state-card-content.html'> <link rel='import' href='../state-summary/state-card-content.html'>
<link rel='import' href='../util/hass-mixins.html'>
<dom-module id='ha-entities-card'> <dom-module id='ha-entities-card'>
<template> <template>
@ -64,30 +65,23 @@
</dom-module> </dom-module>
<script> <script>
Polymer({ class HaEntitiesCard extends window.hassMixins.EventsMixin(Polymer.Element) {
is: 'ha-entities-card', static get is() { return 'ha-entities-card'; }
static get properties() {
return {
hass: Object,
states: Array,
groupEntity: Object,
};
}
properties: { computeTitle(states, groupEntity) {
hass: {
type: Object,
},
states: {
type: Array,
},
groupEntity: {
type: Object,
},
},
computeTitle: function (states, groupEntity) {
return groupEntity ? return groupEntity ?
window.hassUtil.computeStateName(groupEntity) : window.hassUtil.computeStateName(groupEntity) :
window.hassUtil.computeDomain(states[0]).replace(/_/g, ' '); window.hassUtil.computeDomain(states[0]).replace(/_/g, ' ');
}, }
computeTitleClass: function (groupEntity) { computeTitleClass(groupEntity) {
var classes = 'header horizontal layout center '; var classes = 'header horizontal layout center ';
if (groupEntity) { if (groupEntity) {
classes += 'header-more-info'; classes += 'header-more-info';
@ -95,9 +89,9 @@ Polymer({
classes += 'domain'; classes += 'domain';
} }
return classes; return classes;
}, }
entityTapped: function (ev) { entityTapped(ev) {
var entityId; var entityId;
if (ev.target.nodeName === 'STATE-CARD-INPUT_TEXT' || if (ev.target.nodeName === 'STATE-CARD-INPUT_TEXT' ||
(!ev.model && !this.groupEntity)) { (!ev.model && !this.groupEntity)) {
@ -111,9 +105,9 @@ Polymer({
entityId = this.groupEntity.entity_id; entityId = this.groupEntity.entity_id;
} }
this.fire('hass-more-info', { entityId: entityId }); this.fire('hass-more-info', { entityId: entityId });
}, }
showGroupToggle: function (groupEntity, states) { showGroupToggle(groupEntity, states) {
if (!groupEntity || !states || groupEntity.attributes.control === 'hidden' || if (!groupEntity || !states || groupEntity.attributes.control === 'hidden' ||
(groupEntity.state !== 'on' && groupEntity.state !== 'off')) { (groupEntity.state !== 'on' && groupEntity.state !== 'off')) {
return false; return false;
@ -134,6 +128,7 @@ Polymer({
} }
return canToggleCount > 1; return canToggleCount > 1;
}, }
}); }
customElements.define(HaEntitiesCard.is, HaEntitiesCard);
</script> </script>

View File

@ -1,4 +1,4 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel='import' href='../components/ha-card.html'> <link rel='import' href='../components/ha-card.html'>
@ -67,18 +67,17 @@
</dom-module> </dom-module>
<script> <script>
Polymer({ class HaIntroductionCard extends Polymer.Element {
is: 'ha-introduction-card', static get is() { return 'ha-introduction-card'; }
static get properties() {
properties: { return {
hass: { hass: Object,
type: Object,
},
showHideInstruction: { showHideInstruction: {
type: Boolean, type: Boolean,
value: true, value: true,
}, },
}, };
}); }
}
customElements.define(HaIntroductionCard.is, HaIntroductionCard);
</script> </script>

View File

@ -1,4 +1,4 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
@ -7,6 +7,7 @@
<link rel='import' href='../../bower_components/paper-progress/paper-progress.html'> <link rel='import' href='../../bower_components/paper-progress/paper-progress.html'>
<link rel='import' href='../util/media-player-model.html'> <link rel='import' href='../util/media-player-model.html'>
<link rel='import' href='../util/hass-mixins.html'>
<dom-module id='ha-media_player-card'> <dom-module id='ha-media_player-card'>
<template> <template>
@ -205,33 +206,22 @@
</dom-module> </dom-module>
<script> <script>
Polymer({ class HaMediaPlayerCard extends window.hassMixins.EventsMixin(Polymer.Element) {
is: 'ha-media_player-card', static get is() { return 'ha-media_player-card'; }
static get properties() {
properties: { return {
hass: { hass: Object,
type: Object, stateObj: Object,
},
stateObj: {
type: Object,
},
playerObj: { playerObj: {
type: Object, type: Object,
computed: 'computePlayerObj(hass, stateObj)', computed: 'computePlayerObj(hass, stateObj)',
observer: 'playerObjChanged', observer: 'playerObjChanged',
}, },
playbackControlIcon: { playbackControlIcon: {
type: String, type: String,
computed: 'computePlaybackControlIcon(playerObj)', computed: 'computePlaybackControlIcon(playerObj)',
}, },
playbackPosition: Number,
playbackPosition: {
type: Number,
},
/** /**
* The z-depth of the card, from 0-5. * The z-depth of the card, from 0-5.
*/ */
@ -240,13 +230,10 @@ Polymer({
value: 1, value: 1,
reflectToAttribute: true, reflectToAttribute: true,
}, },
}, };
}
created: function () { playerObjChanged(playerObj) {
this.updatePlaybackPosition = this.updatePlaybackPosition.bind(this);
},
playerObjChanged: function (playerObj) {
var picture = playerObj.stateObj.attributes.entity_picture; var picture = playerObj.stateObj.attributes.entity_picture;
var dummy; var dummy;
if (picture) { if (picture) {
@ -281,7 +268,7 @@ Polymer({
if (playerObj.isPlaying && playerObj.showProgress) { if (playerObj.isPlaying && playerObj.showProgress) {
if (!this._positionTracking) { if (!this._positionTracking) {
this._positionTracking = setInterval(this.updatePlaybackPosition, 1000); this._positionTracking = setInterval(() => this.updatePlaybackPosition(), 1000);
} }
} else if (this._positionTracking) { } else if (this._positionTracking) {
clearInterval(this._positionTracking); clearInterval(this._positionTracking);
@ -290,13 +277,13 @@ Polymer({
if (playerObj.showProgress) { if (playerObj.showProgress) {
this.updatePlaybackPosition(); this.updatePlaybackPosition();
} }
}, }
updatePlaybackPosition: function () { updatePlaybackPosition() {
this.playbackPosition = this.playerObj.currentProgress; this.playbackPosition = this.playerObj.currentProgress;
}, }
computeBannerClasses: function (playerObj) { computeBannerClasses(playerObj) {
var cls = 'banner'; var cls = 'banner';
if (playerObj.isOff || playerObj.isIdle) { if (playerObj.isOff || playerObj.isIdle) {
@ -308,56 +295,57 @@ Polymer({
} }
return cls; return cls;
}, }
computeHideProgress: function (playerObj) { computeHideProgress(playerObj) {
return !playerObj.showProgress; return !playerObj.showProgress;
}, }
computeHidePowerButton: function (playerObj) { computeHidePowerButton(playerObj) {
return playerObj.isOff ? !playerObj.supportsTurnOn : !playerObj.supportsTurnOff; return playerObj.isOff ? !playerObj.supportsTurnOn : !playerObj.supportsTurnOff;
}, }
computePlayerObj: function (hass, stateObj) { computePlayerObj(hass, stateObj) {
return new window.MediaPlayerEntity(hass, stateObj); return new window.MediaPlayerEntity(hass, stateObj);
}, }
computePlaybackControlIcon: function (playerObj) { computePlaybackControlIcon(playerObj) {
if (playerObj.isPlaying) { if (playerObj.isPlaying) {
return playerObj.supportsPause ? 'mdi:pause' : 'mdi:stop'; return playerObj.supportsPause ? 'mdi:pause' : 'mdi:stop';
} else if (playerObj.isPaused || playerObj.isOff || playerObj.isIdle) { } else if (playerObj.isPaused || playerObj.isOff || playerObj.isIdle) {
return playerObj.supportsPlay ? 'mdi:play' : null; return playerObj.supportsPlay ? 'mdi:play' : null;
} }
return ''; return '';
}, }
computeStateName: function (stateObj) { computeStateName(stateObj) {
return window.hassUtil.computeStateName(stateObj); return window.hassUtil.computeStateName(stateObj);
}, }
handleNext: function (ev) { handleNext(ev) {
ev.stopPropagation(); ev.stopPropagation();
this.playerObj.nextTrack(); this.playerObj.nextTrack();
}, }
handleOpenMoreInfo: function (ev) { handleOpenMoreInfo(ev) {
ev.stopPropagation(); ev.stopPropagation();
this.fire('hass-more-info', { entityId: this.stateObj.entity_id }); this.fire('hass-more-info', { entityId: this.stateObj.entity_id });
}, }
handlePlaybackControl: function (ev) { handlePlaybackControl(ev) {
ev.stopPropagation(); ev.stopPropagation();
this.playerObj.mediaPlayPause(); this.playerObj.mediaPlayPause();
}, }
handlePrevious: function (ev) { handlePrevious(ev) {
ev.stopPropagation(); ev.stopPropagation();
this.playerObj.previousTrack(); this.playerObj.previousTrack();
}, }
handleTogglePower: function (ev) { handleTogglePower(ev) {
ev.stopPropagation(); ev.stopPropagation();
this.playerObj.togglePower(); this.playerObj.togglePower();
}, }
}); }
customElements.define(HaMediaPlayerCard.is, HaMediaPlayerCard);
</script> </script>

View File

@ -1,4 +1,4 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel='import' href='../../bower_components/paper-button/paper-button.html'> <link rel='import' href='../../bower_components/paper-button/paper-button.html'>
<link rel='import' href='../components/ha-card.html'> <link rel='import' href='../components/ha-card.html'>
@ -29,34 +29,31 @@
</dom-module> </dom-module>
<script> <script>
Polymer({ class HaPersistentNotificationCard extends Polymer.Element {
is: 'ha-persistent_notification-card', static get is() { return 'ha-persistent_notification-card'; }
static get properties() {
properties: { return {
hass: { hass: Object,
type: Object, stateObj: Object,
},
stateObj: {
type: Object,
},
scriptLoaded: { scriptLoaded: {
type: Boolean, type: Boolean,
value: false, value: false,
}, },
}, };
}
observers: [ static get observers() {
return [
'computeContent(stateObj, scriptLoaded)', 'computeContent(stateObj, scriptLoaded)',
], ];
}
computeTitle: function (stateObj) { computeTitle(stateObj) {
return (stateObj.attributes.title || return (stateObj.attributes.title ||
window.hassUtil.computeStateName(stateObj)); window.hassUtil.computeStateName(stateObj));
}, }
loadScript: function () { loadScript() {
var success = function () { var success = function () {
this.scriptLoaded = true; this.scriptLoaded = true;
}.bind(this); }.bind(this);
@ -71,9 +68,9 @@ Polymer({
'/static/micromarkdown-js.html', '/static/micromarkdown-js.html',
success, error success, error
); );
}, }
computeContent: function (stateObj, scriptLoaded) { computeContent(stateObj, scriptLoaded) {
var el = ''; var el = '';
var message = ''; var message = '';
if (scriptLoaded) { if (scriptLoaded) {
@ -81,16 +78,17 @@ Polymer({
message = window.micromarkdown.parse(stateObj.state); message = window.micromarkdown.parse(stateObj.state);
el.innerHTML = message; el.innerHTML = message;
} }
}, }
ready: function () { ready() {
this.loadScript(); this.loadScript();
}, }
dismissTap: function (ev) { dismissTap(ev) {
ev.preventDefault(); ev.preventDefault();
this.hass.callApi('DELETE', 'states/' + this.stateObj.entity_id); this.hass.callApi('DELETE', 'states/' + this.stateObj.entity_id);
}, }
}); }
customElements.define(HaPersistentNotificationCard.is, HaPersistentNotificationCard);
</script> </script>

View File

@ -1,4 +1,4 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel='import' href='../../bower_components/iron-flex-layout/iron-flex-layout-classes.html'> <link rel='import' href='../../bower_components/iron-flex-layout/iron-flex-layout-classes.html'>
<link rel='import' href='../../bower_components/google-apis/google-legacy-loader.html'> <link rel='import' href='../../bower_components/google-apis/google-legacy-loader.html'>
<link rel='import' href='../components/ha-card.html'> <link rel='import' href='../components/ha-card.html'>
@ -95,24 +95,22 @@
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N' 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'
]; ];
Polymer({ class HaWeatherCard extends Polymer.Element {
is: 'ha-weather-card', static get is() { return 'ha-weather-card'; }
static get properties() {
properties: { return {
hass: { hass: Object,
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'checkRequirements' observer: 'checkRequirements'
}, },
}, };
}
computeTitle: function (stateObj) { computeTitle(stateObj) {
return stateObj.attributes.friendly_name; return stateObj.attributes.friendly_name;
}, }
getDataArray: function () { getDataArray() {
var dataArray = []; var dataArray = [];
var data = this.stateObj.attributes.forecast; var data = this.stateObj.attributes.forecast;
var i; var i;
@ -132,9 +130,9 @@
} }
return dataArray; return dataArray;
}, }
checkRequirements: function () { checkRequirements() {
if (!this.stateObj) { if (!this.stateObj) {
return; return;
} }
@ -163,8 +161,8 @@
this.data = this.getDataArray(); this.data = this.getDataArray();
this.drawChart(); this.drawChart();
}, }
drawChart: function () { drawChart() {
var dataGrid = new window.google.visualization.DataTable(); var dataGrid = new window.google.visualization.DataTable();
var options = { var options = {
legend: { legend: {
@ -198,24 +196,25 @@
dataGrid.addRows(dataArray); dataGrid.addRows(dataArray);
this.chartEngine.draw(dataGrid, options); this.chartEngine.draw(dataGrid, options);
}, }
googleApiLoaded: function () { googleApiLoaded() {
window.google.load('visualization', '1', { window.google.load('visualization', '1', {
packages: ['corechart'], packages: ['corechart'],
callback: function () { callback: function () {
this.checkRequirements(); this.checkRequirements();
}.bind(this), }.bind(this),
}); });
}, }
windBearingToText: function (degree) { windBearingToText(degree) {
var degreenum = parseInt(degree); var degreenum = parseInt(degree);
if (isFinite(degreenum)) { if (isFinite(degreenum)) {
return _DEGREE_TEXT[(((degreenum + 11.25) / 22.5) | 0) % 16]; return _DEGREE_TEXT[(((degreenum + 11.25) / 22.5) | 0) % 16];
} }
return ''; return '';
} }
}); }
customElements.define(HaWeatherCard.is, HaWeatherCard);
}()); }());
</script> </script>

View File

@ -245,7 +245,7 @@
cards.columns[getIndex(5)].push({ cards.columns[getIndex(5)].push({
hass: hass, hass: hass,
cardType: 'introduction', cardType: 'introduction',
showHideInstruction: states.size > 0 && !window.HASS_DEMO, showHideInstruction: Object.keys(states).length > 0 && !window.HASS_DEMO,
}); });
} }

View File

@ -298,7 +298,7 @@ Polymer({
}, },
computeShowIntroduction: function (currentView, introductionLoaded, states) { computeShowIntroduction: function (currentView, introductionLoaded, states) {
return currentView === '' && (introductionLoaded || states.size === 0); return currentView === '' && (introductionLoaded || Object.keys(states).length === 0);
}, },
computeStateName: function (stateObj) { computeStateName: function (stateObj) {