diff --git a/ui-ngx/src/app/core/http/entity.service.ts b/ui-ngx/src/app/core/http/entity.service.ts index cf70871a62..7d043c51b0 100644 --- a/ui-ngx/src/app/core/http/entity.service.ts +++ b/ui-ngx/src/app/core/http/entity.service.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Inject, Injectable } from '@angular/core'; +import { Injectable } from '@angular/core'; import { EMPTY, forkJoin, Observable, of, throwError } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { PageLink } from '@shared/models/page/page-link'; @@ -44,9 +44,15 @@ import { AliasInfo, StateParams, SubscriptionInfo } from '@core/api/widget-api.m import { Datasource, DatasourceType, KeyInfo } from '@app/shared/models/widget.models'; import { UtilsService } from '@core/services/utils.service'; import { AliasFilterType, EntityAlias, EntityAliasFilter, EntityAliasFilterResult } from '@shared/models/alias.models'; -import { entityFields, EntityInfo, ImportEntitiesResultInfo, ImportEntityData } from '@shared/models/entity.models'; +import { + EdgeImportEntityData, + entityFields, + EntityInfo, + ImportEntitiesResultInfo, + ImportEntityData +} from '@shared/models/entity.models'; import { EntityRelationService } from '@core/http/entity-relation.service'; -import { deepClone, generateSecret, guid, isDefined, isDefinedAndNotNull } from '@core/utils'; +import { deepClone, isDefined, isDefinedAndNotNull } from '@core/utils'; import { Asset } from '@shared/models/asset.models'; import { Device, DeviceCredentialsType } from '@shared/models/device.models'; import { AttributeService } from '@core/http/attribute.service'; @@ -68,10 +74,9 @@ import { StringOperation } from '@shared/models/query/query.models'; import { alarmFields } from '@shared/models/alarm.models'; -import { EdgeService } from "@core/http/edge.service"; +import { EdgeService } from '@core/http/edge.service'; import { Edge } from '@shared/models/edge.models'; -import { WINDOW } from "@core/services/window.service"; -import { RuleChainType } from "@shared/models/rule-chain.models"; +import { RuleChainType } from '@shared/models/rule-chain.models'; @Injectable({ providedIn: 'root' @@ -92,8 +97,7 @@ export class EntityService { private dashboardService: DashboardService, private entityRelationService: EntityRelationService, private attributeService: AttributeService, - private utils: UtilsService, - @Inject(WINDOW) protected window: Window + private utils: UtilsService ) { } private getEntityObservable(entityType: EntityType, entityId: string, @@ -861,6 +865,51 @@ export class EntityService { public saveEntityParameters(entityType: EntityType, entityData: ImportEntityData, update: boolean, config?: RequestConfig): Observable { + const saveEntityObservable: Observable> = this.getSaveEntityObservable(entityType, entityData, config); + return saveEntityObservable.pipe( + mergeMap((entity) => { + return this.saveEntityData(entity.id, entityData, config).pipe( + map(() => { + return { create: { entity: 1 } } as ImportEntitiesResultInfo; + }), + catchError(err => of({ error: { entity: 1 } } as ImportEntitiesResultInfo)) + ); + }), + catchError(err => { + if (update) { + let findEntityObservable: Observable>; + switch (entityType) { + case EntityType.DEVICE: + findEntityObservable = this.deviceService.findByName(entityData.name, config); + break; + case EntityType.ASSET: + findEntityObservable = this.assetService.findByName(entityData.name, config); + break; + case EntityType.EDGE: + findEntityObservable = this.edgeService.findByName(entityData.name, config); + break; + } + return findEntityObservable.pipe( + mergeMap((entity) => { + const updateEntityTasks: Observable[] = this.getUpdateEntityTasks(entityType, entityData, entity, config); + return forkJoin(updateEntityTasks).pipe( + map(() => { + return { update: { entity: 1 } } as ImportEntitiesResultInfo; + }), + catchError(updateError => of({ error: { entity: 1 } } as ImportEntitiesResultInfo)) + ); + }), + catchError(findErr => of({ error: { entity: 1 } } as ImportEntitiesResultInfo)) + ); + } else { + return of({ error: { entity: 1 } } as ImportEntitiesResultInfo); + } + }) + ); + } + + private getSaveEntityObservable(entityType: EntityType, entityData: ImportEntityData, + config?: RequestConfig): Observable> { let saveEntityObservable: Observable>; switch (entityType) { case EntityType.DEVICE: @@ -892,127 +941,95 @@ export class EntityService { saveEntityObservable = this.assetService.saveAsset(asset, config); break; case EntityType.EDGE: + const edgeEntityData: EdgeImportEntityData = entityData as EdgeImportEntityData; const edge: Edge = { - name: entityData.name, - type: entityData.type, - label: entityData.label, + name: edgeEntityData.name, + type: edgeEntityData.type, + label: edgeEntityData.label, additionalInfo: { - description: entityData.description + description: edgeEntityData.description }, - edgeLicenseKey: entityData.edgeLicenseKey, - cloudEndpoint: entityData.cloudEndpoint, - routingKey: entityData.routingKey, - secret: entityData.secret + edgeLicenseKey: edgeEntityData.edgeLicenseKey, + cloudEndpoint: edgeEntityData.cloudEndpoint, + routingKey: edgeEntityData.routingKey, + secret: edgeEntityData.secret }; - if (edge.cloudEndpoint === '') { - edge.cloudEndpoint = this.window.location.origin; - } - if (edge.routingKey === '') { - edge.routingKey = guid(); - } - if (edge.secret === '') { - edge.secret = generateSecret(20); - } saveEntityObservable = this.edgeService.saveEdge(edge, config); break; } - return saveEntityObservable.pipe( - mergeMap((entity) => { - return this.saveEntityData(entity.id, entityData, config).pipe( - map(() => { - return { create: { entity: 1 } } as ImportEntitiesResultInfo; - }), - catchError(err => of({ error: { entity: 1 } } as ImportEntitiesResultInfo)) - ); - }), - catchError(err => { - if (update) { - let findEntityObservable: Observable>; - switch (entityType) { + return saveEntityObservable; + + } + + private getUpdateEntityTasks(entityType: EntityType, entityData: ImportEntityData | EdgeImportEntityData, + entity: BaseData, config?: RequestConfig): Observable[] { + const tasks: Observable[] = []; + let result; + let additionalInfo; + switch (entityType) { + case EntityType.EDGE: + result = entity as Edge; + additionalInfo = result.additionalInfo || {}; + const edgeEntityData: EdgeImportEntityData = entityData as EdgeImportEntityData; + if (result.label !== edgeEntityData.label || + result.type !== edgeEntityData.type || + result.cloudEndpoint !== edgeEntityData.cloudEndpoint || + result.edgeLicenseKey !== edgeEntityData.edgeLicenseKey || + result.routingKey !== edgeEntityData.routingKey || + result.secret !== edgeEntityData.secret || + additionalInfo.description !== edgeEntityData.description) { + result.type = edgeEntityData.type; + if (edgeEntityData.label !== '') { + result.label = edgeEntityData.label; + } + if (edgeEntityData.description !== '') { + result.additionalInfo = additionalInfo; + result.additionalInfo.description = edgeEntityData.description; + } + if (edgeEntityData.cloudEndpoint !== '') { + result.cloudEndpoint = edgeEntityData.cloudEndpoint; + } + if (edgeEntityData.edgeLicenseKey !== '') { + result.edgeLicenseKey = edgeEntityData.edgeLicenseKey; + } + if (edgeEntityData.routingKey !== '') { + result.routingKey = edgeEntityData.routingKey; + } + if (edgeEntityData.cloudEndpoint !== '') { + result.secret = edgeEntityData.secret; + } + tasks.push(this.edgeService.saveEdge(result, config)); + } + tasks.push(this.saveEntityData(entity.id, edgeEntityData, config)); + break; + case EntityType.ASSET: + case EntityType.DEVICE: + result = entity as (Device | Asset); + additionalInfo = result.additionalInfo || {}; + if (result.label !== entityData.label || + result.type !== entityData.type || + additionalInfo.description !== entityData.description || + (result.id.entityType === EntityType.DEVICE && (additionalInfo.gateway !== entityData.gateway)) ) { + result.label = entityData.label; + result.type = entityData.type; + result.additionalInfo = additionalInfo; + result.additionalInfo.description = entityData.description; + if (result.id.entityType === EntityType.DEVICE) { + result.additionalInfo.gateway = entityData.gateway; + } + switch (result.id.entityType) { case EntityType.DEVICE: - findEntityObservable = this.deviceService.findByName(entityData.name, config); + tasks.push(this.deviceService.saveDevice(result, config)); break; case EntityType.ASSET: - findEntityObservable = this.assetService.findByName(entityData.name, config); - break; - case EntityType.EDGE: - findEntityObservable = this.edgeService.findByName(entityData.name, config); + tasks.push(this.assetService.saveAsset(result, config)); break; } - return findEntityObservable.pipe( - mergeMap((entity) => { - const tasks: Observable[] = []; - if (entity.id.entityType === EntityType.EDGE) { - const result: Edge = entity as Edge; - const additionalInfo = result.additionalInfo || {}; - if (result.label !== entityData.label || - result.type !== entityData.type || - result.cloudEndpoint !== entityData.cloudEndpoint || - result.edgeLicenseKey !== entityData.edgeLicenseKey || - result.routingKey !== entityData.routingKey || - result.secret !== entityData.secret || - additionalInfo.description !== entityData.description) { - result.type = entityData.type; - if (entityData.label !== '') { - result.label = entityData.label; - } - if (entityData.description !== '') { - result.additionalInfo = additionalInfo; - result.additionalInfo.description = entityData.description; - } - if (entityData.cloudEndpoint !== '') { - result.cloudEndpoint = entityData.cloudEndpoint; - } - if (entityData.edgeLicenseKey !== '') { - result.edgeLicenseKey = entityData.edgeLicenseKey; - } - if (entityData.routingKey !== '') { - result.routingKey = entityData.routingKey; - } - if (entityData.cloudEndpoint !== '') { - result.secret = entityData.secret; - } - tasks.push(this.edgeService.saveEdge(result, config)); - } - } else { - const result: Device | Asset = entity as (Device | Asset); - const additionalInfo = result.additionalInfo || {}; - if (result.label !== entityData.label || - result.type !== entityData.type || - additionalInfo.description !== entityData.description || - (result.id.entityType === EntityType.DEVICE && (additionalInfo.gateway !== entityData.gateway)) ) { - result.label = entityData.label; - result.type = entityData.type; - result.additionalInfo = additionalInfo; - result.additionalInfo.description = entityData.description; - if (result.id.entityType === EntityType.DEVICE) { - result.additionalInfo.gateway = entityData.gateway; - } - switch (result.id.entityType) { - case EntityType.DEVICE: - tasks.push(this.deviceService.saveDevice(result, config)); - break; - case EntityType.ASSET: - tasks.push(this.assetService.saveAsset(result, config)); - break; - } - } - } - tasks.push(this.saveEntityData(entity.id, entityData, config)); - return forkJoin(tasks).pipe( - map(() => { - return { update: { entity: 1 } } as ImportEntitiesResultInfo; - }), - catchError(updateError => of({ error: { entity: 1 } } as ImportEntitiesResultInfo)) - ); - }), - catchError(findErr => of({ error: { entity: 1 } } as ImportEntitiesResultInfo)) - ); - } else { - return of({ error: { entity: 1 } } as ImportEntitiesResultInfo); } - }) - ); + tasks.push(this.saveEntityData(entity.id, entityData, config)); + break; + } + return tasks; } public saveEntityData(entityId: EntityId, entityData: ImportEntityData, config?: RequestConfig): Observable { diff --git a/ui-ngx/src/app/modules/home/components/import-export/import-dialog-csv.component.ts b/ui-ngx/src/app/modules/home/components/import-export/import-dialog-csv.component.ts index 8473b9a3af..44038e3c0e 100644 --- a/ui-ngx/src/app/modules/home/components/import-export/import-dialog-csv.component.ts +++ b/ui-ngx/src/app/modules/home/components/import-export/import-dialog-csv.component.ts @@ -32,8 +32,9 @@ import { CsvToJsonResult, ImportEntityColumnType } from '@home/components/import-export/import-export.models'; -import { ImportEntitiesResultInfo, ImportEntityData } from '@app/shared/models/entity.models'; +import { EdgeImportEntityData, ImportEntitiesResultInfo, ImportEntityData } from '@app/shared/models/entity.models'; import { ImportExportService } from '@home/components/import-export/import-export.service'; +import { generateSecret, guid } from '@core/utils'; export interface ImportDialogCsvData { entityType: EntityType; @@ -186,29 +187,14 @@ export class ImportDialogCsvComponent extends DialogComponent[] = []; for (let i = 0; i < partSize; i++) { - const importEntityPromise = - this.entityService.saveEntityParameters(entityType, entitiesData[i], updateData, config).pipe( + let saveEntityPromise: Observable; + saveEntityPromise = this.entityService.saveEntityParameters(entityType, entitiesData[i], updateData, config); + const importEntityPromise = saveEntityPromise.pipe( tap((res) => { if (importEntityCompleted) { importEntityCompleted(); @@ -412,7 +408,7 @@ export class ImportExportService { throw new Error('Invalid rule chain file'); } else if (ruleChainImport.ruleChain.type !== expectedRuleChainType) { this.store.dispatch(new ActionNotificationShow( - {message: this.translate.instant('rulechain.invalid-rulechain-type-error', { expectedRuleChainType: expectedRuleChainType }), + {message: this.translate.instant('rulechain.invalid-rulechain-type-error', {expectedRuleChainType}), type: 'error'})); throw new Error('Invalid rule chain type'); } else { @@ -602,7 +598,7 @@ export class ImportExportService { private editMissingAliases(widgets: Array, isSingleWidget: boolean, customTitle: string, missingEntityAliases: EntityAliases): Observable { - let allowedEntityTypes: Array = + const allowedEntityTypes: Array = this.entityService.prepareAllowedEntityTypesList(null, true); return this.dialog.open { diff --git a/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts b/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts index aed8dd606d..7d4f02d220 100644 --- a/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts +++ b/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts @@ -24,6 +24,7 @@ import { TranslateService } from '@ngx-translate/core'; import { ContactBasedComponent } from '../../components/entity/contact-based.component'; import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; import { getCurrentAuthState } from '@core/auth/auth.selectors'; +import { AuthState } from '@core/auth/auth.models'; @Component({ selector: 'tb-customer', @@ -33,6 +34,8 @@ export class CustomerComponent extends ContactBasedComponent { isPublic = false; + authState: AuthState = getCurrentAuthState(this.store); + constructor(protected store: Store, protected translate: TranslateService, @Inject('entity') protected entityValue: Customer, @@ -80,8 +83,6 @@ export class CustomerComponent extends ContactBasedComponent { } edgesSupportEnabled() { - const authState = getCurrentAuthState(this.store); - return authState.edgesSupportEnabled; + return this.authState.edgesSupportEnabled; } - } diff --git a/ui-ngx/src/app/modules/home/pages/edge/edge.component.ts b/ui-ngx/src/app/modules/home/pages/edge/edge.component.ts index 87c745be28..8bd2d3337b 100644 --- a/ui-ngx/src/app/modules/home/pages/edge/edge.component.ts +++ b/ui-ngx/src/app/modules/home/pages/edge/edge.component.ts @@ -26,7 +26,6 @@ import { NULL_UUID } from '@shared/models/id/has-uuid'; import { ActionNotificationShow } from '@core/notification/notification.actions'; import { generateSecret, guid } from '@core/utils'; import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; -import { WINDOW } from '@core/services/window.service'; @Component({ selector: 'tb-edge', @@ -43,15 +42,14 @@ export class EdgeComponent extends EntityComponent { protected translate: TranslateService, @Inject('entity') protected entityValue: EdgeInfo, @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig, - public fb: FormBuilder, - @Inject(WINDOW) protected window: Window) { + public fb: FormBuilder) { super(store, fb, entityValue, entitiesTableConfigValue); } ngOnInit() { this.edgeScope = this.entitiesTableConfig.componentsData.edgeScope; this.entityForm.patchValue({ - cloudEndpoint: this.window.location.origin + cloudEndpoint: window.location.origin }); super.ngOnInit(); } @@ -94,7 +92,7 @@ export class EdgeComponent extends EntityComponent { name: entity.name, type: entity.type, label: entity.label, - cloudEndpoint: entity.cloudEndpoint ? entity.cloudEndpoint : this.window.location.origin, + cloudEndpoint: entity.cloudEndpoint ? entity.cloudEndpoint : window.location.origin, edgeLicenseKey: entity.edgeLicenseKey, routingKey: entity.routingKey, secret: entity.secret, diff --git a/ui-ngx/src/app/shared/models/entity.models.ts b/ui-ngx/src/app/shared/models/entity.models.ts index 70267c9f6c..ae4b552840 100644 --- a/ui-ngx/src/app/shared/models/entity.models.ts +++ b/ui-ngx/src/app/shared/models/entity.models.ts @@ -43,6 +43,9 @@ export interface ImportEntityData { shared: AttributeData[] }; timeseries: AttributeData[]; +} + +export interface EdgeImportEntityData extends ImportEntityData { secret: string; routingKey: string; cloudEndpoint: string; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 0e1369bd38..f70e698f37 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1974,9 +1974,9 @@ "access-token": "Access token", "isgateway": "Is Gateway", "description": "Description", - "edgeLicenseKey": "License Key", - "cloudEndpoint": "Cloud Endpoint", - "routingKey": "Edge key", + "edge-license-key": "License Key", + "cloud-endpoint": "Cloud Endpoint", + "routing-key": "Edge key", "secret": "Edge secret" }, "stepper-text":{