Polymer .9: convert dev tools

This commit is contained in:
Paulus Schoutsen 2015-05-19 23:38:32 -07:00
parent 33122701b9
commit 5baf16ad6e
7 changed files with 372 additions and 381 deletions

View File

@ -1,60 +1,53 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="entity-list" attributes="cbEntityClicked">
<dom-module id="entity-list">
<style>
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
line-height: 2em;
}
a {
color: var(--accent-color);
}
</style>
<template>
<style>
:host {
display: block;
}
.entityContainer {
font-size: 1rem;
}
</style>
<template if={{cbEntityClicked}}>
<style>
a {
text-decoration: underline;
cursor: pointer;
}
</style>
</template>
<div>
<template repeat="{{entityID in entityIDs}}">
<div class='eventContainer'>
<a on-click={{handleClick}}>{{entityID}}</a>
</div>
<ul>
<template is='dom-repeat' items='[[entities]]' as='entity'>
<li><a href='#' on-click='entitySelected'>[[entity]]</a></li>
</template>
</div>
</ul>
</template>
<script>
var storeListenerMixIn = window.hass.storeListenerMixIn;
</dom-module>
Polymer(Polymer.mixin({
cbEventClicked: null,
entityIDs: [],
<script>
(function() {
Polymer({
is: 'entity-list',
attached: function() {
this.listenToStores(true);
},
behaviors: [StoreListenerBehavior],
detached: function() {
this.stopListeningToStores();
properties: {
entities: {
type: Array,
value: [],
},
},
stateStoreChanged: function(stateStore) {
this.entityIDs = stateStore.entityIDs.toArray();
this.entities = stateStore.entityIDs.toArray();
},
handleClick: function(ev) {
if(this.cbEntityClicked) {
this.cbEntityClicked(ev.path[0].innerHTML);
}
entitySelected: function(ev) {
ev.preventDefault();
this.fire('entity-selected', {entityId: ev.model.entity});
},
}, storeListenerMixIn));
</script>
</polymer-element>
});
})();
</script>

View File

@ -1,62 +1,56 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="events-list" attributes="cbEventClicked">
<dom-module id="events-list">
<style>
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
line-height: 2em;
}
a {
color: var(--accent-color);
}
</style>
<template>
<style>
:host {
display: block;
}
.eventContainer {
font-size: 1rem;
}
</style>
<template if={{cbEventClicked}}>
<style>
a {
text-decoration: underline;
cursor: pointer;
}
</style>
</template>
<div>
<template repeat="{{event in events}}">
<div class='eventContainer'>
<a on-click={{handleClick}}>{{event.event}}</a>
({{event.listener_count}} listeners)
</div>
<ul>
<template is='dom-repeat' items='[[events]]' as='event'>
<li>
<a href='#' on-click='eventSelected'>{{event.event}}</a>
<span> (</span><span>{{event.listener_count}}</span><span> listeners)</span>
</li>
</template>
</div>
</ul>
</template>
<script>
var storeListenerMixIn = window.hass.storeListenerMixIn;
</dom-module>
Polymer(Polymer.mixin({
cbEventClicked: null,
events: [],
<script>
(function() {
Polymer({
is: 'events-list',
attached: function() {
this.listenToStores(true);
},
behaviors: [StoreListenerBehavior],
detached: function() {
this.stopListeningToStores();
properties: {
events: {
type: Array,
value: [],
},
},
eventStoreChanged: function(eventStore) {
this.events = eventStore.all.toArray();
},
handleClick: function(ev) {
if(this.cbEventClicked) {
this.cbEventClicked(ev.path[0].innerHTML);
}
eventSelected: function(ev) {
ev.preventDefault();
this.fire('event-selected', {eventType: ev.model.event.event});
},
}, storeListenerMixIn));
</script>
</polymer-element>
});
})();
</script>

View File

@ -1,72 +1,58 @@
<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/paper-menu/paper-menu.html">
<link rel="import" href="domain-icon.html">
<polymer-element name="services-list" attributes="cbServiceClicked">
<template>
<style>
:host {
display: block;
<dom-module id="services-list" attributes="cbServiceClicked">
<style>
ul {
margin: 0;
padding: 0;
}
core-menu {
margin-top: 0;
font-size: 1rem;
li {
list-style: none;
line-height: 2em;
}
a {
display: block;
color: var(--accent-color);
}
</style>
</style>
<template if={{cbServiceClicked}}>
<style>
a, core-submenu {
text-decoration: underline;
cursor: pointer;
}
</style>
</template>
<div>
<core-menu selected="0">
<template repeat="{{domain in domains}}">
<core-submenu icon="{{domain | getIcon}}" label="{{domain}}">
<template repeat="{{service in domain | getServices}}">
<a on-click={{serviceClicked}} data-domain={{domain}}>{{service}}</a>
</template>
</core-submenu>
</template>
</core-menu>
</div>
<template>
<ul>
<template is='dom-repeat' items="[[domains]]" as="domain">
<template is='dom-repeat' items="[[computeServices(domain)]]" as="service">
<li><a href='#' on-click='serviceClicked'>
<span>[[domain]]</span>/<span>[[service]]</span>
</a></li>
</template>
</template>
</ul>
</template>
<script>
var storeListenerMixIn = window.hass.storeListenerMixIn;
</dom-module>
Polymer(Polymer.mixin({
domains: [],
services: null,
cbServiceClicked: null,
<script>
(function() {
Polymer({
is: 'services-list',
attached: function() {
this.listenToStores(true);
behaviors: [StoreListenerBehavior],
properties: {
domains: {
type: Array,
value: [],
},
services: {
type: Object,
},
},
detached: function() {
this.stopListeningToStores();
},
getIcon: function(domain) {
return hass.uiUtil.domainIcon(domain);
},
getServices: function(domain) {
computeServices: function(domain) {
return this.services.get(domain).toArray();
},
@ -76,15 +62,10 @@
},
serviceClicked: function(ev) {
if(this.cbServiceClicked) {
var target = ev.path[0];
var domain = target.getAttributeNode("data-domain").value;
var service = target.innerHTML;
this.cbServiceClicked(domain, service);
}
}
}, storeListenerMixIn));
</script>
</polymer-element>
ev.preventDefault();
this.fire(
'service-selected', {domain: ev.model.domain, service: ev.model.service});
},
});
})();
</script>

View File

@ -12,11 +12,11 @@
<link rel="import" href="../layouts/partial-states.html">
<link rel="import" href="../layouts/partial-logbook.html">
<link rel="import" href="../layouts/partial-history.html">
<!-- <link rel="import" href="../layouts/partial-dev-fire-event.html">
<link rel="import" href="../layouts/partial-dev-call-service.html">
<link rel="import" href="../layouts/partial-dev-fire-event.html">
<link rel="import" href="../layouts/partial-dev-set-state.html">
<link rel="import" href="../components/ha-notifications.html">
<!--<link rel="import" href="../components/ha-notifications.html">
<link rel="import" href="../components/ha-modals.html"> -->
<link rel="import" href="../components/stream-status.html">
@ -59,7 +59,7 @@
<!-- <ha-notifications></ha-notifications> -->
<!-- <ha-modals></ha-modals> -->
<paper-drawer-panel id="drawer" on-paper-responsive-change="responsiveChanged">
<paper-drawer-panel id="drawer" narrow='{{narrow}}'>
<paper-header-panel mode="scroll" drawer class='sidenav fit'>
<paper-toolbar>
Home Assistant
@ -108,13 +108,13 @@
<div class='text label divider'>Developer Tools</div>
<div class='dev-tools layout horizontal justified'>
<paper-icon-button
icon="settings-remote" data-panel='[[selectedDevService]]'
icon="settings-remote" data-panel$='[[selectedDevService]]'
on-click="handleDevClick"></paper-icon-button>
<paper-icon-button
icon="settings-ethernet" data-panel='[[selectedSetState]]'
icon="settings-ethernet" data-panel$='[[selectedDevState]]'
on-click="handleDevClick"></paper-icon-button>
<paper-icon-button
icon="settings-input-antenna" data-panel='[[selectedDevEvent]]'
icon="settings-input-antenna" data-panel$='[[selectedDevEvent]]'
on-click="handleDevClick"></paper-icon-button>
</div>
</paper-menu>
@ -124,27 +124,26 @@
This is the main partial, never remove it from the DOM but hide it
to speed up when people click on states.
-->
<partial-states hidden$="{{hideStates}}"
main narrow="{{narrow}}"
filter="{{stateFilter}}">
<partial-states hidden$="[[hideStates]]"
main narrow="[[narrow]]"
filter="[[stateFilter]]">
</partial-states>
<template is='dom-if' if="{{isSelectedLogbook}}">
<partial-logbook main narrow="{{narrow}}"></partial-logbook>
<template is='dom-if' if="[[isSelectedLogbook]]">
<partial-logbook main narrow="[[narrow]]"></partial-logbook>
</template>
<template is='dom-if' if="{{isSelectedHistory}}">
<partial-history main narrow="{{narrow}}"></partial-history>
<template is='dom-if' if="[[isSelectedHistory]]">
<partial-history main narrow="[[narrow]]"></partial-history>
</template>
<!--
<template is='dom-if' if="{{selected == 'fire-event'}}">
<partial-dev-fire-event main narrow="{{narrow}}"></partial-dev-fire-event>
<template is='dom-if' if="[[isSelectedDevService]]">
<partial-dev-call-service main narrow="[[narrow]]"></partial-dev-call-service>
</template>
<template is='dom-if' if="{{selected == 'set-state'}}">
<partial-dev-set-state main narrow="{{narrow}}"></partial-dev-set-state>
<template is='dom-if' if="[[isSelectedDevEvent]]">
<partial-dev-fire-event main narrow="[[narrow]]"></partial-dev-fire-event>
</template>
<template is='dom-if' if="[[isSelectedDevState]]">
<partial-dev-set-state main narrow="[[narrow]]"></partial-dev-set-state>
</template>
<template is='dom-if' if="{{selected == 'call-service'}}">
<partial-dev-call-service main narrow="{{narrow}}"></partial-dev-call-service>
</template>-->
</paper-drawer-panel>
</template>
@ -311,10 +310,6 @@
}
},
responsiveChanged: function(ev, detail, sender) {
this.narrow = detail.narrow;
},
closeDrawer: function() {
this.$.drawer.closeDrawer();
},

View File

@ -2,87 +2,100 @@
<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="../bower_components/paper-input/paper-textarea.html">
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/services-list.html">
<polymer-element name="partial-dev-call-service" attributes="narrow togglePanel">
<template>
<dom-module id="partial-dev-call-service">
<style>
.form {
padding: 24px;
background-color: white;
}
.form {
padding: 24px;
background-color: white;
}
.ha-form {
margin-right: 16px;
}
</style>
<template>
<partial-base narrow="[[narrow]]">
<span header-title>Call Service</span>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>Call Service</span>
<div class='form fit'>
<p>
Call a service from a component.
</p>
<div class='form' fit>
<p>
Call a service from a component.
</p>
<div class$='[[computeFormClasses(narrow)]]'>
<div class='ha-form flex'>
<paper-input label="Domain" autofocus value='{{domain}}'></paper-input>
<paper-input label="Service" value='{{service}}'></paper-input>
<paper-textarea label="Service Data (JSON, optional)" value='{{serviceData}}'></paper-textarea>
<paper-button on-click='callService' raised>Call Service</paper-button>
</div>
<div layout horizontal?="{{!narrow}}" vertical?="{{narrow}}">
<div class='ha-form' flex?="{{!narrow}}">
<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>
</paper-input-decorator>
<paper-button on-click={{clickCallService}}>Call Service</paper-button>
</div>
<div class='sidebar'>
<b>Available services:</b>
<services-list cbServiceClicked={{serviceSelected}}></services-list>
<div>
<h4>Available services:</h4>
<services-list on-service-selected='serviceSelected'></services-list>
</div>
</div>
</div>
</div>
</partial-base>
</template>
</dom-module>
</partial-base>
</template>
<script>
var serviceActions = window.hass.serviceActions;
(function() {
var serviceActions = window.hass.serviceActions;
Polymer({
ready: function() {
// to ensure callback methods work..
this.serviceSelected = this.serviceSelected.bind(this);
},
Polymer({
is: 'partial-dev-call-service',
setService: function(domain, service) {
this.$.inputDomain.value = domain;
this.$.inputService.value = service;
},
properties: {
narrow: {
type: Boolean,
value: false,
},
serviceSelected: function(domain, service) {
this.setService(domain, service);
},
domain: {
type: String,
value: '',
},
clickCallService: function() {
try {
serviceActions.callService(
this.$.inputDomain.value,
this.$.inputService.value,
this.$.inputData.value ? JSON.parse(this.$.inputData.value) : {});
} catch (err) {
alert("Error parsing JSON: " + err);
}
}
service: {
type: String,
value: '',
},
});
serviceData: {
type: String,
value: '',
},
},
serviceSelected: function(ev) {
this.domain = ev.detail.domain;
this.service = ev.detail.service;
},
callService: function() {
var serviceData;
try {
serviceData = this.serviceData ? JSON.parse(this.serviceData): {};
} catch (err) {
alert("Error parsing JSON: " + err);
return;
}
serviceActions.callService(this.domain, this.service, serviceData);
},
computeFormClasses: function(narrow) {
return 'layout ' + (narrow ? 'vertical' : 'horizontal');
},
});
})();
</script>
</polymer-element>

View File

@ -2,79 +2,90 @@
<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="../bower_components/paper-input/paper-textarea.html">
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/events-list.html">
<polymer-element name="partial-dev-fire-event" attributes="narrow togglePanel">
<template>
<dom-module id="partial-dev-fire-event">
<style>
.form {
padding: 24px;
background-color: white;
}
.form {
padding: 24px;
background-color: white;
}
.ha-form {
margin-right: 16px;
}
</style>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>Fire Event</span>
<template>
<partial-base narrow="{{narrow}}">
<span header-title>Fire Event</span>
<div class='form' fit>
<p>
Fire an event on the event bus.
</p>
<div class='form fit'>
<p>
Fire an event on the event bus.
</p>
<div layout horizontal?="{{!narrow}}" vertical?="{{narrow}}">
<div class='ha-form' flex?="{{!narrow}}">
<paper-input
id="inputType" label="Event Type" floatingLabel="true"
autofocus required></paper-input>
<paper-input-decorator
label="Event Data (JSON, optional)"
floatingLabel="true">
<div class$='[[computeFormClasses(narrow)]]'>
<div class='ha-form flex'>
<paper-input label="Event Type" autofocus required value='{{eventType}}'></paper-input>
<paper-textarea label="Event Data (JSON, optional)" value='{{eventData}}'></paper-textarea>
<paper-button on-click='fireEvent' raised>Fire Event</paper-button>
</div>
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
</paper-input-decorator>
<paper-button on-click={{clickFireEvent}}>Fire Event</paper-button>
</div>
<div class='sidebar'>
<b>Available events:</b>
<events-list cbEventClicked={{eventSelected}}></event-list>
<div>
<h4>Available events:</h4>
<events-list on-event-selected='eventSelected'></event-list>
</div>
</div>
</div>
</div>
</partial-base>
</partial-base>
</template>
</dom-module>
</template>
<script>
var eventActions = window.hass.eventActions;
(function() {
var eventActions = window.hass.eventActions;
Polymer({
ready: function() {
// to ensure callback methods work..
this.eventSelected = this.eventSelected.bind(this);
},
Polymer({
is: 'partial-dev-fire-event',
eventSelected: function(eventType) {
this.$.inputType.value = eventType;
},
properties: {
eventType: {
type: String,
value: '',
},
clickFireEvent: function() {
try {
eventActions.fire(
this.$.inputType.value,
this.$.inputData.value ? JSON.parse(this.$.inputData.value) : {});
} catch (err) {
alert("Error parsing JSON: " + err);
}
}
});
eventData: {
type: String,
value: '',
},
},
eventSelected: function(ev) {
this.eventType = ev.detail.eventType;
},
clickFireEvent: function() {
var eventData;
try {
eventData = this.eventData ? JSON.parse(this.eventData) : {};
} catch (err) {
alert("Error parsing JSON: " + err);
return;
}
eventActions.fire(this.eventType, eventData);
},
computeFormClasses: function(narrow) {
return 'layout ' + (narrow ? 'vertical' : 'horizontal');
},
});
})();
</script>
</polymer-element>

View File

@ -2,105 +2,109 @@
<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="../bower_components/paper-input/paper-textarea.html">
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/entity-list.html">
<polymer-element name="partial-dev-set-state" attributes="narrow togglePanel">
<template>
<dom-module id="partial-dev-set-state">
<style>
.form {
padding: 24px;
background-color: white;
}
.form {
padding: 24px;
background-color: white;
}
.ha-form {
margin-right: 16px;
}
</style>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>Set State</span>
<template>
<partial-base narrow="[[narrow]]">
<span header-title>Set State</span>
<div class='form' fit>
<div>
Set the representation of a device within Home Assistant.<br />
This will not communicate with the actual device.
</div>
<div layout horizontal?="{{!narrow}}" vertical?="{{narrow}}">
<div class='ha-form' flex?="{{!narrow}}">
<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>
</paper-input-decorator>
<paper-button on-click={{clickSetState}}>Set State</paper-button>
<div class='form fit'>
<div>
Set the representation of a device within Home Assistant.<br />
This will not communicate with the actual device.
</div>
<div class='sidebar'>
<b>Current entities:</b>
<entity-list cbEntityClicked={{entitySelected}}></entity-list>
<div class$='[[computeFormClasses(narrow)]]'>
<div class='ha-form flex'>
<paper-input label="Entity ID" autofocus required value='{{entityId}}'></paper-input>
<paper-input label="State" required value='{{state}}'></paper-input>
<paper-textarea label="State attributes (JSON, optional)" value='{{stateAttributes}}'></paper-textarea>
<paper-button on-click='handleSetState' raised>Set State</paper-button>
</div>
<div class='sidebar'>
<h4>Current entities:</h4>
<entity-list on-entity-selected='entitySelected'></entity-list>
</div>
</div>
</div>
</partial-base>
</template>
</dom-module>
</div>
</partial-base>
</template>
<script>
var stateStore = window.hass.stateStore;
var stateActions = window.hass.stateActions;
(function() {
var stateStore = window.hass.stateStore;
var stateActions = window.hass.stateActions;
Polymer({
ready: function() {
// to ensure callback methods work..
this.entitySelected = this.entitySelected.bind(this);
},
Polymer({
is: 'partial-dev-set-state',
setEntityId: function(entityId) {
this.$.inputEntityID.value = entityId;
},
properties: {
entityId: {
type: String,
value: '',
},
setState: function(state) {
this.$.inputState.value = state;
},
state: {
type: String,
value: '',
},
setStateData: function(stateData) {
var value = stateData ? JSON.stringify(stateData, null, ' ') : "";
stateAttributes: {
type: String,
value: '',
},
},
this.$.inputData.value = value;
setStateData: function(stateData) {
var value = stateData ? JSON.stringify(stateData, null, ' ') : "";
// not according to the spec but it works...
this.$.inputDataWrapper.update(this.$.inputData);
},
this.$.inputData.value = value;
entitySelected: function(entityId) {
this.setEntityId(entityId);
// not according to the spec but it works...
this.$.inputDataWrapper.update(this.$.inputData);
},
var state = stateStore.get(entityId);
this.setState(state.state);
this.setStateData(state.attributes);
},
entitySelected: function(ev) {
var state = stateStore.get(ev.detail.entityId);
clickSetState: function(ev) {
try {
stateActions.set(
this.$.inputEntityID.value,
this.$.inputState.value,
this.$.inputData.value ? JSON.parse(this.$.inputData.value) : {}
);
} catch (err) {
alert("Error parsing JSON: " + err);
}
}
});
this.entityId = state.entityId;
this.state = state.state;
this.stateAttributes = JSON.stringify(state.attributes, null, ' ');
},
handleSetState: function() {
var attr;
try {
attr = this.stateAttributes ? JSON.parse(this.stateAttributes) : {};
} catch (err) {
alert("Error parsing JSON: " + err);
return;
}
stateActions.set(this.entityId, this.state, attr);
},
computeFormClasses: function(narrow) {
return 'layout ' + (narrow ? 'vertical' : 'horizontal');
},
});
})();
</script>
</polymer-element>