mirror of
https://github.com/home-assistant/frontend.git
synced 2025-05-13 06:28:42 +00:00
Logbook: filter by entity and period (#1728)
* Filter logbook by entity_id * Filter logbook by period * Filter logbook styles * CI Fix * Review * Review * CI Fix
This commit is contained in:
parent
69eb007ea2
commit
3b425c3e14
src/panels/logbook
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user