Merge import device/asset functionality
This commit is contained in:
parent
f1ca4c7cfd
commit
05f0619a2d
@ -805,14 +805,28 @@ export class EntityService {
|
||||
case EntityType.DEVICE:
|
||||
const device: Device = {
|
||||
name: entityData.name,
|
||||
type: entityData.type
|
||||
type: entityData.type,
|
||||
label: entityData.label,
|
||||
additionalInfo: {
|
||||
description: entityData.description
|
||||
}
|
||||
};
|
||||
if (entityData.gateway !== null) {
|
||||
device.additionalInfo = {
|
||||
...device.additionalInfo,
|
||||
gateway: entityData.gateway
|
||||
};
|
||||
}
|
||||
saveEntityObservable = this.deviceService.saveDevice(device, config);
|
||||
break;
|
||||
case EntityType.ASSET:
|
||||
const asset: Asset = {
|
||||
name: entityData.name,
|
||||
type: entityData.type
|
||||
type: entityData.type,
|
||||
label: entityData.label,
|
||||
additionalInfo: {
|
||||
description: entityData.description
|
||||
}
|
||||
};
|
||||
saveEntityObservable = this.assetService.saveAsset(asset, config);
|
||||
break;
|
||||
@ -839,7 +853,31 @@ export class EntityService {
|
||||
}
|
||||
return findEntityObservable.pipe(
|
||||
mergeMap((entity) => {
|
||||
return this.saveEntityData(entity.id, entityData, config).pipe(
|
||||
const tasks: Observable<any>[] = [];
|
||||
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;
|
||||
}),
|
||||
|
||||
@ -168,7 +168,7 @@ export class ImportDialogCsvComponent extends DialogComponent<ImportDialogCsvCom
|
||||
const isHeader: boolean = this.importParametersFormGroup.get('isHeader').value;
|
||||
for (let i = 0; i < this.parseData.headers.length; i++) {
|
||||
let columnParam: CsvColumnParam;
|
||||
if (isHeader && this.parseData.headers[i].search(/^(name|type)$/im) === 0) {
|
||||
if (isHeader && this.parseData.headers[i].search(/^(name|type|label)$/im) === 0) {
|
||||
columnParam = {
|
||||
type: ImportEntityColumnType[this.parseData.headers[i].toLowerCase()],
|
||||
key: this.parseData.headers[i].toLowerCase(),
|
||||
@ -195,6 +195,9 @@ export class ImportDialogCsvComponent extends DialogComponent<ImportDialogCsvCom
|
||||
const entityData: ImportEntityData = {
|
||||
name: '',
|
||||
type: '',
|
||||
description: '',
|
||||
gateway: null,
|
||||
label: '',
|
||||
accessToken: '',
|
||||
attributes: {
|
||||
server: [],
|
||||
@ -232,6 +235,15 @@ export class ImportDialogCsvComponent extends DialogComponent<ImportDialogCsvCom
|
||||
case ImportEntityColumnType.type:
|
||||
entityData.type = importData.rows[i][j];
|
||||
break;
|
||||
case ImportEntityColumnType.label:
|
||||
entityData.label = importData.rows[i][j];
|
||||
break;
|
||||
case ImportEntityColumnType.isGateway:
|
||||
entityData.gateway = importData.rows[i][j];
|
||||
break;
|
||||
case ImportEntityColumnType.description:
|
||||
entityData.description = importData.rows[i][j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
entitiesData.push(entityData);
|
||||
|
||||
@ -44,12 +44,15 @@ export interface CsvToJsonResult {
|
||||
export enum ImportEntityColumnType {
|
||||
name = 'NAME',
|
||||
type = 'TYPE',
|
||||
label = 'LABEL',
|
||||
clientAttribute = 'CLIENT_ATTRIBUTE',
|
||||
sharedAttribute = 'SHARED_ATTRIBUTE',
|
||||
serverAttribute = 'SERVER_ATTRIBUTE',
|
||||
timeseries = 'TIMESERIES',
|
||||
entityField = 'ENTITY_FIELD',
|
||||
accessToken = 'ACCESS_TOKEN'
|
||||
accessToken = 'ACCESS_TOKEN',
|
||||
isGateway = 'IS_GATEWAY',
|
||||
description = 'DESCRIPTION'
|
||||
}
|
||||
|
||||
export const importEntityObjectColumns =
|
||||
@ -59,12 +62,15 @@ export const importEntityColumnTypeTranslations = new Map<ImportEntityColumnType
|
||||
[
|
||||
[ImportEntityColumnType.name, 'import.column-type.name'],
|
||||
[ImportEntityColumnType.type, 'import.column-type.type'],
|
||||
[ImportEntityColumnType.label, 'import.column-type.label'],
|
||||
[ImportEntityColumnType.clientAttribute, 'import.column-type.client-attribute'],
|
||||
[ImportEntityColumnType.sharedAttribute, 'import.column-type.shared-attribute'],
|
||||
[ImportEntityColumnType.serverAttribute, 'import.column-type.server-attribute'],
|
||||
[ImportEntityColumnType.timeseries, 'import.column-type.timeseries'],
|
||||
[ImportEntityColumnType.entityField, 'import.column-type.entity-field'],
|
||||
[ImportEntityColumnType.accessToken, 'import.column-type.access-token'],
|
||||
[ImportEntityColumnType.isGateway, 'import.column-type.isgateway'],
|
||||
[ImportEntityColumnType.description, 'import.column-type.description'],
|
||||
]
|
||||
);
|
||||
|
||||
@ -136,7 +142,7 @@ function convertStringToJSType(str: string): any {
|
||||
return parseFloat(str.replace(',', '.'));
|
||||
}
|
||||
if (str.search(/^(true|false)$/im) === 0) {
|
||||
return str === 'true';
|
||||
return str.toLowerCase() === 'true';
|
||||
}
|
||||
if (str === '') {
|
||||
return null;
|
||||
|
||||
@ -42,9 +42,7 @@
|
||||
<mat-header-cell *matHeaderCellDef style="width: 30%"> {{ 'import.column-key' | translate }} </mat-header-cell>
|
||||
<mat-cell *matCellDef="let column">
|
||||
<mat-form-field floatLabel="always" hideRequiredMarker
|
||||
*ngIf="column.type !== importEntityColumnType.name &&
|
||||
column.type !== importEntityColumnType.type &&
|
||||
column.type !== importEntityColumnType.accessToken">
|
||||
*ngIf="isColumnTypeDiffers(column.type)">
|
||||
<mat-label></mat-label>
|
||||
<input matInput required
|
||||
[(ngModel)]="column.key" (ngModelChange)="columnsUpdated()"
|
||||
|
||||
@ -72,6 +72,8 @@ export class TableColumnsAssignmentComponent implements OnInit, ControlValueAcce
|
||||
this.columnTypes.push(
|
||||
{ value: ImportEntityColumnType.name },
|
||||
{ value: ImportEntityColumnType.type },
|
||||
{ value: ImportEntityColumnType.label },
|
||||
{ value: ImportEntityColumnType.description },
|
||||
);
|
||||
switch (this.entityType) {
|
||||
case EntityType.DEVICE:
|
||||
@ -79,7 +81,8 @@ export class TableColumnsAssignmentComponent implements OnInit, ControlValueAcce
|
||||
{ value: ImportEntityColumnType.sharedAttribute },
|
||||
{ value: ImportEntityColumnType.serverAttribute },
|
||||
{ value: ImportEntityColumnType.timeseries },
|
||||
{ value: ImportEntityColumnType.accessToken }
|
||||
{ value: ImportEntityColumnType.accessToken },
|
||||
{ value: ImportEntityColumnType.isGateway }
|
||||
);
|
||||
break;
|
||||
case EntityType.ASSET:
|
||||
@ -109,13 +112,20 @@ export class TableColumnsAssignmentComponent implements OnInit, ControlValueAcce
|
||||
columnsUpdated() {
|
||||
const isSelectName = this.columns.findIndex((column) => column.type === ImportEntityColumnType.name) > -1;
|
||||
const isSelectType = this.columns.findIndex((column) => column.type === ImportEntityColumnType.type) > -1;
|
||||
const isSelectLabel = this.columns.findIndex((column) => column.type === ImportEntityColumnType.label) > -1;
|
||||
const isSelectCredentials = this.columns.findIndex((column) => column.type === ImportEntityColumnType.accessToken) > -1;
|
||||
const isSelectGateway = this.columns.findIndex((column) => column.type === ImportEntityColumnType.isGateway) > -1;
|
||||
const isSelectDescription = this.columns.findIndex((column) => column.type === ImportEntityColumnType.description) > -1;
|
||||
const hasInvalidColumn = this.columns.findIndex((column) => !this.columnValid(column)) > -1;
|
||||
|
||||
this.valid = isSelectName && isSelectType && !hasInvalidColumn;
|
||||
|
||||
this.columnTypes.find((columnType) => columnType.value === ImportEntityColumnType.name).disabled = isSelectName;
|
||||
this.columnTypes.find((columnType) => columnType.value === ImportEntityColumnType.type).disabled = isSelectType;
|
||||
this.columnTypes.find((columnType) => columnType.value === ImportEntityColumnType.label).disabled = isSelectLabel;
|
||||
this.columnTypes.find((columnType) => columnType.value === ImportEntityColumnType.isGateway).disabled = isSelectGateway;
|
||||
this.columnTypes.find((columnType) => columnType.value === ImportEntityColumnType.description).disabled = isSelectDescription;
|
||||
|
||||
const accessTokenColumnType = this.columnTypes.find((columnType) => columnType.value === ImportEntityColumnType.accessToken);
|
||||
if (accessTokenColumnType) {
|
||||
accessTokenColumnType.disabled = isSelectCredentials;
|
||||
@ -127,6 +137,15 @@ export class TableColumnsAssignmentComponent implements OnInit, ControlValueAcce
|
||||
}
|
||||
}
|
||||
|
||||
public isColumnTypeDiffers(columnType: ImportEntityColumnType): boolean {
|
||||
return columnType !== ImportEntityColumnType.name &&
|
||||
columnType !== ImportEntityColumnType.type &&
|
||||
columnType !== ImportEntityColumnType.label &&
|
||||
columnType !== ImportEntityColumnType.accessToken &&
|
||||
columnType !== ImportEntityColumnType.isGateway &&
|
||||
columnType !== ImportEntityColumnType.description;
|
||||
}
|
||||
|
||||
private columnValid(column: CsvColumnParam): boolean {
|
||||
if (!importEntityObjectColumns.includes(column.type)) {
|
||||
return column.key && column.key.trim().length > 0;
|
||||
|
||||
@ -77,6 +77,10 @@
|
||||
[entityType]="entityType.ASSET"
|
||||
>
|
||||
</tb-entity-subtype-autocomplete>
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label translate>asset.label</mat-label>
|
||||
<input matInput formControlName="label">
|
||||
</mat-form-field>
|
||||
<div formGroupName="additionalInfo">
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label translate>asset.description</mat-label>
|
||||
|
||||
@ -64,6 +64,7 @@ export class AssetComponent extends EntityComponent<AssetInfo> {
|
||||
{
|
||||
name: [entity ? entity.name : '', [Validators.required]],
|
||||
type: [entity ? entity.type : null, [Validators.required]],
|
||||
label: [entity ? entity.label : ''],
|
||||
additionalInfo: this.fb.group(
|
||||
{
|
||||
description: [entity && entity.additionalInfo ? entity.additionalInfo.description : ''],
|
||||
@ -76,6 +77,7 @@ export class AssetComponent extends EntityComponent<AssetInfo> {
|
||||
updateForm(entity: AssetInfo) {
|
||||
this.entityForm.patchValue({name: entity.name});
|
||||
this.entityForm.patchValue({type: entity.type});
|
||||
this.entityForm.patchValue({label: entity.label});
|
||||
this.entityForm.patchValue({additionalInfo: {description: entity.additionalInfo ? entity.additionalInfo.description : ''}});
|
||||
}
|
||||
|
||||
|
||||
@ -57,6 +57,7 @@ import { AssetTableHeaderComponent } from '@modules/home/pages/asset/asset-table
|
||||
import { AssetId } from '@app/shared/models/id/asset-id';
|
||||
import { AssetTabsComponent } from '@home/pages/asset/asset-tabs.component';
|
||||
import { HomeDialogsService } from '@home/dialogs/home-dialogs.service';
|
||||
import { DeviceInfo } from '@shared/models/device.models';
|
||||
|
||||
@Injectable()
|
||||
export class AssetsTableConfigResolver implements Resolve<EntityTableConfig<AssetInfo>> {
|
||||
@ -146,12 +147,13 @@ export class AssetsTableConfigResolver implements Resolve<EntityTableConfig<Asse
|
||||
configureColumns(assetScope: string): Array<EntityTableColumn<AssetInfo>> {
|
||||
const columns: Array<EntityTableColumn<AssetInfo>> = [
|
||||
new DateEntityTableColumn<AssetInfo>('createdTime', 'asset.created-time', this.datePipe, '150px'),
|
||||
new EntityTableColumn<AssetInfo>('name', 'asset.name', '33%'),
|
||||
new EntityTableColumn<AssetInfo>('type', 'asset.asset-type', '33%'),
|
||||
new EntityTableColumn<AssetInfo>('name', 'asset.name', '25%'),
|
||||
new EntityTableColumn<AssetInfo>('type', 'asset.asset-type', '25%'),
|
||||
new EntityTableColumn<DeviceInfo>('label', 'asset.label', '25%'),
|
||||
];
|
||||
if (assetScope === 'tenant') {
|
||||
columns.push(
|
||||
new EntityTableColumn<AssetInfo>('customerTitle', 'customer.customer', '33%'),
|
||||
new EntityTableColumn<AssetInfo>('customerTitle', 'customer.customer', '25%'),
|
||||
new EntityTableColumn<AssetInfo>('customerIsPublic', 'asset.public', '60px',
|
||||
entity => {
|
||||
return checkBoxCell(entity.customerIsPublic);
|
||||
|
||||
@ -26,6 +26,7 @@ export interface Asset extends BaseData<AssetId> {
|
||||
customerId?: CustomerId;
|
||||
name: string;
|
||||
type: string;
|
||||
label: string;
|
||||
additionalInfo?: any;
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ export interface Device extends BaseData<DeviceId> {
|
||||
customerId?: CustomerId;
|
||||
name: string;
|
||||
type: string;
|
||||
label?: string;
|
||||
label: string;
|
||||
additionalInfo?: any;
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,9 @@ export interface EntityInfo {
|
||||
export interface ImportEntityData {
|
||||
name: string;
|
||||
type: string;
|
||||
label: string;
|
||||
gateway: boolean;
|
||||
description: string;
|
||||
accessToken: string;
|
||||
attributes: {
|
||||
server: AttributeData[],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user