UI: Improvement load and update time into time series table

This commit is contained in:
Vladyslav_Prykhodko 2021-02-12 17:08:43 +02:00
parent eaa2c5785f
commit d520415d5b
2 changed files with 123 additions and 107 deletions

View File

@ -39,7 +39,8 @@
</mat-toolbar> </mat-toolbar>
<mat-tab-group [ngClass]="{'tb-headless': sources.length === 1}" fxFlex <mat-tab-group [ngClass]="{'tb-headless': sources.length === 1}" fxFlex
[(selectedIndex)]="sourceIndex" (selectedIndexChange)="onSourceIndexChanged()"> [(selectedIndex)]="sourceIndex" (selectedIndexChange)="onSourceIndexChanged()">
<mat-tab *ngFor="let source of sources; trackBy: trackBySourcesIndex" label="{{ source.datasource.name }}"> <mat-tab *ngFor="let source of sources; trackBy: trackBySourcesIndex; let index = index;" label="{{ source.datasource.name }}">
<ng-template [ngIf]="isActiveTab(index)">
<div fxFlex class="table-container"> <div fxFlex class="table-container">
<table mat-table [dataSource]="source.timeseriesDatasource" [trackBy]="trackByRowTimestamp" <table mat-table [dataSource]="source.timeseriesDatasource" [trackBy]="trackByRowTimestamp"
matSort [matSortActive]="source.pageLink.sortOrder.property" [matSortDirection]="source.pageLink.sortDirection()" matSortDisableClear> matSort [matSortActive]="source.pageLink.sortOrder.property" [matSortDirection]="source.pageLink.sortDirection()" matSortDisableClear>
@ -106,6 +107,7 @@
[pageSize]="source.pageLink.pageSize" [pageSize]="source.pageLink.pageSize"
[pageSizeOptions]="pageSizeOptions" [pageSizeOptions]="pageSizeOptions"
showFirstLastButtons></mat-paginator> showFirstLastButtons></mat-paginator>
</ng-template>
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>

View File

@ -40,12 +40,12 @@ import {
} from '@shared/models/widget.models'; } from '@shared/models/widget.models';
import { UtilsService } from '@core/services/utils.service'; import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import {hashCode, isDefined, isDefinedAndNotNull, isNumber} from '@core/utils'; import { hashCode, isDefined, isEqual, isNumber } from '@core/utils';
import cssjs from '@core/css/css'; import cssjs from '@core/css/css';
import { PageLink } from '@shared/models/page/page-link'; import { PageLink } from '@shared/models/page/page-link';
import { Direction, SortOrder, sortOrderFromString } from '@shared/models/page/sort-order'; import { Direction, SortOrder, sortOrderFromString } from '@shared/models/page/sort-order';
import { CollectionViewer, DataSource } from '@angular/cdk/collections'; import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { BehaviorSubject, fromEvent, merge, Observable, of } from 'rxjs'; import { BehaviorSubject, fromEvent, merge, Observable, of, Subscription } from 'rxjs';
import { emptyPageData, PageData } from '@shared/models/page/page-data'; import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { catchError, debounceTime, distinctUntilChanged, map, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, tap } from 'rxjs/operators';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
@ -129,6 +129,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
public showTimestamp = true; public showTimestamp = true;
private dateFormatFilter: string; private dateFormatFilter: string;
private subscriptions: Subscription[] = [];
private searchAction: WidgetAction = { private searchAction: WidgetAction = {
name: 'action.search', name: 'action.search',
show: true, show: true,
@ -166,40 +168,27 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
debounceTime(150), debounceTime(150),
distinctUntilChanged(), distinctUntilChanged(),
tap(() => { tap(() => {
if (this.displayPagination) {
this.paginators.forEach((paginator) => {
paginator.pageIndex = 0;
});
}
this.sources.forEach((source) => { this.sources.forEach((source) => {
source.pageLink.textSearch = this.textSearch; source.pageLink.textSearch = this.textSearch;
if (this.displayPagination) {
source.pageLink.page = 0;
}
}); });
this.updateAllData(); this.loadCurrentSourceRow();
this.ctx.detectChanges();
}) })
) )
.subscribe(); .subscribe();
if (this.displayPagination) { this.sorts.changes.subscribe(() => {
this.sorts.forEach((sort, index) => { this.initSubscriptionsToSortAndPaginator();
sort.sortChange.subscribe(() => this.paginators.toArray()[index].pageIndex = 0);
}); });
}
this.sorts.forEach((sort, index) => { this.initSubscriptionsToSortAndPaginator();
const paginator = this.displayPagination ? this.paginators.toArray()[index] : null;
sort.sortChange.subscribe(() => this.paginators.toArray()[index].pageIndex = 0);
((this.displayPagination ? merge(sort.sortChange, paginator.page) : sort.sortChange) as Observable<any>)
.pipe(
tap(() => this.updateData(sort, paginator, index))
)
.subscribe();
});
this.updateAllData();
} }
public onDataUpdated() { public onDataUpdated() {
this.sources.forEach((source) => { this.updateCurrentSourceData();
source.timeseriesDatasource.dataUpdated(this.data);
});
} }
private initialize() { private initialize() {
@ -305,7 +294,27 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
this.ctx.activeEntityInfo = activeEntityInfo; this.ctx.activeEntityInfo = activeEntityInfo;
} }
private initSubscriptionsToSortAndPaginator() {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.sorts.forEach((sort, index) => {
let paginator = null;
const observables = [sort.sortChange];
if (this.displayPagination) {
paginator = this.paginators.toArray()[index];
this.subscriptions.push(
sort.sortChange.subscribe(() => paginator.pageIndex = 0)
);
observables.push(paginator.page);
}
this.updateData(sort, paginator);
this.subscriptions.push(merge(...observables).pipe(
tap(() => this.updateData(sort, paginator))
).subscribe());
});
}
onSourceIndexChanged() { onSourceIndexChanged() {
this.updateCurrentSourceData();
this.updateActiveEntityInfo(); this.updateActiveEntityInfo();
} }
@ -326,30 +335,19 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
exitFilterMode() { exitFilterMode() {
this.textSearchMode = false; this.textSearchMode = false;
this.textSearch = null; this.textSearch = null;
this.sources.forEach((source, index) => { this.sources.forEach((source) => {
source.pageLink.textSearch = this.textSearch; source.pageLink.textSearch = this.textSearch;
const sort = this.sorts.toArray()[index];
let paginator = null;
if (this.displayPagination) { if (this.displayPagination) {
paginator = this.paginators.toArray()[index]; source.pageLink.page = 0;
paginator.pageIndex = 0;
} }
this.updateData(sort, paginator, index);
}); });
this.loadCurrentSourceRow();
this.ctx.hideTitlePanel = false; this.ctx.hideTitlePanel = false;
this.ctx.detectChanges(true); this.ctx.detectChanges(true);
} }
private updateAllData() { private updateData(sort: MatSort, paginator: MatPaginator) {
this.sources.forEach((source, index) => { const source = this.sources[this.sourceIndex];
const sort = this.sorts.toArray()[index];
const paginator = this.displayPagination ? this.paginators.toArray()[index] : null;
this.updateData(sort, paginator, index);
});
}
private updateData(sort: MatSort, paginator: MatPaginator, index: number) {
const source = this.sources[index];
if (this.displayPagination) { if (this.displayPagination) {
source.pageLink.page = paginator.pageIndex; source.pageLink.page = paginator.pageIndex;
source.pageLink.pageSize = paginator.pageSize; source.pageLink.pageSize = paginator.pageSize;
@ -418,7 +416,6 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
if (!isDefined(content)) { if (!isDefined(content)) {
return ''; return '';
} else { } else {
switch (typeof content) { switch (typeof content) {
case 'string': case 'string':
@ -462,6 +459,18 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
} }
this.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, row, entityLabel); this.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, row, entityLabel);
} }
public isActiveTab(index: number): boolean {
return index === this.sourceIndex;
}
private updateCurrentSourceData() {
this.sources[this.sourceIndex].timeseriesDatasource.dataUpdated(this.data);
}
private loadCurrentSourceRow() {
this.sources[this.sourceIndex].timeseriesDatasource.loadRows();
}
} }
class TimeseriesDatasource implements DataSource<TimeseriesRow> { class TimeseriesDatasource implements DataSource<TimeseriesRow> {
@ -482,6 +491,10 @@ class TimeseriesDatasource implements DataSource<TimeseriesRow> {
} }
connect(collectionViewer: CollectionViewer): Observable<TimeseriesRow[] | ReadonlyArray<TimeseriesRow>> { connect(collectionViewer: CollectionViewer): Observable<TimeseriesRow[] | ReadonlyArray<TimeseriesRow>> {
if (this.rowsSubject.isStopped) {
this.rowsSubject.isStopped = false;
this.pageDataSubject.isStopped = false;
}
return this.rowsSubject.asObservable(); return this.rowsSubject.asObservable();
} }
@ -565,7 +578,8 @@ class TimeseriesDatasource implements DataSource<TimeseriesRow> {
private fetchRows(pageLink: PageLink): Observable<PageData<TimeseriesRow>> { private fetchRows(pageLink: PageLink): Observable<PageData<TimeseriesRow>> {
return this.allRows$.pipe( return this.allRows$.pipe(
map((data) => pageLink.filterData(data)) map((data) => pageLink.filterData(data)),
distinctUntilChanged((prev, curr) => isEqual(prev, curr))
); );
} }
} }