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