Commit b0c5479c645013dbd8679b39fa7ce7d15198ed0a

Authored by Igor Kulikov
1 parent f9375a0f

UI: Entities table model improvements.

@@ -29,8 +29,8 @@ export abstract class ContactBasedComponent<T extends ContactBased<HasId>> exten @@ -29,8 +29,8 @@ export abstract class ContactBasedComponent<T extends ContactBased<HasId>> exten
29 protected constructor(protected store: Store<AppState>, 29 protected constructor(protected store: Store<AppState>,
30 protected fb: FormBuilder, 30 protected fb: FormBuilder,
31 protected entityValue: T, 31 protected entityValue: T,
32 - protected entitiesTableConfig: EntityTableConfig<T>) {  
33 - super(store, fb, entityValue, entitiesTableConfig); 32 + protected entitiesTableConfigValue: EntityTableConfig<T>) {
  33 + super(store, fb, entityValue, entitiesTableConfigValue);
34 } 34 }
35 35
36 buildForm(entity: T): FormGroup { 36 buildForm(entity: T): FormGroup {
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 <tb-entity-details-panel 25 <tb-entity-details-panel
26 [entitiesTableConfig]="entitiesTableConfig" 26 [entitiesTableConfig]="entitiesTableConfig"
27 [entityId]="dataSource.currentEntity?.id" 27 [entityId]="dataSource.currentEntity?.id"
28 - (closeEntityDetails)="isDetailsOpen = false" 28 + (closeEntityDetails)="isDetailsOpen = false; detailsPanelOpened.emit(isDetailsOpen);"
29 (entityUpdated)="onEntityUpdated($event)" 29 (entityUpdated)="onEntityUpdated($event)"
30 (entityAction)="onEntityAction($event)" 30 (entityAction)="onEntityAction($event)"
31 > 31 >
@@ -227,11 +227,12 @@ @@ -227,11 +227,12 @@
227 fxLayoutAlign="center center" 227 fxLayoutAlign="center center"
228 class="no-data-found" translate>{{ translations.noEntities }}</span> 228 class="no-data-found" translate>{{ translations.noEntities }}</span>
229 </div> 229 </div>
230 - <mat-divider></mat-divider>  
231 - <mat-paginator [length]="dataSource.total() | async" 230 + <mat-divider *ngIf="displayPagination"></mat-divider>
  231 + <mat-paginator *ngIf="displayPagination"
  232 + [length]="dataSource.total() | async"
232 [pageIndex]="pageLink.page" 233 [pageIndex]="pageLink.page"
233 [pageSize]="pageLink.pageSize" 234 [pageSize]="pageLink.pageSize"
234 - [pageSizeOptions]="[10, 20, 30]"></mat-paginator> 235 + [pageSizeOptions]="pageSizeOptions"></mat-paginator>
235 </div> 236 </div>
236 </div> 237 </div>
237 </mat-drawer-content> 238 </mat-drawer-content>
@@ -19,7 +19,7 @@ import { @@ -19,7 +19,7 @@ import {
19 ChangeDetectionStrategy, 19 ChangeDetectionStrategy,
20 Component, 20 Component,
21 ComponentFactoryResolver, 21 ComponentFactoryResolver,
22 - ElementRef, 22 + ElementRef, EventEmitter,
23 Input, OnChanges, 23 Input, OnChanges,
24 OnInit, SimpleChanges, 24 OnInit, SimpleChanges,
25 ViewChild 25 ViewChild
@@ -27,14 +27,14 @@ import { @@ -27,14 +27,14 @@ import {
27 import { PageComponent } from '@shared/components/page.component'; 27 import { PageComponent } from '@shared/components/page.component';
28 import { Store } from '@ngrx/store'; 28 import { Store } from '@ngrx/store';
29 import { AppState } from '@core/core.state'; 29 import { AppState } from '@core/core.state';
30 -import { PageLink, TimePageLink } from '@shared/models/page/page-link'; 30 +import { MAX_SAFE_PAGE_SIZE, PageLink, TimePageLink } from '@shared/models/page/page-link';
31 import { MatDialog } from '@angular/material/dialog'; 31 import { MatDialog } from '@angular/material/dialog';
32 import { MatPaginator } from '@angular/material/paginator'; 32 import { MatPaginator } from '@angular/material/paginator';
33 import { MatSort } from '@angular/material/sort'; 33 import { MatSort } from '@angular/material/sort';
34 import { EntitiesDataSource } from '@home/models/datasource/entity-datasource'; 34 import { EntitiesDataSource } from '@home/models/datasource/entity-datasource';
35 import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'; 35 import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
36 import { Direction, SortOrder } from '@shared/models/page/sort-order'; 36 import { Direction, SortOrder } from '@shared/models/page/sort-order';
37 -import { forkJoin, fromEvent, merge, Observable } from 'rxjs'; 37 +import { forkJoin, fromEvent, merge, Observable, Subscription } from 'rxjs';
38 import { TranslateService } from '@ngx-translate/core'; 38 import { TranslateService } from '@ngx-translate/core';
39 import { BaseData, HasId } from '@shared/models/base-data'; 39 import { BaseData, HasId } from '@shared/models/base-data';
40 import { ActivatedRoute } from '@angular/router'; 40 import { ActivatedRoute } from '@angular/router';
@@ -87,12 +87,16 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -87,12 +87,16 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
87 87
88 selectionEnabled; 88 selectionEnabled;
89 89
  90 + defaultPageSize = 10;
  91 + displayPagination = true;
  92 + pageSizeOptions;
90 pageLink: PageLink; 93 pageLink: PageLink;
91 textSearchMode = false; 94 textSearchMode = false;
92 timewindow: Timewindow; 95 timewindow: Timewindow;
93 dataSource: EntitiesDataSource<BaseData<HasId>>; 96 dataSource: EntitiesDataSource<BaseData<HasId>>;
94 97
95 isDetailsOpen = false; 98 isDetailsOpen = false;
  99 + detailsPanelOpened = new EventEmitter<boolean>();
96 100
97 @ViewChild('entityTableHeader', {static: true}) entityTableHeaderAnchor: TbAnchorComponent; 101 @ViewChild('entityTableHeader', {static: true}) entityTableHeaderAnchor: TbAnchorComponent;
98 102
@@ -101,6 +105,10 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -101,6 +105,10 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
101 @ViewChild(MatPaginator) paginator: MatPaginator; 105 @ViewChild(MatPaginator) paginator: MatPaginator;
102 @ViewChild(MatSort) sort: MatSort; 106 @ViewChild(MatSort) sort: MatSort;
103 107
  108 + private sortSubscription: Subscription;
  109 + private updateDataSubscription: Subscription;
  110 + private viewInited = false;
  111 +
104 constructor(protected store: Store<AppState>, 112 constructor(protected store: Store<AppState>,
105 private route: ActivatedRoute, 113 private route: ActivatedRoute,
106 public translate: TranslateService, 114 public translate: TranslateService,
@@ -183,6 +191,10 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -183,6 +191,10 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
183 }; 191 };
184 } 192 }
185 193
  194 + this.displayPagination = this.entitiesTableConfig.displayPagination;
  195 + this.defaultPageSize = this.entitiesTableConfig.defaultPageSize;
  196 + this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
  197 +
186 if (this.entitiesTableConfig.useTimePageLink) { 198 if (this.entitiesTableConfig.useTimePageLink) {
187 this.timewindow = historyInterval(DAY); 199 this.timewindow = historyInterval(DAY);
188 const currentTime = Date.now(); 200 const currentTime = Date.now();
@@ -191,6 +203,7 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -191,6 +203,7 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
191 } else { 203 } else {
192 this.pageLink = new PageLink(10, 0, null, sortOrder); 204 this.pageLink = new PageLink(10, 0, null, sortOrder);
193 } 205 }
  206 + this.pageLink.pageSize = this.displayPagination ? this.defaultPageSize : MAX_SAFE_PAGE_SIZE;
194 this.dataSource = this.entitiesTableConfig.dataSource(() => { 207 this.dataSource = this.entitiesTableConfig.dataSource(() => {
195 this.dataLoaded(); 208 this.dataLoaded();
196 }); 209 });
@@ -200,6 +213,11 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -200,6 +213,11 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
200 if (this.entitiesTableConfig.loadDataOnInit) { 213 if (this.entitiesTableConfig.loadDataOnInit) {
201 this.dataSource.loadEntities(this.pageLink); 214 this.dataSource.loadEntities(this.pageLink);
202 } 215 }
  216 + if (this.viewInited) {
  217 + setTimeout(() => {
  218 + this.updatePaginationSubscriptions();
  219 + }, 0);
  220 + }
203 } 221 }
204 222
205 ngAfterViewInit() { 223 ngAfterViewInit() {
@@ -209,15 +227,31 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -209,15 +227,31 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
209 debounceTime(150), 227 debounceTime(150),
210 distinctUntilChanged(), 228 distinctUntilChanged(),
211 tap(() => { 229 tap(() => {
212 - this.paginator.pageIndex = 0; 230 + if (this.displayPagination) {
  231 + this.paginator.pageIndex = 0;
  232 + }
213 this.updateData(); 233 this.updateData();
214 }) 234 })
215 ) 235 )
216 .subscribe(); 236 .subscribe();
217 237
218 - this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0); 238 + this.updatePaginationSubscriptions();
  239 + this.viewInited = true;
  240 + }
219 241
220 - merge(this.sort.sortChange, this.paginator.page) 242 + private updatePaginationSubscriptions() {
  243 + if (this.sortSubscription) {
  244 + this.sortSubscription.unsubscribe();
  245 + this.sortSubscription = null;
  246 + }
  247 + if (this.updateDataSubscription) {
  248 + this.updateDataSubscription.unsubscribe();
  249 + this.updateDataSubscription = null;
  250 + }
  251 + if (this.displayPagination) {
  252 + this.sortSubscription = this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
  253 + }
  254 + this.updateDataSubscription = (this.displayPagination ? merge(this.sort.sortChange, this.paginator.page) : this.sort.sortChange)
221 .pipe( 255 .pipe(
222 tap(() => this.updateData()) 256 tap(() => this.updateData())
223 ) 257 )
@@ -232,8 +266,12 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -232,8 +266,12 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
232 if (closeDetails) { 266 if (closeDetails) {
233 this.isDetailsOpen = false; 267 this.isDetailsOpen = false;
234 } 268 }
235 - this.pageLink.page = this.paginator.pageIndex;  
236 - this.pageLink.pageSize = this.paginator.pageSize; 269 + if (this.displayPagination) {
  270 + this.pageLink.page = this.paginator.pageIndex;
  271 + this.pageLink.pageSize = this.paginator.pageSize;
  272 + } else {
  273 + this.pageLink.page = 0;
  274 + }
237 if (this.sort.active) { 275 if (this.sort.active) {
238 this.pageLink.sortOrder = { 276 this.pageLink.sortOrder = {
239 property: this.sort.active, 277 property: this.sort.active,
@@ -264,6 +302,12 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -264,6 +302,12 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
264 } 302 }
265 303
266 onRowClick($event: Event, entity) { 304 onRowClick($event: Event, entity) {
  305 + if (!this.entitiesTableConfig.handleRowClick($event, entity)) {
  306 + this.toggleEntityDetails($event, entity);
  307 + }
  308 + }
  309 +
  310 + toggleEntityDetails($event: Event, entity) {
267 if ($event) { 311 if ($event) {
268 $event.stopPropagation(); 312 $event.stopPropagation();
269 } 313 }
@@ -272,6 +316,7 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -272,6 +316,7 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
272 } else { 316 } else {
273 this.isDetailsOpen = !this.isDetailsOpen; 317 this.isDetailsOpen = !this.isDetailsOpen;
274 } 318 }
  319 + this.detailsPanelOpened.emit(this.isDetailsOpen);
275 } 320 }
276 321
277 addEntity($event: Event) { 322 addEntity($event: Event) {
@@ -371,16 +416,20 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn @@ -371,16 +416,20 @@ export class EntitiesTableComponent extends PageComponent implements AfterViewIn
371 exitFilterMode() { 416 exitFilterMode() {
372 this.textSearchMode = false; 417 this.textSearchMode = false;
373 this.pageLink.textSearch = null; 418 this.pageLink.textSearch = null;
374 - this.paginator.pageIndex = 0; 419 + if (this.displayPagination) {
  420 + this.paginator.pageIndex = 0;
  421 + }
375 this.updateData(); 422 this.updateData();
376 } 423 }
377 424
378 resetSortAndFilter(update: boolean = true) { 425 resetSortAndFilter(update: boolean = true) {
379 this.pageLink.textSearch = null; 426 this.pageLink.textSearch = null;
380 if (this.entitiesTableConfig.useTimePageLink) { 427 if (this.entitiesTableConfig.useTimePageLink) {
381 - this.timewindow = historyInterval(24 * 60 * 60 * 1000); 428 + this.timewindow = historyInterval(DAY);
  429 + }
  430 + if (this.displayPagination) {
  431 + this.paginator.pageIndex = 0;
382 } 432 }
383 - this.paginator.pageIndex = 0;  
384 const sortable = this.sort.sortables.get(this.entitiesTableConfig.defaultSortOrder.property); 433 const sortable = this.sort.sortables.get(this.entitiesTableConfig.defaultSortOrder.property);
385 this.sort.active = sortable.id; 434 this.sort.active = sortable.id;
386 this.sort.direction = this.entitiesTableConfig.defaultSortOrder.direction === Direction.ASC ? 'asc' : 'desc'; 435 this.sort.direction = this.entitiesTableConfig.defaultSortOrder.direction === Direction.ASC ? 'asc' : 'desc';
@@ -51,8 +51,6 @@ import { deepClone } from '@core/utils'; @@ -51,8 +51,6 @@ import { deepClone } from '@core/utils';
51 }) 51 })
52 export class EntityDetailsPanelComponent extends PageComponent implements OnInit, AfterViewInit, OnDestroy { 52 export class EntityDetailsPanelComponent extends PageComponent implements OnInit, AfterViewInit, OnDestroy {
53 53
54 - @Input() entitiesTableConfig: EntityTableConfig<BaseData<HasId>>;  
55 -  
56 @Output() 54 @Output()
57 closeEntityDetails = new EventEmitter<void>(); 55 closeEntityDetails = new EventEmitter<void>();
58 56
@@ -66,6 +64,7 @@ export class EntityDetailsPanelComponent extends PageComponent implements OnInit @@ -66,6 +64,7 @@ export class EntityDetailsPanelComponent extends PageComponent implements OnInit
66 entityTabsComponent: EntityTabsComponent<BaseData<HasId>>; 64 entityTabsComponent: EntityTabsComponent<BaseData<HasId>>;
67 detailsForm: NgForm; 65 detailsForm: NgForm;
68 66
  67 + entitiesTableConfigValue: EntityTableConfig<BaseData<HasId>>;
69 isEditValue = false; 68 isEditValue = false;
70 selectedTab = 0; 69 selectedTab = 0;
71 70
@@ -102,9 +101,26 @@ export class EntityDetailsPanelComponent extends PageComponent implements OnInit @@ -102,9 +101,26 @@ export class EntityDetailsPanelComponent extends PageComponent implements OnInit
102 } 101 }
103 } 102 }
104 103
  104 + @Input()
  105 + set entitiesTableConfig(entitiesTableConfig: EntityTableConfig<BaseData<HasId>>) {
  106 + this.entitiesTableConfigValue = entitiesTableConfig;
  107 + if (this.entityComponent) {
  108 + this.entityComponent.entitiesTableConfig = entitiesTableConfig;
  109 + }
  110 + if (this.entityTabsComponent) {
  111 + this.entityTabsComponent.entitiesTableConfig = entitiesTableConfig;
  112 + }
  113 + }
  114 +
  115 + get entitiesTableConfig(): EntityTableConfig<BaseData<HasId>> {
  116 + return this.entitiesTableConfigValue;
  117 + }
  118 +
105 set isEdit(val: boolean) { 119 set isEdit(val: boolean) {
106 this.isEditValue = val; 120 this.isEditValue = val;
107 - this.entityComponent.isEdit = val; 121 + if (this.entityComponent) {
  122 + this.entityComponent.isEdit = val;
  123 + }
108 if (this.entityTabsComponent) { 124 if (this.entityTabsComponent) {
109 this.entityTabsComponent.isEdit = val; 125 this.entityTabsComponent.isEdit = val;
110 } 126 }
@@ -20,12 +20,25 @@ import { Input, OnInit, Directive } from '@angular/core'; @@ -20,12 +20,25 @@ import { Input, OnInit, Directive } from '@angular/core';
20 import { Store } from '@ngrx/store'; 20 import { Store } from '@ngrx/store';
21 import { AppState } from '@core/core.state'; 21 import { AppState } from '@core/core.state';
22 import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; 22 import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
  23 +import { PageLink } from '@shared/models/page/page-link';
23 24
24 @Directive() 25 @Directive()
25 -export abstract class EntityTableHeaderComponent<T extends BaseData<HasId>> extends PageComponent implements OnInit { 26 +export abstract class EntityTableHeaderComponent<T extends BaseData<HasId>,
  27 + P extends PageLink = PageLink,
  28 + L extends BaseData<HasId> = T,
  29 + C extends EntityTableConfig<T, P, L> = EntityTableConfig<T, P, L>>
  30 + extends PageComponent implements OnInit {
  31 +
  32 + entitiesTableConfigValue: C;
26 33
27 @Input() 34 @Input()
28 - entitiesTableConfig: EntityTableConfig<T>; 35 + set entitiesTableConfig(entitiesTableConfig: C) {
  36 + this.setEntitiesTableConfig(entitiesTableConfig);
  37 + }
  38 +
  39 + get entitiesTableConfig(): C {
  40 + return this.entitiesTableConfigValue;
  41 + }
29 42
30 protected constructor(protected store: Store<AppState>) { 43 protected constructor(protected store: Store<AppState>) {
31 super(store); 44 super(store);
@@ -34,4 +47,8 @@ export abstract class EntityTableHeaderComponent<T extends BaseData<HasId>> exte @@ -34,4 +47,8 @@ export abstract class EntityTableHeaderComponent<T extends BaseData<HasId>> exte
34 ngOnInit() { 47 ngOnInit() {
35 } 48 }
36 49
  50 + protected setEntitiesTableConfig(entitiesTableConfig: C) {
  51 + this.entitiesTableConfigValue = entitiesTableConfig;
  52 + }
  53 +
37 } 54 }
@@ -39,6 +39,15 @@ export abstract class EntityComponent<T extends BaseData<HasId>, @@ -39,6 +39,15 @@ export abstract class EntityComponent<T extends BaseData<HasId>,
39 isEditValue: boolean; 39 isEditValue: boolean;
40 40
41 @Input() 41 @Input()
  42 + set entitiesTableConfig(entitiesTableConfig: C) {
  43 + this.entitiesTableConfigValue = entitiesTableConfig;
  44 + }
  45 +
  46 + get entitiesTableConfig(): C {
  47 + return this.entitiesTableConfigValue;
  48 + }
  49 +
  50 + @Input()
42 set isEdit(isEdit: boolean) { 51 set isEdit(isEdit: boolean) {
43 this.isEditValue = isEdit; 52 this.isEditValue = isEdit;
44 this.updateFormState(); 53 this.updateFormState();
@@ -72,7 +81,7 @@ export abstract class EntityComponent<T extends BaseData<HasId>, @@ -72,7 +81,7 @@ export abstract class EntityComponent<T extends BaseData<HasId>,
72 protected constructor(protected store: Store<AppState>, 81 protected constructor(protected store: Store<AppState>,
73 protected fb: FormBuilder, 82 protected fb: FormBuilder,
74 protected entityValue: T, 83 protected entityValue: T,
75 - protected entitiesTableConfig: C) { 84 + protected entitiesTableConfigValue: C) {
76 super(store); 85 super(store);
77 this.entityForm = this.buildForm(this.entityValue); 86 this.entityForm = this.buildForm(this.entityValue);
78 } 87 }
@@ -29,7 +29,6 @@ import { @@ -29,7 +29,6 @@ import {
29 OnDestroy, 29 OnDestroy,
30 OnInit, 30 OnInit,
31 SimpleChanges, 31 SimpleChanges,
32 - Type,  
33 ViewChild, 32 ViewChild,
34 ViewContainerRef, 33 ViewContainerRef,
35 ViewEncapsulation 34 ViewEncapsulation
@@ -44,7 +43,8 @@ import { @@ -44,7 +43,8 @@ import {
44 Widget, 43 Widget,
45 WidgetActionDescriptor, 44 WidgetActionDescriptor,
46 widgetActionSources, 45 widgetActionSources,
47 - WidgetActionType, WidgetComparisonSettings, 46 + WidgetActionType,
  47 + WidgetComparisonSettings,
48 WidgetResource, 48 WidgetResource,
49 widgetType, 49 widgetType,
50 WidgetTypeParameters 50 WidgetTypeParameters
@@ -90,27 +90,7 @@ import { DashboardService } from '@core/http/dashboard.service'; @@ -90,27 +90,7 @@ import { DashboardService } from '@core/http/dashboard.service';
90 import { DatasourceService } from '@core/api/datasource.service'; 90 import { DatasourceService } from '@core/api/datasource.service';
91 import { WidgetSubscription } from '@core/api/widget-subscription'; 91 import { WidgetSubscription } from '@core/api/widget-subscription';
92 import { EntityService } from '@core/http/entity.service'; 92 import { EntityService } from '@core/http/entity.service';
93 -import { AssetService } from '@core/http/asset.service';  
94 -import { DialogService } from '@core/services/dialog.service';  
95 -import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service';  
96 -import { DatePipe } from '@angular/common';  
97 -import { AttributeService } from '@core/http/attribute.service';  
98 -import { TranslateService } from '@ngx-translate/core';  
99 -import { HttpClient } from '@angular/common/http';  
100 -import { EntityRelationService } from '@app/core/http/entity-relation.service';  
101 -  
102 -const ServicesMap = new Map<string, Type<any>>();  
103 -ServicesMap.set('deviceService', DeviceService);  
104 -ServicesMap.set('assetService', AssetService);  
105 -ServicesMap.set('attributeService', AttributeService);  
106 -ServicesMap.set('entityRelationService', EntityRelationService);  
107 -ServicesMap.set('entityService', EntityService);  
108 -ServicesMap.set('dialogs', DialogService);  
109 -ServicesMap.set('customDialog', CustomDialogService);  
110 -ServicesMap.set('date', DatePipe);  
111 -ServicesMap.set('utils', UtilsService);  
112 -ServicesMap.set('translate', TranslateService);  
113 -ServicesMap.set('http', HttpClient); 93 +import { ServicesMap } from '@home/models/services.map';
114 94
115 @Component({ 95 @Component({
116 selector: 'tb-widget', 96 selector: 'tb-widget',
@@ -39,6 +39,7 @@ export type EntityByIdOperation<T extends BaseData<HasId>> = (id: HasUUID) => Ob @@ -39,6 +39,7 @@ export type EntityByIdOperation<T extends BaseData<HasId>> = (id: HasUUID) => Ob
39 export type EntityIdOneWayOperation = (id: HasUUID) => Observable<any>; 39 export type EntityIdOneWayOperation = (id: HasUUID) => Observable<any>;
40 export type EntityActionFunction<T extends BaseData<HasId>> = (action: EntityAction<T>) => boolean; 40 export type EntityActionFunction<T extends BaseData<HasId>> = (action: EntityAction<T>) => boolean;
41 export type CreateEntityOperation<T extends BaseData<HasId>> = () => Observable<T>; 41 export type CreateEntityOperation<T extends BaseData<HasId>> = () => Observable<T>;
  42 +export type EntityRowClickFunction<T extends BaseData<HasId>> = (event: Event, entity: T) => boolean;
42 43
43 export type CellContentFunction<T extends BaseData<HasId>> = (entity: T, key: string) => string; 44 export type CellContentFunction<T extends BaseData<HasId>> = (entity: T, key: string) => string;
44 export type CellTooltipFunction<T extends BaseData<HasId>> = (entity: T, key: string) => string | undefined; 45 export type CellTooltipFunction<T extends BaseData<HasId>> = (entity: T, key: string) => string | undefined;
@@ -147,12 +148,14 @@ export class EntityTableConfig<T extends BaseData<HasId>, P extends PageLink = P @@ -147,12 +148,14 @@ export class EntityTableConfig<T extends BaseData<HasId>, P extends PageLink = P
147 entityTabsComponent: Type<EntityTabsComponent<T, P, L>>; 148 entityTabsComponent: Type<EntityTabsComponent<T, P, L>>;
148 addDialogStyle = {}; 149 addDialogStyle = {};
149 defaultSortOrder: SortOrder = {property: 'createdTime', direction: Direction.ASC}; 150 defaultSortOrder: SortOrder = {property: 'createdTime', direction: Direction.ASC};
  151 + displayPagination = true;
  152 + defaultPageSize = 10;
150 columns: Array<EntityColumn<L>> = []; 153 columns: Array<EntityColumn<L>> = [];
151 cellActionDescriptors: Array<CellActionDescriptor<L>> = []; 154 cellActionDescriptors: Array<CellActionDescriptor<L>> = [];
152 groupActionDescriptors: Array<GroupActionDescriptor<L>> = []; 155 groupActionDescriptors: Array<GroupActionDescriptor<L>> = [];
153 headerActionDescriptors: Array<HeaderActionDescriptor> = []; 156 headerActionDescriptors: Array<HeaderActionDescriptor> = [];
154 addActionDescriptors: Array<HeaderActionDescriptor> = []; 157 addActionDescriptors: Array<HeaderActionDescriptor> = [];
155 - headerComponent: Type<EntityTableHeaderComponent<L>>; 158 + headerComponent: Type<EntityTableHeaderComponent<T, P, L>>;
156 addEntity: CreateEntityOperation<T> = null; 159 addEntity: CreateEntityOperation<T> = null;
157 dataSource: (dataLoadedFunction: () => void) => EntitiesDataSource<L> = (dataLoadedFunction: () => void) => { 160 dataSource: (dataLoadedFunction: () => void) => EntitiesDataSource<L> = (dataLoadedFunction: () => void) => {
158 return new EntitiesDataSource(this.entitiesFetchFunction, this.entitySelectionEnabled, dataLoadedFunction); 161 return new EntitiesDataSource(this.entitiesFetchFunction, this.entitySelectionEnabled, dataLoadedFunction);
@@ -169,6 +172,7 @@ export class EntityTableConfig<T extends BaseData<HasId>, P extends PageLink = P @@ -169,6 +172,7 @@ export class EntityTableConfig<T extends BaseData<HasId>, P extends PageLink = P
169 deleteEntity: EntityIdOneWayOperation = () => of(); 172 deleteEntity: EntityIdOneWayOperation = () => of();
170 entitiesFetchFunction: EntitiesFetchFunction<L, P> = () => of(emptyPageData<L>()); 173 entitiesFetchFunction: EntitiesFetchFunction<L, P> = () => of(emptyPageData<L>());
171 onEntityAction: EntityActionFunction<T> = () => false; 174 onEntityAction: EntityActionFunction<T> = () => false;
  175 + handleRowClick: EntityRowClickFunction<L> = () => false;
172 entityTitle: EntityStringFunction<T> = (entity) => entity?.name; 176 entityTitle: EntityStringFunction<T> = (entity) => entity?.name;
173 } 177 }
174 178
  1 +///
  2 +/// Copyright © 2016-2020 The Thingsboard Authors
  3 +///
  4 +/// Licensed under the Apache License, Version 2.0 (the "License");
  5 +/// you may not use this file except in compliance with the License.
  6 +/// You may obtain a copy of the License at
  7 +///
  8 +/// http://www.apache.org/licenses/LICENSE-2.0
  9 +///
  10 +/// Unless required by applicable law or agreed to in writing, software
  11 +/// distributed under the License is distributed on an "AS IS" BASIS,
  12 +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +/// See the License for the specific language governing permissions and
  14 +/// limitations under the License.
  15 +///
  16 +
  17 +import { Type } from '@angular/core';
  18 +import { DeviceService } from '@core/http/device.service';
  19 +import { AssetService } from '@core/http/asset.service';
  20 +import { AttributeService } from '@core/http/attribute.service';
  21 +import { EntityRelationService } from '@core/http/entity-relation.service';
  22 +import { EntityService } from '@core/http/entity.service';
  23 +import { DialogService } from '@core/services/dialog.service';
  24 +import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service';
  25 +import { DatePipe } from '@angular/common';
  26 +import { UtilsService } from '@core/services/utils.service';
  27 +import { TranslateService } from '@ngx-translate/core';
  28 +import { HttpClient } from '@angular/common/http';
  29 +
  30 +export const ServicesMap = new Map<string, Type<any>>(
  31 + [
  32 + ['deviceService', DeviceService],
  33 + ['assetService', AssetService],
  34 + ['attributeService', AttributeService],
  35 + ['entityRelationService', EntityRelationService],
  36 + ['entityService', EntityService],
  37 + ['dialogs', DialogService],
  38 + ['customDialog', CustomDialogService],
  39 + ['date', DatePipe],
  40 + ['utils', UtilsService],
  41 + ['translate', TranslateService],
  42 + ['http', HttpClient]
  43 + ]
  44 +);
@@ -40,9 +40,9 @@ export class AssetComponent extends EntityComponent<AssetInfo> { @@ -40,9 +40,9 @@ export class AssetComponent extends EntityComponent<AssetInfo> {
40 constructor(protected store: Store<AppState>, 40 constructor(protected store: Store<AppState>,
41 protected translate: TranslateService, 41 protected translate: TranslateService,
42 @Inject('entity') protected entityValue: AssetInfo, 42 @Inject('entity') protected entityValue: AssetInfo,
43 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<AssetInfo>, 43 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<AssetInfo>,
44 public fb: FormBuilder) { 44 public fb: FormBuilder) {
45 - super(store, fb, entityValue, entitiesTableConfig); 45 + super(store, fb, entityValue, entitiesTableConfigValue);
46 } 46 }
47 47
48 ngOnInit() { 48 ngOnInit() {
@@ -35,9 +35,9 @@ export class CustomerComponent extends ContactBasedComponent<Customer> { @@ -35,9 +35,9 @@ export class CustomerComponent extends ContactBasedComponent<Customer> {
35 constructor(protected store: Store<AppState>, 35 constructor(protected store: Store<AppState>,
36 protected translate: TranslateService, 36 protected translate: TranslateService,
37 @Inject('entity') protected entityValue: Customer, 37 @Inject('entity') protected entityValue: Customer,
38 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<Customer>, 38 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<Customer>,
39 protected fb: FormBuilder) { 39 protected fb: FormBuilder) {
40 - super(store, fb, entityValue, entitiesTableConfig); 40 + super(store, fb, entityValue, entitiesTableConfigValue);
41 } 41 }
42 42
43 hideDelete() { 43 hideDelete() {
@@ -47,9 +47,9 @@ export class DashboardFormComponent extends EntityComponent<Dashboard> { @@ -47,9 +47,9 @@ export class DashboardFormComponent extends EntityComponent<Dashboard> {
47 protected translate: TranslateService, 47 protected translate: TranslateService,
48 private dashboardService: DashboardService, 48 private dashboardService: DashboardService,
49 @Inject('entity') protected entityValue: Dashboard, 49 @Inject('entity') protected entityValue: Dashboard,
50 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<Dashboard>, 50 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<Dashboard>,
51 public fb: FormBuilder) { 51 public fb: FormBuilder) {
52 - super(store, fb, entityValue, entitiesTableConfig); 52 + super(store, fb, entityValue, entitiesTableConfigValue);
53 } 53 }
54 54
55 ngOnInit() { 55 ngOnInit() {
@@ -44,9 +44,9 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { @@ -44,9 +44,9 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
44 private deviceService: DeviceService, 44 private deviceService: DeviceService,
45 private clipboardService: ClipboardService, 45 private clipboardService: ClipboardService,
46 @Inject('entity') protected entityValue: DeviceInfo, 46 @Inject('entity') protected entityValue: DeviceInfo,
47 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<DeviceInfo>, 47 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<DeviceInfo>,
48 public fb: FormBuilder) { 48 public fb: FormBuilder) {
49 - super(store, fb, entityValue, entitiesTableConfig); 49 + super(store, fb, entityValue, entitiesTableConfigValue);
50 } 50 }
51 51
52 ngOnInit() { 52 ngOnInit() {
@@ -52,9 +52,9 @@ export class EntityViewComponent extends EntityComponent<EntityViewInfo> { @@ -52,9 +52,9 @@ export class EntityViewComponent extends EntityComponent<EntityViewInfo> {
52 constructor(protected store: Store<AppState>, 52 constructor(protected store: Store<AppState>,
53 protected translate: TranslateService, 53 protected translate: TranslateService,
54 @Inject('entity') protected entityValue: EntityViewInfo, 54 @Inject('entity') protected entityValue: EntityViewInfo,
55 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<EntityViewInfo>, 55 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<EntityViewInfo>,
56 public fb: FormBuilder) { 56 public fb: FormBuilder) {
57 - super(store, fb, entityValue, entitiesTableConfig); 57 + super(store, fb, entityValue, entitiesTableConfigValue);
58 } 58 }
59 59
60 ngOnInit() { 60 ngOnInit() {
@@ -34,9 +34,9 @@ export class RuleChainComponent extends EntityComponent<RuleChain> { @@ -34,9 +34,9 @@ export class RuleChainComponent extends EntityComponent<RuleChain> {
34 constructor(protected store: Store<AppState>, 34 constructor(protected store: Store<AppState>,
35 protected translate: TranslateService, 35 protected translate: TranslateService,
36 @Inject('entity') protected entityValue: RuleChain, 36 @Inject('entity') protected entityValue: RuleChain,
37 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<RuleChain>, 37 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<RuleChain>,
38 public fb: FormBuilder) { 38 public fb: FormBuilder) {
39 - super(store, fb, entityValue, entitiesTableConfig); 39 + super(store, fb, entityValue, entitiesTableConfigValue);
40 } 40 }
41 41
42 hideDelete() { 42 hideDelete() {
@@ -34,9 +34,9 @@ export class TenantComponent extends ContactBasedComponent<Tenant> { @@ -34,9 +34,9 @@ export class TenantComponent extends ContactBasedComponent<Tenant> {
34 constructor(protected store: Store<AppState>, 34 constructor(protected store: Store<AppState>,
35 protected translate: TranslateService, 35 protected translate: TranslateService,
36 @Inject('entity') protected entityValue: Tenant, 36 @Inject('entity') protected entityValue: Tenant,
37 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<Tenant>, 37 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<Tenant>,
38 protected fb: FormBuilder) { 38 protected fb: FormBuilder) {
39 - super(store, fb, entityValue, entitiesTableConfig); 39 + super(store, fb, entityValue, entitiesTableConfigValue);
40 } 40 }
41 41
42 hideDelete() { 42 hideDelete() {
@@ -42,9 +42,9 @@ export class UserComponent extends EntityComponent<User> { @@ -42,9 +42,9 @@ export class UserComponent extends EntityComponent<User> {
42 42
43 constructor(protected store: Store<AppState>, 43 constructor(protected store: Store<AppState>,
44 @Inject('entity') protected entityValue: User, 44 @Inject('entity') protected entityValue: User,
45 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<User>, 45 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<User>,
46 public fb: FormBuilder) { 46 public fb: FormBuilder) {
47 - super(store, fb, entityValue, entitiesTableConfig); 47 + super(store, fb, entityValue, entitiesTableConfigValue);
48 } 48 }
49 49
50 hideDelete() { 50 hideDelete() {
@@ -31,9 +31,9 @@ export class WidgetsBundleComponent extends EntityComponent<WidgetsBundle> { @@ -31,9 +31,9 @@ export class WidgetsBundleComponent extends EntityComponent<WidgetsBundle> {
31 31
32 constructor(protected store: Store<AppState>, 32 constructor(protected store: Store<AppState>,
33 @Inject('entity') protected entityValue: WidgetsBundle, 33 @Inject('entity') protected entityValue: WidgetsBundle,
34 - @Inject('entitiesTableConfig') protected entitiesTableConfig: EntityTableConfig<WidgetsBundle>, 34 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<WidgetsBundle>,
35 public fb: FormBuilder) { 35 public fb: FormBuilder) {
36 - super(store, fb, entityValue, entitiesTableConfig); 36 + super(store, fb, entityValue, entitiesTableConfigValue);
37 } 37 }
38 38
39 hideDelete() { 39 hideDelete() {
@@ -19,6 +19,8 @@ import { emptyPageData, PageData } from '@shared/models/page/page-data'; @@ -19,6 +19,8 @@ import { emptyPageData, PageData } from '@shared/models/page/page-data';
19 import { getDescendantProp, isObject } from '@core/utils'; 19 import { getDescendantProp, isObject } from '@core/utils';
20 import { SortDirection } from '@angular/material/sort'; 20 import { SortDirection } from '@angular/material/sort';
21 21
  22 +export const MAX_SAFE_PAGE_SIZE = 2147483647;
  23 +
22 export type PageLinkSearchFunction<T> = (entity: T, textSearch: string) => boolean; 24 export type PageLinkSearchFunction<T> = (entity: T, textSearch: string) => boolean;
23 25
24 const defaultPageLinkSearchFunction: PageLinkSearchFunction<any> = 26 const defaultPageLinkSearchFunction: PageLinkSearchFunction<any> =