722 lines
24 KiB
TypeScript
722 lines
24 KiB
TypeScript
///
|
|
/// Copyright © 2016-2020 The Thingsboard Authors
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
|
|
import {
|
|
AfterViewInit,
|
|
Component,
|
|
ElementRef,
|
|
Input,
|
|
NgZone,
|
|
OnInit,
|
|
ViewChild,
|
|
ViewContainerRef
|
|
} from '@angular/core';
|
|
import { PageComponent } from '@shared/components/page.component';
|
|
import { Store } from '@ngrx/store';
|
|
import { AppState } from '@core/core.state';
|
|
import { WidgetAction, WidgetContext } from '@home/models/widget-component.models';
|
|
import {
|
|
DataKey,
|
|
Datasource,
|
|
DatasourceData,
|
|
WidgetActionDescriptor,
|
|
WidgetConfig
|
|
} from '@shared/models/widget.models';
|
|
import { IWidgetSubscription } from '@core/api/widget-api.models';
|
|
import { UtilsService } from '@core/services/utils.service';
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
import { createLabelFromDatasource, deepClone, hashCode, isDefined, isNumber } from '@core/utils';
|
|
import cssjs from '@core/css/css';
|
|
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
|
|
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
|
|
import { BehaviorSubject, fromEvent, merge, Observable, of } from 'rxjs';
|
|
import { emptyPageData, PageData } from '@shared/models/page/page-data';
|
|
import { EntityId } from '@shared/models/id/entity-id';
|
|
import { entityTypeTranslations } from '@shared/models/entity-type.models';
|
|
import { debounceTime, distinctUntilChanged, map, tap } from 'rxjs/operators';
|
|
import { MatPaginator } from '@angular/material/paginator';
|
|
import { MatSort, SortDirection } from '@angular/material/sort';
|
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
|
import {
|
|
CellContentInfo,
|
|
CellStyleInfo,
|
|
constructTableCssString,
|
|
DisplayColumn,
|
|
EntityColumn,
|
|
EntityData, entityDataSortOrderFromString, findColumnByEntityKey, findEntityKeyByColumnDef,
|
|
getCellContentInfo,
|
|
getCellStyleInfo,
|
|
getColumnWidth,
|
|
getEntityValue,
|
|
TableWidgetDataKeySettings,
|
|
TableWidgetSettings,
|
|
widthStyle
|
|
} from '@home/components/widget/lib/table-widget.models';
|
|
import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
|
|
import { ComponentPortal, PortalInjector } from '@angular/cdk/portal';
|
|
import {
|
|
DISPLAY_COLUMNS_PANEL_DATA,
|
|
DisplayColumnsPanelComponent,
|
|
DisplayColumnsPanelData
|
|
} from '@home/components/widget/lib/display-columns-panel.component';
|
|
import {
|
|
Direction,
|
|
EntityDataPageLink,
|
|
entityDataPageLinkSortDirection,
|
|
EntityKeyType,
|
|
KeyFilter
|
|
} from '@shared/models/query/query.models';
|
|
|
|
interface EntitiesTableWidgetSettings extends TableWidgetSettings {
|
|
entitiesTitle: string;
|
|
displayEntityName: boolean;
|
|
entityNameColumnTitle: string;
|
|
displayEntityLabel: boolean;
|
|
entityLabelColumnTitle: string;
|
|
displayEntityType: boolean;
|
|
}
|
|
|
|
@Component({
|
|
selector: 'tb-entities-table-widget',
|
|
templateUrl: './entities-table-widget.component.html',
|
|
styleUrls: ['./entities-table-widget.component.scss', './table-widget.scss']
|
|
})
|
|
export class EntitiesTableWidgetComponent extends PageComponent implements OnInit, AfterViewInit {
|
|
|
|
@Input()
|
|
ctx: WidgetContext;
|
|
|
|
@ViewChild('searchInput') searchInputField: ElementRef;
|
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
|
@ViewChild(MatSort) sort: MatSort;
|
|
|
|
public displayPagination = true;
|
|
public pageSizeOptions;
|
|
public pageLink: EntityDataPageLink;
|
|
public sortOrderProperty: string;
|
|
public textSearchMode = false;
|
|
public columns: Array<EntityColumn> = [];
|
|
public displayedColumns: string[] = [];
|
|
public actionCellDescriptors: WidgetActionDescriptor[];
|
|
public entityDatasource: EntityDatasource;
|
|
|
|
private settings: EntitiesTableWidgetSettings;
|
|
private widgetConfig: WidgetConfig;
|
|
private subscription: IWidgetSubscription;
|
|
|
|
private defaultPageSize = 10;
|
|
private defaultSortOrder = 'entityName';
|
|
|
|
private contentsInfo: {[key: string]: CellContentInfo} = {};
|
|
private stylesInfo: {[key: string]: CellStyleInfo} = {};
|
|
private columnWidth: {[key: string]: string} = {};
|
|
|
|
private searchAction: WidgetAction = {
|
|
name: 'action.search',
|
|
show: true,
|
|
icon: 'search',
|
|
onAction: () => {
|
|
this.enterFilterMode();
|
|
}
|
|
};
|
|
|
|
private columnDisplayAction: WidgetAction = {
|
|
name: 'entity.columns-to-display',
|
|
show: true,
|
|
icon: 'view_column',
|
|
onAction: ($event) => {
|
|
this.editColumnsToDisplay($event);
|
|
}
|
|
};
|
|
|
|
constructor(protected store: Store<AppState>,
|
|
private elementRef: ElementRef,
|
|
private ngZone: NgZone,
|
|
private overlay: Overlay,
|
|
private viewContainerRef: ViewContainerRef,
|
|
private utils: UtilsService,
|
|
private translate: TranslateService,
|
|
private domSanitizer: DomSanitizer) {
|
|
super(store);
|
|
|
|
// const sortOrder: EntityDataSortOrder = sortOrderFromString(this.defaultSortOrder);
|
|
this.pageLink = {
|
|
page: 0,
|
|
pageSize: this.defaultPageSize,
|
|
textSearch: null
|
|
};
|
|
// new PageLink(this.defaultPageSize, 0, null, sortOrder);
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
this.ctx.$scope.entitiesTableWidget = this;
|
|
this.settings = this.ctx.settings;
|
|
this.widgetConfig = this.ctx.widgetConfig;
|
|
this.subscription = this.ctx.defaultSubscription;
|
|
this.initializeConfig();
|
|
this.updateDatasources();
|
|
this.ctx.updateWidgetParams();
|
|
}
|
|
|
|
ngAfterViewInit(): void {
|
|
fromEvent(this.searchInputField.nativeElement, 'keyup')
|
|
.pipe(
|
|
debounceTime(150),
|
|
distinctUntilChanged(),
|
|
tap(() => {
|
|
if (this.displayPagination) {
|
|
this.paginator.pageIndex = 0;
|
|
}
|
|
this.updateData();
|
|
})
|
|
)
|
|
.subscribe();
|
|
|
|
if (this.displayPagination) {
|
|
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
|
|
}
|
|
(this.displayPagination ? merge(this.sort.sortChange, this.paginator.page) : this.sort.sortChange)
|
|
.pipe(
|
|
tap(() => this.updateData())
|
|
)
|
|
.subscribe();
|
|
this.updateData();
|
|
}
|
|
|
|
public onDataUpdated() {
|
|
this.ngZone.run(() => {
|
|
this.entityDatasource.dataUpdated(); // .updateEntitiesData(this.subscription.data);
|
|
this.ctx.detectChanges();
|
|
});
|
|
}
|
|
|
|
public pageLinkSortDirection(): SortDirection {
|
|
return entityDataPageLinkSortDirection(this.pageLink);
|
|
}
|
|
|
|
private initializeConfig() {
|
|
this.ctx.widgetActions = [this.searchAction, this.columnDisplayAction];
|
|
|
|
this.actionCellDescriptors = this.ctx.actionsApi.getActionDescriptors('actionCellButton');
|
|
|
|
let entitiesTitle: string;
|
|
|
|
if (this.settings.entitiesTitle && this.settings.entitiesTitle.length) {
|
|
entitiesTitle = this.utils.customTranslation(this.settings.entitiesTitle, this.settings.entitiesTitle);
|
|
} else {
|
|
entitiesTitle = this.translate.instant('entity.entities');
|
|
}
|
|
|
|
const datasource = this.subscription.datasources[0];
|
|
this.ctx.widgetTitle = createLabelFromDatasource(datasource, entitiesTitle);
|
|
|
|
this.searchAction.show = isDefined(this.settings.enableSearch) ? this.settings.enableSearch : true;
|
|
this.displayPagination = isDefined(this.settings.displayPagination) ? this.settings.displayPagination : true;
|
|
this.columnDisplayAction.show = isDefined(this.settings.enableSelectColumnDisplay) ? this.settings.enableSelectColumnDisplay : true;
|
|
|
|
const pageSize = this.settings.defaultPageSize;
|
|
if (isDefined(pageSize) && isNumber(pageSize) && pageSize > 0) {
|
|
this.defaultPageSize = pageSize;
|
|
}
|
|
this.pageSizeOptions = [this.defaultPageSize, this.defaultPageSize * 2, this.defaultPageSize * 3];
|
|
this.pageLink.pageSize = this.displayPagination ? this.defaultPageSize : Number.POSITIVE_INFINITY;
|
|
|
|
const cssString = constructTableCssString(this.widgetConfig);
|
|
const cssParser = new cssjs();
|
|
cssParser.testMode = false;
|
|
const namespace = 'entities-table-' + hashCode(cssString);
|
|
cssParser.cssPreviewNamespace = namespace;
|
|
cssParser.createStyleElement(namespace, cssString);
|
|
$(this.elementRef.nativeElement).addClass(namespace);
|
|
}
|
|
|
|
private updateDatasources() {
|
|
|
|
const displayEntityName = isDefined(this.settings.displayEntityName) ? this.settings.displayEntityName : true;
|
|
const displayEntityLabel = isDefined(this.settings.displayEntityLabel) ? this.settings.displayEntityLabel : false;
|
|
let entityNameColumnTitle: string;
|
|
let entityLabelColumnTitle: string;
|
|
if (this.settings.entityNameColumnTitle && this.settings.entityNameColumnTitle.length) {
|
|
entityNameColumnTitle = this.utils.customTranslation(this.settings.entityNameColumnTitle, this.settings.entityNameColumnTitle);
|
|
} else {
|
|
entityNameColumnTitle = this.translate.instant('entity.entity-name');
|
|
}
|
|
if (this.settings.entityLabelColumnTitle && this.settings.entityLabelColumnTitle.length) {
|
|
entityLabelColumnTitle = this.utils.customTranslation(this.settings.entityLabelColumnTitle, this.settings.entityLabelColumnTitle);
|
|
} else {
|
|
entityLabelColumnTitle = this.translate.instant('entity.entity-label');
|
|
}
|
|
const displayEntityType = isDefined(this.settings.displayEntityType) ? this.settings.displayEntityType : true;
|
|
|
|
if (displayEntityName) {
|
|
this.columns.push(
|
|
{
|
|
name: 'entityName',
|
|
label: 'entityName',
|
|
def: 'entityName',
|
|
title: entityNameColumnTitle,
|
|
entityKey: {
|
|
key: 'name',
|
|
type: EntityKeyType.ENTITY_FIELD
|
|
}
|
|
} as EntityColumn
|
|
);
|
|
this.contentsInfo.entityName = {
|
|
useCellContentFunction: false
|
|
};
|
|
this.stylesInfo.entityName = {
|
|
useCellStyleFunction: false
|
|
};
|
|
this.columnWidth.entityName = '0px';
|
|
}
|
|
if (displayEntityLabel) {
|
|
this.columns.push(
|
|
{
|
|
name: 'entityLabel',
|
|
label: 'entityLabel',
|
|
def: 'entityLabel',
|
|
title: entityLabelColumnTitle,
|
|
entityKey: {
|
|
key: 'label',
|
|
type: EntityKeyType.ENTITY_FIELD
|
|
}
|
|
} as EntityColumn
|
|
);
|
|
this.contentsInfo.entityLabel = {
|
|
useCellContentFunction: false
|
|
};
|
|
this.stylesInfo.entityLabel = {
|
|
useCellStyleFunction: false
|
|
};
|
|
this.columnWidth.entityLabel = '0px';
|
|
}
|
|
if (displayEntityType) {
|
|
this.columns.push(
|
|
{
|
|
name: 'entityType',
|
|
label: 'entityType',
|
|
def: 'entityType',
|
|
title: this.translate.instant('entity.entity-type'),
|
|
entityKey: {
|
|
key: 'entityType',
|
|
type: EntityKeyType.ENTITY_FIELD
|
|
}
|
|
} as EntityColumn
|
|
);
|
|
this.contentsInfo.entityType = {
|
|
useCellContentFunction: false
|
|
};
|
|
this.stylesInfo.entityType = {
|
|
useCellStyleFunction: false
|
|
};
|
|
this.columnWidth.entityType = '0px';
|
|
}
|
|
|
|
const dataKeys: Array<DataKey> = [];
|
|
|
|
const datasource = this.subscription.options.datasources ? this.subscription.options.datasources[0] : null;
|
|
|
|
if (datasource) {
|
|
datasource.dataKeys.forEach((entityDataKey) => {
|
|
const dataKey: EntityColumn = deepClone(entityDataKey) as EntityColumn;
|
|
dataKey.entityKey = {
|
|
key: dataKey.name,
|
|
type: null
|
|
};
|
|
if (dataKey.type === DataKeyType.function) {
|
|
dataKey.name = dataKey.label;
|
|
dataKey.entityKey.type = EntityKeyType.ENTITY_FIELD;
|
|
} else if (dataKey.type === DataKeyType.entityField) {
|
|
dataKey.entityKey.type = EntityKeyType.ENTITY_FIELD;
|
|
} else if (dataKey.type === DataKeyType.attribute) {
|
|
dataKey.entityKey.type = EntityKeyType.ATTRIBUTE;
|
|
} else if (dataKey.type === DataKeyType.timeseries) {
|
|
dataKey.entityKey.type = EntityKeyType.TIME_SERIES;
|
|
}
|
|
dataKeys.push(dataKey);
|
|
|
|
dataKey.title = this.utils.customTranslation(dataKey.label, dataKey.label);
|
|
dataKey.def = 'def' + this.columns.length;
|
|
const keySettings: TableWidgetDataKeySettings = dataKey.settings;
|
|
|
|
this.stylesInfo[dataKey.def] = getCellStyleInfo(keySettings);
|
|
this.contentsInfo[dataKey.def] = getCellContentInfo(keySettings, 'value, entity, ctx');
|
|
this.contentsInfo[dataKey.def].units = dataKey.units;
|
|
this.contentsInfo[dataKey.def].decimals = dataKey.decimals;
|
|
this.columnWidth[dataKey.def] = getColumnWidth(keySettings);
|
|
this.columns.push(dataKey);
|
|
});
|
|
this.displayedColumns.push(...this.columns.map(column => column.def));
|
|
}
|
|
|
|
if (this.settings.defaultSortOrder && this.settings.defaultSortOrder.length) {
|
|
this.defaultSortOrder = this.settings.defaultSortOrder;
|
|
}
|
|
|
|
this.pageLink.sortOrder = entityDataSortOrderFromString(this.defaultSortOrder, this.columns);
|
|
let sortColumn: EntityColumn;
|
|
if (this.pageLink.sortOrder) {
|
|
sortColumn = findColumnByEntityKey(this.pageLink.sortOrder.key, this.columns);
|
|
}
|
|
this.sortOrderProperty = sortColumn ? sortColumn.def : null;
|
|
|
|
if (this.actionCellDescriptors.length) {
|
|
this.displayedColumns.push('actions');
|
|
}
|
|
this.entityDatasource = new EntityDatasource(
|
|
this.translate, dataKeys, this.subscription);
|
|
}
|
|
|
|
private editColumnsToDisplay($event: Event) {
|
|
if ($event) {
|
|
$event.stopPropagation();
|
|
}
|
|
const target = $event.target || $event.srcElement || $event.currentTarget;
|
|
const config = new OverlayConfig();
|
|
config.backdropClass = 'cdk-overlay-transparent-backdrop';
|
|
config.hasBackdrop = true;
|
|
const connectedPosition: ConnectedPosition = {
|
|
originX: 'end',
|
|
originY: 'bottom',
|
|
overlayX: 'end',
|
|
overlayY: 'top'
|
|
};
|
|
config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement)
|
|
.withPositions([connectedPosition]);
|
|
|
|
const overlayRef = this.overlay.create(config);
|
|
overlayRef.backdropClick().subscribe(() => {
|
|
overlayRef.dispose();
|
|
});
|
|
|
|
const columns: DisplayColumn[] = this.columns.map(column => {
|
|
return {
|
|
title: column.title,
|
|
def: column.def,
|
|
display: this.displayedColumns.indexOf(column.def) > -1
|
|
};
|
|
});
|
|
|
|
const injectionTokens = new WeakMap<any, any>([
|
|
[DISPLAY_COLUMNS_PANEL_DATA, {
|
|
columns,
|
|
columnsUpdated: (newColumns) => {
|
|
this.displayedColumns = newColumns.filter(column => column.display).map(column => column.def);
|
|
this.displayedColumns.push('actions');
|
|
}
|
|
} as DisplayColumnsPanelData],
|
|
[OverlayRef, overlayRef]
|
|
]);
|
|
const injector = new PortalInjector(this.viewContainerRef.injector, injectionTokens);
|
|
overlayRef.attach(new ComponentPortal(DisplayColumnsPanelComponent,
|
|
this.viewContainerRef, injector));
|
|
this.ctx.detectChanges();
|
|
}
|
|
|
|
private enterFilterMode() {
|
|
this.textSearchMode = true;
|
|
this.pageLink.textSearch = '';
|
|
this.ctx.hideTitlePanel = true;
|
|
this.ctx.detectChanges(true);
|
|
setTimeout(() => {
|
|
this.searchInputField.nativeElement.focus();
|
|
this.searchInputField.nativeElement.setSelectionRange(0, 0);
|
|
}, 10);
|
|
}
|
|
|
|
exitFilterMode() {
|
|
this.textSearchMode = false;
|
|
this.pageLink.textSearch = null;
|
|
if (this.displayPagination) {
|
|
this.paginator.pageIndex = 0;
|
|
}
|
|
this.updateData();
|
|
this.ctx.hideTitlePanel = false;
|
|
this.ctx.detectChanges(true);
|
|
}
|
|
|
|
private updateData() {
|
|
if (this.displayPagination) {
|
|
this.pageLink.page = this.paginator.pageIndex;
|
|
this.pageLink.pageSize = this.paginator.pageSize;
|
|
} else {
|
|
this.pageLink.page = 0;
|
|
}
|
|
this.pageLink.sortOrder = {
|
|
key: findEntityKeyByColumnDef(this.sort.active, this.columns),
|
|
direction: Direction[this.sort.direction.toUpperCase()]
|
|
};
|
|
const keyFilters: KeyFilter[] = null; // TODO:
|
|
this.entityDatasource.loadEntities(this.pageLink, keyFilters);
|
|
this.ctx.detectChanges();
|
|
}
|
|
|
|
public trackByColumnDef(index, column: EntityColumn) {
|
|
return column.def;
|
|
}
|
|
|
|
public headerStyle(key: EntityColumn): any {
|
|
const columnWidth = this.columnWidth[key.def];
|
|
return widthStyle(columnWidth);
|
|
}
|
|
|
|
public cellStyle(entity: EntityData, key: EntityColumn): any {
|
|
let style: any = {};
|
|
if (entity && key) {
|
|
const styleInfo = this.stylesInfo[key.def];
|
|
const value = getEntityValue(entity, key);
|
|
if (styleInfo.useCellStyleFunction && styleInfo.cellStyleFunction) {
|
|
try {
|
|
style = styleInfo.cellStyleFunction(value);
|
|
} catch (e) {
|
|
style = {};
|
|
}
|
|
} else {
|
|
style = this.defaultStyle(key, value);
|
|
}
|
|
}
|
|
if (!style.width) {
|
|
const columnWidth = this.columnWidth[key.def];
|
|
style = {...style, ...widthStyle(columnWidth)};
|
|
}
|
|
return style;
|
|
}
|
|
|
|
public cellContent(entity: EntityData, key: EntityColumn): SafeHtml {
|
|
if (entity && key) {
|
|
const contentInfo = this.contentsInfo[key.def];
|
|
const value = getEntityValue(entity, key);
|
|
let content = '';
|
|
if (contentInfo.useCellContentFunction && contentInfo.cellContentFunction) {
|
|
try {
|
|
content = contentInfo.cellContentFunction(value, entity, this.ctx);
|
|
} catch (e) {
|
|
content = '' + value;
|
|
}
|
|
} else {
|
|
const decimals = (contentInfo.decimals || contentInfo.decimals === 0) ? contentInfo.decimals : this.ctx.widgetConfig.decimals;
|
|
const units = contentInfo.units || this.ctx.widgetConfig.units;
|
|
content = this.ctx.utils.formatValue(value, decimals, units, true);
|
|
}
|
|
return isDefined(content) ? this.domSanitizer.bypassSecurityTrustHtml(content) : '';
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
public onRowClick($event: Event, entity: EntityData, isDouble?: boolean) {
|
|
if ($event) {
|
|
$event.stopPropagation();
|
|
}
|
|
this.entityDatasource.toggleCurrentEntity(entity);
|
|
const actionSourceId = isDouble ? 'rowDoubleClick' : 'rowClick';
|
|
const descriptors = this.ctx.actionsApi.getActionDescriptors(actionSourceId);
|
|
if (descriptors.length) {
|
|
let entityId;
|
|
let entityName;
|
|
let entityLabel;
|
|
if (entity) {
|
|
entityId = entity.id;
|
|
entityName = entity.entityName;
|
|
entityLabel = entity.entityLabel;
|
|
}
|
|
this.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName, null, entityLabel);
|
|
}
|
|
}
|
|
|
|
public onActionButtonClick($event: Event, entity: EntityData, actionDescriptor: WidgetActionDescriptor) {
|
|
if ($event) {
|
|
$event.stopPropagation();
|
|
}
|
|
let entityId;
|
|
let entityName;
|
|
let entityLabel;
|
|
if (entity) {
|
|
entityId = entity.id;
|
|
entityName = entity.entityName;
|
|
entityLabel = entity.entityLabel;
|
|
}
|
|
this.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, null, entityLabel);
|
|
}
|
|
|
|
private defaultStyle(key: EntityColumn, value: any): any {
|
|
return {};
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class EntityDatasource implements DataSource<EntityData> {
|
|
|
|
private entitiesSubject = new BehaviorSubject<EntityData[]>([]);
|
|
private pageDataSubject = new BehaviorSubject<PageData<EntityData>>(emptyPageData<EntityData>());
|
|
|
|
// private allEntities: Array<EntityData> = [];
|
|
// private allEntitiesSubject = new BehaviorSubject<EntityData[]>([]);
|
|
// private allEntities$: Observable<Array<EntityData>> = this.allEntitiesSubject.asObservable();
|
|
|
|
private currentEntity: EntityData = null;
|
|
|
|
constructor(
|
|
private translate: TranslateService,
|
|
private dataKeys: Array<DataKey>,
|
|
private subscription: IWidgetSubscription
|
|
// datasources: Array<Datasource>
|
|
) {
|
|
/*
|
|
for (const datasource of datasources) {
|
|
if (datasource.type === DatasourceType.entity && !datasource.entityId) {
|
|
continue;
|
|
}
|
|
const entity: EntityData = {
|
|
id: {} as EntityId,
|
|
entityName: datasource.entityName,
|
|
entityLabel: datasource.entityLabel ? datasource.entityLabel : datasource.entityName
|
|
};
|
|
if (datasource.entityId) {
|
|
entity.id.id = datasource.entityId;
|
|
}
|
|
if (datasource.entityType) {
|
|
entity.id.entityType = datasource.entityType;
|
|
entity.entityType = this.translate.instant(entityTypeTranslations.get(datasource.entityType).type);
|
|
} else {
|
|
entity.entityType = '';
|
|
}
|
|
this.dataKeys.forEach((dataKey) => {
|
|
entity[dataKey.label] = '';
|
|
});
|
|
this.allEntities.push(entity);
|
|
}
|
|
this.allEntitiesSubject.next(this.allEntities);*/
|
|
}
|
|
|
|
connect(collectionViewer: CollectionViewer): Observable<EntityData[] | ReadonlyArray<EntityData>> {
|
|
return this.entitiesSubject.asObservable();
|
|
}
|
|
|
|
disconnect(collectionViewer: CollectionViewer): void {
|
|
this.entitiesSubject.complete();
|
|
this.pageDataSubject.complete();
|
|
}
|
|
|
|
loadEntities(pageLink: EntityDataPageLink, keyFilters: KeyFilter[]) {
|
|
this.subscription.subscribeForLatestData(0, pageLink, keyFilters);
|
|
/* this.fetchEntities(pageLink).pipe(
|
|
catchError(() => of(emptyPageData<EntityData>())),
|
|
).subscribe(
|
|
(pageData) => {
|
|
this.entitiesSubject.next(pageData.data);
|
|
this.pageDataSubject.next(pageData);
|
|
}
|
|
);*/
|
|
}
|
|
|
|
dataUpdated() {
|
|
const datasourcesPageData = this.subscription.datasourcePages[0];
|
|
const dataPageData = this.subscription.dataPages[0];
|
|
const entities = new Array<EntityData>();
|
|
datasourcesPageData.data.forEach((datasource, index) => {
|
|
entities.push(this.datasourceToEntityData(datasource, dataPageData.data[index]));
|
|
});
|
|
const entitiesPageData: PageData<EntityData> = {
|
|
data: entities,
|
|
totalPages: datasourcesPageData.totalPages,
|
|
totalElements: datasourcesPageData.totalElements,
|
|
hasNext: datasourcesPageData.hasNext
|
|
};
|
|
this.entitiesSubject.next(entities);
|
|
this.pageDataSubject.next(entitiesPageData);
|
|
}
|
|
|
|
private datasourceToEntityData(datasource: Datasource, data: DatasourceData[]): EntityData {
|
|
const entity: EntityData = {
|
|
id: {} as EntityId,
|
|
entityName: datasource.entityName,
|
|
entityLabel: datasource.entityLabel ? datasource.entityLabel : datasource.entityName
|
|
};
|
|
if (datasource.entityId) {
|
|
entity.id.id = datasource.entityId;
|
|
}
|
|
if (datasource.entityType) {
|
|
entity.id.entityType = datasource.entityType;
|
|
entity.entityType = this.translate.instant(entityTypeTranslations.get(datasource.entityType).type);
|
|
} else {
|
|
entity.entityType = '';
|
|
}
|
|
this.dataKeys.forEach((dataKey, index) => {
|
|
const keyData = data[index].data;
|
|
if (keyData && keyData.length && keyData[0].length > 1) {
|
|
const value = keyData[0][1];
|
|
entity[dataKey.label] = value;
|
|
} else {
|
|
entity[dataKey.label] = '';
|
|
}
|
|
});
|
|
return entity;
|
|
}
|
|
|
|
/* updateEntitiesData(data: DatasourceData[]) {
|
|
for (let i = 0; i < this.allEntities.length; i++) {
|
|
const entity = this.allEntities[i];
|
|
for (let a = 0; a < this.dataKeys.length; a++) {
|
|
const dataKey = this.dataKeys[a];
|
|
const index = i * this.dataKeys.length + a;
|
|
const keyData = data[index].data;
|
|
if (keyData && keyData.length && keyData[0].length > 1) {
|
|
const value = keyData[0][1];
|
|
entity[dataKey.label] = value;
|
|
} else {
|
|
entity[dataKey.label] = '';
|
|
}
|
|
}
|
|
}
|
|
this.allEntitiesSubject.next(this.allEntities);
|
|
}*/
|
|
|
|
isEmpty(): Observable<boolean> {
|
|
return this.entitiesSubject.pipe(
|
|
map((entities) => !entities.length)
|
|
);
|
|
}
|
|
|
|
total(): Observable<number> {
|
|
return this.pageDataSubject.pipe(
|
|
map((pageData) => pageData.totalElements)
|
|
);
|
|
}
|
|
|
|
public toggleCurrentEntity(entity: EntityData): boolean {
|
|
if (this.currentEntity !== entity) {
|
|
this.currentEntity = entity;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public isCurrentEntity(entity: EntityData): boolean {
|
|
return (this.currentEntity && entity && this.currentEntity.id && entity.id) &&
|
|
(this.currentEntity.id.id === entity.id.id);
|
|
}
|
|
|
|
/* private fetchEntities(pageLink: PageLink): Observable<PageData<EntityData>> {
|
|
return this.allEntities$.pipe(
|
|
map((data) => pageLink.filterData(data))
|
|
);
|
|
}*/
|
|
}
|