From ab93e5455c4348bf01ef85d5f84df66280ab2e4b Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 23 Jun 2020 17:47:34 +0300 Subject: [PATCH] UI: entity data fixes --- .../app/core/api/entity-data-subscription.ts | 8 ++-- .../src/app/core/api/widget-subscription.ts | 34 +++++++--------- ui-ngx/src/app/core/http/entity.service.ts | 21 +--------- .../components/widget/widget.component.ts | 15 ++++++- .../app/shared/models/query/query.models.ts | 39 +++++++++++++++++++ 5 files changed, 73 insertions(+), 44 deletions(-) diff --git a/ui-ngx/src/app/core/api/entity-data-subscription.ts b/ui-ngx/src/app/core/api/entity-data-subscription.ts index 591a5436d4..6a3f9a7f48 100644 --- a/ui-ngx/src/app/core/api/entity-data-subscription.ts +++ b/ui-ngx/src/app/core/api/entity-data-subscription.ts @@ -23,6 +23,7 @@ import { EntityFilter, EntityKey, EntityKeyType, + entityKeyTypeToDataKeyType, KeyFilter, TsValue } from '@shared/models/query/query.models'; @@ -41,8 +42,8 @@ import { PageData } from '@shared/models/page/page-data'; import { DataAggregator } from '@core/api/data-aggregator'; import { NULL_UUID } from '@shared/models/id/has-uuid'; import { EntityType } from '@shared/models/entity-type.models'; -import Timeout = NodeJS.Timeout; import { Observable, of, ReplaySubject, Subject } from 'rxjs'; +import Timeout = NodeJS.Timeout; export interface EntityDataSubscriptionOptions { datasourceType: DatasourceType; @@ -473,7 +474,8 @@ export class EntityDataSubscription { if (this.entityDataSubscriptionOptions.type === widgetType.latest && entityData.latest) { for (const type of Object.keys(entityData.latest)) { const subscriptionData = this.toSubscriptionData(entityData.latest[type], false); - this.onData(subscriptionData, type, dataIndex, true, dataUpdatedCb); + const dataKeyType = entityKeyTypeToDataKeyType(EntityKeyType[type]); + this.onData(subscriptionData, dataKeyType, dataIndex, true, dataUpdatedCb); } } if (this.entityDataSubscriptionOptions.type === widgetType.timeseries && entityData.timeseries) { @@ -486,7 +488,7 @@ export class EntityDataSubscription { } } - private onData(sourceData: SubscriptionData, type: string, dataIndex: number, detectChanges: boolean, + private onData(sourceData: SubscriptionData, type: DataKeyType, dataIndex: number, detectChanges: boolean, dataUpdatedCb: DataUpdatedCb) { for (const keyName of Object.keys(sourceData)) { const keyData = sourceData[keyName]; diff --git a/ui-ngx/src/app/core/api/widget-subscription.ts b/ui-ngx/src/app/core/api/widget-subscription.ts index 1e94d23624..8c1e98411b 100644 --- a/ui-ngx/src/app/core/api/widget-subscription.ts +++ b/ui-ngx/src/app/core/api/widget-subscription.ts @@ -52,7 +52,13 @@ import { EntityId } from '@app/shared/models/id/entity-id'; import * as moment_ from 'moment'; import { PageData } from '@shared/models/page/page-data'; import { EntityDataListener } from '@core/api/entity-data.service'; -import { EntityData, EntityDataPageLink, EntityKeyType, KeyFilter } from '@shared/models/query/query.models'; +import { + EntityData, + EntityDataPageLink, + entityDataToEntityInfo, + EntityKeyType, + KeyFilter +} from '@shared/models/query/query.models'; import { map } from 'rxjs/operators'; const moment = moment_; @@ -414,6 +420,7 @@ export class WidgetSubscription implements IWidgetSubscription { this.configureLoadedData(); this.hasResolvedData = true; this.notifyDataLoaded(); + this.onDataUpdated(true); }) ); } @@ -881,7 +888,6 @@ export class WidgetSubscription implements IWidgetSubscription { private dataSubscribe() { if (!this.hasDataPageLink) { - this.notifyDataLoading(); if (this.type === widgetType.timeseries && this.timeWindowConfig) { this.updateRealtimeSubscription(); if (this.comparisonEnabled) { @@ -897,7 +903,6 @@ export class WidgetSubscription implements IWidgetSubscription { this.ctx.entityDataService.startSubscription(listener); }); if (forceUpdate) { - this.notifyDataLoaded(); this.onDataUpdated(); } } @@ -1269,23 +1274,11 @@ export class WidgetSubscription implements IWidgetSubscription { newDatasource.entityId = entityData.entityId.id; newDatasource.entityType = entityData.entityId.entityType as EntityType; if (configDatasource.type === DatasourceType.entity) { - let name; - let label; - if (entityData.latest && entityData.latest[EntityKeyType.ENTITY_FIELD]) { - const fields = entityData.latest[EntityKeyType.ENTITY_FIELD]; - if (fields.name) { - name = fields.name.value; - } - if (fields.label) { - label = fields.label.value; - } - } - name = name || 'TODO'; - label = label || 'TODO'; - newDatasource.name = name; - newDatasource.entityName = name; - newDatasource.entityLabel = label; - newDatasource.entityDescription = 'TODO'; + const entityInfo = entityDataToEntityInfo(entityData); + newDatasource.name = entityInfo.name; + newDatasource.entityName = entityInfo.name; + newDatasource.entityLabel = entityInfo.label; + newDatasource.entityDescription = entityInfo.entityDescription; } newDatasource.generated = index > 0 ? true : false; return newDatasource; @@ -1296,7 +1289,6 @@ export class WidgetSubscription implements IWidgetSubscription { const startIndex = configuredDatasource.dataKeyStartIndex; const dataKeysCount = configuredDatasource.dataKeys.length; const index = startIndex + dataIndex*dataKeysCount + dataKeyIndex; - this.notifyDataLoaded(); let update = true; let currentData: DataSetHolder; if (this.displayLegend && this.legendData.keys[index].dataKey.hidden) { diff --git a/ui-ngx/src/app/core/http/entity.service.ts b/ui-ngx/src/app/core/http/entity.service.ts index 1440cfe4f3..f6da263cc4 100644 --- a/ui-ngx/src/app/core/http/entity.service.ts +++ b/ui-ngx/src/app/core/http/entity.service.ts @@ -54,7 +54,7 @@ import { AttributeService } from '@core/http/attribute.service'; import { createDefaultEntityDataPageLink, EntityData, - EntityDataQuery, + EntityDataQuery, entityDataToEntityInfo, EntityFilter, EntityKeyType } from '@shared/models/query/query.models'; @@ -365,23 +365,6 @@ export class EntityService { return this.http.post>('/api/entitiesQuery/find', query, defaultHttpOptionsFromConfig(config)); } - private entityDataToEntityInfo(entityData: EntityData): EntityInfo { - const entityInfo: EntityInfo = { - id: entityData.entityId.id, - entityType: entityData.entityId.entityType as EntityType - }; - if (entityData.latest && entityData.latest[EntityKeyType.ENTITY_FIELD]) { - const fields = entityData.latest[EntityKeyType.ENTITY_FIELD]; - if (fields.name) { - entityInfo.name = fields.name.value; - } - if (fields.label) { - entityInfo.label = fields.label.value; - } - } - return entityInfo; - } - public findSingleEntityInfoByEntityFilter(filter: EntityFilter, config?: RequestConfig): Observable { const query: EntityDataQuery = { entityFilter: filter, @@ -401,7 +384,7 @@ export class EntityService { map((data) => { if (data.data.length) { const entityData = data.data[0]; - return this.entityDataToEntityInfo(entityData); + return entityDataToEntityInfo(entityData); } else { return null; } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 800ccab847..64419bb996 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -138,6 +138,8 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI subscriptionInited = false; destroyed = false; widgetSizeDetected = false; + widgetInstanceInited = false; + dataUpdatePending = false; cafs: {[cafId: string]: CancelAnimationFrame} = {}; @@ -363,6 +365,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI subscription.destroy(); } this.subscriptionInited = false; + this.dataUpdatePending = false; this.widgetContext.subscriptions = {}; if (this.widgetContext.inited) { this.widgetContext.inited = false; @@ -375,6 +378,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI try { if (shouldDestroyWidgetInstance) { this.widgetTypeInstance.onDestroy(); + this.widgetInstanceInited = false; } } catch (e) { this.handleWidgetException(e); @@ -479,6 +483,11 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI try { if (this.displayWidgetInstance()) { this.widgetTypeInstance.onInit(); + this.widgetInstanceInited = true; + if (this.dataUpdatePending) { + this.widgetTypeInstance.onDataUpdated(); + this.dataUpdatePending = false; + } } else { this.loadingData = false; } @@ -798,7 +807,11 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI onDataUpdated: () => { try { if (this.displayWidgetInstance()) { - this.widgetTypeInstance.onDataUpdated(); + if (this.widgetInstanceInited) { + this.widgetTypeInstance.onDataUpdated(); + } else { + this.dataUpdatePending = true; + } } } catch (e){} }, diff --git a/ui-ngx/src/app/shared/models/query/query.models.ts b/ui-ngx/src/app/shared/models/query/query.models.ts index b2eaa52d53..06e790a608 100644 --- a/ui-ngx/src/app/shared/models/query/query.models.ts +++ b/ui-ngx/src/app/shared/models/query/query.models.ts @@ -17,6 +17,9 @@ import { AliasFilterType, EntityFilters } from '@shared/models/alias.models'; import { EntityId } from '@shared/models/id/entity-id'; import { SortDirection } from '@angular/material/sort'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { EntityInfo } from '@shared/models/entity.models'; +import { EntityType } from '@shared/models/entity-type.models'; export enum EntityKeyType { ATTRIBUTE = 'ATTRIBUTE', @@ -27,6 +30,20 @@ export enum EntityKeyType { ENTITY_FIELD = 'ENTITY_FIELD' } +export function entityKeyTypeToDataKeyType(entityKeyType: EntityKeyType): DataKeyType { + switch (entityKeyType) { + case EntityKeyType.ATTRIBUTE: + case EntityKeyType.CLIENT_ATTRIBUTE: + case EntityKeyType.SHARED_ATTRIBUTE: + case EntityKeyType.SERVER_ATTRIBUTE: + return DataKeyType.attribute + case EntityKeyType.TIME_SERIES: + return DataKeyType.timeseries; + case EntityKeyType.ENTITY_FIELD: + return DataKeyType.entityField; + } +} + export interface EntityKey { type: EntityKeyType; key: string; @@ -168,3 +185,25 @@ export interface EntityData { latest: {[entityKeyType: string]: {[key: string]: TsValue}}; timeseries: {[key: string]: Array}; } + +export function entityDataToEntityInfo(entityData: EntityData): EntityInfo { + const entityInfo: EntityInfo = { + id: entityData.entityId.id, + entityType: entityData.entityId.entityType as EntityType + }; + if (entityData.latest && entityData.latest[EntityKeyType.ENTITY_FIELD]) { + const fields = entityData.latest[EntityKeyType.ENTITY_FIELD]; + if (fields.name) { + entityInfo.name = fields.name.value; + } else { + entityInfo.name = ''; + } + if (fields.label) { + entityInfo.label = fields.label.value; + } else { + entityInfo.label = ''; + } + entityInfo.entityDescription = 'TODO: Not implemented'; + } + return entityInfo; +}