Polymer .9: More info dialog with default content

This commit is contained in:
Paulus Schoutsen 2015-05-20 23:41:54 -07:00
parent de243855c4
commit 69ae1d3534
8 changed files with 242 additions and 178 deletions

View File

@ -21,6 +21,7 @@
"iron-image": "PolymerElements/iron-image#^0.9", "iron-image": "PolymerElements/iron-image#^0.9",
"paper-toast": "PolymerElements/paper-toast#^0.9", "paper-toast": "PolymerElements/paper-toast#^0.9",
"paper-dialog": "PolymerElements/paper-dialog#^0.9", "paper-dialog": "PolymerElements/paper-dialog#^0.9",
"paper-dialog-scrollable": "polymerelements/paper-dialog-scrollable#^0.9",
"paper-spinner": "PolymerElements/paper-spinner#^0.9", "paper-spinner": "PolymerElements/paper-spinner#^0.9",
"paper-button": "PolymerElements/paper-button#^0.9", "paper-button": "PolymerElements/paper-button#^0.9",
"paper-input": "PolymerElements/paper-input#^0.9", "paper-input": "PolymerElements/paper-input#^0.9",

View File

@ -3,7 +3,12 @@
<link rel="import" href="../components/state-info.html"> <link rel="import" href="../components/state-info.html">
<dom-module is="state-card-toggle"> <dom-module id="state-card-toggle">
<style>
paper-toggle-button {
margin-left: 16px;
}
</style>
<template> <template>
<div class='horizontal justified layout'> <div class='horizontal justified layout'>
<state-info state-obj="[[stateObj]]"></state-info> <state-info state-obj="[[stateObj]]"></state-info>

View File

@ -1,120 +1,146 @@
<link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="ha-dialog.html"> <link rel="import" href="../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
<!-- <link rel="import" href="ha-dialog.html"> -->
<link rel="import" href="../cards/state-card-content.html"> <link rel="import" href="../cards/state-card-content.html">
<link rel="import" href="../components/state-timeline.html"> <link rel="import" href="../components/state-history-charts.html">
<link rel="import" href="../more-infos/more-info-content.html"> <link rel="import" href="../more-infos/more-info-content.html">
<polymer-element name="more-info-dialog"> <dom-module id="more-info-dialog">
<template> <style>
<ha-dialog id="dialog" on-core-overlay-open="{{dialogOpenChanged}}"> state-card-content {
<div> margin-bottom: 24px;
<state-card-content stateObj="{{stateObj}}" style='margin-bottom: 24px;'> }
</state-card-content> </style>
<template if="{{hasHistoryComponent}}"> <template>
<state-timeline stateHistory="{{stateHistory}}" isLoadingData="{{isLoadingHistoryData}}"></state-timeline> <paper-dialog id="dialog" on-core-overlay-open="dialogOpenChanged" with-backdrop>
</template> <div>
<more-info-content <state-card-content state-obj="[[stateObj]]"></state-card-content>
stateObj="{{stateObj}}" <template is='dom-if' if="[[hasHistoryComponent]]">
dialogOpen="{{dialogOpen}}"></more-info-content> <state-history-charts stateHistory="[[stateHistory]]"
</div> isLoadingData="[[isLoadingHistoryData]]"></state-history-charts>
</ha-dialog> </template>
</template> <paper-dialog-scrollable>
<more-info-content state-obj="[[stateObj]]"
dialog-open="[[dialogOpen]]"></more-info-content>
</paper-dialog-scrollable>
</div>
</paper-dialog>
</template>
</dom-module>
<script> <script>
var storeListenerMixIn = window.hass.storeListenerMixIn; (function() {
var stateStore = window.hass.stateStore; var stateStore = window.hass.stateStore;
var stateHistoryStore = window.hass.stateHistoryStore; var stateHistoryStore = window.hass.stateHistoryStore;
var stateHistoryActions = window.hass.stateHistoryActions; var stateHistoryActions = window.hass.stateHistoryActions;
Polymer(Polymer.mixin({ Polymer({
entityId: false, is: 'more-info-dialog',
stateObj: null,
stateHistory: null,
hasHistoryComponent: false,
dialogOpen: false,
isLoadingHistoryData: false,
observe: { behaviors: [StoreListenerBehavior],
'stateObj.attributes': 'reposition'
},
created: function() { properties: {
this.dialogOpenChanged = this.dialogOpenChanged.bind(this); entityId: {
}, type: String,
},
attached: function() { stateObj: {
this.listenToStores(true); type: Object,
}, observer: 'reposition',
},
detached: function() { stateHistory: {
this.stopListeningToStores(); type: Object,
}, },
componentStoreChanged: function(componentStore) { isLoadingHistoryData: {
this.hasHistoryComponent = componentStore.isLoaded('history'); type: Boolean,
}, value: false,
},
stateStoreChanged: function() { hasHistoryComponent: {
var newState = this.entityId ? stateStore.get(this.entityId) : null; type: Boolean,
value: false,
},
if (newState !== this.stateObj) { dialogOpen: {
this.stateObj = newState; type: Boolean,
} value: false,
}, },
},
stateHistoryStoreChanged: function() { componentStoreChanged: function(componentStore) {
var newHistory; this.hasHistoryComponent = componentStore.isLoaded('history');
},
if (this.hasHistoryComponent && this.entityId) { stateStoreChanged: function() {
newHistory = stateHistoryStore.get(this.entityId); var newState = this.entityId ? stateStore.get(this.entityId) : null;
} else {
newHistory = null;
}
this.isLoadingHistoryData = false;
if (newHistory !== this.stateHistory) {
this.stateHistory = newHistory;
}
},
dialogOpenChanged: function(ev) { if (newState !== this.stateObj) {
// we get CustomEvent, undefined and true/false from polymer… this.stateObj = newState;
if (typeof ev === 'object') { }
this.dialogOpen = ev.detail; },
}
},
changeEntityId: function(entityId) { stateHistoryStoreChanged: function() {
this.entityId = entityId; var newHistory;
this.stateStoreChanged(); if (this.hasHistoryComponent && this.entityId) {
this.stateHistoryStoreChanged(); newHistory = stateHistoryStore.get(this.entityId);
} else {
newHistory = null;
}
if (this.hasHistoryComponent && stateHistoryStore.isStale(entityId)) { this.isLoadingHistoryData = false;
this.isLoadingHistoryData = true;
stateHistoryActions.fetch(entityId);
}
},
/** if (newHistory !== this.stateHistory) {
* Whenever the attributes change, the more info component can this.stateHistory = newHistory;
* hide or show elements. We will reposition the dialog. }
*/ },
reposition: function(oldVal, newVal) {
// Only resize if already open
if(this.$.dialog.opened) {
this.job('resizeAfterLayoutChange', function() {
this.$.dialog.resizeHandler();
}.bind(this), 1000);
}
},
show: function(entityId) { dialogOpenChanged: function(ev) {
this.changeEntityId(entityId); // we get CustomEvent, undefined and true/false from polymer…
console.log('debug', ev);
if (typeof ev === 'object') {
this.dialogOpen = ev.detail;
}
},
this.job('showDialogAfterRender', function() { changeEntityId: function(entityId) {
this.$.dialog.toggle(); this.entityId = entityId;
}.bind(this));
}, this.stateStoreChanged();
}, storeListenerMixIn)); this.stateHistoryStoreChanged();
if (this.hasHistoryComponent && stateHistoryStore.isStale(entityId)) {
this.isLoadingHistoryData = true;
stateHistoryActions.fetch(entityId);
}
},
/**
* Whenever the attributes change, the more info component can
* hide or show elements. We will reposition the dialog.
*/
reposition: function(newVal, oldVal) {
// Only resize if already open
if(this.dialogOpen) {
this.debounce('resizeAfterLayoutChange', function() {
this.$.dialog.resizeHandler();
}.bind(this), 1000);
}
},
show: function(entityId) {
this.changeEntityId(entityId);
this.debounce('showDialogAfterRender', function() {
this.$.dialog.toggle();
}.bind(this));
},
});
})();
</script> </script>
</polymer-element>

View File

@ -16,11 +16,12 @@
<link rel="import" href="../layouts/partial-dev-fire-event.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="../layouts/partial-dev-set-state.html">
<link rel="import" href="../components/ha-notifications.html"> <link rel="import" href="../managers/notification-manager.html">
<!--<link rel="import" href="../components/ha-modals.html"> --> <link rel="import" href="../managers/modal-manager.html">
<link rel="import" href="../components/stream-status.html"> <link rel="import" href="../components/stream-status.html">
<dom-module is="home-assistant-main"> <dom-module id="home-assistant-main">
<style> <style>
.sidenav { .sidenav {
background: #fafafa; background: #fafafa;
@ -54,10 +55,9 @@
} }
</style> </style>
<template> <template>
<ha-notifications></ha-notifications> <notification-manager></notification-manager>
<!-- <ha-modals></ha-modals> --> <modal-manager></modal-manager>
<paper-drawer-panel id="drawer" narrow='{{narrow}}'> <paper-drawer-panel id="drawer" narrow='{{narrow}}'>
<paper-header-panel mode="scroll" drawer class='sidenav fit'> <paper-header-panel mode="scroll" drawer class='sidenav fit'>

View File

@ -2,24 +2,29 @@
<link rel="import" href="../dialogs/more-info-dialog.html"> <link rel="import" href="../dialogs/more-info-dialog.html">
<polymer-element name="ha-modals"> <dom-module id="modal-manager">
<template> <template>
<more-info-dialog id="moreInfoDialog"></more-info-dialog> <more-info-dialog id="moreInfoDialog"></more-info-dialog>
</template> </template>
<script> </dom-module>
var uiActions = window.hass.uiActions,
<script>
(function() {
var uiConstants = window.hass.uiConstants,
dispatcher = window.hass.dispatcher; dispatcher = window.hass.dispatcher;
Polymer({ Polymer({
is: 'modal-manager',
ready: function() { ready: function() {
dispatcher.register(function(payload) { dispatcher.register(function(payload) {
switch (payload.actionType) { switch (payload.actionType) {
case uiActions.ACTION_SHOW_DIALOG_MORE_INFO: case uiConstants.ACTION_SHOW_DIALOG_MORE_INFO:
this.$.moreInfoDialog.show(payload.entityId); this.$.moreInfoDialog.show(payload.entityId);
break; break;
} }
}.bind(this)); }.bind(this));
}, },
}); });
</script> })();
</polymer-element> </script>

View File

@ -2,7 +2,7 @@
<link rel="import" href="../bower_components/paper-toast/paper-toast.html"> <link rel="import" href="../bower_components/paper-toast/paper-toast.html">
<dom-module id="ha-notifications"> <dom-module id="notification-manager">
<style> <style>
paper-toast { paper-toast {
z-index: 1; z-index: 1;
@ -16,7 +16,7 @@
<script> <script>
(function() { (function() {
Polymer({ Polymer({
is: 'ha-notifications', is: 'notification-manager',
behaviors: [StoreListenerBehavior], behaviors: [StoreListenerBehavior],

View File

@ -1,73 +1,92 @@
<link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="more-info-default.html"> <link rel="import" href="more-info-default.html">
<link rel="import" href="more-info-light.html"> <!-- <link rel="import" href="more-info-light.html">
<link rel="import" href="more-info-group.html"> <link rel="import" href="more-info-group.html">
<link rel="import" href="more-info-sun.html"> <link rel="import" href="more-info-sun.html">
<link rel="import" href="more-info-configurator.html"> <link rel="import" href="more-info-configurator.html">
<link rel="import" href="more-info-thermostat.html"> <link rel="import" href="more-info-thermostat.html">
<link rel="import" href="more-info-script.html"> <link rel="import" href="more-info-script.html"> -->
<polymer-element name="more-info-content" attributes="stateObj dialogOpen"> <dom-module id="more-info-content">
<template>
<style> <style>
:host { :host {
display: block; display: block;
} }
</style> </style>
<div id='moreInfoContainer' class='{{classNames}}'></div> </dom-module>
</template>
<script> <script>
Polymer({ (function() {
classNames: '', var uiUtil = window.hass.uiUtil;
dialogOpen: false,
observe: { Polymer({
'stateObj.attributes': 'stateAttributesChanged', is: 'more-info-content',
},
dialogOpenChanged: function(oldVal, newVal) { properties: {
var moreInfoContainer = this.$.moreInfoContainer; stateObj: {
type: Object,
observer: 'stateObjChanged',
},
if (moreInfoContainer.lastChild) { dialogOpen: {
moreInfoContainer.lastChild.dialogOpen = newVal; type: Boolean,
} value: false,
}, },
stateObjChanged: function(oldVal, newVal) { classNames: {
var moreInfoContainer = this.$.moreInfoContainer; type: String,
value: '',
if (!newVal) {
if (moreInfoContainer.lastChild) {
moreInfoContainer.removeChild(moreInfoContainer.lastChild);
} }
return; },
} classNames: '',
dialogOpen: false,
observe: {
'stateObj.attributes': 'stateAttributesChanged',
},
dialogOpenChanged: function(newVal, oldVal) {
var moreInfoContainer = this.$.moreInfoContainer;
if (!oldVal || oldVal.moreInfoType != newVal.moreInfoType) {
if (moreInfoContainer.lastChild) { if (moreInfoContainer.lastChild) {
moreInfoContainer.removeChild(moreInfoContainer.lastChild); moreInfoContainer.lastChild.dialogOpen = newVal;
}
},
stateObjChanged: function(newVal, oldVal) {
var root = Polymer.dom(this);
if (!newVal) {
if (root.lastChild) {
root.removeChild(root.lastChild);
}
return;
} }
var moreInfo = document.createElement("more-info-" + newVal.moreInfoType); var newMoreInfoType = uiUtil.stateMoreInfoType(newVal);
moreInfo.stateObj = newVal; newMoreInfoType = 'default';
moreInfo.dialogOpen = this.dialogOpen;
moreInfoContainer.appendChild(moreInfo);
} else { if (!oldVal || uiUtil.stateMoreInfoType(oldVal) != newMoreInfoType) {
if (root.lastChild) {
root.removeChild(root.lastChild);
}
moreInfoContainer.lastChild.dialogOpen = this.dialogOpen; var moreInfo = document.createElement("more-info-" + newMoreInfoType);
moreInfoContainer.lastChild.stateObj = newVal; moreInfo.stateObj = newVal;
moreInfo.dialogOpen = this.dialogOpen;
root.appendChild(moreInfo);
} } else {
},
stateAttributesChanged: function(oldVal, newVal) { root.lastChild.dialogOpen = this.dialogOpen;
if (!newVal) return; root.lastChild.stateObj = newVal;
this.classNames = Object.keys(newVal).map( }
function(key) { return "has-" + key; }).join(' ');
}, this.classNames = Object.keys(newVal.attributes).map(
}); function(key) { return "has-" + key; }).join(' ');
},
});
})();
</script> </script>
</polymer-element>

View File

@ -1,34 +1,42 @@
<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-style/core-style.html">
<polymer-element name="more-info-default" attributes="stateObj"> <dom-module id="more-info-default">
<template>
<core-style ref='ha-key-value-table'></core-style>
<style> <style>
.data-entry .value { .data-entry .value {
max-width: 200px; max-width: 200px;
} }
</style> </style>
<!-- <core-style ref='ha-key-value-table'></core-style> -->
<div layout vertical> <template>
<div class='layout vertical'>
<template repeat="{{key in stateObj.attributes | getKeys}}"> <template is='dom-repeat' items="[[getAttributes(stateObj)]]" as="attribute">
<div layout justified horizontal class='data-entry'> <div class='data-entry layout justified horizontal'>
<div class='key'> <div class='key'>[[attribute]]</div>
{{key}} <div class='value'>[[getAttributeValue(stateObj, attribute)]]</div>
</div> </div>
<div class='value'> </template>
{{stateObj.attributes[key]}} </div>
</div> </template>
</div> </dom-module>
</template>
</div>
</template>
<script> <script>
(function() {
Polymer({ Polymer({
getKeys: function(obj) { is: 'more-info-default',
return Object.keys(obj || {});
} properties: {
stateObj: {
type: Object,
},
},
getAttributes: function(stateObj) {
return stateObj ? Object.keys(stateObj.attributes) : [];
},
getAttributeValue: function(stateObj, attribute) {
return stateObj.attributes[attribute];
},
}); });
})();
</script> </script>
</polymer-element>