mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-11 11:26:35 +00:00
Optimise performance state panel
This commit is contained in:
parent
59d347672f
commit
882ebfedd1
@ -1 +1 @@
|
|||||||
Subproject commit 28b2e7ab6e9fecef769382f462b3c5c7c9964c49
|
Subproject commit 11a648c2931f4f381af439b1c52d9ff028bd0626
|
@ -128,7 +128,11 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
},
|
},
|
||||||
|
|
||||||
paneVisible: {
|
panelVisible: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
|
||||||
|
viewVisible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -138,13 +142,19 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
observers: [
|
observers: [
|
||||||
'updateCards(columns, states, showIntroduction, paneVisible)',
|
'updateCards(columns, states, showIntroduction, panelVisible, viewVisible)',
|
||||||
],
|
],
|
||||||
|
|
||||||
updateCards: function (columns, states, showIntroduction, paneVisible) {
|
updateCards: function (columns, states, showIntroduction,
|
||||||
if (!paneVisible) {
|
panelVisible, viewVisible) {
|
||||||
|
if (!panelVisible || !viewVisible) {
|
||||||
|
console.log('cancelling update cards',
|
||||||
|
this.getAttribute('data-view') || 'default-view',
|
||||||
|
panelVisible, viewVisible);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log('updateCards', this.getAttribute('data-view') || 'default-view',
|
||||||
|
panelVisible, viewVisible);
|
||||||
this.debounce(
|
this.debounce(
|
||||||
'updateCards',
|
'updateCards',
|
||||||
function () { this.cards = this.computeCards(columns, states,
|
function () { this.cards = this.computeCards(columns, states,
|
||||||
@ -153,6 +163,11 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
computeCards: function (columns, states, showIntroduction) {
|
computeCards: function (columns, states, showIntroduction) {
|
||||||
|
// Things might have changed since it got scheduled.
|
||||||
|
if (!this.panelVisible || !this.viewVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error('computeCards', this.getAttribute('data-view') || 'default-view', states.size, this.viewVisible)
|
||||||
var hass = this.hass;
|
var hass = this.hass;
|
||||||
var byDomain = states.groupBy(function (entity) { return entity.domain; });
|
var byDomain = states.groupBy(function (entity) { return entity.domain; });
|
||||||
var hasGroup = {};
|
var hasGroup = {};
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
<link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">
|
|
||||||
|
|
||||||
<link rel='import' href='../util/hass-behavior.html'>
|
|
||||||
|
|
||||||
<dom-module id="ha-view-tabs">
|
|
||||||
<template>
|
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
--paper-tabs-selection-bar-color: #FFF;
|
|
||||||
}
|
|
||||||
paper-tab {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<paper-tabs
|
|
||||||
selected='[[currentView]]'
|
|
||||||
attr-for-selected='data-entity'
|
|
||||||
on-iron-select='viewSelected'
|
|
||||||
scrollable=''
|
|
||||||
>
|
|
||||||
<paper-tab data-entity='' on-tap='viewTapped'>[[locationName]]</paper-tab>
|
|
||||||
<template is='dom-repeat' items='[[views]]'>
|
|
||||||
<paper-tab data-entity$='[[item.entityId]]' on-tap='viewTapped'>
|
|
||||||
<template is='dom-if' if='[[item.attributes.icon]]'>
|
|
||||||
<iron-icon icon='[[item.attributes.icon]]'></iron-icon>
|
|
||||||
</template>
|
|
||||||
<template is='dom-if' if='[[!item.attributes.icon]]'>
|
|
||||||
[[item.entityDisplay]]
|
|
||||||
</template>
|
|
||||||
</paper-tab>
|
|
||||||
</template>
|
|
||||||
</paper-tabs>
|
|
||||||
</template>
|
|
||||||
</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: function () {
|
|
||||||
this.fire('view-tapped');
|
|
||||||
},
|
|
||||||
|
|
||||||
viewSelected: function (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>
|
|
@ -30,7 +30,7 @@
|
|||||||
attr-for-selected='id'
|
attr-for-selected='id'
|
||||||
fallback-selection='panel-resolver'
|
fallback-selection='panel-resolver'
|
||||||
selected='[[activePane]]'
|
selected='[[activePane]]'
|
||||||
selected-attribute='pane-visible'
|
selected-attribute='panel-visible'
|
||||||
>
|
>
|
||||||
<partial-cards
|
<partial-cards
|
||||||
id='states'
|
id='states'
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
|
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
|
||||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||||
|
<link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">
|
||||||
|
|
||||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||||
<link rel="import" href="../../bower_components/app-layout/app-scroll-effects/app-scroll-effects.html">
|
<link rel="import" href="../../bower_components/app-layout/app-scroll-effects/app-scroll-effects.html">
|
||||||
@ -9,7 +10,6 @@
|
|||||||
|
|
||||||
<link rel="import" href="../components/ha-menu-button.html">
|
<link rel="import" href="../components/ha-menu-button.html">
|
||||||
<link rel="import" href="../components/ha-cards.html">
|
<link rel="import" href="../components/ha-cards.html">
|
||||||
<link rel="import" href="../components/ha-view-tabs.html">
|
|
||||||
|
|
||||||
<dom-module id="partial-cards">
|
<dom-module id="partial-cards">
|
||||||
<template>
|
<template>
|
||||||
@ -24,9 +24,10 @@
|
|||||||
background-color: #E5E5E5;
|
background-color: #E5E5E5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-view-tabs {
|
paper-tabs {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
--paper-tabs-selection-bar-color: #FFF;
|
--paper-tabs-selection-bar-color: #FFF;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -34,7 +35,7 @@
|
|||||||
<app-header effects="waterfall" condenses fixed>
|
<app-header effects="waterfall" condenses fixed>
|
||||||
<app-toolbar>
|
<app-toolbar>
|
||||||
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
||||||
<div main-title>[[computeTitle(hasViews, locationName)]]</div>
|
<div main-title>[[computeTitle(views, locationName)]]</div>
|
||||||
<paper-icon-button
|
<paper-icon-button
|
||||||
icon="mdi:refresh"
|
icon="mdi:refresh"
|
||||||
class$="[[computeRefreshButtonClass(isFetching)]]"
|
class$="[[computeRefreshButtonClass(isFetching)]]"
|
||||||
@ -45,20 +46,60 @@
|
|||||||
on-tap="handleListenClick"></paper-icon-button>
|
on-tap="handleListenClick"></paper-icon-button>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
|
|
||||||
<ha-view-tabs
|
<div sticky>
|
||||||
sticky
|
<paper-tabs
|
||||||
hass='[[hass]]'
|
scrollable
|
||||||
on-view-tapped='scrollToTop'
|
selected='[[currentView]]'
|
||||||
></ha-view-tabs>
|
attr-for-selected='data-entity'
|
||||||
|
on-iron-select='handleViewSelected'
|
||||||
|
>
|
||||||
|
<paper-tab
|
||||||
|
data-entity=''
|
||||||
|
on-tap='handleViewTapped'
|
||||||
|
>[[locationName]]</paper-tab>
|
||||||
|
<template is='dom-repeat' items='[[views]]'>
|
||||||
|
<paper-tab
|
||||||
|
data-entity$='[[item.entityId]]'
|
||||||
|
on-tap='handleViewTapped'
|
||||||
|
>
|
||||||
|
<template is='dom-if' if='[[item.attributes.icon]]'>
|
||||||
|
<iron-icon icon='[[item.attributes.icon]]'></iron-icon>
|
||||||
|
</template>
|
||||||
|
<template is='dom-if' if='[[!item.attributes.icon]]'>
|
||||||
|
[[item.entityDisplay]]
|
||||||
|
</template>
|
||||||
|
</paper-tab>
|
||||||
|
</template>
|
||||||
|
</paper-tabs>
|
||||||
|
</div>
|
||||||
</app-header>
|
</app-header>
|
||||||
|
|
||||||
|
<iron-pages
|
||||||
|
attr-for-selected='data-view'
|
||||||
|
selected='[[currentView]]'
|
||||||
|
selected-attribute='view-visible'
|
||||||
|
>
|
||||||
<ha-cards
|
<ha-cards
|
||||||
|
data-view=''
|
||||||
show-introduction='[[computeShowIntroduction(currentView, introductionLoaded, states)]]'
|
show-introduction='[[computeShowIntroduction(currentView, introductionLoaded, states)]]'
|
||||||
states='[[states]]'
|
states='[[states]]'
|
||||||
columns='[[columns]]'
|
columns='[[_columns]]'
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
pane-visible='[[paneVisible]]'
|
panel-visible='[[panelVisible]]'
|
||||||
></ha-cards>
|
></ha-cards>
|
||||||
|
|
||||||
|
<template is='dom-repeat' items='[[views]]'>
|
||||||
|
<ha-cards
|
||||||
|
data-view$='[[item.entityId]]'
|
||||||
|
show-introduction='[[computeShowIntroduction(currentView, introductionLoaded, states)]]'
|
||||||
|
states='[[states]]'
|
||||||
|
columns='[[_columns]]'
|
||||||
|
hass='[[hass]]'
|
||||||
|
panel-visible='[[panelVisible]]'
|
||||||
|
></ha-cards>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</iron-pages>
|
||||||
</app-header-layout>
|
</app-header-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -80,9 +121,20 @@ Polymer({
|
|||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
paneVisible: {
|
showMenu: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
|
observer: 'handleWindowChange',
|
||||||
|
},
|
||||||
|
|
||||||
|
panelVisible: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
_columns: {
|
||||||
|
type: Number,
|
||||||
|
value: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
isFetching: {
|
isFetching: {
|
||||||
@ -126,12 +178,6 @@ Polymer({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
showMenu: {
|
|
||||||
type: Boolean,
|
|
||||||
value: false,
|
|
||||||
observer: 'windowChange',
|
|
||||||
},
|
|
||||||
|
|
||||||
currentView: {
|
currentView: {
|
||||||
type: String,
|
type: String,
|
||||||
bindNuclear: function (hass) {
|
bindNuclear: function (hass) {
|
||||||
@ -142,12 +188,16 @@ Polymer({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
hasViews: {
|
views: {
|
||||||
type: Boolean,
|
type: Array,
|
||||||
bindNuclear: function (hass) {
|
bindNuclear: function (hass) {
|
||||||
return [
|
return [
|
||||||
hass.viewGetters.views,
|
hass.viewGetters.views,
|
||||||
function (views) { return views.size > 0; },
|
function (views) {
|
||||||
|
return views.valueSeq()
|
||||||
|
.sortBy(function (view) { return view.attributes.order; })
|
||||||
|
.toArray();
|
||||||
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -158,37 +208,31 @@ Polymer({
|
|||||||
return hass.viewGetters.currentViewEntities;
|
return hass.viewGetters.currentViewEntities;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
columns: {
|
|
||||||
type: Number,
|
|
||||||
value: 1,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
created: function () {
|
created: function () {
|
||||||
var sizes = [];
|
var sizes = [300, 600, 900, 1200];
|
||||||
var col;
|
var col;
|
||||||
this.windowChange = this.windowChange.bind(this);
|
this.handleWindowChange = this.handleWindowChange.bind(this);
|
||||||
for (col = 0; col < 5; col++) {
|
|
||||||
sizes.push(300 + (col * 300));
|
|
||||||
}
|
|
||||||
this.mqls = sizes.map(function (width) {
|
this.mqls = sizes.map(function (width) {
|
||||||
var mql = window.matchMedia('(min-width: ' + width + 'px)');
|
var mql = window.matchMedia('(min-width: ' + width + 'px)');
|
||||||
mql.addListener(this.windowChange);
|
mql.addListener(this.handleWindowChange);
|
||||||
return mql;
|
return mql;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
detached: function () {
|
detached: function () {
|
||||||
this.mqls.forEach(function (mql) {
|
this.mqls.forEach(function (mql) {
|
||||||
mql.removeListener(this.windowChange);
|
mql.removeListener(this.handleWindowChange);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
windowChange: function () {
|
handleWindowChange: function () {
|
||||||
var matchColumns = this.mqls.reduce(function (cols, mql) { return cols + mql.matches; }, 0);
|
var matchColumns = this.mqls.reduce(function (cols, mql) {
|
||||||
|
return cols + mql.matches;
|
||||||
|
}, 0);
|
||||||
// Do -1 column if the menu is docked and open
|
// Do -1 column if the menu is docked and open
|
||||||
this.columns = Math.max(1, matchColumns - (!this.narrow && this.showMenu));
|
this._columns = Math.max(1, matchColumns - (!this.narrow && this.showMenu));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,24 +282,31 @@ Polymer({
|
|||||||
this.hass.voiceActions.listen();
|
this.hass.voiceActions.listen();
|
||||||
},
|
},
|
||||||
|
|
||||||
computeMenuButtonClass: function (narrow, showMenu) {
|
handleViewSelected: function (ev) {
|
||||||
return !narrow && showMenu ? 'menu-icon invisible' : 'menu-icon';
|
var view = ev.detail.item.getAttribute('data-entity') || null;
|
||||||
|
var current = this.currentView || null;
|
||||||
|
if (view !== current) {
|
||||||
|
this.async(function () {
|
||||||
|
console.warn('changing view')
|
||||||
|
this.hass.viewActions.selectView(view);
|
||||||
|
}.bind(this), 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleViewTapped: function (ev) {
|
||||||
|
this.scrollToTop();
|
||||||
},
|
},
|
||||||
|
|
||||||
computeRefreshButtonClass: function (isFetching) {
|
computeRefreshButtonClass: function (isFetching) {
|
||||||
return isFetching ? 'ha-spin' : '';
|
return isFetching ? 'ha-spin' : '';
|
||||||
},
|
},
|
||||||
|
|
||||||
computeTitle: function (hasViews, locationName) {
|
computeTitle: function (views, locationName) {
|
||||||
return hasViews ? 'Home Assistant' : locationName;
|
return views.length > 0 ? 'Home Assistant' : locationName;
|
||||||
},
|
},
|
||||||
|
|
||||||
computeShowIntroduction: function (currentView, introductionLoaded, states) {
|
computeShowIntroduction: function (currentView, introductionLoaded, states) {
|
||||||
return currentView === '' && (introductionLoaded || states.size === 0);
|
return currentView === '' && (introductionLoaded || states.size === 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
computeHasViews: function (views) {
|
|
||||||
return views.length > 0;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -84,7 +84,12 @@ Polymer({
|
|||||||
},
|
},
|
||||||
|
|
||||||
panelChanged: function (panel) {
|
panelChanged: function (panel) {
|
||||||
if (!panel) return;
|
if (!panel) {
|
||||||
|
if (this.$.panel.lastChild) {
|
||||||
|
this.$.panel.removeChild(this.$.panel.lastChild);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.resolved = false;
|
this.resolved = false;
|
||||||
this.errorLoading = false;
|
this.errorLoading = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user