Commit 99c9c099ba2e61d4a3ce917e2c2464bb81a694e3

Authored by Igor Kulikov
1 parent 2b711151

Add Entity Type alias. Fix Key filter value conditional processing.

... ... @@ -155,7 +155,7 @@ export class EntityDataSubscription {
155 155 clearTimeout(this.timer);
156 156 this.timer = null;
157 157 }
158   - if (this.datasourceType === DatasourceType.entity) {
  158 + if (this.datasourceType === DatasourceType.entity || this.datasourceType === DatasourceType.entityCount) {
159 159 if (this.subscriber) {
160 160 this.subscriber.unsubscribe();
161 161 this.subscriber = null;
... ... @@ -318,24 +318,30 @@ export class EntityDataSubscription {
318 318 entityType: null
319 319 };
320 320
321   - const entityData: EntityData = {
322   - entityId,
323   - timeseries: {},
324   - latest: {}
325   - };
326   - entityData.latest[EntityKeyType.ENTITY_FIELD] = {
327   - name: {ts: Date.now(), value: DatasourceType.entityCount},
328   - };
329   -
330 321 const countKey = this.entityDataSubscriptionOptions.dataKeys[0];
331 322
  323 + let dataReceived = false;
  324 +
332 325 this.subscriber.entityCount$.subscribe(
333 326 (entityCountUpdate) => {
334   - if (!entityData.latest[EntityKeyType.COUNT]) {
335   - entityData.latest[EntityKeyType.COUNT] = {};
336   - entityData.latest[EntityKeyType.COUNT][countKey.name] = {
337   - ts: Date.now(),
338   - value: entityCountUpdate.count + ''
  327 + if (!dataReceived) {
  328 + const entityData: EntityData = {
  329 + entityId,
  330 + latest: {
  331 + [EntityKeyType.ENTITY_FIELD]: {
  332 + name: {
  333 + ts: Date.now(),
  334 + value: DatasourceType.entityCount
  335 + }
  336 + },
  337 + [EntityKeyType.COUNT]: {
  338 + [countKey.name]: {
  339 + ts: Date.now(),
  340 + value: entityCountUpdate.count + ''
  341 + }
  342 + }
  343 + },
  344 + timeseries: {}
339 345 };
340 346 const pageData: PageData<EntityData> = {
341 347 data: [entityData],
... ... @@ -344,12 +350,20 @@ export class EntityDataSubscription {
344 350 totalPages: 1
345 351 };
346 352 this.onPageData(pageData);
  353 + dataReceived = true;
347 354 } else {
348   - const update = [deepClone(entityData)];
349   - update[0].latest[EntityKeyType.COUNT][countKey.name] = {
350   - ts: Date.now(),
351   - value: entityCountUpdate.count + ''
352   - };
  355 + const update: EntityData[] = [{
  356 + entityId,
  357 + latest: {
  358 + [EntityKeyType.COUNT]: {
  359 + [countKey.name]: {
  360 + ts: Date.now(),
  361 + value: entityCountUpdate.count + ''
  362 + }
  363 + }
  364 + },
  365 + timeseries: {}
  366 + }];
353 367 this.onDataUpdate(update);
354 368 }
355 369 }
... ...
... ... @@ -481,6 +481,8 @@ export class EntityService {
481 481 return entityTypes.indexOf(filter.entityType) > -1 ? true : false;
482 482 case AliasFilterType.entityName:
483 483 return entityTypes.indexOf(filter.entityType) > -1 ? true : false;
  484 + case AliasFilterType.entityType:
  485 + return entityTypes.indexOf(filter.entityType) > -1 ? true : false;
484 486 case AliasFilterType.stateEntity:
485 487 return true;
486 488 case AliasFilterType.assetType:
... ... @@ -540,6 +542,8 @@ export class EntityService {
540 542 return true;
541 543 case AliasFilterType.entityName:
542 544 return true;
  545 + case AliasFilterType.entityType:
  546 + return true;
543 547 case AliasFilterType.stateEntity:
544 548 return true;
545 549 case AliasFilterType.assetType:
... ... @@ -805,6 +809,9 @@ export class EntityService {
805 809 case AliasFilterType.entityName:
806 810 result.entityFilter = deepClone(filter);
807 811 return of(result);
  812 + case AliasFilterType.entityType:
  813 + result.entityFilter = deepClone(filter);
  814 + return of(result);
808 815 case AliasFilterType.stateEntity:
809 816 result.stateEntity = true;
810 817 if (stateEntityId) {
... ...
... ... @@ -76,6 +76,10 @@ export class EntityFilterViewComponent implements ControlValueAccessor {
76 76 this.filterDisplayValue = this.translate.instant(entityTypeTranslations.get(entityType).nameStartsWith,
77 77 {prefix});
78 78 break;
  79 + case AliasFilterType.entityType:
  80 + entityType = this.filter.entityType;
  81 + this.filterDisplayValue = this.translate.instant(entityTypeTranslations.get(entityType).typePlural);
  82 + break;
79 83 case AliasFilterType.stateEntity:
80 84 this.filterDisplayValue = this.translate.instant('alias.filter-type-state-entity-description');
81 85 break;
... ...
... ... @@ -59,6 +59,13 @@
59 59 </mat-error>
60 60 </mat-form-field>
61 61 </ng-template>
  62 + <ng-template [ngSwitchCase]="aliasFilterType.entityType">
  63 + <tb-entity-type-select required
  64 + showLabel
  65 + [allowedEntityTypes]="allowedEntityTypes"
  66 + formControlName="entityType">
  67 + </tb-entity-type-select>
  68 + </ng-template>
62 69 <ng-template [ngSwitchCase]="aliasFilterType.stateEntity">
63 70 <mat-form-field floatLabel="always" class="mat-block">
64 71 <mat-label translate>alias.state-entity-parameter-name</mat-label>
... ...
... ... @@ -123,6 +123,11 @@ export class EntityFilterComponent implements ControlValueAccessor, OnInit {
123 123 entityNameFilter: [filter ? filter.entityNameFilter : '', [Validators.required]],
124 124 });
125 125 break;
  126 + case AliasFilterType.entityType:
  127 + this.filterFormGroup = this.fb.group({
  128 + entityType: [filter ? filter.entityType : null, [Validators.required]]
  129 + });
  130 + break;
126 131 case AliasFilterType.stateEntity:
127 132 this.filterFormGroup = this.fb.group({
128 133 stateEntityParamName: [filter ? filter.stateEntityParamName : null, []],
... ...
... ... @@ -107,12 +107,15 @@ export class KeyFilterDialogComponent extends
107 107 key: [this.data.keyFilter.key.key, [Validators.required]]
108 108 }
109 109 ),
110   - value: [this.data.keyFilter.value],
111 110 valueType: [this.data.keyFilter.valueType, [Validators.required]],
112 111 predicates: [this.data.keyFilter.predicates, [Validators.required]]
113 112 }
114 113 );
115   -
  114 + if (this.data.telemetryKeysOnly) {
  115 + this.keyFilterFormGroup.addControl(
  116 + 'value', this.fb.control(this.data.keyFilter.value)
  117 + );
  118 + }
116 119 if (!this.data.readonly) {
117 120 this.keyFilterFormGroup.get('valueType').valueChanges.pipe(
118 121 takeUntil(this.destroy$)
... ... @@ -144,12 +147,14 @@ export class KeyFilterDialogComponent extends
144 147 } else {
145 148 this.showAutocomplete = false;
146 149 }
147   - if (type === EntityKeyType.CONSTANT) {
148   - this.keyFilterFormGroup.get('value').setValidators(Validators.required);
149   - this.keyFilterFormGroup.get('value').updateValueAndValidity();
150   - } else {
151   - this.keyFilterFormGroup.get('value').clearValidators();
152   - this.keyFilterFormGroup.get('value').updateValueAndValidity();
  150 + if (this.data.telemetryKeysOnly) {
  151 + if (type === EntityKeyType.CONSTANT) {
  152 + this.keyFilterFormGroup.get('value').setValidators(Validators.required);
  153 + this.keyFilterFormGroup.get('value').updateValueAndValidity();
  154 + } else {
  155 + this.keyFilterFormGroup.get('value').clearValidators();
  156 + this.keyFilterFormGroup.get('value').updateValueAndValidity();
  157 + }
153 158 }
154 159 });
155 160
... ...
... ... @@ -24,7 +24,7 @@ import {
24 24 NG_VALUE_ACCESSOR
25 25 } from '@angular/forms';
26 26 import { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
27   -import { EntityTypeFilter } from '@shared/models/relation.models';
  27 +import { RelationEntityTypeFilter } from '@shared/models/relation.models';
28 28 import { PageComponent } from '@shared/components/page.component';
29 29 import { Store } from '@ngrx/store';
30 30 import { AppState } from '@core/core.state';
... ... @@ -80,7 +80,7 @@ export class RelationFiltersComponent extends PageComponent implements ControlVa
80 80 this.disabled = isDisabled;
81 81 }
82 82
83   - writeValue(filters: Array<EntityTypeFilter>): void {
  83 + writeValue(filters: Array<RelationEntityTypeFilter>): void {
84 84 if (this.valueChangeSubscription) {
85 85 this.valueChangeSubscription.unsubscribe();
86 86 }
... ... @@ -102,14 +102,14 @@ export class RelationFiltersComponent extends PageComponent implements ControlVa
102 102
103 103 public addFilter() {
104 104 const relationFiltersFormArray = this.relationFiltersFormGroup.get('relationFilters') as FormArray;
105   - const filter: EntityTypeFilter = {
  105 + const filter: RelationEntityTypeFilter = {
106 106 relationType: null,
107 107 entityTypes: []
108 108 };
109 109 relationFiltersFormArray.push(this.createRelationFilterFormGroup(filter));
110 110 }
111 111
112   - private createRelationFilterFormGroup(filter: EntityTypeFilter): AbstractControl {
  112 + private createRelationFilterFormGroup(filter: RelationEntityTypeFilter): AbstractControl {
113 113 return this.fb.group({
114 114 relationType: [filter ? filter.relationType : null],
115 115 entityTypes: [filter ? filter.entityTypes : []]
... ... @@ -117,7 +117,7 @@ export class RelationFiltersComponent extends PageComponent implements ControlVa
117 117 }
118 118
119 119 private updateModel() {
120   - const filters: Array<EntityTypeFilter> = this.relationFiltersFormGroup.get('relationFilters').value;
  120 + const filters: Array<RelationEntityTypeFilter> = this.relationFiltersFormGroup.get('relationFilters').value;
121 121 this.propagateChange(filters);
122 122 }
123 123 }
... ...
... ... @@ -16,14 +16,14 @@
16 16
17 17 import { EntityType } from '@shared/models/entity-type.models';
18 18 import { EntityId } from '@shared/models/id/entity-id';
19   -import { EntitySearchDirection, EntityTypeFilter } from '@shared/models/relation.models';
20   -import { EntityInfo } from './entity.models';
  19 +import { EntitySearchDirection, RelationEntityTypeFilter } from '@shared/models/relation.models';
21 20 import { EntityFilter } from '@shared/models/query/query.models';
22 21
23 22 export enum AliasFilterType {
24 23 singleEntity = 'singleEntity',
25 24 entityList = 'entityList',
26 25 entityName = 'entityName',
  26 + entityType = 'entityType',
27 27 stateEntity = 'stateEntity',
28 28 assetType = 'assetType',
29 29 deviceType = 'deviceType',
... ... @@ -40,6 +40,7 @@ export const aliasFilterTypeTranslationMap = new Map<AliasFilterType, string>(
40 40 [ AliasFilterType.singleEntity, 'alias.filter-type-single-entity' ],
41 41 [ AliasFilterType.entityList, 'alias.filter-type-entity-list' ],
42 42 [ AliasFilterType.entityName, 'alias.filter-type-entity-name' ],
  43 + [ AliasFilterType.entityType, 'alias.filter-type-entity-type' ],
43 44 [ AliasFilterType.stateEntity, 'alias.filter-type-state-entity' ],
44 45 [ AliasFilterType.assetType, 'alias.filter-type-asset-type' ],
45 46 [ AliasFilterType.deviceType, 'alias.filter-type-device-type' ],
... ... @@ -66,6 +67,10 @@ export interface EntityNameFilter {
66 67 entityNameFilter?: string;
67 68 }
68 69
  70 +export interface EntityTypeFilter {
  71 + entityType?: EntityType;
  72 +}
  73 +
69 74 export interface StateEntityFilter {
70 75 stateEntityParamName?: string;
71 76 defaultStateEntity?: EntityId;
... ... @@ -92,7 +97,7 @@ export interface RelationsQueryFilter {
92 97 defaultStateEntity?: EntityId;
93 98 rootEntity?: EntityId;
94 99 direction?: EntitySearchDirection;
95   - filters?: Array<EntityTypeFilter>;
  100 + filters?: Array<RelationEntityTypeFilter>;
96 101 maxLevel?: number;
97 102 fetchLastLevelOnly?: boolean;
98 103 }
... ... @@ -129,6 +134,7 @@ export type EntityFilters =
129 134 SingleEntityFilter &
130 135 EntityListFilter &
131 136 EntityNameFilter &
  137 + EntityTypeFilter &
132 138 StateEntityFilter &
133 139 AssetTypeFilter &
134 140 DeviceTypeFilter &
... ...
... ... @@ -351,14 +351,14 @@ export interface KeyFilterPredicateInfo {
351 351 export interface KeyFilter {
352 352 key: EntityKey;
353 353 valueType: EntityKeyValueType;
354   - value: string | number | boolean;
  354 + value?: string | number | boolean;
355 355 predicate: KeyFilterPredicate;
356 356 }
357 357
358 358 export interface KeyFilterInfo {
359 359 key: EntityKey;
360 360 valueType: EntityKeyValueType;
361   - value: string | number | boolean;
  361 + value?: string | number | boolean;
362 362 predicates: Array<KeyFilterPredicateInfo>;
363 363 }
364 364
... ...
... ... @@ -52,7 +52,7 @@ export const directionTypeTranslations = new Map<EntitySearchDirection, string>(
52 52 ]
53 53 );
54 54
55   -export interface EntityTypeFilter {
  55 +export interface RelationEntityTypeFilter {
56 56 relationType: string;
57 57 entityTypes: Array<EntityType>;
58 58 }
... ... @@ -68,7 +68,7 @@ export interface RelationsSearchParameters {
68 68
69 69 export interface EntityRelationsQuery {
70 70 parameters: RelationsSearchParameters;
71   - filters: Array<EntityTypeFilter>;
  71 + filters: Array<RelationEntityTypeFilter>;
72 72 }
73 73
74 74 export interface EntitySearchQuery {
... ...
... ... @@ -299,6 +299,7 @@
299 299 "filter-type-single-entity": "Single entity",
300 300 "filter-type-entity-list": "Entity list",
301 301 "filter-type-entity-name": "Entity name",
  302 + "filter-type-entity-type": "Entity type",
302 303 "filter-type-state-entity": "Entity from dashboard state",
303 304 "filter-type-state-entity-description": "Entity taken from dashboard state parameters",
304 305 "filter-type-asset-type": "Asset type",
... ...