Frontend: Clicking a card opens more info screen

This commit is contained in:
Paulus Schoutsen 2014-12-29 22:47:29 -08:00
parent 89a548252a
commit d5737aafce
27 changed files with 671 additions and 662 deletions

View file

@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "78343829ea70bf07a9e939b321587122"
VERSION = "9e0c2f360a70a0f7fc95e814d7e99dc1"

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,23 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="state-card-display.html">
<link rel="import" href="state-card-toggle.html">
<polymer-element name="state-card-content" attributes="api stateObj" noscript>
<template>
<template id="display">
<state-card-display
stateObj="{{stateObj}}">
</state-card-display>
</template>
<template id="toggle">
<state-card-toggle
stateObj="{{stateObj}}"
api="{{api}}">
</state-card-display>
</template>
<template bind ref="{{stateObj.cardType}}"></template>
</template>
</polymer-element>

View file

@ -0,0 +1,23 @@
<script src="../bower_components/moment/moment.js"></script>
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../components/state-info.html">
<polymer-element name="state-card-display" attributes="stateObj" noscript>
<template>
<style>
.state {
margin-left: 10px;
text-transform: capitalize;
font-weight: 300;
font-size: 1.3rem;
text-align: right;
}
</style>
<div horizontal justified layout>
<state-info stateObj="{{stateObj}}"></state-info>
<div class='state'>{{stateObj.stateDisplay}}</div>
</div>
</template>
</polymer-element>

View file

@ -0,0 +1,92 @@
<script src="../bower_components/moment/moment.js"></script>
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../components/state-info.html">
<polymer-element name="state-card-toggle" attributes="stateObj api">
<template>
<style>
/* the splash while enabling */
paper-toggle-button::shadow paper-radio-button::shadow #ink[checked] {
color: #0091ea;
}
/* filling of circle when checked */
paper-toggle-button::shadow paper-radio-button::shadow #onRadio {
background-color: #039be5;
}
/* line when checked */
paper-toggle-button::shadow #toggleBar[checked] {
background-color: #039be5;
}
</style>
<div horizontal justified layout>
<state-info flex stateObj="{{stateObj}}"></state-info>
<paper-toggle-button self-center
checked="{{toggleChecked}}"
on-click="{{toggleClicked}}">
</paper-toggle-button>
</div>
</template>
<script>
Polymer({
toggleChecked: -1,
observe: {
'stateObj.state': 'stateChanged'
},
// prevent the event from propegating
toggleClicked: function(ev) {
ev.stopPropagation();
},
toggleCheckedChanged: function(oldVal, newVal) {
// to filter out init
if(oldVal === -1) {
return;
}
if(newVal && this.stateObj.state == "off") {
this.turn_on();
} else if(!newVal && this.stateObj.state == "on") {
this.turn_off();
}
},
stateChanged: function(oldVal, newVal) {
this.toggleChecked = newVal === "on";
},
turn_on: function() {
// We call stateChanged after a successful call to re-sync the toggle
// with the state. It will be out of sync if our service call did not
// result in the entity to be turned on. Since the state is not changing,
// the resync is not called automatic.
this.api.turn_on(this.stateObj.entity_id, {
success: function() {
this.stateChanged(this.stateObj.state, this.stateObj.state);
}.bind(this)
});
},
turn_off: function() {
// We call stateChanged after a successful call to re-sync the toggle
// with the state. It will be out of sync if our service call did not
// result in the entity to be turned on. Since the state is not changing,
// the resync is not called automatic.
this.api.turn_off(this.stateObj.entity_id, {
success: function() {
this.stateChanged(this.stateObj.state, this.stateObj.state);
}.bind(this)
});
},
});
</script>
</polymer-element>

View file

@ -0,0 +1,34 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="state-card-content.html">
<polymer-element name="state-card" attributes="api stateObj" on-click="cardClicked">
<template>
<style>
:host {
background-color: #fff;
border-radius: 2px;
box-shadow: rgba(0, 0, 0, 0.098) 0px 2px 4px, rgba(0, 0, 0, 0.098) 0px 0px 3px;
transition: all 0.30s ease-out;
position: relative;
background-color: white;
padding: 16px;
width: 100%;
cursor: pointer;
}
</style>
<state-card-content stateObj={{stateObj}} api={{api}}></state-card-content>
</template>
<script>
Polymer({
cardClicked: function() {
this.api.showStateCardDialog(this.stateObj.entity_id);
},
});
</script>
</polymer-element>

View file

@ -1,9 +1,9 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-icon/core-icon.html">
<link rel="import" href="bower_components/core-icons/social-icons.html">
<link rel="import" href="bower_components/core-icons/image-icons.html">
<link rel="import" href="bower_components/core-icons/hardware-icons.html">
<link rel="import" href="../bower_components/core-icon/core-icon.html">
<link rel="import" href="../bower_components/core-icons/social-icons.html">
<link rel="import" href="../bower_components/core-icons/image-icons.html">
<link rel="import" href="../bower_components/core-icons/hardware-icons.html">
<polymer-element name="domain-icon"
attributes="domain state" constructor="DomainIcon">

View file

@ -1,4 +1,4 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="entity-list" attributes="api cbEntityClicked">
<template>

View file

@ -1,4 +1,4 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="events-list" attributes="api cbEventClicked">
<template>

View file

@ -1,7 +1,7 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-menu/core-menu.html">
<link rel="import" href="bower_components/core-menu/core-submenu.html">
<link rel="import" href="bower_components/core-item/core-item.html">
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-menu/core-menu.html">
<link rel="import" href="../bower_components/core-menu/core-submenu.html">
<link rel="import" href="../bower_components/core-item/core-item.html">
<link rel="import" href="domain-icon.html">

View file

@ -1,5 +1,5 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-image/core-image.html">
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-image/core-image.html">
<link rel="import" href="domain-icon.html">

View file

@ -1,21 +1,15 @@
<script src="bower_components/moment/moment.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-tooltip/core-tooltip.html">
<link rel="import" href="bower_components/core-style/core-style.html">
<script src="../bower_components/moment/moment.js"></script>
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-tooltip/core-tooltip.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="state-badge.html">
<polymer-element name="state-info"
attributes="stateObj cb_edit">
<polymer-element name="state-info" attributes="stateObj">
<template>
<style>
state-badge {
float: left;
cursor: pointer;
}
state-badge:hover {
background-color: #039be5;
}
.name {
@ -35,10 +29,7 @@
</style>
<div>
<state-badge
stateObj="{{stateObj}}"
on-click="{{editClicked}}">
</state-badge>
<state-badge stateObj="{{stateObj}}"></state-badge>
<div class='info'>
<div class='name'>
@ -57,17 +48,10 @@
<script>
Polymer({
stateObj: {},
lastChangedFromNow: function(lastChanged) {
return moment(lastChanged, "HH:mm:ss DD-MM-YYYY").fromNow();
},
editClicked: function() {
if(this.cb_edit) {
this.cb_edit(this.stateObj.entity_id);
}
},
}
});
</script>

View file

@ -0,0 +1,89 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../bower_components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="../components/events-list.html">
<polymer-element name="event-fire-dialog" attributes="api">
<template>
<paper-action-dialog
id="dialog" heading="Fire Event"
transition="core-transition-bottom"
backdrop="true" layered="false">
<core-style ref='ha-dialog'></core-style>
<div layout horizontal>
<div class='ha-form'>
<paper-input
id="inputType" label="Event Type" floatingLabel="true"
autofocus required></paper-input>
<paper-input-decorator
label="Event Data (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
</div>
<div class='sidebar'>
<b>Available events:</b>
<events-list api={{api}} cbEventClicked={{eventSelected}}></event-list>
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickFireEvent}}>Fire Event</paper-button>
</paper-dialog>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.eventSelected = this.eventSelected.bind(this);
},
show: function(eventType, eventData) {
this.setEventType(eventType);
this.setEventData(eventData);
this.$.dialog.toggle();
},
setEventType: function(eventType) {
this.$.inputType.value = eventType;
},
setEventData: function(eventData) {
this.$.inputData.value = eventData;
// this.$.inputDataWrapper.update();
},
eventSelected: function(eventType) {
this.setEventType(eventType);
},
clickFireEvent: function() {
var data;
if(this.$.inputData.value !== "") {
data = JSON.parse(this.$.inputData.value);
} else {
data = {};
}
this.api.fire_event(this.$.inputType.value, data);
}
});
</script>
</polymer-element>

View file

@ -0,0 +1,86 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../bower_components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="../bower_components/paper-dialog/paper-dialog-transition.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="../components/services-list.html">
<polymer-element name="service-call-dialog" attributes="api">
<template>
<paper-action-dialog
id="dialog" heading="Call Service"
transition="core-transition-bottom"
backdrop="true" layered="false">
<core-style ref='ha-dialog'></core-style>
<div layout horizontal>
<div class='ha-form'>
<paper-input id="inputDomain" label="Domain" floatingLabel="true" autofocus required></paper-input>
<paper-input id="inputService" label="Service" floatingLabel="true" required></paper-input>
<paper-input-decorator
label="Service Data (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
</div>
<div class='sidebar'>
<b>Available services:</b>
<services-list api={{api}} cbServiceClicked={{serviceSelected}}></event-list>
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickCallService}}>Call Service</paper-button>
</paper-action-dialog>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.serviceSelected = this.serviceSelected.bind(this)
},
show: function(domain, service, serviceData) {
this.setService(domain, service);
this.$.inputData.value = serviceData;
// this.$.inputDataWrapper.update();
this.$.dialog.toggle();
},
setService: function(domain, service) {
this.$.inputDomain.value = domain;
this.$.inputService.value = service;
},
serviceSelected: function(domain, service) {
this.setService(domain, service);
},
clickCallService: function() {
var data;
if(this.$.inputData.value != "") {
data = JSON.parse(this.$.inputData.value);
}
this.api.call_service(
this.$.inputDomain.value,
this.$.inputService.value,
data);
}
});
</script>
</polymer-element>

View file

@ -0,0 +1,39 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../cards/state-card-content.html">
<polymer-element name="state-card-dialog" attributes="api">
<template>
<paper-action-dialog
id="dialog"
transition="core-transition-bottom"
backdrop="true" layered="false">
<core-style ref='ha-dialog'></core-style>
<div>
<state-card-content stateObj="{{stateObj}}" api="{{api}}"></state-card-content>
</div>
<paper-button dismissive>Dismiss</paper-button>
<paper-button affirmative on-click={{editClicked}}>Edit State</paper-button>
</paper-action-dialog>
</template>
<script>
Polymer({
stateObj: {},
show: function(stateObj) {
this.stateObj = stateObj;
this.$.dialog.toggle();
},
editClicked: function(ev) {
this.api.showEditStateDialog(this.stateObj.entity_id);
}
});
</script>
</polymer-element>

View file

@ -0,0 +1,93 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../bower_components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="../components/entity-list.html">
<polymer-element name="state-set-dialog" attributes="api">
<template>
<paper-action-dialog
id="dialog" heading="Set State"
transition="core-transition-bottom"
backdrop="true" layered="false">
<core-style ref='ha-dialog'></core-style>
<div layout horizontal>
<div class='ha-form'>
<paper-input id="inputEntityID" label="Entity ID" floatingLabel="true" autofocus required></paper-input>
<paper-input id="inputState" label="State" floatingLabel="true" required></paper-input>
<paper-input-decorator
label="State attributes (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
</div>
<div class='sidebar'>
<b>Current entities:</b>
<entity-list api={{api}} cbEntityClicked={{entitySelected}}></entity-list>
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickSetState}}>Set State</paper-button>
</paper-action-dialog>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.entitySelected = this.entitySelected.bind(this);
},
show: function(entityId, state, stateData) {
this.setEntityId(entityId);
this.setState(state);
this.setStateData(stateData);
this.$.dialog.toggle();
},
setEntityId: function(entityId) {
this.$.inputEntityID.value = entityId;
},
setState: function(state) {
this.$.inputState.value = state;
},
setStateData: function(stateData) {
var value = stateData ? JSON.stringify(stateData, null, ' ') : "";
this.$.inputData.value = value;
},
entitySelected: function(entityId) {
this.setEntityId(entityId);
var state = this.api.getState(entityId);
this.setState(state.state);
this.setStateData(state.attributes);
},
clickSetState: function() {
this.api.set_state(
this.$.inputEntityID.value,
this.$.inputState.value,
JSON.parse(this.$.inputData.value)
);
}
});
</script>
</polymer-element>

View file

@ -1,109 +0,0 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-input/paper-input.html">
<link rel="import" href="bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="events-list.html">
<polymer-element name="event-fire-dialog" attributes="api">
<template>
<paper-action-dialog id="dialog" heading="Fire Event" transition="core-transition-bottom" backdrop>
<style>
:host {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
}
paper-input {
display: block;
}
paper-input:first-child {
padding-top: 0;
}
.eventContainer {
margin-left: 30px;
}
@media all and (max-width: 620px) {
paper-action-dialog {
margin: 0;
width: 100%;
height: calc(100% - 64px);
top: 64px;
}
.eventContainer {
display: none;
}
}
</style>
<div layout horizontal>
<div>
<paper-input id="inputType" label="Event Type" floatingLabel="true" autofocus required></paper-input>
<paper-input-decorator
label="Event Data (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
</div>
<div class='eventContainer'>
<b>Available events:</b>
<events-list api={{api}} cbEventClicked={{eventSelected}}></event-list>
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickFireEvent}}>Fire Event</paper-button>
</paper-dialog>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.eventSelected = this.eventSelected.bind(this)
},
show: function(eventType, eventData) {
this.setEventType(eventType);
this.setEventData(eventData);
this.$.dialog.toggle();
},
setEventType: function(eventType) {
this.$.inputType.value = eventType;
},
setEventData: function(eventData) {
this.$.inputData.value = eventData;
// this.$.inputDataWrapper.update();
},
eventSelected: function(eventType) {
this.setEventType(eventType);
},
clickFireEvent: function() {
var data;
if(this.$.inputData.value != "") {
data = JSON.parse(this.$.inputData.value);
} else {
data = {};
}
this.api.fire_event(this.$.inputType.value, data);
}
});
</script>
</polymer-element>

View file

@ -1,16 +1,18 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/paper-toast/paper-toast.html">
<link rel="import" href="event-fire-dialog.html">
<link rel="import" href="service-call-dialog.html">
<link rel="import" href="state-set-dialog.html">
<link rel="import" href="dialogs/event-fire-dialog.html">
<link rel="import" href="dialogs/service-call-dialog.html">
<link rel="import" href="dialogs/state-set-dialog.html">
<link rel="import" href="dialogs/state-card-dialog.html">
<polymer-element name="home-assistant-api" attributes="auth">
<template>
<paper-toast id="toast" role="alert" text=""></paper-toast>
<event-fire-dialog id="eventDialog" api={{api}}></event-fire-dialog>
<service-call-dialog id="serviceDialog" api={{api}}></service-call-dialog>
<state-set-dialog id="stateDialog" api={{api}}></state-set-dialog>
<state-set-dialog id="stateSetDialog" api={{api}}></state-set-dialog>
<state-card-dialog id="stateCardDialog" api={{api}}></state-card-dialog>
</template>
<script>
@ -22,12 +24,12 @@
this.entity_id = json.entity_id;
var parts = json.entity_id.split(".");
this.domain = parts[0];
this.entity = parts[1];
this.object_id = parts[1];
if(this.attributes.friendly_name) {
this.entityDisplay = this.attributes.friendly_name;
} else {
this.entityDisplay = this.entity.replace(/_/g, " ");
this.entityDisplay = this.object_id.replace(/_/g, " ");
}
this.state = json.state;
@ -330,6 +332,10 @@
},
// show dialogs
showStateCardDialog: function(entityId) {
this.$.stateCardDialog.show(this.getState(entityId));
},
showEditStateDialog: function(entityId) {
var state = this.getState(entityId);
@ -341,7 +347,7 @@
state = state || "";
stateAttributes = stateAttributes || null;
this.$.stateDialog.show(entityId, state, stateAttributes);
this.$.stateSetDialog.show(entityId, state, stateAttributes);
},
showFireEventDialog: function(eventType, eventData) {

View file

@ -8,7 +8,7 @@
<link rel="import" href="bower_components/core-menu/core-menu.html">
<link rel="import" href="bower_components/paper-item/paper-item.html">
<link rel="import" href="states-cards.html">
<link rel="import" href="state-cards.html">
<polymer-element name="home-assistant-main" attributes="api">
<template>
@ -110,10 +110,10 @@
</div>
</core-toolbar>
<states-cards
<state-cards
api="{{api}}"
filter="{{selectedTab}}"
class="content"></states-cards>
class="content"></state-cards>
</core-header-panel>

View file

@ -0,0 +1,39 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-style/core-style.html">
<polymer-element name="home-assistant-style" noscript>
<template>
<core-style id="ha-dialog">
paper-action-dialog, paper-dialog {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
min-width: 350px;
}
paper-action-dialog .sidebar, paper-dialog .sidebar {
margin-left: 30px;
}
@media all and (max-width: 620px) {
paper-action-dialog, paper-dialog {
margin: 0;
width: 100%;
height: calc(100% - 64px);
top: 64px;
}
paper-action-dialog .sidebar, paper-dialog .sidebar {
display: none;
}
}
.ha-form paper-input {
display: block;
}
.ha-form paper-input:first-child {
padding-top: 0;
}
</core-style>
</template>
</polymer-element>

View file

@ -1,108 +0,0 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="bower_components/paper-dialog/paper-dialog-transition.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-input/paper-input.html">
<link rel="import" href="bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="services-list.html">
<polymer-element name="service-call-dialog" attributes="api">
<template>
<paper-action-dialog id="dialog" heading="Call Service" transition="core-transition-bottom" backdrop="true">
<style>
:host {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
}
paper-input {
display: block;
}
paper-input:first-child {
padding-top: 0;
}
.serviceContainer {
margin-left: 30px;
}
@media all and (max-width: 620px) {
paper-action-dialog {
margin: 0;
width: 100%;
height: calc(100% - 64px);
top: 64px;
}
.serviceContainer {
display: none;
}
}
</style>
<div layout horizontal>
<div>
<paper-input id="inputDomain" label="Domain" floatingLabel="true" autofocus required></paper-input>
<paper-input id="inputService" label="Service" floatingLabel="true" required></paper-input>
<paper-input-decorator
label="Service Data (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
</div>
<div class='serviceContainer'>
<b>Available services:</b>
<services-list api={{api}} cbServiceClicked={{serviceSelected}}></event-list>
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickCallService}}>Call Service</paper-button>
</paper-action-dialog>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.serviceSelected = this.serviceSelected.bind(this)
},
show: function(domain, service, serviceData) {
this.setService(domain, service);
this.$.inputData.value = serviceData;
// this.$.inputDataWrapper.update();
this.$.dialog.toggle();
},
setService: function(domain, service) {
this.$.inputDomain.value = domain;
this.$.inputService.value = service;
},
serviceSelected: function(domain, service) {
this.setService(domain, service);
},
clickCallService: function() {
var data;
if(this.$.inputData.value != "") {
data = JSON.parse(this.$.inputData.value);
}
this.api.call_service(
this.$.inputDomain.value,
this.$.inputService.value,
data);
}
});
</script>
</polymer-element>

View file

@ -6,6 +6,7 @@
<link rel="import" href="home-assistant-main.html">
<link rel="import" href="home-assistant-api.html">
<link rel="import" href="home-assistant-style.html">
<polymer-element name="splash-login" attributes="auth">
<template>
@ -37,6 +38,7 @@
</style>
<home-assistant-style></home-assistant-style>
<home-assistant-api auth="{{auth}}" id="api"></home-assistant-api>
<div layout horizontal center fit class='login' id="splash">

View file

@ -1,30 +0,0 @@
<script src="bower_components/moment/moment.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-style/core-style.html">
<link rel="import" href="state-info.html">
<polymer-element name="state-card-display"
attributes="stateObj cb_edit"
noscript>
<template>
<core-style ref='state-card'></core-style>
<style>
.state {
text-transform: capitalize;
font-weight: 300;
font-size: 1.3rem;
text-align: right;
}
</style>
<div horizontal justified layout>
<state-info
stateObj="{{stateObj}}"
cb_edit="{{cb_edit}}">
</state-info>
<div class='state'>{{stateObj.stateDisplay}}</div>
</div>
</template>
</polymer-element>

View file

@ -1,117 +0,0 @@
<script src="bower_components/moment/moment.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="bower_components/core-style/core-style.html">
<link rel="import" href="state-badge.html">
<polymer-element name="state-card-toggle"
attributes="stateObj cb_turn_on, cb_turn_off cb_edit">
<template>
<core-style ref='state-card'></core-style>
<style>
.state {
text-align: right;
}
/* the splash while enabling */
paper-toggle-button::shadow paper-radio-button::shadow #ink[checked] {
color: #0091ea;
}
/* filling of circle when checked */
paper-toggle-button::shadow paper-radio-button::shadow #onRadio {
background-color: #039be5;
}
/* line when checked */
paper-toggle-button::shadow #toggleBar[checked] {
background-color: #039be5;
}
</style>
<div horizontal justified layout>
<state-info
stateObj="{{stateObj}}"
cb_edit="{{cb_edit}}">
</state-info>
<div class='state toggle' self-center flex>
<paper-toggle-button checked="{{toggleChecked}}">
</paper-toggle-button>
</div>
</div>
</template>
<script>
Polymer({
stateObj: {},
cb_turn_on: null,
cb_turn_off: null,
cb_edit: null,
toggleChecked: -1,
observe: {
'stateObj.state': 'stateChanged'
},
lastChangedFromNow: function(lastChanged) {
return moment(lastChanged, "HH:mm:ss DD-MM-YYYY").fromNow();
},
toggleCheckedChanged: function(oldVal, newVal) {
// to filter out init
if(oldVal === -1) {
return;
}
if(newVal && this.stateObj.state == "off") {
this.turn_on();
} else if(!newVal && this.stateObj.state == "on") {
this.turn_off();
}
},
stateChanged: function(oldVal, newVal) {
this.toggleChecked = newVal === "on";
},
turn_on: function() {
// We call stateChanged after a successful call to re-sync the toggle
// with the state. It will be out of sync if our service call did not
// result in the entity to be turned on. Since the state is not changing,
// the resync is not called automatic.
if(this.cb_turn_on) {
this.cb_turn_on(this.stateObj.entity_id, {
success: function() {
this.stateChanged(this.stateObj.state, this.stateObj.state);
}.bind(this)
});
}
},
turn_off: function() {
// We call stateChanged after a successful call to re-sync the toggle
// with the state. It will be out of sync if our service call did not
// result in the entity to be turned on. Since the state is not changing,
// the resync is not called automatic.
if(this.cb_turn_off) {
this.cb_turn_off(this.stateObj.entity_id, {
success: function() {
this.stateChanged(this.stateObj.state, this.stateObj.state);
}.bind(this)
});
}
},
editClicked: function() {
if(this.cb_edit) {
this.cb_edit(this.stateObj.entity_id);
}
},
});
</script>
</polymer-element>

View file

@ -0,0 +1,75 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="cards/state-card.html">
<polymer-element name="state-cards" attributes="api filter">
<template>
<style>
:host {
display: block;
width: 100%;
}
@media all and (min-width: 764px) {
:host {
padding-bottom: 8px;
}
.state-card {
width: calc(50% - 44px);
margin: 8px 0 0 8px;
}
}
@media all and (min-width: 1100px) {
.state-card {
width: calc(33% - 38px);
}
}
@media all and (min-width: 1450px) {
.state-card {
width: calc(25% - 42px);
}
}
</style>
<div horizontal layout wrap>
<template repeat="{{state in getStates(api.states, filter)}}">
<state-card class="state-card" stateObj={{state}} api={{api}}></state-card>
</template>
</div>
</template>
<script>
Polymer({
filter: null,
getStates: function(states, filter) {
if(!states) {
return [];
}
if(!filter) {
// if no filter, return all non-group states
return states.filter(function(state) {
return state.domain != 'group';
});
} else {
// we have a filter, return the parent filter and its children
var filter_state = this.api.getState(this.filter);
var map_states = function(entity_id) {
return this.api.getState(entity_id);
}.bind(this);
return [filter_state].concat(
filter_state.attributes.entity_id.map(map_states));
}
},
});
</script>
</polymer-element>

View file

@ -1,115 +0,0 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-input/paper-input.html">
<link rel="import" href="bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="entity-list.html">
<polymer-element name="state-set-dialog" attributes="api">
<template>
<paper-action-dialog id="dialog" heading="Set State" transition="core-transition-bottom" backdrop="true">
<style>
:host {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
}
paper-input {
display: block;
}
paper-input:first-child {
padding-top: 0;
}
.stateContainer {
margin-left: 30px;
}
@media all and (max-width: 620px) {
paper-action-dialog {
margin: 0;
width: 100%;
height: calc(100% - 64px);
top: 64px;
}
.stateContainer {
display: none;
}
}
</style>
<div layout horizontal>
<div>
<paper-input id="inputEntityID" label="Entity ID" floatingLabel="true" autofocus required></paper-input>
<paper-input id="inputState" label="State" floatingLabel="true" required></paper-input>
<paper-input-decorator
label="State attributes (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
</div>
<div class='stateContainer'>
<b>Current entities:</b>
<entity-list api={{api}} cbEntityClicked={{entitySelected}}></entity-list>
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickSetState}}>Set State</paper-button>
</paper-action-dialog>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.entitySelected = this.entitySelected.bind(this)
},
show: function(entityId, state, stateData) {
this.setEntityId(entityId);
this.setState(state);
this.setStateData(stateData);
this.$.dialog.toggle();
},
setEntityId: function(entityId) {
this.$.inputEntityID.value = entityId;
},
setState: function(state) {
this.$.inputState.value = state;
},
setStateData: function(stateData) {
var value = stateData ? JSON.stringify(stateData, null, ' ') : "";
this.$.inputData.value = value;
},
entitySelected: function(entityId) {
this.setEntityId(entityId);
var state = this.api.getState(entityId);
this.setState(state.state);
this.setStateData(state.attributes);
},
clickSetState: function() {
this.api.set_state(
this.$.inputEntityID.value,
this.$.inputState.value,
JSON.parse(this.$.inputData.value)
);
}
});
</script>
</polymer-element>

View file

@ -1,117 +0,0 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-style/core-style.html">
<link rel="import" href="state-card-display.html">
<link rel="import" href="state-card-toggle.html">
<polymer-element name="states-cards" attributes="api filter">
<template>
<style>
:host {
display: block;
width: 100%;
}
@media all and (min-width: 764px) {
:host {
padding-bottom: 8px;
}
.state-card {
width: calc(50% - 44px);
margin: 8px 0 0 8px;
}
}
@media all and (min-width: 1100px) {
.state-card {
width: calc(33% - 38px);
}
}
@media all and (min-width: 1450px) {
.state-card {
width: calc(25% - 42px);
}
}
</style>
<core-style id="state-card">
<!-- generic state card CSS -->
:host {
background-color: #fff;
border-radius: 2px;
box-shadow: rgba(0, 0, 0, 0.098) 0px 2px 4px, rgba(0, 0, 0, 0.098) 0px 0px 3px;
transition: all 0.30s ease-out;
position: relative;
background-color: white;
padding: 16px;
width: 100%;
}
</core-style>
<div horizontal layout wrap>
<template id="display">
<state-card-display
class='state-card'
stateObj="{{state}}"
cb_edit={{editCallback}}>
</state-card-display>
</template>
<template id="toggle">
<state-card-toggle
class='state-card'
stateObj="{{state}}"
cb_turn_on="{{api.turn_on}}"
cb_turn_off="{{api.turn_off}}"
cb_edit={{editCallback}}>
</state-card-display>
</template>
<template repeat="{{state in getStates(api.states, filter)}}">
<template bind ref="{{state.cardType}}"></template>
</template>
</div>
</template>
<script>
Polymer({
filter: null,
getStates: function(states, filter) {
if(!states) {
return [];
}
if(!filter) {
// if no filter, return all non-group states
return states.filter(function(state) {
return state.domain != 'group';
});
} else {
// we have a filter, return the parent filter and its children
var filter_state = this.api.getState(this.filter);
var map_states = function(entity_id) {
return this.api.getState(entity_id);
}.bind(this);
return [filter_state].concat(
filter_state.attributes.entity_id.map(map_states));
}
},
ready: function() {
this.editCallback = this.editCallback.bind(this);
},
editCallback: function(entityId) {
this.api.showEditStateDialog(entityId);
},
});
</script>
</polymer-element>