Logbook: filter by entity and period ()

* Filter logbook by entity_id

* Filter logbook by period

* Filter logbook styles

* CI Fix

* Review

* Review

* CI Fix
This commit is contained in:
Nikolay Vasilchuk 2018-10-11 12:46:16 +03:00 committed by Paulus Schoutsen
parent 69eb007ea2
commit 3b425c3e14
3 changed files with 167 additions and 34 deletions

@ -1,6 +1,7 @@
import { PolymerElement } from '@polymer/polymer/polymer-element.js'; import { PolymerElement } from '@polymer/polymer/polymer-element.js';
var DATE_CACHE = {}; const DATA_CACHE = {};
const ALL_ENTITIES = '*';
class HaLogbookData extends PolymerElement { class HaLogbookData extends PolymerElement {
static get properties() { static get properties() {
@ -12,7 +13,17 @@ class HaLogbookData extends PolymerElement {
filterDate: { filterDate: {
type: String, type: String,
observer: 'filterDateChanged', observer: 'filterDataChanged',
},
filterPeriod: {
type: Number,
observer: 'filterDataChanged',
},
filterEntity: {
type: String,
observer: 'filterDataChanged',
}, },
isLoading: { isLoading: {
@ -33,41 +44,70 @@ class HaLogbookData extends PolymerElement {
hassChanged(newHass, oldHass) { hassChanged(newHass, oldHass) {
if (!oldHass && this.filterDate) { if (!oldHass && this.filterDate) {
this.filterDateChanged(this.filterDate); this.updateData();
} }
} }
filterDateChanged(filterDate) { filterDataChanged(newValue, oldValue) {
if (oldValue !== undefined) {
this.updateData();
}
}
updateData() {
if (!this.hass) return; if (!this.hass) return;
this._setIsLoading(true); this._setIsLoading(true);
this.getDate(filterDate).then(function (logbookEntries) { this.getDate(this.filterDate, this.filterPeriod, this.filterEntity)
this._setEntries(logbookEntries); .then((logbookEntries) => {
this._setIsLoading(false); this._setEntries(logbookEntries);
}.bind(this)); this._setIsLoading(false);
});
} }
getDate(date) { getDate(date, period, entityId) {
if (!DATE_CACHE[date]) { if (!entityId) entityId = ALL_ENTITIES;
DATE_CACHE[date] = this.hass.callApi('GET', 'logbook/' + date).then(
function (logbookEntries) { if (!DATA_CACHE[period]) DATA_CACHE[period] = [];
logbookEntries.reverse(); if (!DATA_CACHE[period][date]) DATA_CACHE[period][date] = [];
return logbookEntries;
}, if (DATA_CACHE[period][date][entityId]) {
function () { return DATA_CACHE[period][date][entityId];
DATE_CACHE[date] = false;
return null;
}
);
} }
return DATE_CACHE[date]; if (entityId !== ALL_ENTITIES && DATA_CACHE[period][date][ALL_ENTITIES]) {
return DATA_CACHE[period][date][ALL_ENTITIES].then(function (entities) {
return entities.filter(function (entity) {
return entity.entity_id === entityId;
});
});
}
DATA_CACHE[period][date][entityId] = this._getFromServer(date, period, entityId);
return DATA_CACHE[period][date][entityId];
}
_getFromServer(date, period, entityId) {
let url = 'logbook/' + date + '?period=' + period;
if (entityId !== ALL_ENTITIES) {
url += '&entity=' + entityId;
}
return this.hass.callApi('GET', url).then(
function (logbookEntries) {
logbookEntries.reverse();
return logbookEntries;
},
function () {
return null;
}
);
} }
refreshLogbook() { refreshLogbook() {
DATE_CACHE[this.filterDate] = null; DATA_CACHE[this.filterPeriod][this.filterDate] = [];
this.filterDateChanged(this.filterDate); this.updateData();
} }
} }

@ -5,6 +5,7 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import formatTime from '../../common/datetime/format_time.js'; import formatTime from '../../common/datetime/format_time.js';
import formatDate from '../../common/datetime/format_date.js';
import EventsMixin from '../../mixins/events-mixin.js'; import EventsMixin from '../../mixins/events-mixin.js';
import domainIcon from '../../common/entity/domain_icon.js'; import domainIcon from '../../common/entity/domain_icon.js';
@ -50,6 +51,10 @@ class HaLogbook extends EventsMixin(PolymerElement) {
</template> </template>
<template is="dom-repeat" items="[[entries]]"> <template is="dom-repeat" items="[[entries]]">
<template is="dom-if" if="{{_needHeader(entries.*, index)}}">
<h4 class="date">[[_formatDate(item.when)]]</h4>
</template>
<div class="horizontal layout entry"> <div class="horizontal layout entry">
<div class="time">[[_formatTime(item.when)]]</div> <div class="time">[[_formatTime(item.when)]]</div>
<iron-icon icon="[[_computeIcon(item.domain)]]"></iron-icon> <iron-icon icon="[[_computeIcon(item.domain)]]"></iron-icon>
@ -85,6 +90,17 @@ class HaLogbook extends EventsMixin(PolymerElement) {
return formatTime(new Date(date), this.language); return formatTime(new Date(date), this.language);
} }
_formatDate(date) {
return formatDate(new Date(date), this.language);
}
_needHeader(change, index) {
if (!index) return true;
const current = this.get('when', change.base[index]);
const previous = this.get('when', change.base[index - 1]);
return current && previous && current.substr(0, 10) !== previous.substr(0, 10);
}
_computeIcon(domain) { _computeIcon(domain) {
return domainIcon(domain); return domainIcon(domain);
} }

@ -9,6 +9,7 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import '@vaadin/vaadin-date-picker/vaadin-date-picker.js'; import '@vaadin/vaadin-date-picker/vaadin-date-picker.js';
import '../../components/ha-menu-button.js'; import '../../components/ha-menu-button.js';
import '../../components/entity/ha-entity-picker.js';
import '../../resources/ha-date-picker-style.js'; import '../../resources/ha-date-picker-style.js';
import '../../resources/ha-style.js'; import '../../resources/ha-style.js';
@ -31,16 +32,36 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) {
paper-spinner { paper-spinner {
position: absolute; position: absolute;
top: 15px; left: 50%;
left: 186px; top: 50%;
transform: translate(-50%, -50%);
}
.wrap {
margin-bottom: 24px;
} }
vaadin-date-picker { vaadin-date-picker {
--vaadin-date-picker-clear-icon: { --vaadin-date-picker-clear-icon: {
display: none; display: none;
} }
margin-bottom: 24px;
max-width: 200px; max-width: 200px;
margin-right: 16px;
}
paper-dropdown-menu {
max-width: 100px;
margin-right: 16px;
}
paper-item {
cursor: pointer;
}
ha-entity-picker {
display: inline-block;
width: 100%;
max-width: 400px;
} }
[hidden] { [hidden] {
@ -53,6 +74,8 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) {
is-loading='{{isLoading}}' is-loading='{{isLoading}}'
entries='{{entries}}' entries='{{entries}}'
filter-date='[[_computeFilterDate(_currentDate)]]' filter-date='[[_computeFilterDate(_currentDate)]]'
filter-period='[[_computeFilterDays(_periodIndex)]]'
filter-entity='[[entityId]]'
></ha-logbook-data> ></ha-logbook-data>
<app-header-layout has-scrolling-region> <app-header-layout has-scrolling-region>
@ -75,14 +98,38 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) {
alt="[[localize('ui.common.loading')]]" alt="[[localize('ui.common.loading')]]"
></paper-spinner> ></paper-spinner>
<vaadin-date-picker <div class="flex layout horizontal wrap">
id='picker' <vaadin-date-picker
value='{{_currentDate}}' id='picker'
label="[[localize('ui.panel.logbook.showing_entries')]]" value='{{_currentDate}}'
disabled='[[isLoading]]' label="[[localize('ui.panel.logbook.showing_entries')]]"
required disabled='[[isLoading]]'
></vaadin-date-picker> required
></vaadin-date-picker>
<paper-dropdown-menu
label-float
label="[[localize('ui.panel.logbook.period')]]"
disabled='[[isLoading]]'
>
<paper-listbox
slot="dropdown-content"
selected="{{_periodIndex}}"
>
<paper-item>[[localize('ui.duration.day', 'count', 1)]]</paper-item>
<paper-item>[[localize('ui.duration.day', 'count', 3)]]</paper-item>
<paper-item>[[localize('ui.duration.week', 'count', 1)]]</paper-item>
</paper-listbox>
</paper-dropdown-menu>
<ha-entity-picker
hass="[[hass]]"
value="{{_entityId}}"
label="[[localize('ui.components.entity.entity-picker.entity')]]"
disabled='[[isLoading]]'
on-change='_entityPicked'
></ha-entity-picker>
</div>
<ha-logbook hass='[[hass]]' entries="[[entries]]" hidden$='[[isLoading]]'></ha-logbook> <ha-logbook hass='[[hass]]' entries="[[entries]]" hidden$='[[isLoading]]'></ha-logbook>
</div> </div>
@ -116,6 +163,22 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) {
} }
}, },
_periodIndex: {
type: Number,
value: 0,
},
_entityId: {
type: String,
value: '',
},
entityId: {
type: String,
value: '',
readOnly: true,
},
isLoading: { isLoading: {
type: Boolean, type: Boolean,
}, },
@ -145,6 +208,20 @@ class HaPanelLogbook extends LocalizeMixin(PolymerElement) {
return new Date(parts[0], parts[1], parts[2]).toISOString(); return new Date(parts[0], parts[1], parts[2]).toISOString();
} }
_computeFilterDays(periodIndex) {
switch (periodIndex) {
case 1:
return 3;
case 2:
return 7;
default: return 1;
}
}
_entityPicked(ev) {
this._setEntityId(ev.target.value);
}
refreshLogbook() { refreshLogbook() {
this.shadowRoot.querySelector('ha-logbook-data').refreshLogbook(); this.shadowRoot.querySelector('ha-logbook-data').refreshLogbook();
} }