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",
"paper-toast": "PolymerElements/paper-toast#^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-button": "PolymerElements/paper-button#^0.9",
"paper-input": "PolymerElements/paper-input#^0.9",

View File

@ -3,7 +3,12 @@
<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>
<div class='horizontal justified layout'>
<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="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="../components/state-timeline.html">
<link rel="import" href="../components/state-history-charts.html">
<link rel="import" href="../more-infos/more-info-content.html">
<polymer-element name="more-info-dialog">
<template>
<ha-dialog id="dialog" on-core-overlay-open="{{dialogOpenChanged}}">
<div>
<state-card-content stateObj="{{stateObj}}" style='margin-bottom: 24px;'>
</state-card-content>
<template if="{{hasHistoryComponent}}">
<state-timeline stateHistory="{{stateHistory}}" isLoadingData="{{isLoadingHistoryData}}"></state-timeline>
</template>
<more-info-content
stateObj="{{stateObj}}"
dialogOpen="{{dialogOpen}}"></more-info-content>
</div>
</ha-dialog>
</template>
<dom-module id="more-info-dialog">
<style>
state-card-content {
margin-bottom: 24px;
}
</style>
<template>
<paper-dialog id="dialog" on-core-overlay-open="dialogOpenChanged" with-backdrop>
<div>
<state-card-content state-obj="[[stateObj]]"></state-card-content>
<template is='dom-if' if="[[hasHistoryComponent]]">
<state-history-charts stateHistory="[[stateHistory]]"
isLoadingData="[[isLoadingHistoryData]]"></state-history-charts>
</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>
var storeListenerMixIn = window.hass.storeListenerMixIn;
var stateStore = window.hass.stateStore;
var stateHistoryStore = window.hass.stateHistoryStore;
var stateHistoryActions = window.hass.stateHistoryActions;
(function() {
var stateStore = window.hass.stateStore;
var stateHistoryStore = window.hass.stateHistoryStore;
var stateHistoryActions = window.hass.stateHistoryActions;
Polymer(Polymer.mixin({
entityId: false,
stateObj: null,
stateHistory: null,
hasHistoryComponent: false,
dialogOpen: false,
isLoadingHistoryData: false,
Polymer({
is: 'more-info-dialog',
observe: {
'stateObj.attributes': 'reposition'
},
behaviors: [StoreListenerBehavior],
created: function() {
this.dialogOpenChanged = this.dialogOpenChanged.bind(this);
},
properties: {
entityId: {
type: String,
},
attached: function() {
this.listenToStores(true);
},
stateObj: {
type: Object,
observer: 'reposition',
},
detached: function() {
this.stopListeningToStores();
},
stateHistory: {
type: Object,
},
componentStoreChanged: function(componentStore) {
this.hasHistoryComponent = componentStore.isLoaded('history');
},
isLoadingHistoryData: {
type: Boolean,
value: false,
},
stateStoreChanged: function() {
var newState = this.entityId ? stateStore.get(this.entityId) : null;
hasHistoryComponent: {
type: Boolean,
value: false,
},
if (newState !== this.stateObj) {
this.stateObj = newState;
}
},
dialogOpen: {
type: Boolean,
value: false,
},
},
stateHistoryStoreChanged: function() {
var newHistory;
componentStoreChanged: function(componentStore) {
this.hasHistoryComponent = componentStore.isLoaded('history');
},
if (this.hasHistoryComponent && this.entityId) {
newHistory = stateHistoryStore.get(this.entityId);
} else {
newHistory = null;
}
this.isLoadingHistoryData = false;
if (newHistory !== this.stateHistory) {
this.stateHistory = newHistory;
}
},
stateStoreChanged: function() {
var newState = this.entityId ? stateStore.get(this.entityId) : null;
dialogOpenChanged: function(ev) {
// we get CustomEvent, undefined and true/false from polymer…
if (typeof ev === 'object') {
this.dialogOpen = ev.detail;
}
},
if (newState !== this.stateObj) {
this.stateObj = newState;
}
},
changeEntityId: function(entityId) {
this.entityId = entityId;
stateHistoryStoreChanged: function() {
var newHistory;
this.stateStoreChanged();
this.stateHistoryStoreChanged();
if (this.hasHistoryComponent && this.entityId) {
newHistory = stateHistoryStore.get(this.entityId);
} else {
newHistory = null;
}
if (this.hasHistoryComponent && stateHistoryStore.isStale(entityId)) {
this.isLoadingHistoryData = true;
stateHistoryActions.fetch(entityId);
}
},
this.isLoadingHistoryData = false;
/**
* Whenever the attributes change, the more info component can
* 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);
}
},
if (newHistory !== this.stateHistory) {
this.stateHistory = newHistory;
}
},
show: function(entityId) {
this.changeEntityId(entityId);
dialogOpenChanged: function(ev) {
// 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() {
this.$.dialog.toggle();
}.bind(this));
},
}, storeListenerMixIn));
changeEntityId: function(entityId) {
this.entityId = entityId;
this.stateStoreChanged();
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>
</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-set-state.html">
<link rel="import" href="../components/ha-notifications.html">
<!--<link rel="import" href="../components/ha-modals.html"> -->
<link rel="import" href="../managers/notification-manager.html">
<link rel="import" href="../managers/modal-manager.html">
<link rel="import" href="../components/stream-status.html">
<dom-module is="home-assistant-main">
<dom-module id="home-assistant-main">
<style>
.sidenav {
background: #fafafa;
@ -54,10 +55,9 @@
}
</style>
<template>
<ha-notifications></ha-notifications>
<!-- <ha-modals></ha-modals> -->
<notification-manager></notification-manager>
<modal-manager></modal-manager>
<paper-drawer-panel id="drawer" narrow='{{narrow}}'>
<paper-header-panel mode="scroll" drawer class='sidenav fit'>

View File

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

View File

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

View File

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

View File

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