mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-13 12:26:35 +00:00
Merge pull request #63 from home-assistant/inline-javascript
Clean up - step 2: Break up app in core + ui and inline some scripts
This commit is contained in:
commit
c1cbd33d41
11
.eslintrc
11
.eslintrc
@ -2,6 +2,15 @@
|
|||||||
"extends": "airbnb-base",
|
"extends": "airbnb-base",
|
||||||
"globals": {
|
"globals": {
|
||||||
"__DEV__": false,
|
"__DEV__": false,
|
||||||
"__DEMO__": false
|
"Polymer": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"new-cap": 0,
|
||||||
|
"prefer-template": 0,
|
||||||
|
"object-shorthand": 0,
|
||||||
|
"func-names": 0,
|
||||||
|
"prefer-arrow-callback": 0,
|
||||||
|
"no-underscore-dangle": 0,
|
||||||
|
"no-var": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
src/app-core.js
Normal file
23
src/app-core.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
import HomeAssistant from 'home-assistant-js';
|
||||||
|
|
||||||
|
window.moment = moment;
|
||||||
|
|
||||||
|
// While we figure out how ha-entity-marker can keep it's references
|
||||||
|
window.hass = new HomeAssistant();
|
||||||
|
|
||||||
|
window.validateAuth = function validateAuth(hass, authToken, rememberAuth) {
|
||||||
|
hass.authActions.validate(authToken, {
|
||||||
|
rememberAuth,
|
||||||
|
useStreaming: hass.localStoragePreferences.useStreaming,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
window.removeInitMsg = function removeInitMessage() {
|
||||||
|
// remove the HTML init message
|
||||||
|
const initMsg = document.getElementById('ha-init-skeleton');
|
||||||
|
if (initMsg) {
|
||||||
|
initMsg.parentElement.removeChild(initMsg);
|
||||||
|
}
|
||||||
|
};
|
@ -4,7 +4,6 @@ import dynamicContentUpdater from '../util/dynamic-content-updater';
|
|||||||
|
|
||||||
require('./ha-camera-card');
|
require('./ha-camera-card');
|
||||||
require('./ha-entities-card');
|
require('./ha-entities-card');
|
||||||
require('./ha-introduction-card');
|
|
||||||
require('./ha-media_player-card');
|
require('./ha-media_player-card');
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
import canToggle from '../util/can-toggle';
|
import canToggle from '../util/can-toggle';
|
||||||
|
|
||||||
require('../components/ha-card');
|
|
||||||
require('../components/entity/ha-entity-toggle');
|
require('../components/entity/ha-entity-toggle');
|
||||||
require('../state-summary/state-card-content');
|
require('../state-summary/state-card-content');
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<ha-card header="Welcome Home!">
|
<ha-card header="Welcome Home!">
|
||||||
<div class='content'>
|
<div class='content'>
|
||||||
<template is='dom-if' if='[[showInstallInstruction]]'>
|
<template is='dom-if' if='[[hass.demo]]'>
|
||||||
To install Home Assistant, run:<br />
|
To install Home Assistant, run:<br />
|
||||||
<code class='install'>
|
<code class='install'>
|
||||||
pip3 install homeassistant<br />
|
pip3 install homeassistant<br />
|
||||||
@ -39,7 +39,7 @@
|
|||||||
</template>
|
</template>
|
||||||
Here are some resources to get started.
|
Here are some resources to get started.
|
||||||
<ul>
|
<ul>
|
||||||
<template is='dom-if' if='[[showInstallInstruction]]'>
|
<template is='dom-if' if='[[hass.demo]]'>
|
||||||
<li><a href='https://home-assistant.io/getting-started/'>Home Assistant website</a></li>
|
<li><a href='https://home-assistant.io/getting-started/'>Home Assistant website</a></li>
|
||||||
<li><a href='https://home-assistant.io/getting-started/'>Installation instructions</a></li>
|
<li><a href='https://home-assistant.io/getting-started/'>Installation instructions</a></li>
|
||||||
<li><a href='https://home-assistant.io/getting-started/troubleshooting/'>Troubleshooting your installation</a></li>
|
<li><a href='https://home-assistant.io/getting-started/troubleshooting/'>Troubleshooting your installation</a></li>
|
||||||
@ -64,3 +64,20 @@
|
|||||||
</ha-card>
|
</ha-card>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-introduction-card',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
showHideInstruction: {
|
||||||
|
type: Boolean,
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
require('../components/ha-card');
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-introduction-card',
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
showInstallInstruction: {
|
|
||||||
type: Boolean,
|
|
||||||
value: __DEMO__,
|
|
||||||
},
|
|
||||||
showHideInstruction: {
|
|
||||||
type: Boolean,
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
@ -25,3 +25,34 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'entity-list',
|
||||||
|
|
||||||
|
behaviors: [window.hassBehavior],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
entities: {
|
||||||
|
type: Array,
|
||||||
|
bindNuclear: function (hass) {
|
||||||
|
return [
|
||||||
|
hass.entityGetters.entityMap,
|
||||||
|
function (map) {
|
||||||
|
return map.valueSeq().sortBy(function (entity) { return entity.entityId; }).toArray();
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
entitySelected: function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.fire('entity-selected', { entityId: ev.model.entity.entityId });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'entity-list',
|
|
||||||
|
|
||||||
behaviors: [window.hassBehavior],
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
entities: {
|
|
||||||
type: Array,
|
|
||||||
bindNuclear: hass => [
|
|
||||||
hass.entityGetters.entityMap,
|
|
||||||
(map) => map.valueSeq().sortBy((entity) => entity.entityId).toArray(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
entitySelected(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
this.fire('entity-selected', { entityId: ev.model.entity.entityId });
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,7 +1,5 @@
|
|||||||
import Polymer from '../../polymer';
|
import Polymer from '../../polymer';
|
||||||
|
|
||||||
require('../../components/ha-label-badge');
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Leaflet clones this element before adding it to the map. This messes up
|
Leaflet clones this element before adding it to the map. This messes up
|
||||||
our Poylmer object and we lose the reference to the `hass` object.
|
our Poylmer object and we lose the reference to the `hass` object.
|
||||||
|
@ -2,8 +2,6 @@ import Polymer from '../../polymer';
|
|||||||
import domainIcon from '../../util/domain-icon';
|
import domainIcon from '../../util/domain-icon';
|
||||||
import stateIcon from '../../util/state-icon';
|
import stateIcon from '../../util/state-icon';
|
||||||
|
|
||||||
require('../../components/ha-label-badge');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'ha-state-label-badge',
|
is: 'ha-state-label-badge',
|
||||||
|
|
||||||
|
@ -28,3 +28,34 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'events-list',
|
||||||
|
|
||||||
|
behaviors: [window.hassBehavior],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
type: Array,
|
||||||
|
bindNuclear: function (hass) {
|
||||||
|
return [
|
||||||
|
hass.eventGetters.entityMap,
|
||||||
|
function (map) {
|
||||||
|
return map.valueSeq().sortBy(function (event) { return event.event; }).toArray();
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
eventSelected: function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.fire('event-selected', { eventType: ev.model.event.event });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'events-list',
|
|
||||||
|
|
||||||
behaviors: [window.hassBehavior],
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
events: {
|
|
||||||
type: Array,
|
|
||||||
bindNuclear: hass => [
|
|
||||||
hass.eventGetters.entityMap,
|
|
||||||
(map) => map.valueSeq().sortBy((event) => event.event).toArray(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
eventSelected(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
this.fire('event-selected', { eventType: ev.model.event.event });
|
|
||||||
},
|
|
||||||
});
|
|
@ -25,3 +25,23 @@
|
|||||||
<content></content>
|
<content></content>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-card',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
header: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* The z-depth of the card, from 0-5.
|
||||||
|
*/
|
||||||
|
elevation: {
|
||||||
|
type: Number,
|
||||||
|
value: 1,
|
||||||
|
reflectToAttribute: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@ -1,19 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-card',
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
header: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* The z-depth of the card, from 0-5.
|
|
||||||
*/
|
|
||||||
elevation: {
|
|
||||||
type: Number,
|
|
||||||
value: 1,
|
|
||||||
reflectToAttribute: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,6 +1,5 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
require('.//ha-demo-badge');
|
|
||||||
require('../cards/ha-badges-card');
|
require('../cards/ha-badges-card');
|
||||||
require('../cards/ha-card-chooser');
|
require('../cards/ha-card-chooser');
|
||||||
|
|
||||||
@ -109,8 +108,9 @@ export default new Polymer({
|
|||||||
}
|
}
|
||||||
if (showIntroduction) {
|
if (showIntroduction) {
|
||||||
cards.columns[getIndex(5)].push({
|
cards.columns[getIndex(5)].push({
|
||||||
|
hass,
|
||||||
cardType: 'introduction',
|
cardType: 'introduction',
|
||||||
showHideInstruction: states.size > 0 && !__DEMO__,
|
showHideInstruction: states.size > 0 && !hass.demo,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,3 +10,134 @@
|
|||||||
<canvas width='[[width]]' height='[[height]]'></canvas>
|
<canvas width='[[width]]' height='[[height]]'></canvas>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Color-picker custom element
|
||||||
|
* Originally created by bbrewer97202 (Ben Brewer). MIT Licensed.
|
||||||
|
* https://github.com/bbrewer97202/color-picker-element
|
||||||
|
*
|
||||||
|
* Adapted to work with Polymer.
|
||||||
|
*/
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-color-picker',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
color: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
mousedown: 'onMouseDown',
|
||||||
|
mouseup: 'onMouseUp',
|
||||||
|
touchstart: 'onTouchStart',
|
||||||
|
touchend: 'onTouchEnd',
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseDown: function (ev) {
|
||||||
|
this.onMouseMove(ev);
|
||||||
|
this.addEventListener('mousemove', this.onMouseMove);
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseUp: function () {
|
||||||
|
this.removeEventListener('mousemove', this.onMouseMove);
|
||||||
|
},
|
||||||
|
|
||||||
|
onTouchStart: function (ev) {
|
||||||
|
this.onTouchMove(ev);
|
||||||
|
this.addEventListener('touchmove', this.onTouchMove);
|
||||||
|
},
|
||||||
|
|
||||||
|
onTouchEnd: function () {
|
||||||
|
this.removeEventListener('touchmove', this.onTouchMove);
|
||||||
|
},
|
||||||
|
|
||||||
|
onTouchMove: function (ev) {
|
||||||
|
if (!this.mouseMoveIsThrottled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.mouseMoveIsThrottled = false;
|
||||||
|
this.processColorSelect(ev.touches[0]);
|
||||||
|
this.async(function () { this.mouseMoveIsThrottled = true; }.bind(this), 100);
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseMove: function (ev) {
|
||||||
|
if (!this.mouseMoveIsThrottled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.mouseMoveIsThrottled = false;
|
||||||
|
this.processColorSelect(ev);
|
||||||
|
this.async(function () { this.mouseMoveIsThrottled = true; }.bind(this), 100);
|
||||||
|
},
|
||||||
|
|
||||||
|
processColorSelect: function (ev) {
|
||||||
|
var rect = this.canvas.getBoundingClientRect();
|
||||||
|
|
||||||
|
// boundary check because people can move off-canvas.
|
||||||
|
if (ev.clientX < rect.left || ev.clientX >= rect.left + rect.width ||
|
||||||
|
ev.clientY < rect.top || ev.clientY >= rect.top + rect.height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onColorSelect(ev.clientX - rect.left, ev.clientY - rect.top);
|
||||||
|
},
|
||||||
|
|
||||||
|
onColorSelect: function (x, y) {
|
||||||
|
var data = this.context.getImageData(x, y, 1, 1).data;
|
||||||
|
|
||||||
|
this.setColor({ r: data[0], g: data[1], b: data[2] });
|
||||||
|
},
|
||||||
|
|
||||||
|
setColor: function (rgb) {
|
||||||
|
this.color = rgb;
|
||||||
|
|
||||||
|
this.fire('colorselected', { rgb: this.color });
|
||||||
|
},
|
||||||
|
|
||||||
|
ready: function () {
|
||||||
|
this.setColor = this.setColor.bind(this);
|
||||||
|
this.mouseMoveIsThrottled = true;
|
||||||
|
this.canvas = this.children[0];
|
||||||
|
this.context = this.canvas.getContext('2d');
|
||||||
|
this.drawGradient();
|
||||||
|
},
|
||||||
|
|
||||||
|
drawGradient: function () {
|
||||||
|
var style;
|
||||||
|
if (!this.width || !this.height) {
|
||||||
|
style = getComputedStyle(this);
|
||||||
|
}
|
||||||
|
var width = this.width || parseInt(style.width, 10);
|
||||||
|
var height = this.height || parseInt(style.height, 10);
|
||||||
|
|
||||||
|
var colorGradient = this.context.createLinearGradient(0, 0, width, 0);
|
||||||
|
colorGradient.addColorStop(0, 'rgb(255,0,0)');
|
||||||
|
colorGradient.addColorStop(0.16, 'rgb(255,0,255)');
|
||||||
|
colorGradient.addColorStop(0.32, 'rgb(0,0,255)');
|
||||||
|
colorGradient.addColorStop(0.48, 'rgb(0,255,255)');
|
||||||
|
colorGradient.addColorStop(0.64, 'rgb(0,255,0)');
|
||||||
|
colorGradient.addColorStop(0.80, 'rgb(255,255,0)');
|
||||||
|
colorGradient.addColorStop(1, 'rgb(255,0,0)');
|
||||||
|
this.context.fillStyle = colorGradient;
|
||||||
|
this.context.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
var bwGradient = this.context.createLinearGradient(0, 0, 0, height);
|
||||||
|
bwGradient.addColorStop(0, 'rgba(255,255,255,1)');
|
||||||
|
bwGradient.addColorStop(0.5, 'rgba(255,255,255,0)');
|
||||||
|
bwGradient.addColorStop(0.5, 'rgba(0,0,0,0)');
|
||||||
|
bwGradient.addColorStop(1, 'rgba(0,0,0,1)');
|
||||||
|
|
||||||
|
this.context.fillStyle = bwGradient;
|
||||||
|
this.context.fillRect(0, 0, width, height);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
/**
|
|
||||||
* Color-picker custom element
|
|
||||||
* Originally created by bbrewer97202 (Ben Brewer). MIT Licensed.
|
|
||||||
* https://github.com/bbrewer97202/color-picker-element
|
|
||||||
*
|
|
||||||
* Adapted to work with Polymer.
|
|
||||||
*/
|
|
||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-color-picker',
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
color: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
width: {
|
|
||||||
type: Number,
|
|
||||||
},
|
|
||||||
|
|
||||||
height: {
|
|
||||||
type: Number,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
listeners: {
|
|
||||||
mousedown: 'onMouseDown',
|
|
||||||
mouseup: 'onMouseUp',
|
|
||||||
touchstart: 'onTouchStart',
|
|
||||||
touchend: 'onTouchEnd',
|
|
||||||
},
|
|
||||||
|
|
||||||
onMouseDown(ev) {
|
|
||||||
this.onMouseMove(ev);
|
|
||||||
this.addEventListener('mousemove', this.onMouseMove);
|
|
||||||
},
|
|
||||||
|
|
||||||
onMouseUp() {
|
|
||||||
this.removeEventListener('mousemove', this.onMouseMove);
|
|
||||||
},
|
|
||||||
|
|
||||||
onTouchStart(ev) {
|
|
||||||
this.onTouchMove(ev);
|
|
||||||
this.addEventListener('touchmove', this.onTouchMove);
|
|
||||||
},
|
|
||||||
|
|
||||||
onTouchEnd() {
|
|
||||||
this.removeEventListener('touchmove', this.onTouchMove);
|
|
||||||
},
|
|
||||||
|
|
||||||
onTouchMove(ev) {
|
|
||||||
if (!this.mouseMoveIsThrottled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.mouseMoveIsThrottled = false;
|
|
||||||
this.processColorSelect(ev.touches[0]);
|
|
||||||
this.async(() => { this.mouseMoveIsThrottled = true; }, 100);
|
|
||||||
},
|
|
||||||
|
|
||||||
onMouseMove(ev) {
|
|
||||||
if (!this.mouseMoveIsThrottled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.mouseMoveIsThrottled = false;
|
|
||||||
this.processColorSelect(ev);
|
|
||||||
this.async(() => { this.mouseMoveIsThrottled = true; }, 100);
|
|
||||||
},
|
|
||||||
|
|
||||||
processColorSelect(ev) {
|
|
||||||
const rect = this.canvas.getBoundingClientRect();
|
|
||||||
|
|
||||||
// boundary check because people can move off-canvas.
|
|
||||||
if (ev.clientX < rect.left || ev.clientX >= rect.left + rect.width ||
|
|
||||||
ev.clientY < rect.top || ev.clientY >= rect.top + rect.height) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onColorSelect(ev.clientX - rect.left, ev.clientY - rect.top);
|
|
||||||
},
|
|
||||||
|
|
||||||
onColorSelect(x, y) {
|
|
||||||
const data = this.context.getImageData(x, y, 1, 1).data;
|
|
||||||
|
|
||||||
this.setColor({ r: data[0], g: data[1], b: data[2] });
|
|
||||||
},
|
|
||||||
|
|
||||||
setColor(rgb) {
|
|
||||||
this.color = rgb;
|
|
||||||
|
|
||||||
this.fire('colorselected', { rgb: this.color });
|
|
||||||
},
|
|
||||||
|
|
||||||
ready() {
|
|
||||||
this.setColor = this.setColor.bind(this);
|
|
||||||
this.mouseMoveIsThrottled = true;
|
|
||||||
this.canvas = this.children[0];
|
|
||||||
this.context = this.canvas.getContext('2d');
|
|
||||||
this.drawGradient();
|
|
||||||
},
|
|
||||||
|
|
||||||
drawGradient() {
|
|
||||||
let style;
|
|
||||||
if (!this.width || !this.height) {
|
|
||||||
style = getComputedStyle(this);
|
|
||||||
}
|
|
||||||
const width = this.width || parseInt(style.width, 10);
|
|
||||||
const height = this.height || parseInt(style.height, 10);
|
|
||||||
|
|
||||||
const colorGradient = this.context.createLinearGradient(0, 0, width, 0);
|
|
||||||
colorGradient.addColorStop(0, 'rgb(255,0,0)');
|
|
||||||
colorGradient.addColorStop(0.16, 'rgb(255,0,255)');
|
|
||||||
colorGradient.addColorStop(0.32, 'rgb(0,0,255)');
|
|
||||||
colorGradient.addColorStop(0.48, 'rgb(0,255,255)');
|
|
||||||
colorGradient.addColorStop(0.64, 'rgb(0,255,0)');
|
|
||||||
colorGradient.addColorStop(0.80, 'rgb(255,255,0)');
|
|
||||||
colorGradient.addColorStop(1, 'rgb(255,0,0)');
|
|
||||||
this.context.fillStyle = colorGradient;
|
|
||||||
this.context.fillRect(0, 0, width, height);
|
|
||||||
|
|
||||||
const bwGradient = this.context.createLinearGradient(0, 0, 0, height);
|
|
||||||
bwGradient.addColorStop(0, 'rgba(255,255,255,1)');
|
|
||||||
bwGradient.addColorStop(0.5, 'rgba(255,255,255,0)');
|
|
||||||
bwGradient.addColorStop(0.5, 'rgba(0,0,0,0)');
|
|
||||||
bwGradient.addColorStop(1, 'rgba(0,0,0,1)');
|
|
||||||
|
|
||||||
this.context.fillStyle = bwGradient;
|
|
||||||
this.context.fillRect(0, 0, width, height);
|
|
||||||
},
|
|
||||||
});
|
|
@ -16,3 +16,9 @@
|
|||||||
></ha-label-badge>
|
></ha-label-badge>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-demo-badge',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
require('./ha-label-badge');
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-demo-badge',
|
|
||||||
});
|
|
@ -83,3 +83,54 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Beware: Polymer will not call computeHideIcon and computeHideValue if any of
|
||||||
|
// the parameters are undefined. Set to null if not using.
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-label-badge',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
value: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
value: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
value: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
image: {
|
||||||
|
type: String,
|
||||||
|
value: null,
|
||||||
|
observer: 'imageChanged',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
computeClasses: function (value) {
|
||||||
|
return value && value.length > 4 ? 'value big' : 'value';
|
||||||
|
},
|
||||||
|
|
||||||
|
computeHideIcon: function (icon, value, image) {
|
||||||
|
return !icon || value || image;
|
||||||
|
},
|
||||||
|
|
||||||
|
computeHideValue: function (value, image) {
|
||||||
|
return !value || image;
|
||||||
|
},
|
||||||
|
|
||||||
|
imageChanged: function (newVal) {
|
||||||
|
this.$.badge.style.backgroundImage = newVal ? `url(${newVal})` : '';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@ -1,50 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
// Beware: Polymer will not call computeHideIcon and computeHideValue if any of
|
|
||||||
// the parameters are undefined. Set to null if not using.
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-label-badge',
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
icon: {
|
|
||||||
type: String,
|
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
description: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
image: {
|
|
||||||
type: String,
|
|
||||||
value: null,
|
|
||||||
observer: 'imageChanged',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
computeClasses(value) {
|
|
||||||
return value && value.length > 4 ? 'value big' : 'value';
|
|
||||||
},
|
|
||||||
|
|
||||||
computeHideIcon(icon, value, image) {
|
|
||||||
return !icon || value || image;
|
|
||||||
},
|
|
||||||
|
|
||||||
computeHideValue(value, image) {
|
|
||||||
return !value || image;
|
|
||||||
},
|
|
||||||
|
|
||||||
imageChanged(newVal) {
|
|
||||||
this.$.badge.style.backgroundImage = newVal ? `url(${newVal})` : '';
|
|
||||||
},
|
|
||||||
});
|
|
@ -14,7 +14,28 @@
|
|||||||
No logbook entries found.
|
No logbook entries found.
|
||||||
</template>
|
</template>
|
||||||
<template is='dom-repeat' items="[[entries]]">
|
<template is='dom-repeat' items="[[entries]]">
|
||||||
<logbook-entry entry-obj="[[item]]"></logbook-entry>
|
<logbook-entry entry-obj="[[item]]" hass='[[hass]]'></logbook-entry>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-logbook',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
entries: {
|
||||||
|
type: Array,
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
noEntries: function (entries) {
|
||||||
|
return !entries.length;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
require('./logbook-entry');
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-logbook',
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
entries: {
|
|
||||||
type: Object,
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
noEntries(entries) {
|
|
||||||
return !entries.length;
|
|
||||||
},
|
|
||||||
});
|
|
@ -169,3 +169,86 @@
|
|||||||
|
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-sidebar',
|
||||||
|
|
||||||
|
behaviors: [window.hassBehavior],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
menuShown: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
|
||||||
|
menuSelected: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
narrow: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
|
||||||
|
selected: {
|
||||||
|
type: String,
|
||||||
|
bindNuclear: function (hass) { return hass.navigationGetters.activePane; },
|
||||||
|
},
|
||||||
|
|
||||||
|
hasHistoryComponent: {
|
||||||
|
type: Boolean,
|
||||||
|
bindNuclear: function (hass) { return hass.configGetters.isComponentLoaded('history'); },
|
||||||
|
},
|
||||||
|
|
||||||
|
hasLogbookComponent: {
|
||||||
|
type: Boolean,
|
||||||
|
bindNuclear: function (hass) { return hass.configGetters.isComponentLoaded('logbook'); },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created: function () {
|
||||||
|
this._boundUpdateStyles = this.updateStyles.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
menuSelect: function () {
|
||||||
|
this.debounce('updateStyles', this._boundUpdateStyles, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
menuClicked: function (ev) {
|
||||||
|
var target = ev.target;
|
||||||
|
var checks = 5;
|
||||||
|
|
||||||
|
// find panel to select
|
||||||
|
while (checks && !target.getAttribute('data-panel')) {
|
||||||
|
target = target.parentElement;
|
||||||
|
checks--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checks) {
|
||||||
|
this.selectPanel(target.getAttribute('data-panel'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleMenu: function () {
|
||||||
|
this.fire('close-menu');
|
||||||
|
},
|
||||||
|
|
||||||
|
selectPanel: function (newChoice) {
|
||||||
|
if (newChoice === this.selected) {
|
||||||
|
return;
|
||||||
|
} else if (newChoice === 'logout') {
|
||||||
|
this.handleLogOut();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.hass.navigationActions.navigate.apply(null, newChoice.split('/'));
|
||||||
|
this.debounce('updateStyles', this._boundUpdateStyles, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleLogOut: function () {
|
||||||
|
this.hass.authActions.logOut();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
require('./stream-status');
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-sidebar',
|
|
||||||
|
|
||||||
behaviors: [window.hassBehavior],
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
menuShown: {
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
|
|
||||||
menuSelected: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
narrow: {
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
|
|
||||||
selected: {
|
|
||||||
type: String,
|
|
||||||
bindNuclear: hass => hass.navigationGetters.activePane,
|
|
||||||
},
|
|
||||||
|
|
||||||
hasHistoryComponent: {
|
|
||||||
type: Boolean,
|
|
||||||
bindNuclear: hass => hass.configGetters.isComponentLoaded('history'),
|
|
||||||
},
|
|
||||||
|
|
||||||
hasLogbookComponent: {
|
|
||||||
type: Boolean,
|
|
||||||
bindNuclear: hass => hass.configGetters.isComponentLoaded('logbook'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
menuSelect() {
|
|
||||||
this.debounce('updateStyles', () => this.updateStyles(), 1);
|
|
||||||
},
|
|
||||||
|
|
||||||
menuClicked(ev) {
|
|
||||||
let target = ev.target;
|
|
||||||
let checks = 5;
|
|
||||||
|
|
||||||
// find panel to select
|
|
||||||
while (checks && !target.getAttribute('data-panel')) {
|
|
||||||
target = target.parentElement;
|
|
||||||
checks--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checks) {
|
|
||||||
this.selectPanel(target.getAttribute('data-panel'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleMenu() {
|
|
||||||
this.fire('close-menu');
|
|
||||||
},
|
|
||||||
|
|
||||||
selectPanel(newChoice) {
|
|
||||||
if (newChoice === this.selected) {
|
|
||||||
return;
|
|
||||||
} else if (newChoice === 'logout') {
|
|
||||||
this.handleLogOut();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.hass.navigationActions.navigate.apply(null, newChoice.split('/'));
|
|
||||||
this.debounce('updateStyles', () => this.updateStyles(), 1);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleLogOut() {
|
|
||||||
this.hass.authActions.logOut();
|
|
||||||
},
|
|
||||||
});
|
|
@ -23,3 +23,58 @@
|
|||||||
</paper-tabs>
|
</paper-tabs>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-view-tabs',
|
||||||
|
|
||||||
|
behaviors: [window.hassBehavior],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
locationName: {
|
||||||
|
type: String,
|
||||||
|
bindNuclear: function (hass) { return hass.configGetters.locationName; },
|
||||||
|
},
|
||||||
|
|
||||||
|
currentView: {
|
||||||
|
type: String,
|
||||||
|
bindNuclear: function (hass) {
|
||||||
|
return [
|
||||||
|
hass.viewGetters.currentView,
|
||||||
|
function (view) { return view || ''; },
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
views: {
|
||||||
|
type: Array,
|
||||||
|
bindNuclear: function (hass) {
|
||||||
|
return [
|
||||||
|
hass.viewGetters.views,
|
||||||
|
function (views) {
|
||||||
|
return views.valueSeq()
|
||||||
|
.sortBy(function (view) { return view.attributes.order; })
|
||||||
|
.toArray();
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
viewTapped() {
|
||||||
|
this.fire('view-tapped');
|
||||||
|
},
|
||||||
|
|
||||||
|
viewSelected(ev) {
|
||||||
|
var view = ev.detail.item.getAttribute('data-entity') || null;
|
||||||
|
var current = this.currentView || null;
|
||||||
|
if (view !== current) {
|
||||||
|
this.async(function () { this.hass.viewActions.selectView(view); }.bind(this), 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'ha-view-tabs',
|
|
||||||
|
|
||||||
behaviors: [window.hassBehavior],
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
locationName: {
|
|
||||||
type: String,
|
|
||||||
bindNuclear: hass => hass.configGetters.locationName,
|
|
||||||
},
|
|
||||||
|
|
||||||
currentView: {
|
|
||||||
type: String,
|
|
||||||
bindNuclear: hass => [
|
|
||||||
hass.viewGetters.currentView,
|
|
||||||
view => view || '',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
views: {
|
|
||||||
type: Array,
|
|
||||||
bindNuclear: hass => [
|
|
||||||
hass.viewGetters.views,
|
|
||||||
views => views.valueSeq()
|
|
||||||
.sortBy(view => view.attributes.order)
|
|
||||||
.toArray(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
viewTapped() {
|
|
||||||
this.fire('view-tapped');
|
|
||||||
},
|
|
||||||
|
|
||||||
viewSelected(ev) {
|
|
||||||
const view = ev.detail.item.getAttribute('data-entity') || null;
|
|
||||||
const current = this.currentView || null;
|
|
||||||
this.expectChange = true;
|
|
||||||
if (view !== current) {
|
|
||||||
this.async(() => this.hass.viewActions.selectView(view), 0);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
@ -18,3 +18,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'loading-box',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'loading-box',
|
|
||||||
});
|
|
@ -2,7 +2,6 @@ import Polymer from '../polymer';
|
|||||||
|
|
||||||
require('./domain-icon');
|
require('./domain-icon');
|
||||||
require('./display-time');
|
require('./display-time');
|
||||||
require('./relative-ha-datetime');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'logbook-entry',
|
is: 'logbook-entry',
|
||||||
|
@ -5,3 +5,60 @@
|
|||||||
<span>[[relativeTime]]</span>
|
<span>[[relativeTime]]</span>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'relative-ha-datetime',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
datetime: {
|
||||||
|
type: String,
|
||||||
|
observer: 'datetimeChanged',
|
||||||
|
},
|
||||||
|
|
||||||
|
datetimeObj: {
|
||||||
|
type: Object,
|
||||||
|
observer: 'datetimeObjChanged',
|
||||||
|
},
|
||||||
|
|
||||||
|
parsedDateTime: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
relativeTime: {
|
||||||
|
type: String,
|
||||||
|
value: 'not set',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created: function () {
|
||||||
|
this.updateRelative = this.updateRelative.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
attached: function () {
|
||||||
|
// update every 60 seconds
|
||||||
|
this.updateInterval = setInterval(this.updateRelative, 60000);
|
||||||
|
},
|
||||||
|
|
||||||
|
detached: function () {
|
||||||
|
clearInterval(this.updateInterval);
|
||||||
|
},
|
||||||
|
|
||||||
|
datetimeChanged: function (newVal) {
|
||||||
|
this.parsedDateTime = newVal ? new Date(newVal) : null;
|
||||||
|
|
||||||
|
this.updateRelative();
|
||||||
|
},
|
||||||
|
|
||||||
|
datetimeObjChanged: function (newVal) {
|
||||||
|
this.parsedDateTime = newVal;
|
||||||
|
|
||||||
|
this.updateRelative();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateRelative: function () {
|
||||||
|
this.relativeTime = this.parsedDateTime ?
|
||||||
|
window.moment(this.parsedDateTime).fromNow() : '';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
const UPDATE_INTERVAL = 60000; // 60 seconds
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'relative-ha-datetime',
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
datetime: {
|
|
||||||
type: String,
|
|
||||||
observer: 'datetimeChanged',
|
|
||||||
},
|
|
||||||
|
|
||||||
datetimeObj: {
|
|
||||||
type: Object,
|
|
||||||
observer: 'datetimeObjChanged',
|
|
||||||
},
|
|
||||||
|
|
||||||
parsedDateTime: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
relativeTime: {
|
|
||||||
type: String,
|
|
||||||
value: 'not set',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.updateRelative = this.updateRelative.bind(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
attached() {
|
|
||||||
this.updateInterval = setInterval(this.updateRelative, UPDATE_INTERVAL);
|
|
||||||
},
|
|
||||||
|
|
||||||
detached() {
|
|
||||||
clearInterval(this.updateInterval);
|
|
||||||
},
|
|
||||||
|
|
||||||
datetimeChanged(newVal) {
|
|
||||||
this.parsedDateTime = newVal ? new Date(newVal) : null;
|
|
||||||
|
|
||||||
this.updateRelative();
|
|
||||||
},
|
|
||||||
|
|
||||||
datetimeObjChanged(newVal) {
|
|
||||||
this.parsedDateTime = newVal;
|
|
||||||
|
|
||||||
this.updateRelative();
|
|
||||||
},
|
|
||||||
|
|
||||||
updateRelative() {
|
|
||||||
this.relativeTime = this.parsedDateTime ?
|
|
||||||
window.moment(this.parsedDateTime).fromNow() : '';
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,6 +1,5 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
require('./loading-box');
|
|
||||||
require('./state-history-chart-timeline');
|
require('./state-history-chart-timeline');
|
||||||
require('./state-history-chart-line');
|
require('./state-history-chart-line');
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
require('./entity/state-badge');
|
require('./entity/state-badge');
|
||||||
require('./relative-ha-datetime');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'state-info',
|
is: 'state-info',
|
||||||
|
@ -25,3 +25,35 @@
|
|||||||
<paper-toggle-button id="toggle" on-change='toggleChanged' checked$='[[isStreaming]]' hidden$="[[hasError]]"></paper-toggle-button>
|
<paper-toggle-button id="toggle" on-change='toggleChanged' checked$='[[isStreaming]]' hidden$="[[hasError]]"></paper-toggle-button>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'stream-status',
|
||||||
|
|
||||||
|
behaviors: [window.hassBehavior],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
isStreaming: {
|
||||||
|
type: Boolean,
|
||||||
|
bindNuclear: function (hass) { return hass.streamGetters.isStreamingEvents; },
|
||||||
|
},
|
||||||
|
|
||||||
|
hasError: {
|
||||||
|
type: Boolean,
|
||||||
|
bindNuclear: function (hass) { return hass.streamGetters.hasStreamingEventsError; },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleChanged: function () {
|
||||||
|
if (this.isStreaming) {
|
||||||
|
this.hass.streamActions.stop();
|
||||||
|
} else {
|
||||||
|
this.hass.streamActions.start();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'stream-status',
|
|
||||||
|
|
||||||
behaviors: [window.hassBehavior],
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
isStreaming: {
|
|
||||||
type: Boolean,
|
|
||||||
bindNuclear: hass => hass.streamGetters.isStreamingEvents,
|
|
||||||
},
|
|
||||||
|
|
||||||
hasError: {
|
|
||||||
type: Boolean,
|
|
||||||
bindNuclear: hass => hass.streamGetters.hasStreamingEventsError,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleChanged() {
|
|
||||||
if (this.isStreaming) {
|
|
||||||
this.hass.streamActions.stop();
|
|
||||||
} else {
|
|
||||||
this.hass.streamActions.start();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,14 +1,17 @@
|
|||||||
<link rel='import' href='../bower_components/polymer/polymer.html'>
|
<link rel='import' href='../bower_components/polymer/polymer.html'>
|
||||||
<link rel='import' href='../bower_components/paper-spinner/paper-spinner.html'>
|
<link rel='import' href='../bower_components/paper-spinner/paper-spinner.html'>
|
||||||
|
|
||||||
|
<script src='../build/_app_core_compiled.js'></script>
|
||||||
|
|
||||||
<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='./util/roboto.html'>
|
<link rel='import' href='./util/roboto.html'>
|
||||||
<link rel='import' href='../bower_components/paper-styles/typography.html'>
|
<link rel='import' href='../bower_components/paper-styles/typography.html'>
|
||||||
<link rel="import" href="../bower_components/iron-iconset-svg/iron-iconset-svg.html">
|
<link rel="import" href="../bower_components/iron-iconset-svg/iron-iconset-svg.html">
|
||||||
|
|
||||||
|
<link rel='import' href='./util/hass-behavior.html'>
|
||||||
<link rel='import' href='./layouts/login-form.html'>
|
<link rel='import' href='./layouts/login-form.html'>
|
||||||
<link rel='import' href='./layouts/home-assistant-main.html'>
|
<link rel='import' href='./layouts/home-assistant-main.html'>
|
||||||
|
<link rel='import' href='./resources/home-assistant-style.html'>
|
||||||
<link rel='import' href='resources/home-assistant-style.html'>
|
|
||||||
|
|
||||||
<dom-module id='home-assistant'>
|
<dom-module id='home-assistant'>
|
||||||
<style>
|
<style>
|
||||||
@ -29,9 +32,94 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template is='dom-if' if='[[loaded]]'>
|
<template is='dom-if' if='[[loaded]]'>
|
||||||
<home-assistant-main hass='[[hass]]'></home-assistant-main>
|
<home-assistant-main hass='[[hass]]' hidden$='[[!loaded]]'></home-assistant-main>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'home-assistant',
|
||||||
|
|
||||||
|
hostAttributes: {
|
||||||
|
auth: null,
|
||||||
|
icons: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
behaviors: [window.hassBehavior],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
value: window.hass,
|
||||||
|
},
|
||||||
|
auth: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
icons: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
dataLoaded: {
|
||||||
|
type: Boolean,
|
||||||
|
bindNuclear: function (hass) { return hass.syncGetters.isDataLoaded; },
|
||||||
|
},
|
||||||
|
iconsLoaded: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
loaded: {
|
||||||
|
type: Boolean,
|
||||||
|
computed: 'computeLoaded(dataLoaded, iconsLoaded)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
computeLoaded: function (dataLoaded, iconsLoaded) {
|
||||||
|
return dataLoaded && iconsLoaded;
|
||||||
|
},
|
||||||
|
|
||||||
|
computeForceShowLoading: function (dataLoaded, iconsLoaded) {
|
||||||
|
return dataLoaded && !iconsLoaded;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadIcons: function () {
|
||||||
|
// If the import fails, we'll try to import again, must be a server glitch
|
||||||
|
// Since HTML imports only resolve once, we import another url.
|
||||||
|
var success = function () {
|
||||||
|
this.iconsLoaded = true;
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
this.importHref(`/static/mdi-${this.icons}.html`,
|
||||||
|
success,
|
||||||
|
function () {
|
||||||
|
this.importHref('/static/mdi.html', success, success);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
created: function () {
|
||||||
|
if (!('serviceWorker' in navigator)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.serviceWorker.register('/service_worker.js');
|
||||||
|
},
|
||||||
|
|
||||||
|
ready: function () {
|
||||||
|
var hass = this.hass;
|
||||||
|
hass.reactor.batch(function () {
|
||||||
|
// if auth was given, tell the backend
|
||||||
|
if (this.auth) {
|
||||||
|
window.validateAuth(this.hass, this.auth, false);
|
||||||
|
} else if (hass.localStoragePreferences.authToken) {
|
||||||
|
window.validateAuth(this.hass, hass.localStoragePreferences.authToken, true);
|
||||||
|
}
|
||||||
|
hass.navigationActions.showSidebar(hass.localStoragePreferences.showSidebar);
|
||||||
|
});
|
||||||
|
|
||||||
|
hass.startLocalStoragePreferencesSync();
|
||||||
|
|
||||||
|
this.loadIcons();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<script src='../build/_app_compiled.js'></script>
|
<script src='../build/_app_compiled.js'></script>
|
||||||
|
@ -1,99 +1 @@
|
|||||||
import moment from 'moment';
|
|
||||||
import Polymer from './polymer';
|
|
||||||
|
|
||||||
import HomeAssistant from 'home-assistant-js';
|
|
||||||
import validateAuth from './util/validate-auth';
|
|
||||||
import hassBehavior from './util/hass-behavior';
|
|
||||||
|
|
||||||
window.hassBehavior = hassBehavior;
|
|
||||||
window.moment = moment;
|
|
||||||
|
|
||||||
require('./layouts/login-form');
|
|
||||||
require('./layouts/home-assistant-main');
|
require('./layouts/home-assistant-main');
|
||||||
|
|
||||||
// While we figure out how ha-entity-marker can keep it's references
|
|
||||||
window.hass = new HomeAssistant();
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'home-assistant',
|
|
||||||
|
|
||||||
hostAttributes: {
|
|
||||||
auth: null,
|
|
||||||
icons: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
behaviors: [window.hassBehavior],
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
value: window.hass,
|
|
||||||
},
|
|
||||||
auth: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
icons: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
dataLoaded: {
|
|
||||||
type: Boolean,
|
|
||||||
bindNuclear: hass => hass.syncGetters.isDataLoaded,
|
|
||||||
},
|
|
||||||
iconsLoaded: {
|
|
||||||
type: Boolean,
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
loaded: {
|
|
||||||
type: Boolean,
|
|
||||||
computed: 'computeLoaded(dataLoaded, iconsLoaded)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
computeLoaded(dataLoaded, iconsLoaded) {
|
|
||||||
return dataLoaded && iconsLoaded;
|
|
||||||
},
|
|
||||||
|
|
||||||
computeForceShowLoading(dataLoaded, iconsLoaded) {
|
|
||||||
return dataLoaded && !iconsLoaded;
|
|
||||||
},
|
|
||||||
|
|
||||||
loadIcons() {
|
|
||||||
// If the import fails, we'll try to import again, must be a server glitch
|
|
||||||
// Since HTML imports only resolve once, we import another url.
|
|
||||||
const success = () => { this.iconsLoaded = true; };
|
|
||||||
this.importHref(`/static/mdi-${this.icons}.html`,
|
|
||||||
success,
|
|
||||||
() => this.importHref('/static/mdi.html', success, success));
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
if (!('serviceWorker' in navigator)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigator.serviceWorker.register('/service_worker.js').catch(err => {
|
|
||||||
if (__DEV__) {
|
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.warn('Unable to register service worker', err);
|
|
||||||
/* eslint-enable no-console */
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
ready() {
|
|
||||||
const hass = this.hass;
|
|
||||||
hass.reactor.batch(() => {
|
|
||||||
// if auth was given, tell the backend
|
|
||||||
if (this.auth) {
|
|
||||||
validateAuth(this.hass, this.auth, false);
|
|
||||||
} else if (hass.localStoragePreferences.authToken) {
|
|
||||||
validateAuth(this.hass, hass.localStoragePreferences.authToken, true);
|
|
||||||
}
|
|
||||||
hass.navigationActions.showSidebar(hass.localStoragePreferences.showSidebar);
|
|
||||||
});
|
|
||||||
|
|
||||||
hass.startLocalStoragePreferencesSync();
|
|
||||||
|
|
||||||
this.loadIcons();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
import removeInitMsg from '../util/remove-init-message';
|
|
||||||
|
|
||||||
require('../components/ha-sidebar');
|
|
||||||
require('../layouts/partial-cards');
|
require('../layouts/partial-cards');
|
||||||
require('../layouts/partial-logbook');
|
require('../layouts/partial-logbook');
|
||||||
require('../layouts/partial-history');
|
require('../layouts/partial-history');
|
||||||
@ -16,13 +13,6 @@ require('../managers/notification-manager');
|
|||||||
require('../dialogs/more-info-dialog');
|
require('../dialogs/more-info-dialog');
|
||||||
require('../dialogs/ha-voice-command-dialog');
|
require('../dialogs/ha-voice-command-dialog');
|
||||||
|
|
||||||
// const {
|
|
||||||
// navigationActions,
|
|
||||||
// navigationGetters,
|
|
||||||
// startUrlSync,
|
|
||||||
// stopUrlSync,
|
|
||||||
// } = hass;
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'home-assistant-main',
|
is: 'home-assistant-main',
|
||||||
|
|
||||||
@ -35,7 +25,7 @@ export default new Polymer({
|
|||||||
|
|
||||||
narrow: {
|
narrow: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
activePane: {
|
activePane: {
|
||||||
@ -91,6 +81,7 @@ export default new Polymer({
|
|||||||
|
|
||||||
showSidebar: {
|
showSidebar: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
bindNuclear: hass => hass.navigationGetters.showSidebar,
|
bindNuclear: hass => hass.navigationGetters.showSidebar,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -122,7 +113,7 @@ export default new Polymer({
|
|||||||
},
|
},
|
||||||
|
|
||||||
attached() {
|
attached() {
|
||||||
removeInitMsg();
|
window.removeInitMsg();
|
||||||
this.hass.startUrlSync();
|
this.hass.startUrlSync();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -65,3 +65,95 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'login-form',
|
||||||
|
|
||||||
|
behaviors: [window.hassBehavior],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
errorMessage: {
|
||||||
|
type: String,
|
||||||
|
bindNuclear: function (hass) { return hass.authGetters.attemptErrorMessage; },
|
||||||
|
},
|
||||||
|
|
||||||
|
isInvalid: {
|
||||||
|
type: Boolean,
|
||||||
|
bindNuclear: function (hass) { return hass.authGetters.isInvalidAttempt; },
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidating: {
|
||||||
|
type: Boolean,
|
||||||
|
observer: 'isValidatingChanged',
|
||||||
|
bindNuclear: function (hass) { return hass.authGetters.isValidating; },
|
||||||
|
},
|
||||||
|
|
||||||
|
loadingResources: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
forceShowLoading: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
showLoading: {
|
||||||
|
type: Boolean,
|
||||||
|
computed: 'computeShowSpinner(forceShowLoading, isValidating)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
keydown: 'passwordKeyDown',
|
||||||
|
'loginButton.tap': 'validatePassword',
|
||||||
|
},
|
||||||
|
|
||||||
|
observers: [
|
||||||
|
'validatingChanged(isValidating, isInvalid)',
|
||||||
|
],
|
||||||
|
|
||||||
|
attached: function () {
|
||||||
|
window.removeInitMsg();
|
||||||
|
},
|
||||||
|
|
||||||
|
computeShowSpinner: function (forceShowLoading, isValidating) {
|
||||||
|
return forceShowLoading || isValidating;
|
||||||
|
},
|
||||||
|
|
||||||
|
validatingChanged: function (isValidating, isInvalid) {
|
||||||
|
if (!isValidating && !isInvalid) {
|
||||||
|
this.$.passwordInput.value = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidatingChanged: function (newVal) {
|
||||||
|
if (!newVal) {
|
||||||
|
this.async(function () { this.$.passwordInput.focus(); }.bind(this), 10);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
passwordKeyDown: function (ev) {
|
||||||
|
// validate on enter
|
||||||
|
if (ev.keyCode === 13) {
|
||||||
|
this.validatePassword();
|
||||||
|
ev.preventDefault();
|
||||||
|
// clear error after we start typing again
|
||||||
|
} else if (this.isInvalid) {
|
||||||
|
this.isInvalid = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
validatePassword: function () {
|
||||||
|
this.$.hideKeyboardOnFocus.focus();
|
||||||
|
|
||||||
|
window.validateAuth(this.hass, this.$.passwordInput.value,
|
||||||
|
this.$.rememberLogin.checked);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
import validateAuth from '../util/validate-auth';
|
|
||||||
import removeInitMsg from '../util/remove-init-message';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'login-form',
|
|
||||||
|
|
||||||
behaviors: [window.hassBehavior],
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
hass: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
errorMessage: {
|
|
||||||
type: String,
|
|
||||||
bindNuclear: hass => hass.authGetters.attemptErrorMessage,
|
|
||||||
},
|
|
||||||
|
|
||||||
isInvalid: {
|
|
||||||
type: Boolean,
|
|
||||||
bindNuclear: hass => hass.authGetters.isInvalidAttempt,
|
|
||||||
},
|
|
||||||
|
|
||||||
isValidating: {
|
|
||||||
type: Boolean,
|
|
||||||
observer: 'isValidatingChanged',
|
|
||||||
bindNuclear: hass => hass.authGetters.isValidating,
|
|
||||||
},
|
|
||||||
|
|
||||||
loadingResources: {
|
|
||||||
type: Boolean,
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
forceShowLoading: {
|
|
||||||
type: Boolean,
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
showLoading: {
|
|
||||||
type: Boolean,
|
|
||||||
computed: 'computeShowSpinner(forceShowLoading, isValidating)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
listeners: {
|
|
||||||
keydown: 'passwordKeyDown',
|
|
||||||
'loginButton.tap': 'validatePassword',
|
|
||||||
},
|
|
||||||
|
|
||||||
observers: [
|
|
||||||
'validatingChanged(isValidating, isInvalid)',
|
|
||||||
],
|
|
||||||
|
|
||||||
attached() {
|
|
||||||
removeInitMsg();
|
|
||||||
},
|
|
||||||
|
|
||||||
computeShowSpinner(forceShowLoading, isValidating) {
|
|
||||||
return forceShowLoading || isValidating;
|
|
||||||
},
|
|
||||||
|
|
||||||
validatingChanged(isValidating, isInvalid) {
|
|
||||||
if (!isValidating && !isInvalid) {
|
|
||||||
this.$.passwordInput.value = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isValidatingChanged(newVal) {
|
|
||||||
if (!newVal) {
|
|
||||||
this.async(() => this.$.passwordInput.focus(), 10);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
passwordKeyDown(ev) {
|
|
||||||
// validate on enter
|
|
||||||
if (ev.keyCode === 13) {
|
|
||||||
this.validatePassword();
|
|
||||||
ev.preventDefault();
|
|
||||||
// clear error after we start typing again
|
|
||||||
} else if (this.isInvalid) {
|
|
||||||
this.isInvalid = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
validatePassword() {
|
|
||||||
this.$.hideKeyboardOnFocus.focus();
|
|
||||||
|
|
||||||
validateAuth(this.hass, this.$.passwordInput.value, this.$.rememberLogin.checked);
|
|
||||||
},
|
|
||||||
});
|
|
@ -2,7 +2,6 @@ import Polymer from '../polymer';
|
|||||||
|
|
||||||
require('./partial-base');
|
require('./partial-base');
|
||||||
require('../components/ha-cards');
|
require('../components/ha-cards');
|
||||||
require('../components/ha-view-tabs');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'partial-cards',
|
is: 'partial-cards',
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class='header'>Available services</div>
|
<div class='header'>Available services</div>
|
||||||
<services-list on-service-selected='serviceSelected'></services-list>
|
<services-list on-service-selected='serviceSelected' hass='[[hass]]'></services-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</partial-base>
|
</partial-base>
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class='header'>Available Events</div>
|
<div class='header'>Available Events</div>
|
||||||
<events-list on-event-selected='eventSelected'></event-list>
|
<events-list on-event-selected='eventSelected' hass='[[hass]]'></event-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</partial-base>
|
</partial-base>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
require('./partial-base');
|
require('./partial-base');
|
||||||
require('../components/events-list');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'partial-dev-fire-event',
|
is: 'partial-dev-fire-event',
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class='header'>Current entities</div>
|
<div class='header'>Current entities</div>
|
||||||
<entity-list on-entity-selected='entitySelected'></entity-list>
|
<entity-list on-entity-selected='entitySelected' hass='[[hass]]'></entity-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</partial-base>
|
</partial-base>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
require('./partial-base');
|
require('./partial-base');
|
||||||
require('../components/entity-list');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'partial-dev-set-state',
|
is: 'partial-dev-set-state',
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<loading-box hidden$='[[!isLoading]]'>Loading logbook entries</loading-box>
|
<loading-box hidden$='[[!isLoading]]'>Loading logbook entries</loading-box>
|
||||||
</div>
|
</div>
|
||||||
<ha-logbook entries="[[entries]]" hidden$='[[isLoading]]'></ha-logbook>
|
<ha-logbook hass='[[hass]]' entries="[[entries]]" hidden$='[[isLoading]]'></ha-logbook>
|
||||||
</div>
|
</div>
|
||||||
</partial-base>
|
</partial-base>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
require('./partial-base');
|
require('./partial-base');
|
||||||
require('../components/ha-logbook');
|
require('../components/logbook-entry');
|
||||||
require('../components/loading-box');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'partial-logbook',
|
is: 'partial-logbook',
|
||||||
|
@ -12,7 +12,38 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<img class='camera-image' src="[[computeCameraImageUrl(stateObj)]]"
|
<img class='camera-image' src="[[computeCameraImageUrl(hass, stateObj)]]"
|
||||||
on-load='imageLoaded' />
|
on-load='imageLoaded' />
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'more-info-camera',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
stateObj: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
imageLoaded: function () {
|
||||||
|
this.fire('iron-resize');
|
||||||
|
},
|
||||||
|
|
||||||
|
computeCameraImageUrl: function (hass, stateObj) {
|
||||||
|
if (hass.demo) {
|
||||||
|
return '/demo/webcam.jpg';
|
||||||
|
} else if (stateObj) {
|
||||||
|
return `/api/camera_proxy_stream/${stateObj.entityId}` +
|
||||||
|
`?token=${stateObj.attributes.access_token}`;
|
||||||
|
}
|
||||||
|
// Return an empty image if no stateObj (= dialog not open)
|
||||||
|
return 'data:image/gif;base64,R0lGODlhAQABAAAAACw=';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@ -1,26 +0,0 @@
|
|||||||
import Polymer from '../polymer';
|
|
||||||
|
|
||||||
export default new Polymer({
|
|
||||||
is: 'more-info-camera',
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
stateObj: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
imageLoaded() {
|
|
||||||
this.fire('iron-resize');
|
|
||||||
},
|
|
||||||
|
|
||||||
computeCameraImageUrl(stateObj) {
|
|
||||||
if (__DEMO__) {
|
|
||||||
return '/demo/webcam.jpg';
|
|
||||||
} else if (stateObj) {
|
|
||||||
return `/api/camera_proxy_stream/${stateObj.entityId}` +
|
|
||||||
`?token=${stateObj.attributes.access_token}`;
|
|
||||||
}
|
|
||||||
// Return an empty image if no stateObj (= dialog not open)
|
|
||||||
return 'data:image/gif;base64,R0lGODlhAQABAAAAACw=';
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,7 +1,5 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
require('../components/loading-box');
|
|
||||||
|
|
||||||
export default new Polymer({
|
export default new Polymer({
|
||||||
is: 'more-info-configurator',
|
is: 'more-info-configurator',
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ require('./more-info-thermostat');
|
|||||||
require('./more-info-script');
|
require('./more-info-script');
|
||||||
require('./more-info-light');
|
require('./more-info-light');
|
||||||
require('./more-info-media_player');
|
require('./more-info-media_player');
|
||||||
require('./more-info-camera');
|
|
||||||
require('./more-info-updater');
|
require('./more-info-updater');
|
||||||
require('./more-info-alarm_control_panel');
|
require('./more-info-alarm_control_panel');
|
||||||
require('./more-info-lock');
|
require('./more-info-lock');
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
import attributeClassNames from '../util/attribute-class-names';
|
import attributeClassNames from '../util/attribute-class-names';
|
||||||
|
|
||||||
require('../components/ha-color-picker');
|
|
||||||
|
|
||||||
const ATTRIBUTE_CLASSES = ['brightness', 'rgb_color', 'color_temp'];
|
const ATTRIBUTE_CLASSES = ['brightness', 'rgb_color', 'color_temp'];
|
||||||
|
|
||||||
function pickColor(hass, entityId, color) {
|
function pickColor(hass, entityId, color) {
|
||||||
|
36
src/util/hass-behavior.html
Normal file
36
src/util/hass-behavior.html
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<script>
|
||||||
|
window.hassBehavior = {
|
||||||
|
attached: function attached() {
|
||||||
|
var hass = this.hass;
|
||||||
|
|
||||||
|
if (!hass) {
|
||||||
|
throw new Error('No hass property found on ' + this.nodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.nuclearUnwatchFns = Object.keys(this.properties).reduce(
|
||||||
|
function bindGetters(unwatchFns, key) {
|
||||||
|
if (!('bindNuclear' in this.properties[key])) {
|
||||||
|
return unwatchFns;
|
||||||
|
}
|
||||||
|
|
||||||
|
var getter = this.properties[key].bindNuclear(hass);
|
||||||
|
|
||||||
|
if (!getter) {
|
||||||
|
throw new Error(`Undefined getter specified for key ${key}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this[key] = hass.reactor.evaluate(getter);
|
||||||
|
|
||||||
|
return unwatchFns.concat(hass.reactor.observe(getter, function updateAttribute(val) {
|
||||||
|
this[key] = val;
|
||||||
|
}.bind(this)));
|
||||||
|
}.bind(this), []);
|
||||||
|
},
|
||||||
|
|
||||||
|
detached: function detached() {
|
||||||
|
while (this.nuclearUnwatchFns.length) {
|
||||||
|
this.nuclearUnwatchFns.shift()();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -1,44 +0,0 @@
|
|||||||
export default {
|
|
||||||
|
|
||||||
attached() {
|
|
||||||
const hass = this.hass;
|
|
||||||
|
|
||||||
if (!hass) {
|
|
||||||
throw new Error(`No hass property found on ${this.nodeName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.nuclearUnwatchFns = Object.keys(this.properties).reduce(
|
|
||||||
(unwatchFns, key) => {
|
|
||||||
if (!('bindNuclear' in this.properties[key])) {
|
|
||||||
return unwatchFns;
|
|
||||||
}
|
|
||||||
|
|
||||||
let getter = this.properties[key].bindNuclear;
|
|
||||||
|
|
||||||
if (typeof getter !== 'function') {
|
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.warn(`Component ${this.nodeName} uses old style bindNuclear`);
|
|
||||||
/* eslint-enable no-console */
|
|
||||||
} else {
|
|
||||||
getter = getter(hass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!getter) {
|
|
||||||
throw new Error(`Undefined getter specified for key ${key}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this[key] = hass.reactor.evaluate(getter);
|
|
||||||
|
|
||||||
return unwatchFns.concat(hass.reactor.observe(getter, (val) => {
|
|
||||||
this[key] = val;
|
|
||||||
}));
|
|
||||||
}, []);
|
|
||||||
},
|
|
||||||
|
|
||||||
detached() {
|
|
||||||
while (this.nuclearUnwatchFns.length) {
|
|
||||||
this.nuclearUnwatchFns.shift()();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
@ -1,7 +0,0 @@
|
|||||||
export default function removeInitMessage() {
|
|
||||||
// remove the HTML init message
|
|
||||||
const initMsg = document.getElementById('ha-init-skeleton');
|
|
||||||
if (initMsg) {
|
|
||||||
initMsg.parentElement.removeChild(initMsg);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export default function (hass, authToken, rememberAuth) {
|
|
||||||
hass.authActions.validate(authToken, {
|
|
||||||
rememberAuth,
|
|
||||||
useStreaming: hass.localStoragePreferences.useStreaming,
|
|
||||||
});
|
|
||||||
}
|
|
@ -9,6 +9,7 @@ var definePlugin = new webpack.DefinePlugin({
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
_app_compiled: './src/home-assistant.js',
|
_app_compiled: './src/home-assistant.js',
|
||||||
|
_app_core_compiled: './src/app-core.js',
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: 'build',
|
path: 'build',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user