Commit fd8dee0a9d5252d6d65d8bfeef906bf401e3ee61

Authored by Vladyslav_Prykhodko
Committed by Andrew Shvayka
1 parent ca2e08f8

UI: Add firmware type

@@ -361,7 +361,7 @@ export class EntityService { @@ -361,7 +361,7 @@ export class EntityService {
361 break; 361 break;
362 case EntityType.FIRMWARE: 362 case EntityType.FIRMWARE:
363 pageLink.sortOrder.property = 'title'; 363 pageLink.sortOrder.property = 'title';
364 - entitiesObservable = this.firmwareService.getFirmwares(pageLink, true, config); 364 + entitiesObservable = this.firmwareService.getFirmwares(pageLink, config);
365 break; 365 break;
366 } 366 }
367 return entitiesObservable; 367 return entitiesObservable;
@@ -20,7 +20,7 @@ import { PageLink } from '@shared/models/page/page-link'; @@ -20,7 +20,7 @@ import { PageLink } from '@shared/models/page/page-link';
20 import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils'; 20 import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils';
21 import { Observable } from 'rxjs'; 21 import { Observable } from 'rxjs';
22 import { PageData } from '@shared/models/page/page-data'; 22 import { PageData } from '@shared/models/page/page-data';
23 -import { Firmware, FirmwareInfo } from '@shared/models/firmware.models'; 23 +import { Firmware, FirmwareInfo, FirmwareType } from '@shared/models/firmware.models';
24 import { catchError, map, mergeMap } from 'rxjs/operators'; 24 import { catchError, map, mergeMap } from 'rxjs/operators';
25 import { deepClone, isDefinedAndNotNull } from '@core/utils'; 25 import { deepClone, isDefinedAndNotNull } from '@core/utils';
26 26
@@ -34,12 +34,13 @@ export class FirmwareService { @@ -34,12 +34,13 @@ export class FirmwareService {
34 34
35 } 35 }
36 36
37 - public getFirmwares(pageLink: PageLink, hasData?: boolean, config?: RequestConfig): Observable<PageData<FirmwareInfo>> {  
38 - let url = `/api/firmwares`;  
39 - if (isDefinedAndNotNull(hasData)) {  
40 - url += `/${hasData}`;  
41 - }  
42 - url += `${pageLink.toQuery()}`; 37 + public getFirmwares(pageLink: PageLink, config?: RequestConfig): Observable<PageData<FirmwareInfo>> {
  38 + return this.http.get<PageData<FirmwareInfo>>(`/api/firmwares${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config));
  39 + }
  40 +
  41 + public getFirmwaresInfoByDeviceProfileId(pageLink: PageLink, deviceProfileId: string, type: FirmwareType,
  42 + hasData = true, config?: RequestConfig): Observable<PageData<FirmwareInfo>> {
  43 + const url = `/api/firmwares/${deviceProfileId}/${type}/${hasData}${pageLink.toQuery()}`;
43 return this.http.get<PageData<FirmwareInfo>>(url, defaultHttpOptionsFromConfig(config)); 44 return this.http.get<PageData<FirmwareInfo>>(url, defaultHttpOptionsFromConfig(config));
44 } 45 }
45 46
@@ -60,10 +60,6 @@ @@ -60,10 +60,6 @@
60 {{ 'device-profile.type-required' | translate }} 60 {{ 'device-profile.type-required' | translate }}
61 </mat-error> 61 </mat-error>
62 </mat-form-field> 62 </mat-form-field>
63 - <tb-firmware-autocomplete  
64 - [useFullEntityId]="true"  
65 - formControlName="firmwareId">  
66 - </tb-firmware-autocomplete>  
67 <mat-form-field class="mat-block"> 63 <mat-form-field class="mat-block">
68 <mat-label translate>device-profile.description</mat-label> 64 <mat-label translate>device-profile.description</mat-label>
69 <textarea matInput formControlName="description" rows="2"></textarea> 65 <textarea matInput formControlName="description" rows="2"></textarea>
@@ -108,7 +108,6 @@ export class AddDeviceProfileDialogComponent extends @@ -108,7 +108,6 @@ export class AddDeviceProfileDialogComponent extends
108 type: [DeviceProfileType.DEFAULT, [Validators.required]], 108 type: [DeviceProfileType.DEFAULT, [Validators.required]],
109 defaultRuleChainId: [null, []], 109 defaultRuleChainId: [null, []],
110 defaultQueueName: ['', []], 110 defaultQueueName: ['', []],
111 - firmwareId: [null],  
112 description: ['', []] 111 description: ['', []]
113 } 112 }
114 ); 113 );
@@ -187,7 +186,6 @@ export class AddDeviceProfileDialogComponent extends @@ -187,7 +186,6 @@ export class AddDeviceProfileDialogComponent extends
187 transportType: this.transportConfigFormGroup.get('transportType').value, 186 transportType: this.transportConfigFormGroup.get('transportType').value,
188 provisionType: deviceProvisionConfiguration.type, 187 provisionType: deviceProvisionConfiguration.type,
189 provisionDeviceKey, 188 provisionDeviceKey,
190 - firmwareId: this.deviceProfileDetailsFormGroup.get('firmwareId').value,  
191 description: this.deviceProfileDetailsFormGroup.get('description').value, 189 description: this.deviceProfileDetailsFormGroup.get('description').value,
192 profileData: { 190 profileData: {
193 configuration: createDeviceProfileConfiguration(DeviceProfileType.DEFAULT), 191 configuration: createDeviceProfileConfiguration(DeviceProfileType.DEFAULT),
@@ -65,8 +65,16 @@ @@ -65,8 +65,16 @@
65 </tb-queue-type-list> 65 </tb-queue-type-list>
66 <tb-firmware-autocomplete 66 <tb-firmware-autocomplete
67 [useFullEntityId]="true" 67 [useFullEntityId]="true"
  68 + [type]="firmwareTypes.FIRMWARE"
  69 + [deviceProfileId]="deviceProfileId?.id"
68 formControlName="firmwareId"> 70 formControlName="firmwareId">
69 </tb-firmware-autocomplete> 71 </tb-firmware-autocomplete>
  72 + <tb-firmware-autocomplete
  73 + [useFullEntityId]="true"
  74 + [type]="firmwareTypes.SOFTWARE"
  75 + [deviceProfileId]="deviceProfileId?.id"
  76 + formControlName="softwareId">
  77 + </tb-firmware-autocomplete>
70 <mat-form-field fxHide class="mat-block"> 78 <mat-form-field fxHide class="mat-block">
71 <mat-label translate>device-profile.type</mat-label> 79 <mat-label translate>device-profile.type</mat-label>
72 <mat-select formControlName="type" required> 80 <mat-select formControlName="type" required>
@@ -40,6 +40,7 @@ import { EntityType } from '@shared/models/entity-type.models'; @@ -40,6 +40,7 @@ import { EntityType } from '@shared/models/entity-type.models';
40 import { RuleChainId } from '@shared/models/id/rule-chain-id'; 40 import { RuleChainId } from '@shared/models/id/rule-chain-id';
41 import { ServiceType } from '@shared/models/queue.models'; 41 import { ServiceType } from '@shared/models/queue.models';
42 import { EntityId } from '@shared/models/id/entity-id'; 42 import { EntityId } from '@shared/models/id/entity-id';
  43 +import { FirmwareType } from '@shared/models/firmware.models';
43 44
44 @Component({ 45 @Component({
45 selector: 'tb-device-profile', 46 selector: 'tb-device-profile',
@@ -69,6 +70,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -69,6 +70,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
69 70
70 deviceProfileId: EntityId; 71 deviceProfileId: EntityId;
71 72
  73 + firmwareTypes = FirmwareType;
  74 +
72 constructor(protected store: Store<AppState>, 75 constructor(protected store: Store<AppState>,
73 protected translate: TranslateService, 76 protected translate: TranslateService,
74 @Optional() @Inject('entity') protected entityValue: DeviceProfile, 77 @Optional() @Inject('entity') protected entityValue: DeviceProfile,
@@ -110,6 +113,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -110,6 +113,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
110 defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []], 113 defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
111 defaultQueueName: [entity ? entity.defaultQueueName : '', []], 114 defaultQueueName: [entity ? entity.defaultQueueName : '', []],
112 firmwareId: [entity ? entity.firmwareId : null], 115 firmwareId: [entity ? entity.firmwareId : null],
  116 + softwareId: [entity ? entity.softwareId : null],
113 description: [entity ? entity.description : '', []], 117 description: [entity ? entity.description : '', []],
114 } 118 }
115 ); 119 );
@@ -186,6 +190,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -186,6 +190,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
186 this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false}); 190 this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false});
187 this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false}); 191 this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false});
188 this.entityForm.patchValue({firmwareId: entity.firmwareId}, {emitEvent: false}); 192 this.entityForm.patchValue({firmwareId: entity.firmwareId}, {emitEvent: false});
  193 + this.entityForm.patchValue({softwareId: entity.softwareId}, {emitEvent: false});
189 this.entityForm.patchValue({description: entity.description}, {emitEvent: false}); 194 this.entityForm.patchValue({description: entity.description}, {emitEvent: false});
190 } 195 }
191 196
@@ -48,10 +48,6 @@ @@ -48,10 +48,6 @@
48 <mat-label translate>device.label</mat-label> 48 <mat-label translate>device.label</mat-label>
49 <input matInput formControlName="label"> 49 <input matInput formControlName="label">
50 </mat-form-field> 50 </mat-form-field>
51 - <tb-firmware-autocomplete  
52 - [useFullEntityId]="true"  
53 - formControlName="firmwareId">  
54 - </tb-firmware-autocomplete>  
55 <mat-form-field class="mat-block" style="padding-bottom: 14px;"> 51 <mat-form-field class="mat-block" style="padding-bottom: 14px;">
56 <mat-label translate>device-profile.transport-type</mat-label> 52 <mat-label translate>device-profile.transport-type</mat-label>
57 <mat-select formControlName="transportType" required> 53 <mat-select formControlName="transportType" required>
@@ -107,7 +107,6 @@ export class DeviceWizardDialogComponent extends @@ -107,7 +107,6 @@ export class DeviceWizardDialogComponent extends
107 this.deviceWizardFormGroup = this.fb.group({ 107 this.deviceWizardFormGroup = this.fb.group({
108 name: ['', Validators.required], 108 name: ['', Validators.required],
109 label: [''], 109 label: [''],
110 - firmwareId: [null],  
111 gateway: [false], 110 gateway: [false],
112 overwriteActivityTime: [false], 111 overwriteActivityTime: [false],
113 transportType: [DeviceTransportType.DEFAULT, Validators.required], 112 transportType: [DeviceTransportType.DEFAULT, Validators.required],
@@ -313,7 +312,6 @@ export class DeviceWizardDialogComponent extends @@ -313,7 +312,6 @@ export class DeviceWizardDialogComponent extends
313 const device = { 312 const device = {
314 name: this.deviceWizardFormGroup.get('name').value, 313 name: this.deviceWizardFormGroup.get('name').value,
315 label: this.deviceWizardFormGroup.get('label').value, 314 label: this.deviceWizardFormGroup.get('label').value,
316 - firmwareId: this.deviceWizardFormGroup.get('firmwareId').value,  
317 deviceProfileId: profileId, 315 deviceProfileId: profileId,
318 additionalInfo: { 316 additionalInfo: {
319 gateway: this.deviceWizardFormGroup.get('gateway').value, 317 gateway: this.deviceWizardFormGroup.get('gateway').value,
@@ -103,8 +103,16 @@ @@ -103,8 +103,16 @@
103 </mat-form-field> 103 </mat-form-field>
104 <tb-firmware-autocomplete 104 <tb-firmware-autocomplete
105 [useFullEntityId]="true" 105 [useFullEntityId]="true"
  106 + [type]="firmwareTypes.FIRMWARE"
  107 + [deviceProfileId]="entityForm.get('deviceProfileId').value?.id"
106 formControlName="firmwareId"> 108 formControlName="firmwareId">
107 </tb-firmware-autocomplete> 109 </tb-firmware-autocomplete>
  110 + <tb-firmware-autocomplete
  111 + [useFullEntityId]="true"
  112 + [type]="firmwareTypes.SOFTWARE"
  113 + [deviceProfileId]="entityForm.get('deviceProfileId').value?.id"
  114 + formControlName="softwareId">
  115 + </tb-firmware-autocomplete>
108 <tb-device-data 116 <tb-device-data
109 formControlName="deviceData" 117 formControlName="deviceData"
110 required> 118 required>
@@ -34,6 +34,7 @@ import { ActionNotificationShow } from '@core/notification/notification.actions' @@ -34,6 +34,7 @@ import { ActionNotificationShow } from '@core/notification/notification.actions'
34 import { TranslateService } from '@ngx-translate/core'; 34 import { TranslateService } from '@ngx-translate/core';
35 import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; 35 import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
36 import { Subject } from 'rxjs'; 36 import { Subject } from 'rxjs';
  37 +import { FirmwareType } from '@shared/models/firmware.models';
37 38
38 @Component({ 39 @Component({
39 selector: 'tb-device', 40 selector: 'tb-device',
@@ -48,6 +49,8 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { @@ -48,6 +49,8 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
48 49
49 deviceScope: 'tenant' | 'customer' | 'customer_user' | 'edge'; 50 deviceScope: 'tenant' | 'customer' | 'customer_user' | 'edge';
50 51
  52 + firmwareTypes = FirmwareType;
  53 +
51 constructor(protected store: Store<AppState>, 54 constructor(protected store: Store<AppState>,
52 protected translate: TranslateService, 55 protected translate: TranslateService,
53 @Inject('entity') protected entityValue: DeviceInfo, 56 @Inject('entity') protected entityValue: DeviceInfo,
@@ -80,6 +83,7 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { @@ -80,6 +83,7 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
80 name: [entity ? entity.name : '', [Validators.required]], 83 name: [entity ? entity.name : '', [Validators.required]],
81 deviceProfileId: [entity ? entity.deviceProfileId : null, [Validators.required]], 84 deviceProfileId: [entity ? entity.deviceProfileId : null, [Validators.required]],
82 firmwareId: [entity ? entity.firmwareId : null], 85 firmwareId: [entity ? entity.firmwareId : null],
  86 + softwareId: [entity ? entity.softwareId : null],
83 label: [entity ? entity.label : ''], 87 label: [entity ? entity.label : ''],
84 deviceData: [entity ? entity.deviceData : null, [Validators.required]], 88 deviceData: [entity ? entity.deviceData : null, [Validators.required]],
85 additionalInfo: this.fb.group( 89 additionalInfo: this.fb.group(
@@ -94,19 +98,19 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { @@ -94,19 +98,19 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
94 } 98 }
95 99
96 updateForm(entity: DeviceInfo) { 100 updateForm(entity: DeviceInfo) {
97 - this.entityForm.patchValue({name: entity.name});  
98 - this.entityForm.patchValue({deviceProfileId: entity.deviceProfileId});  
99 - this.entityForm.patchValue({firmwareId: entity.firmwareId});  
100 - this.entityForm.patchValue({label: entity.label});  
101 - this.entityForm.patchValue({deviceData: entity.deviceData});  
102 this.entityForm.patchValue({ 101 this.entityForm.patchValue({
103 - additionalInfo:  
104 - {  
105 - gateway: entity.additionalInfo ? entity.additionalInfo.gateway : false,  
106 - overwriteActivityTime: entity.additionalInfo ? entity.additionalInfo.overwriteActivityTime : false  
107 - } 102 + name: entity.name,
  103 + deviceProfileId: entity.deviceProfileId,
  104 + firmwareId: entity.firmwareId,
  105 + softwareId: entity.softwareId,
  106 + label: entity.label,
  107 + deviceData: entity.deviceData,
  108 + additionalInfo: {
  109 + gateway: entity.additionalInfo ? entity.additionalInfo.gateway : false,
  110 + overwriteActivityTime: entity.additionalInfo ? entity.additionalInfo.overwriteActivityTime : false,
  111 + description: entity.additionalInfo ? entity.additionalInfo.description : ''
  112 + }
108 }); 113 });
109 - this.entityForm.patchValue({additionalInfo: {description: entity.additionalInfo ? entity.additionalInfo.description : ''}});  
110 } 114 }
111 115
112 116
@@ -152,6 +156,10 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { @@ -152,6 +156,10 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
152 this.entityForm.markAsDirty(); 156 this.entityForm.markAsDirty();
153 } 157 }
154 } 158 }
  159 + this.entityForm.patchValue({
  160 + firmwareId: null,
  161 + softwareId: null
  162 + });
155 } 163 }
156 } 164 }
157 } 165 }
@@ -21,7 +21,12 @@ import { @@ -21,7 +21,12 @@ import {
21 EntityTableColumn, 21 EntityTableColumn,
22 EntityTableConfig 22 EntityTableConfig
23 } from '@home/models/entity/entities-table-config.models'; 23 } from '@home/models/entity/entities-table-config.models';
24 -import { Firmware, FirmwareInfo } from '@shared/models/firmware.models'; 24 +import {
  25 + ChecksumAlgorithmTranslationMap,
  26 + Firmware,
  27 + FirmwareInfo,
  28 + FirmwareTypeTranslationMap
  29 +} from '@shared/models/firmware.models';
25 import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; 30 import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models';
26 import { TranslateService } from '@ngx-translate/core'; 31 import { TranslateService } from '@ngx-translate/core';
27 import { DatePipe } from '@angular/common'; 32 import { DatePipe } from '@angular/common';
@@ -49,14 +54,17 @@ export class FirmwareTableConfigResolve implements Resolve<EntityTableConfig<Fir @@ -49,14 +54,17 @@ export class FirmwareTableConfigResolve implements Resolve<EntityTableConfig<Fir
49 54
50 this.config.columns.push( 55 this.config.columns.push(
51 new DateEntityTableColumn<FirmwareInfo>('createdTime', 'common.created-time', this.datePipe, '150px'), 56 new DateEntityTableColumn<FirmwareInfo>('createdTime', 'common.created-time', this.datePipe, '150px'),
52 - new EntityTableColumn<FirmwareInfo>('title', 'firmware.title', '33%'),  
53 - new EntityTableColumn<FirmwareInfo>('version', 'firmware.version', '33%'),  
54 - new EntityTableColumn<FirmwareInfo>('fileName', 'firmware.file-name', '33%'), 57 + new EntityTableColumn<FirmwareInfo>('title', 'firmware.title', '25%'),
  58 + new EntityTableColumn<FirmwareInfo>('version', 'firmware.version', '25%'),
  59 + new EntityTableColumn<FirmwareInfo>('type', 'firmware.type', '25%', entity => {
  60 + return this.translate.instant(FirmwareTypeTranslationMap.get(entity.type));
  61 + }),
  62 + new EntityTableColumn<FirmwareInfo>('fileName', 'firmware.file-name', '25%'),
55 new EntityTableColumn<FirmwareInfo>('dataSize', 'firmware.file-size', '70px', entity => { 63 new EntityTableColumn<FirmwareInfo>('dataSize', 'firmware.file-size', '70px', entity => {
56 return this.fileSize.transform(entity.dataSize || 0); 64 return this.fileSize.transform(entity.dataSize || 0);
57 }), 65 }),
58 new EntityTableColumn<FirmwareInfo>('checksum', 'firmware.checksum', '540px', entity => { 66 new EntityTableColumn<FirmwareInfo>('checksum', 'firmware.checksum', '540px', entity => {
59 - return `${entity.checksumAlgorithm}: ${entity.checksum}`; 67 + return `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}`;
60 }, () => ({}), false) 68 }, () => ({}), false)
61 ); 69 );
62 70
@@ -67,10 +67,27 @@ @@ -67,10 +67,27 @@
67 </mat-error> 67 </mat-error>
68 </mat-form-field> 68 </mat-form-field>
69 </div> 69 </div>
  70 + <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayout.xs="column">
  71 + <mat-form-field fxFlex="45">
  72 + <mat-label translate>firmware.type</mat-label>
  73 + <input *ngIf="!isAdd" matInput type="text" [readonly]="isEdit" [disabled]="!isEdit"
  74 + value="{{ firmwareTypeTranslationMap.get(entityForm.get('type').value) | translate }}">
  75 + <mat-select formControlName="type" required *ngIf="isAdd">
  76 + <mat-option *ngFor="let firmwareType of firmwareTypes" [value]="firmwareType">
  77 + {{ firmwareTypeTranslationMap.get(firmwareType) | translate }}
  78 + </mat-option>
  79 + </mat-select>
  80 + </mat-form-field>
  81 + <tb-device-profile-autocomplete
  82 + formControlName="deviceProfileId" fxFlex
  83 + [editProfileEnabled]="false">
  84 + </tb-device-profile-autocomplete>
  85 + </div>
70 <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column"> 86 <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column">
71 <mat-form-field class="mat-block" fxFlex="33"> 87 <mat-form-field class="mat-block" fxFlex="33">
72 <mat-label translate>firmware.checksum-algorithm</mat-label> 88 <mat-label translate>firmware.checksum-algorithm</mat-label>
73 - <input *ngIf="!isAdd" matInput formControlName="checksumAlgorithm" type="text" [readonly]="isEdit"> 89 + <input *ngIf="!isAdd" matInput type="text" [readonly]="isEdit" [disabled]="!isEdit"
  90 + value="{{ checksumAlgorithmTranslationMap.get(entityForm.get('checksumAlgorithm').value) | translate }}">
74 <mat-select formControlName="checksumAlgorithm" *ngIf="isAdd"> 91 <mat-select formControlName="checksumAlgorithm" *ngIf="isAdd">
75 <mat-option [value]=null></mat-option> 92 <mat-option [value]=null></mat-option>
76 <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm"> 93 <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm">
@@ -22,7 +22,13 @@ import { TranslateService } from '@ngx-translate/core'; @@ -22,7 +22,13 @@ import { TranslateService } from '@ngx-translate/core';
22 import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; 22 import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
23 import { FormBuilder, FormGroup, Validators } from '@angular/forms'; 23 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
24 import { EntityComponent } from '@home/components/entity/entity.component'; 24 import { EntityComponent } from '@home/components/entity/entity.component';
25 -import { ChecksumAlgorithm, ChecksumAlgorithmTranslationMap, Firmware } from '@shared/models/firmware.models'; 25 +import {
  26 + ChecksumAlgorithm,
  27 + ChecksumAlgorithmTranslationMap,
  28 + Firmware,
  29 + FirmwareType,
  30 + FirmwareTypeTranslationMap
  31 +} from '@shared/models/firmware.models';
26 import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; 32 import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
27 import { ActionNotificationShow } from '@core/notification/notification.actions'; 33 import { ActionNotificationShow } from '@core/notification/notification.actions';
28 34
@@ -36,6 +42,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI @@ -36,6 +42,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
36 42
37 checksumAlgorithms = Object.values(ChecksumAlgorithm); 43 checksumAlgorithms = Object.values(ChecksumAlgorithm);
38 checksumAlgorithmTranslationMap = ChecksumAlgorithmTranslationMap; 44 checksumAlgorithmTranslationMap = ChecksumAlgorithmTranslationMap;
  45 + firmwareTypes = Object.values(FirmwareType);
  46 + firmwareTypeTranslationMap = FirmwareTypeTranslationMap;
39 47
40 constructor(protected store: Store<AppState>, 48 constructor(protected store: Store<AppState>,
41 protected translate: TranslateService, 49 protected translate: TranslateService,
@@ -83,6 +91,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI @@ -83,6 +91,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
83 const form = this.fb.group({ 91 const form = this.fb.group({
84 title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], 92 title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]],
85 version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], 93 version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]],
  94 + type: [entity?.type ? entity.type : FirmwareType.FIRMWARE, [Validators.required]],
  95 + deviceProfileId: [entity ? entity.deviceProfileId : null],
86 checksumAlgorithm: [entity ? entity.checksumAlgorithm : null], 96 checksumAlgorithm: [entity ? entity.checksumAlgorithm : null],
87 checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], 97 checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)],
88 additionalInfo: this.fb.group( 98 additionalInfo: this.fb.group(
@@ -105,6 +115,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI @@ -105,6 +115,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
105 this.entityForm.patchValue({ 115 this.entityForm.patchValue({
106 title: entity.title, 116 title: entity.title,
107 version: entity.version, 117 version: entity.version,
  118 + type: entity.type,
  119 + deviceProfileId: entity.deviceProfileId,
108 checksumAlgorithm: entity.checksumAlgorithm, 120 checksumAlgorithm: entity.checksumAlgorithm,
109 checksum: entity.checksum, 121 checksum: entity.checksum,
110 fileName: entity.fileName, 122 fileName: entity.fileName,
@@ -37,11 +37,11 @@ @@ -37,11 +37,11 @@
37 <mat-option *ngIf="!(filteredFirmwares | async)?.length" [value]="null" class="tb-not-found"> 37 <mat-option *ngIf="!(filteredFirmwares | async)?.length" [value]="null" class="tb-not-found">
38 <div class="tb-not-found-content" (click)="$event.stopPropagation()"> 38 <div class="tb-not-found-content" (click)="$event.stopPropagation()">
39 <div *ngIf="!textIsNotEmpty(searchText); else searchNotEmpty"> 39 <div *ngIf="!textIsNotEmpty(searchText); else searchNotEmpty">
40 - <span translate>firmware.no-firmware-text</span> 40 + <span>{{ notFoundFirmware | translate }}</span>
41 </div> 41 </div>
42 <ng-template #searchNotEmpty> 42 <ng-template #searchNotEmpty>
43 <span> 43 <span>
44 - {{ translate.get('firmware.no-firmware-matching', 44 + {{ translate.get(notMatchingFirmware,
45 {entity: truncate.transform(searchText, true, 6, &apos;...&apos;)}) | async }} 45 {entity: truncate.transform(searchText, true, 6, &apos;...&apos;)}) | async }}
46 </span> 46 </span>
47 </ng-template> 47 </ng-template>
@@ -28,7 +28,7 @@ import { BaseData } from '@shared/models/base-data'; @@ -28,7 +28,7 @@ import { BaseData } from '@shared/models/base-data';
28 import { EntityService } from '@core/http/entity.service'; 28 import { EntityService } from '@core/http/entity.service';
29 import { TruncatePipe } from '@shared/pipe/truncate.pipe'; 29 import { TruncatePipe } from '@shared/pipe/truncate.pipe';
30 import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; 30 import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
31 -import { FirmwareInfo } from '@shared/models/firmware.models'; 31 +import { FirmwareInfo, FirmwareType } from '@shared/models/firmware.models';
32 import { FirmwareService } from '@core/http/firmware.service'; 32 import { FirmwareService } from '@core/http/firmware.service';
33 import { PageLink } from '@shared/models/page/page-link'; 33 import { PageLink } from '@shared/models/page/page-link';
34 import { Direction } from '@shared/models/page/sort-order'; 34 import { Direction } from '@shared/models/page/sort-order';
@@ -50,6 +50,12 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn @@ -50,6 +50,12 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
50 modelValue: string | null; 50 modelValue: string | null;
51 51
52 @Input() 52 @Input()
  53 + type = FirmwareType.FIRMWARE;
  54 +
  55 + @Input()
  56 + deviceProfileId: string;
  57 +
  58 + @Input()
53 labelText: string; 59 labelText: string;
54 60
55 @Input() 61 @Input()
@@ -81,6 +87,23 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn @@ -81,6 +87,23 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
81 87
82 private dirty = false; 88 private dirty = false;
83 89
  90 + private firmwareTypeTranslation = new Map<FirmwareType, any>(
  91 + [
  92 + [FirmwareType.FIRMWARE, {
  93 + label: 'firmware.firmware',
  94 + required: 'firmware.firmware-required',
  95 + noFound: 'firmware.no-firmware-text',
  96 + noMatching: 'firmware.no-firmware-matching'
  97 + }],
  98 + [FirmwareType.SOFTWARE, {
  99 + label: 'firmware.software',
  100 + required: 'firmware.software-required',
  101 + noFound: 'firmware.no-software-text',
  102 + noMatching: 'firmware.no-software-matching'
  103 + }]
  104 + ]
  105 + );
  106 +
84 private propagateChange = (v: any) => { }; 107 private propagateChange = (v: any) => { };
85 108
86 constructor(private store: Store<AppState>, 109 constructor(private store: Store<AppState>,
@@ -209,7 +232,8 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn @@ -209,7 +232,8 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
209 property: 'title', 232 property: 'title',
210 direction: Direction.ASC 233 direction: Direction.ASC
211 }); 234 });
212 - return this.firmwareService.getFirmwares(pageLink, true, {ignoreLoading: true}).pipe( 235 + return this.firmwareService.getFirmwaresInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type,
  236 + true, {ignoreLoading: true}).pipe(
213 map((data) => data && data.data.length ? data.data : null) 237 map((data) => data && data.data.length ? data.data : null)
214 ); 238 );
215 } 239 }
@@ -223,11 +247,19 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn @@ -223,11 +247,19 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
223 } 247 }
224 248
225 get placeholderText(): string { 249 get placeholderText(): string {
226 - return this.labelText || 'firmware.firmware'; 250 + return this.labelText || this.firmwareTypeTranslation.get(this.type).label;
227 } 251 }
228 252
229 get requiredErrorText(): string { 253 get requiredErrorText(): string {
230 - return this.requiredText || 'firmware.firmware-required'; 254 + return this.requiredText || this.firmwareTypeTranslation.get(this.type).required;
  255 + }
  256 +
  257 + get notFoundFirmware(): string {
  258 + return this.firmwareTypeTranslation.get(this.type).noFound;
  259 + }
  260 +
  261 + get notMatchingFirmware(): string {
  262 + return this.firmwareTypeTranslation.get(this.type).noMatching;
231 } 263 }
232 264
233 firmwareTitleText(firmware: FirmwareInfo): string { 265 firmwareTitleText(firmware: FirmwareInfo): string {
@@ -467,6 +467,7 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> { @@ -467,6 +467,7 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> {
467 defaultRuleChainId?: RuleChainId; 467 defaultRuleChainId?: RuleChainId;
468 defaultQueueName?: string; 468 defaultQueueName?: string;
469 firmwareId?: FirmwareId; 469 firmwareId?: FirmwareId;
  470 + softwareId?: FirmwareId;
470 profileData: DeviceProfileData; 471 profileData: DeviceProfileData;
471 } 472 }
472 473
@@ -522,6 +523,7 @@ export interface Device extends BaseData<DeviceId> { @@ -522,6 +523,7 @@ export interface Device extends BaseData<DeviceId> {
522 type: string; 523 type: string;
523 label: string; 524 label: string;
524 firmwareId?: FirmwareId; 525 firmwareId?: FirmwareId;
  526 + softwareId?: FirmwareId;
525 deviceProfileId?: DeviceProfileId; 527 deviceProfileId?: DeviceProfileId;
526 deviceData?: DeviceData; 528 deviceData?: DeviceData;
527 additionalInfo?: any; 529 additionalInfo?: any;
@@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
17 import { BaseData } from '@shared/models/base-data'; 17 import { BaseData } from '@shared/models/base-data';
18 import { TenantId } from '@shared/models/id/tenant-id'; 18 import { TenantId } from '@shared/models/id/tenant-id';
19 import { FirmwareId } from '@shared/models/id/firmware-id'; 19 import { FirmwareId } from '@shared/models/id/firmware-id';
  20 +import { DeviceProfileId } from '@shared/models/id/device-profile-id';
20 21
21 export enum ChecksumAlgorithm { 22 export enum ChecksumAlgorithm {
22 MD5 = 'md5', 23 MD5 = 'md5',
@@ -32,14 +33,28 @@ export const ChecksumAlgorithmTranslationMap = new Map<ChecksumAlgorithm, string @@ -32,14 +33,28 @@ export const ChecksumAlgorithmTranslationMap = new Map<ChecksumAlgorithm, string
32 ] 33 ]
33 ); 34 );
34 35
  36 +export enum FirmwareType {
  37 + FIRMWARE = 'FIRMWARE',
  38 + SOFTWARE = 'SOFTWARE'
  39 +}
  40 +
  41 +export const FirmwareTypeTranslationMap = new Map<FirmwareType, string>(
  42 + [
  43 + [FirmwareType.FIRMWARE, 'firmware.types.firmware'],
  44 + [FirmwareType.SOFTWARE, 'firmware.types.software']
  45 + ]
  46 +);
  47 +
35 export interface FirmwareInfo extends BaseData<FirmwareId> { 48 export interface FirmwareInfo extends BaseData<FirmwareId> {
36 tenantId?: TenantId; 49 tenantId?: TenantId;
  50 + type: FirmwareType;
  51 + deviceProfileId?: DeviceProfileId;
37 title?: string; 52 title?: string;
38 version?: string; 53 version?: string;
39 hasData?: boolean; 54 hasData?: boolean;
40 fileName: string; 55 fileName: string;
41 - checksum?: ChecksumAlgorithm;  
42 - checksumAlgorithm?: string; 56 + checksum?: string;
  57 + checksumAlgorithm?: ChecksumAlgorithm;
43 contentType: string; 58 contentType: string;
44 dataSize?: number; 59 dataSize?: number;
45 additionalInfo?: any; 60 additionalInfo?: any;
@@ -1928,6 +1928,8 @@ @@ -1928,6 +1928,8 @@
1928 "idCopiedMessage": "Firmware Id has been copied to clipboard", 1928 "idCopiedMessage": "Firmware Id has been copied to clipboard",
1929 "no-firmware-matching": "No firmware matching '{{entity}}' were found.", 1929 "no-firmware-matching": "No firmware matching '{{entity}}' were found.",
1930 "no-firmware-text": "No firmwares found", 1930 "no-firmware-text": "No firmwares found",
  1931 + "no-software-matching": "No sowtware matching '{{entity}}' were found.",
  1932 + "no-software-text": "No software found",
1931 "file-name": "File name", 1933 "file-name": "File name",
1932 "file-size": "File size", 1934 "file-size": "File size",
1933 "file-size-bytes": "File size in bytes", 1935 "file-size-bytes": "File size in bytes",
@@ -1936,8 +1938,15 @@ @@ -1936,8 +1938,15 @@
1936 "firmware-required": "Firmware is required.", 1938 "firmware-required": "Firmware is required.",
1937 "search": "Search firmwares", 1939 "search": "Search firmwares",
1938 "selected-firmware": "{ count, plural, 1 {1 firmware} other {# firmwares} } selected", 1940 "selected-firmware": "{ count, plural, 1 {1 firmware} other {# firmwares} } selected",
  1941 + "software": "Software",
  1942 + "software-required": "Software is required.",
1939 "title": "Title", 1943 "title": "Title",
1940 "title-required": "Title is required.", 1944 "title-required": "Title is required.",
  1945 + "type": "Firmware type",
  1946 + "types": {
  1947 + "firmware": "Firmware",
  1948 + "software": "Software"
  1949 + },
1941 "version": "Version", 1950 "version": "Version",
1942 "version-required": "Version is required.", 1951 "version-required": "Version is required.",
1943 "warning-after-save-no-edit": "Once the firmware is saved, it will not be possible to change the title and version fields." 1952 "warning-after-save-no-edit": "Once the firmware is saved, it will not be possible to change the title and version fields."