Commit 874f5e84485ec6cc1f41e2a4f625fc9dc3c66d0b

Authored by Vladyslav_Prykhodko
1 parent a7239c9d

UI: Rename firmware to OtaPackage

Showing 25 changed files with 356 additions and 328 deletions
... ... @@ -75,12 +75,12 @@ import {
75 75 StringOperation
76 76 } from '@shared/models/query/query.models';
77 77 import { alarmFields } from '@shared/models/alarm.models';
78   -import { FirmwareService } from '@core/http/firmware.service';
79   -import { EdgeService } from "@core/http/edge.service";
  78 +import { OtaPackageService } from '@core/http/ota-package.service';
  79 +import { EdgeService } from '@core/http/edge.service';
80 80 import { Edge, EdgeEventType } from '@shared/models/edge.models';
81   -import { RuleChainType } from "@shared/models/rule-chain.models";
82   -import { WidgetService } from "@core/http/widget.service";
83   -import { DeviceProfileService } from "@core/http/device-profile.service";
  81 +import { RuleChainType } from '@shared/models/rule-chain.models';
  82 +import { WidgetService } from '@core/http/widget.service';
  83 +import { DeviceProfileService } from '@core/http/device-profile.service';
84 84
85 85 @Injectable({
86 86 providedIn: 'root'
... ... @@ -101,7 +101,7 @@ export class EntityService {
101 101 private dashboardService: DashboardService,
102 102 private entityRelationService: EntityRelationService,
103 103 private attributeService: AttributeService,
104   - private firmwareService: FirmwareService,
  104 + private otaPackageService: OtaPackageService,
105 105 private widgetService: WidgetService,
106 106 private deviceProfileService: DeviceProfileService,
107 107 private utils: UtilsService
... ... @@ -142,8 +142,8 @@ export class EntityService {
142 142 case EntityType.ALARM:
143 143 console.error('Get Alarm Entity is not implemented!');
144 144 break;
145   - case EntityType.FIRMWARE:
146   - observable = this.firmwareService.getFirmwareInfo(entityId, config);
  145 + case EntityType.OTA_PACKAGE:
  146 + observable = this.otaPackageService.getOtaPackageInfo(entityId, config);
147 147 break;
148 148 }
149 149 return observable;
... ... @@ -359,9 +359,9 @@ export class EntityService {
359 359 case EntityType.ALARM:
360 360 console.error('Get Alarm Entities is not implemented!');
361 361 break;
362   - case EntityType.FIRMWARE:
  362 + case EntityType.OTA_PACKAGE:
363 363 pageLink.sortOrder.property = 'title';
364   - entitiesObservable = this.firmwareService.getFirmwares(pageLink, config);
  364 + entitiesObservable = this.otaPackageService.getOtaPackages(pageLink, config);
365 365 break;
366 366 }
367 367 return entitiesObservable;
... ...
ui-ngx/src/app/core/http/ota-package.service.ts renamed from ui-ngx/src/app/core/http/firmware.service.ts
... ... @@ -20,40 +20,40 @@ import { PageLink } from '@shared/models/page/page-link';
20 20 import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils';
21 21 import { Observable } from 'rxjs';
22 22 import { PageData } from '@shared/models/page/page-data';
23   -import { ChecksumAlgorithm, Firmware, FirmwareInfo, FirmwareType } from '@shared/models/firmware.models';
  23 +import { ChecksumAlgorithm, OtaPackage, OtaPackageInfo, OtaUpdateType } from '@shared/models/ota-package.models';
24 24 import { catchError, map, mergeMap } from 'rxjs/operators';
25 25 import { deepClone } from '@core/utils';
26 26
27 27 @Injectable({
28 28 providedIn: 'root'
29 29 })
30   -export class FirmwareService {
  30 +export class OtaPackageService {
31 31 constructor(
32 32 private http: HttpClient
33 33 ) {
34 34
35 35 }
36 36
37   - public getFirmwares(pageLink: PageLink, config?: RequestConfig): Observable<PageData<FirmwareInfo>> {
38   - return this.http.get<PageData<FirmwareInfo>>(`/api/firmwares${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config));
  37 + public getOtaPackages(pageLink: PageLink, config?: RequestConfig): Observable<PageData<OtaPackageInfo>> {
  38 + return this.http.get<PageData<OtaPackageInfo>>(`/api/otaPackages${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config));
39 39 }
40 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()}`;
44   - return this.http.get<PageData<FirmwareInfo>>(url, defaultHttpOptionsFromConfig(config));
  41 + public getOtaPackagesInfoByDeviceProfileId(pageLink: PageLink, deviceProfileId: string, type: OtaUpdateType,
  42 + hasData = true, config?: RequestConfig): Observable<PageData<OtaPackageInfo>> {
  43 + const url = `/api/otaPackages/${deviceProfileId}/${type}/${hasData}${pageLink.toQuery()}`;
  44 + return this.http.get<PageData<OtaPackageInfo>>(url, defaultHttpOptionsFromConfig(config));
45 45 }
46 46
47   - public getFirmware(firmwareId: string, config?: RequestConfig): Observable<Firmware> {
48   - return this.http.get<Firmware>(`/api/firmware/${firmwareId}`, defaultHttpOptionsFromConfig(config));
  47 + public getOtaPackage(otaPackageId: string, config?: RequestConfig): Observable<OtaPackage> {
  48 + return this.http.get<OtaPackage>(`/api/otaPackages/${otaPackageId}`, defaultHttpOptionsFromConfig(config));
49 49 }
50 50
51   - public getFirmwareInfo(firmwareId: string, config?: RequestConfig): Observable<FirmwareInfo> {
52   - return this.http.get<FirmwareInfo>(`/api/firmware/info/${firmwareId}`, defaultHttpOptionsFromConfig(config));
  51 + public getOtaPackageInfo(otaPackageId: string, config?: RequestConfig): Observable<OtaPackageInfo> {
  52 + return this.http.get<OtaPackageInfo>(`/api/otaPackage/info/${otaPackageId}`, defaultHttpOptionsFromConfig(config));
53 53 }
54 54
55   - public downloadFirmware(firmwareId: string): Observable<any> {
56   - return this.http.get(`/api/firmware/${firmwareId}/download`, { responseType: 'arraybuffer', observe: 'response' }).pipe(
  55 + public downloadOtaPackage(otaPackageId: string): Observable<any> {
  56 + return this.http.get(`/api/otaPackage/${otaPackageId}/download`, { responseType: 'arraybuffer', observe: 'response' }).pipe(
57 57 map((response) => {
58 58 const headers = response.headers;
59 59 const filename = headers.get('x-filename');
... ... @@ -80,35 +80,35 @@ export class FirmwareService {
80 80 );
81 81 }
82 82
83   - public saveFirmware(firmware: Firmware, config?: RequestConfig): Observable<Firmware> {
84   - if (!firmware.file) {
85   - return this.saveFirmwareInfo(firmware, config);
  83 + public saveOtaPackage(otaPackage: OtaPackage, config?: RequestConfig): Observable<OtaPackage> {
  84 + if (!otaPackage.file) {
  85 + return this.saveOtaPackageInfo(otaPackage, config);
86 86 }
87   - const firmwareInfo = deepClone(firmware);
88   - delete firmwareInfo.file;
89   - delete firmwareInfo.checksum;
90   - delete firmwareInfo.checksumAlgorithm;
91   - return this.saveFirmwareInfo(firmwareInfo, config).pipe(
  87 + const otaPackageInfo = deepClone(otaPackage);
  88 + delete otaPackageInfo.file;
  89 + delete otaPackageInfo.checksum;
  90 + delete otaPackageInfo.checksumAlgorithm;
  91 + return this.saveOtaPackageInfo(otaPackageInfo, config).pipe(
92 92 mergeMap(res => {
93   - return this.uploadFirmwareFile(res.id.id, firmware.file, firmware.checksumAlgorithm, firmware.checksum).pipe(
94   - catchError(() => this.deleteFirmware(res.id.id))
  93 + return this.uploadOtaPackageFile(res.id.id, otaPackage.file, otaPackage.checksumAlgorithm, otaPackage.checksum).pipe(
  94 + catchError(() => this.deleteOtaPackage(res.id.id))
95 95 );
96 96 })
97 97 );
98 98 }
99 99
100   - public saveFirmwareInfo(firmware: FirmwareInfo, config?: RequestConfig): Observable<Firmware> {
101   - return this.http.post<Firmware>('/api/firmware', firmware, defaultHttpOptionsFromConfig(config));
  100 + public saveOtaPackageInfo(otaPackageInfo: OtaPackageInfo, config?: RequestConfig): Observable<OtaPackage> {
  101 + return this.http.post<OtaPackage>('/api/otaPackage', otaPackageInfo, defaultHttpOptionsFromConfig(config));
102 102 }
103 103
104   - public uploadFirmwareFile(firmwareId: string, file: File, checksumAlgorithm: ChecksumAlgorithm,
105   - checksum?: string, config?: RequestConfig): Observable<any> {
  104 + public uploadOtaPackageFile(otaPackageId: string, file: File, checksumAlgorithm: ChecksumAlgorithm,
  105 + checksum?: string, config?: RequestConfig): Observable<any> {
106 106 if (!config) {
107 107 config = {};
108 108 }
109 109 const formData = new FormData();
110 110 formData.append('file', file);
111   - let url = `/api/firmware/${firmwareId}?checksumAlgorithm=${checksumAlgorithm}`;
  111 + let url = `/api/otaPackage/${otaPackageId}?checksumAlgorithm=${checksumAlgorithm}`;
112 112 if (checksum) {
113 113 url += `&checksum=${checksum}`;
114 114 }
... ... @@ -116,8 +116,8 @@ export class FirmwareService {
116 116 defaultHttpUploadOptions(config.ignoreLoading, config.ignoreErrors, config.resendRequest));
117 117 }
118 118
119   - public deleteFirmware(firmwareId: string, config?: RequestConfig) {
120   - return this.http.delete(`/api/firmware/${firmwareId}`, defaultHttpOptionsFromConfig(config));
  119 + public deleteOtaPackage(otaPackageId: string, config?: RequestConfig) {
  120 + return this.http.delete(`/api/otaPackage/${otaPackageId}`, defaultHttpOptionsFromConfig(config));
121 121 }
122 122
123 123 }
... ...
... ... @@ -276,9 +276,9 @@ export class MenuService {
276 276 },
277 277 {
278 278 id: guid(),
279   - name: 'firmware.firmware',
  279 + name: 'ota-update.ota-updates',
280 280 type: 'link',
281   - path: '/firmwares',
  281 + path: '/otaUpdates',
282 282 icon: 'memory'
283 283 },
284 284 {
... ... @@ -423,9 +423,9 @@ export class MenuService {
423 423 path: '/deviceProfiles'
424 424 },
425 425 {
426   - name: 'firmware.firmware',
  426 + name: 'ota-update.ota-updates',
427 427 icon: 'memory',
428   - path: '/firmwares'
  428 + path: '/otaUpdates'
429 429 }
430 430 ]
431 431 },
... ...
... ... @@ -66,4 +66,5 @@
66 66 <mat-error *ngIf="selectDeviceProfileFormGroup.get('deviceProfile').hasError('required')">
67 67 {{ 'device-profile.device-profile-required' | translate }}
68 68 </mat-error>
  69 + <mat-hint *ngIf="!!hint">{{ hint | translate }}</mat-hint>
69 70 </mat-form-field>
... ...
... ... @@ -91,6 +91,9 @@ export class DeviceProfileAutocompleteComponent implements ControlValueAccessor,
91 91 @Input()
92 92 disabled: boolean;
93 93
  94 + @Input()
  95 + hint: string;
  96 +
94 97 @Output()
95 98 deviceProfileUpdated = new EventEmitter<DeviceProfileId>();
96 99
... ...
... ... @@ -67,18 +67,18 @@
67 67 [queueType]="serviceType"
68 68 formControlName="defaultQueueName">
69 69 </tb-queue-type-list>
70   - <tb-firmware-autocomplete
  70 + <tb-ota-package-autocomplete
71 71 [useFullEntityId]="true"
72   - [type]="firmwareTypes.FIRMWARE"
  72 + [type]="otaUpdateType.FIRMWARE"
73 73 [deviceProfileId]="deviceProfileId?.id"
74 74 formControlName="firmwareId">
75   - </tb-firmware-autocomplete>
76   - <tb-firmware-autocomplete
  75 + </tb-ota-package-autocomplete>
  76 + <tb-ota-package-autocomplete
77 77 [useFullEntityId]="true"
78   - [type]="firmwareTypes.SOFTWARE"
  78 + [type]="otaUpdateType.SOFTWARE"
79 79 [deviceProfileId]="deviceProfileId?.id"
80 80 formControlName="softwareId">
81   - </tb-firmware-autocomplete>
  81 + </tb-ota-package-autocomplete>
82 82 <mat-form-field fxHide class="mat-block">
83 83 <mat-label translate>device-profile.type</mat-label>
84 84 <mat-select formControlName="type" required>
... ...
... ... @@ -40,7 +40,7 @@ import { EntityType } from '@shared/models/entity-type.models';
40 40 import { RuleChainId } from '@shared/models/id/rule-chain-id';
41 41 import { ServiceType } from '@shared/models/queue.models';
42 42 import { EntityId } from '@shared/models/id/entity-id';
43   -import { FirmwareType } from '@shared/models/firmware.models';
  43 +import { OtaUpdateType } from '@shared/models/ota-package.models';
44 44 import { DashboardId } from '@shared/models/id/dashboard-id';
45 45
46 46 @Component({
... ... @@ -71,7 +71,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
71 71
72 72 deviceProfileId: EntityId;
73 73
74   - firmwareTypes = FirmwareType;
  74 + otaUpdateType = OtaUpdateType;
75 75
76 76 constructor(protected store: Store<AppState>,
77 77 protected translate: TranslateService,
... ...
... ... @@ -35,7 +35,7 @@ import { Router } from '@angular/router';
35 35 import { BroadcastService } from '@core/services/broadcast.service';
36 36 import { ImportExportService } from '@home/components/import-export/import-export.service';
37 37 import { DeviceProfileService } from '@core/http/device-profile.service';
38   -import { FirmwareService } from '@core/http/firmware.service';
  38 +import { OtaPackageService } from '@core/http/ota-package.service';
39 39
40 40 export const ServicesMap = new Map<string, Type<any>>(
41 41 [
... ... @@ -59,6 +59,6 @@ export const ServicesMap = new Map<string, Type<any>>(
59 59 ['router', Router],
60 60 ['importExport', ImportExportService],
61 61 ['deviceProfileService', DeviceProfileService],
62   - ['firmwareService', FirmwareService]
  62 + ['otaPackageService', OtaPackageService]
63 63 ]
64 64 );
... ...
... ... @@ -101,18 +101,18 @@
101 101 <mat-label translate>device.label</mat-label>
102 102 <input matInput formControlName="label">
103 103 </mat-form-field>
104   - <tb-firmware-autocomplete
  104 + <tb-ota-package-autocomplete
105 105 [useFullEntityId]="true"
106   - [type]="firmwareTypes.FIRMWARE"
  106 + [type]="otaUpdateType.FIRMWARE"
107 107 [deviceProfileId]="entityForm.get('deviceProfileId').value?.id"
108 108 formControlName="firmwareId">
109   - </tb-firmware-autocomplete>
110   - <tb-firmware-autocomplete
  109 + </tb-ota-package-autocomplete>
  110 + <tb-ota-package-autocomplete
111 111 [useFullEntityId]="true"
112   - [type]="firmwareTypes.SOFTWARE"
  112 + [type]="otaUpdateType.SOFTWARE"
113 113 [deviceProfileId]="entityForm.get('deviceProfileId').value?.id"
114 114 formControlName="softwareId">
115   - </tb-firmware-autocomplete>
  115 + </tb-ota-package-autocomplete>
116 116 <tb-device-data
117 117 formControlName="deviceData"
118 118 required>
... ...
... ... @@ -34,7 +34,7 @@ import { ActionNotificationShow } from '@core/notification/notification.actions'
34 34 import { TranslateService } from '@ngx-translate/core';
35 35 import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
36 36 import { Subject } from 'rxjs';
37   -import { FirmwareType } from '@shared/models/firmware.models';
  37 +import { OtaUpdateType } from '@shared/models/ota-package.models';
38 38
39 39 @Component({
40 40 selector: 'tb-device',
... ... @@ -49,7 +49,7 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
49 49
50 50 deviceScope: 'tenant' | 'customer' | 'customer_user' | 'edge';
51 51
52   - firmwareTypes = FirmwareType;
  52 + otaUpdateType = OtaUpdateType;
53 53
54 54 constructor(protected store: Store<AppState>,
55 55 protected translate: TranslateService,
... ...
... ... @@ -35,7 +35,7 @@ import { modulesMap } from '../../common/modules-map';
35 35 import { DeviceProfileModule } from './device-profile/device-profile.module';
36 36 import { ApiUsageModule } from '@home/pages/api-usage/api-usage.module';
37 37 import { EdgeModule } from '@home/pages/edge/edge.module';
38   -import { FirmwareModule } from '@home/pages/firmware/firmware.module';
  38 +import { OtaUpdateModule } from '@home/pages/ota-update/ota-update.module';
39 39
40 40 @NgModule({
41 41 exports: [
... ... @@ -55,7 +55,7 @@ import { FirmwareModule } from '@home/pages/firmware/firmware.module';
55 55 DashboardModule,
56 56 AuditLogModule,
57 57 ApiUsageModule,
58   - FirmwareModule,
  58 + OtaUpdateModule,
59 59 UserModule
60 60 ],
61 61 providers: [
... ...
ui-ngx/src/app/modules/home/pages/ota-update/ota-update-routing.module.ts renamed from ui-ngx/src/app/modules/home/pages/firmware/firmware-routing.module.ts
... ... @@ -18,22 +18,22 @@ import { RouterModule, Routes } from '@angular/router';
18 18 import { EntitiesTableComponent } from '@home/components/entity/entities-table.component';
19 19 import { Authority } from '@shared/models/authority.enum';
20 20 import { NgModule } from '@angular/core';
21   -import { FirmwareTableConfigResolve } from '@home/pages/firmware/firmware-table-config.resolve';
  21 +import { OtaUpdateTableConfigResolve } from '@home/pages/ota-update/ota-update-table-config.resolve';
22 22
23 23 const routes: Routes = [
24 24 {
25   - path: 'firmwares',
  25 + path: 'otaUpdates',
26 26 component: EntitiesTableComponent,
27 27 data: {
28 28 auth: [Authority.TENANT_ADMIN],
29   - title: 'firmware.firmware',
  29 + title: 'ota-update.ota-updates',
30 30 breadcrumb: {
31   - label: 'firmware.firmware',
  31 + label: 'ota-update.ota-updates',
32 32 icon: 'memory'
33 33 }
34 34 },
35 35 resolve: {
36   - entitiesTableConfig: FirmwareTableConfigResolve
  36 + entitiesTableConfig: OtaUpdateTableConfigResolve
37 37 }
38 38 }
39 39 ];
... ... @@ -42,7 +42,7 @@ const routes: Routes = [
42 42 imports: [RouterModule.forChild(routes)],
43 43 exports: [RouterModule],
44 44 providers: [
45   - FirmwareTableConfigResolve
  45 + OtaUpdateTableConfigResolve
46 46 ]
47 47 })
48   -export class FirmwareRoutingModule{ }
  48 +export class OtaUpdateRoutingModule { }
... ...
ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts renamed from ui-ngx/src/app/modules/home/pages/firmware/firmware-table-config.resolve.ts
... ... @@ -23,90 +23,91 @@ import {
23 23 } from '@home/models/entity/entities-table-config.models';
24 24 import {
25 25 ChecksumAlgorithmTranslationMap,
26   - Firmware,
27   - FirmwareInfo,
28   - FirmwareTypeTranslationMap
29   -} from '@shared/models/firmware.models';
  26 + OtaPackage,
  27 + OtaPackageInfo,
  28 + OtaUpdateTypeTranslationMap
  29 +} from '@shared/models/ota-package.models';
30 30 import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models';
31 31 import { TranslateService } from '@ngx-translate/core';
32 32 import { DatePipe } from '@angular/common';
33   -import { FirmwareService } from '@core/http/firmware.service';
  33 +import { OtaPackageService } from '@core/http/ota-package.service';
34 34 import { PageLink } from '@shared/models/page/page-link';
35   -import { FirmwaresComponent } from '@home/pages/firmware/firmwares.component';
  35 +import { OtaUpdateComponent } from '@home/pages/ota-update/ota-update.component';
36 36 import { EntityAction } from '@home/models/entity/entity-component.models';
37 37 import { FileSizePipe } from '@shared/pipe/file-size.pipe';
38 38
39 39 @Injectable()
40   -export class FirmwareTableConfigResolve implements Resolve<EntityTableConfig<Firmware, PageLink, FirmwareInfo>> {
  40 +export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<OtaPackage, PageLink, OtaPackageInfo>> {
41 41
42   - private readonly config: EntityTableConfig<Firmware, PageLink, FirmwareInfo> = new EntityTableConfig<Firmware, PageLink, FirmwareInfo>();
  42 + private readonly config: EntityTableConfig<OtaPackage, PageLink, OtaPackageInfo> =
  43 + new EntityTableConfig<OtaPackage, PageLink, OtaPackageInfo>();
43 44
44 45 constructor(private translate: TranslateService,
45 46 private datePipe: DatePipe,
46   - private firmwareService: FirmwareService,
  47 + private otaPackageService: OtaPackageService,
47 48 private fileSize: FileSizePipe) {
48   - this.config.entityType = EntityType.FIRMWARE;
49   - this.config.entityComponent = FirmwaresComponent;
50   - this.config.entityTranslations = entityTypeTranslations.get(EntityType.FIRMWARE);
51   - this.config.entityResources = entityTypeResources.get(EntityType.FIRMWARE);
  49 + this.config.entityType = EntityType.OTA_PACKAGE;
  50 + this.config.entityComponent = OtaUpdateComponent;
  51 + this.config.entityTranslations = entityTypeTranslations.get(EntityType.OTA_PACKAGE);
  52 + this.config.entityResources = entityTypeResources.get(EntityType.OTA_PACKAGE);
52 53
53   - this.config.entityTitle = (firmware) => firmware ? firmware.title : '';
  54 + this.config.entityTitle = (otaPackage) => otaPackage ? otaPackage.title : '';
54 55
55 56 this.config.columns.push(
56   - new DateEntityTableColumn<FirmwareInfo>('createdTime', 'common.created-time', this.datePipe, '150px'),
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));
  57 + new DateEntityTableColumn<OtaPackageInfo>('createdTime', 'common.created-time', this.datePipe, '150px'),
  58 + new EntityTableColumn<OtaPackageInfo>('title', 'ota-update.title', '25%'),
  59 + new EntityTableColumn<OtaPackageInfo>('version', 'ota-update.version', '25%'),
  60 + new EntityTableColumn<OtaPackageInfo>('type', 'ota-update.package-type', '25%', entity => {
  61 + return this.translate.instant(OtaUpdateTypeTranslationMap.get(entity.type));
61 62 }),
62   - new EntityTableColumn<FirmwareInfo>('fileName', 'firmware.file-name', '25%'),
63   - new EntityTableColumn<FirmwareInfo>('dataSize', 'firmware.file-size', '70px', entity => {
  63 + new EntityTableColumn<OtaPackageInfo>('fileName', 'ota-update.file-name', '25%'),
  64 + new EntityTableColumn<OtaPackageInfo>('dataSize', 'ota-update.file-size', '70px', entity => {
64 65 return this.fileSize.transform(entity.dataSize || 0);
65 66 }),
66   - new EntityTableColumn<FirmwareInfo>('checksum', 'firmware.checksum', '540px', entity => {
  67 + new EntityTableColumn<OtaPackageInfo>('checksum', 'ota-update.checksum', '540px', entity => {
67 68 return `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}`;
68 69 }, () => ({}), false)
69 70 );
70 71
71 72 this.config.cellActionDescriptors.push(
72 73 {
73   - name: this.translate.instant('firmware.download'),
  74 + name: this.translate.instant('ota-update.download'),
74 75 icon: 'file_download',
75   - isEnabled: (firmware) => firmware.hasData,
76   - onAction: ($event, entity) => this.exportFirmware($event, entity)
  76 + isEnabled: (otaPackage) => otaPackage.hasData,
  77 + onAction: ($event, entity) => this.exportPackage($event, entity)
77 78 }
78 79 );
79 80
80   - this.config.deleteEntityTitle = firmware => this.translate.instant('firmware.delete-firmware-title',
81   - { firmwareTitle: firmware.title });
82   - this.config.deleteEntityContent = () => this.translate.instant('firmware.delete-firmware-text');
83   - this.config.deleteEntitiesTitle = count => this.translate.instant('firmware.delete-firmwares-title', {count});
84   - this.config.deleteEntitiesContent = () => this.translate.instant('firmware.delete-firmwares-text');
  81 + this.config.deleteEntityTitle = otaPackage => this.translate.instant('ota-update.delete-ota-update-title',
  82 + { title: otaPackage.title });
  83 + this.config.deleteEntityContent = () => this.translate.instant('ota-update.delete-ota-update-text');
  84 + this.config.deleteEntitiesTitle = count => this.translate.instant('ota-update.delete-ota-updates-title', {count});
  85 + this.config.deleteEntitiesContent = () => this.translate.instant('ota-update.delete-ota-updates-text');
85 86
86   - this.config.entitiesFetchFunction = pageLink => this.firmwareService.getFirmwares(pageLink);
87   - this.config.loadEntity = id => this.firmwareService.getFirmwareInfo(id.id);
88   - this.config.saveEntity = firmware => this.firmwareService.saveFirmware(firmware);
89   - this.config.deleteEntity = id => this.firmwareService.deleteFirmware(id.id);
  87 + this.config.entitiesFetchFunction = pageLink => this.otaPackageService.getOtaPackages(pageLink);
  88 + this.config.loadEntity = id => this.otaPackageService.getOtaPackageInfo(id.id);
  89 + this.config.saveEntity = otaPackage => this.otaPackageService.saveOtaPackage(otaPackage);
  90 + this.config.deleteEntity = id => this.otaPackageService.deleteOtaPackage(id.id);
90 91
91   - this.config.onEntityAction = action => this.onFirmwareAction(action);
  92 + this.config.onEntityAction = action => this.onPackageAction(action);
92 93 }
93 94
94   - resolve(): EntityTableConfig<Firmware, PageLink, FirmwareInfo> {
95   - this.config.tableTitle = this.translate.instant('firmware.firmware');
  95 + resolve(): EntityTableConfig<OtaPackage, PageLink, OtaPackageInfo> {
  96 + this.config.tableTitle = this.translate.instant('ota-update.packages-repository');
96 97 return this.config;
97 98 }
98 99
99   - exportFirmware($event: Event, firmware: FirmwareInfo) {
  100 + exportPackage($event: Event, otaPackageInfo: OtaPackageInfo) {
100 101 if ($event) {
101 102 $event.stopPropagation();
102 103 }
103   - this.firmwareService.downloadFirmware(firmware.id.id).subscribe();
  104 + this.otaPackageService.downloadOtaPackage(otaPackageInfo.id.id).subscribe();
104 105 }
105 106
106   - onFirmwareAction(action: EntityAction<FirmwareInfo>): boolean {
  107 + onPackageAction(action: EntityAction<OtaPackageInfo>): boolean {
107 108 switch (action.action) {
108   - case 'uploadFirmware':
109   - this.exportFirmware(action.event, action.entity);
  109 + case 'uploadPackage':
  110 + this.exportPackage(action.event, action.entity);
110 111 return true;
111 112 }
112 113 return false;
... ...
ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.html renamed from ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html
... ... @@ -18,114 +18,112 @@
18 18 <div class="tb-details-buttons" fxLayout.xs="column">
19 19 <button mat-raised-button color="primary" fxFlex.xs
20 20 [disabled]="(isLoading$ | async) || !entity?.hasData"
21   - (click)="onEntityAction($event, 'uploadFirmware')"
  21 + (click)="onEntityAction($event, 'uploadPackage')"
22 22 [fxShow]="!isEdit">
23   - {{ 'firmware.download' | translate }}
  23 + {{ 'ota-update.download' | translate }}
24 24 </button>
25 25 <button mat-raised-button color="primary" fxFlex.xs
26 26 [disabled]="(isLoading$ | async)"
27 27 (click)="onEntityAction($event, 'delete')"
28 28 [fxShow]="!hideDelete() && !isEdit">
29   - {{ 'firmware.delete' | translate }}
  29 + {{ 'ota-update.delete' | translate }}
30 30 </button>
31 31 <div fxLayout="row" fxLayout.xs="column">
32 32 <button mat-raised-button
33 33 ngxClipboard
34   - (cbOnSuccess)="onFirmwareIdCopied()"
  34 + (cbOnSuccess)="onPackageIdCopied()"
35 35 [cbContent]="entity?.id?.id"
36 36 [fxShow]="!isEdit">
37 37 <mat-icon svgIcon="mdi:clipboard-arrow-left"></mat-icon>
38   - <span translate>firmware.copyId</span>
  38 + <span translate>ota-update.copyId</span>
39 39 </button>
40 40 <button mat-raised-button
41 41 ngxClipboard
42   - (cbOnSuccess)="onFirmwareChecksumCopied()"
  42 + (cbOnSuccess)="onPackageChecksumCopied()"
43 43 [cbContent]="entity?.checksum"
44 44 [fxShow]="!isEdit">
45 45 <mat-icon svgIcon="mdi:clipboard-arrow-left"></mat-icon>
46   - <span translate>firmware.copy-checksum</span>
  46 + <span translate>ota-update.copy-checksum</span>
47 47 </button>
48 48 </div>
49 49 </div>
50   -<div class="mat-padding" fxLayout="column">
  50 +<div class="mat-padding" fxLayout="column" fxLayoutGap="8px">
51 51 <form [formGroup]="entityForm">
52   - <fieldset [disabled]="(isLoading$ | async) || !isEdit">
53   - <mat-hint class="tb-hint" translate *ngIf="isAdd">firmware.warning-after-save-no-edit</mat-hint>
  52 + <fieldset [disabled]="(isLoading$ | async) || !isEdit" fxLayout="column" fxLayoutGap="8px">
54 53 <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayout.xs="column">
55 54 <mat-form-field class="mat-block" fxFlex="45">
56   - <mat-label translate>firmware.title</mat-label>
  55 + <mat-label translate>ota-update.title</mat-label>
57 56 <input matInput formControlName="title" type="text" required [readonly]="!isAdd">
58 57 <mat-error *ngIf="entityForm.get('title').hasError('required')">
59   - {{ 'firmware.title-required' | translate }}
  58 + {{ 'ota-update.title-required' | translate }}
60 59 </mat-error>
61 60 </mat-form-field>
62 61 <mat-form-field class="mat-block" fxFlex>
63   - <mat-label translate>firmware.version</mat-label>
  62 + <mat-label translate>ota-update.version</mat-label>
64 63 <input matInput formControlName="version" type="text" required [readonly]="!isAdd">
65 64 <mat-error *ngIf="entityForm.get('version').hasError('required')">
66   - {{ 'firmware.version-required' | translate }}
  65 + {{ 'ota-update.version-required' | translate }}
67 66 </mat-error>
68 67 </mat-form-field>
69 68 </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>
  69 + <tb-device-profile-autocomplete
  70 + formControlName="deviceProfileId"
  71 + required
  72 + [hint]="'ota-update.chose-compatible-device-profile'"
  73 + [editProfileEnabled]="false"
  74 + [addNewProfile]="false"
  75 + [selectDefaultProfile]="true">
  76 + </tb-device-profile-autocomplete>
  77 + <mat-form-field class="mat-block">
  78 + <mat-label translate>ota-update.package-type</mat-label>
  79 + <mat-select formControlName="type" required>
  80 + <mat-option *ngFor="let packageType of packageTypes" [value]="packageType">
  81 + {{ otaUpdateTypeTranslationMap.get(packageType) | translate }}
  82 + </mat-option>
  83 + </mat-select>
  84 + </mat-form-field>
  85 + <div class="mat-caption" translate *ngIf="isAdd">ota-update.warning-after-save-no-edit</div>
86 86 <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column">
87 87 <mat-form-field class="mat-block" fxFlex="33">
88   - <mat-label translate>firmware.checksum-algorithm</mat-label>
89   - <input *ngIf="!isAdd" matInput type="text" [readonly]="isEdit" [disabled]="!isEdit"
90   - value="{{ checksumAlgorithmTranslationMap.get(entityForm.get('checksumAlgorithm').value) | translate }}">
91   - <mat-select formControlName="checksumAlgorithm" *ngIf="isAdd">
  88 + <mat-label translate>ota-update.checksum-algorithm</mat-label>
  89 + <mat-select formControlName="checksumAlgorithm">
92 90 <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm">
93 91 {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }}
94 92 </mat-option>
95 93 </mat-select>
96 94 </mat-form-field>
97 95 <mat-form-field class="mat-block" fxFlex>
98   - <mat-label translate>firmware.checksum</mat-label>
  96 + <mat-label translate>ota-update.checksum</mat-label>
99 97 <input matInput formControlName="checksum" type="text" [readonly]="!isAdd">
100 98 </mat-form-field>
101 99 </div>
102   - <section *ngIf="isAdd" style="padding-top: 8px">
  100 + <section *ngIf="isAdd">
103 101 <tb-file-input
104 102 formControlName="file"
105 103 workFromFileObj="true"
106 104 required
107   - dropLabel="{{'resource.drop-file' | translate}}">
  105 + dropLabel="{{'ota-update.drop-file' | translate}}">
108 106 </tb-file-input>
109 107 </section>
110 108 <section *ngIf="!isAdd">
111 109 <div fxLayout="row" fxLayoutGap.gt-md="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column">
112 110 <mat-form-field class="mat-block" fxFlex="33">
113   - <mat-label translate>firmware.file-name</mat-label>
  111 + <mat-label translate>ota-update.file-name</mat-label>
114 112 <input matInput formControlName="fileName" type="text" readonly>
115 113 </mat-form-field>
116 114 <mat-form-field class="mat-block" fxFlex>
117   - <mat-label translate>firmware.file-size-bytes</mat-label>
  115 + <mat-label translate>ota-update.file-size-bytes</mat-label>
118 116 <input matInput formControlName="dataSize" type="text" readonly>
119 117 </mat-form-field>
120 118 <mat-form-field class="mat-block" fxFlex>
121   - <mat-label translate>firmware.content-type</mat-label>
  119 + <mat-label translate>ota-update.content-type</mat-label>
122 120 <input matInput formControlName="contentType" type="text" readonly>
123 121 </mat-form-field>
124 122 </div>
125 123 </section>
126 124 <div formGroupName="additionalInfo">
127 125 <mat-form-field class="mat-block">
128   - <mat-label translate>firmware.description</mat-label>
  126 + <mat-label translate>ota-update.description</mat-label>
129 127 <textarea matInput formControlName="description" rows="2"></textarea>
130 128 </mat-form-field>
131 129 </div>
... ...
ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts renamed from ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts
... ... @@ -25,29 +25,29 @@ import { EntityComponent } from '@home/components/entity/entity.component';
25 25 import {
26 26 ChecksumAlgorithm,
27 27 ChecksumAlgorithmTranslationMap,
28   - Firmware,
29   - FirmwareType,
30   - FirmwareTypeTranslationMap
31   -} from '@shared/models/firmware.models';
  28 + OtaPackage,
  29 + OtaUpdateType,
  30 + OtaUpdateTypeTranslationMap
  31 +} from '@shared/models/ota-package.models';
32 32 import { ActionNotificationShow } from '@core/notification/notification.actions';
33 33
34 34 @Component({
35   - selector: 'tb-firmware',
36   - templateUrl: './firmwares.component.html'
  35 + selector: 'tb-ota-update',
  36 + templateUrl: './ota-update.component.html'
37 37 })
38   -export class FirmwaresComponent extends EntityComponent<Firmware> implements OnInit, OnDestroy {
  38 +export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements OnInit, OnDestroy {
39 39
40 40 private destroy$ = new Subject();
41 41
42 42 checksumAlgorithms = Object.values(ChecksumAlgorithm);
43 43 checksumAlgorithmTranslationMap = ChecksumAlgorithmTranslationMap;
44   - firmwareTypes = Object.values(FirmwareType);
45   - firmwareTypeTranslationMap = FirmwareTypeTranslationMap;
  44 + packageTypes = Object.values(OtaUpdateType);
  45 + otaUpdateTypeTranslationMap = OtaUpdateTypeTranslationMap;
46 46
47 47 constructor(protected store: Store<AppState>,
48 48 protected translate: TranslateService,
49   - @Inject('entity') protected entityValue: Firmware,
50   - @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<Firmware>,
  49 + @Inject('entity') protected entityValue: OtaPackage,
  50 + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<OtaPackage>,
51 51 public fb: FormBuilder) {
52 52 super(store, fb, entityValue, entitiesTableConfigValue);
53 53 }
... ... @@ -66,12 +66,12 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
66 66 }
67 67 }
68 68
69   - buildForm(entity: Firmware): FormGroup {
  69 + buildForm(entity: OtaPackage): FormGroup {
70 70 const form = this.fb.group({
71 71 title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]],
72 72 version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]],
73   - type: [entity?.type ? entity.type : FirmwareType.FIRMWARE, [Validators.required]],
74   - deviceProfileId: [entity ? entity.deviceProfileId : null],
  73 + type: [entity?.type ? entity.type : OtaUpdateType.FIRMWARE, Validators.required],
  74 + deviceProfileId: [entity ? entity.deviceProfileId : null, Validators.required],
75 75 checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256],
76 76 checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)],
77 77 additionalInfo: this.fb.group(
... ... @@ -90,7 +90,7 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
90 90 return form;
91 91 }
92 92
93   - updateForm(entity: Firmware) {
  93 + updateForm(entity: OtaPackage) {
94 94 this.entityForm.patchValue({
95 95 title: entity.title,
96 96 version: entity.version,
... ... @@ -105,12 +105,18 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
105 105 description: entity.additionalInfo ? entity.additionalInfo.description : ''
106 106 }
107 107 });
  108 + if (!this.isAdd && this.entityForm.enabled) {
  109 + this.entityForm.disable({emitEvent: false});
  110 + this.entityForm.get('additionalInfo').enable({emitEvent: false});
  111 + // this.entityForm.get('dataSize').disable({emitEvent: false});
  112 + // this.entityForm.get('contentType').disable({emitEvent: false});
  113 + }
108 114 }
109 115
110   - onFirmwareIdCopied() {
  116 + onPackageIdCopied() {
111 117 this.store.dispatch(new ActionNotificationShow(
112 118 {
113   - message: this.translate.instant('firmware.idCopiedMessage'),
  119 + message: this.translate.instant('ota-update.idCopiedMessage'),
114 120 type: 'success',
115 121 duration: 750,
116 122 verticalPosition: 'bottom',
... ... @@ -118,10 +124,10 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
118 124 }));
119 125 }
120 126
121   - onFirmwareChecksumCopied() {
  127 + onPackageChecksumCopied() {
122 128 this.store.dispatch(new ActionNotificationShow(
123 129 {
124   - message: this.translate.instant('firmware.checksum-copied-message'),
  130 + message: this.translate.instant('ota-update.checksum-copied-message'),
125 131 type: 'success',
126 132 duration: 750,
127 133 verticalPosition: 'bottom',
... ...
ui-ngx/src/app/modules/home/pages/ota-update/ota-update.module.ts renamed from ui-ngx/src/app/modules/home/pages/firmware/firmware.module.ts
... ... @@ -18,18 +18,18 @@ import { NgModule } from '@angular/core';
18 18 import { CommonModule } from '@angular/common';
19 19 import { SharedModule } from '@shared/shared.module';
20 20 import { HomeComponentsModule } from '@home/components/home-components.module';
21   -import { FirmwareRoutingModule } from '@home/pages/firmware/firmware-routing.module';
22   -import { FirmwaresComponent } from '@home/pages/firmware/firmwares.component';
  21 +import { OtaUpdateRoutingModule } from '@home/pages/ota-update/ota-update-routing.module';
  22 +import { OtaUpdateComponent } from '@home/pages/ota-update/ota-update.component';
23 23
24 24 @NgModule({
25 25 declarations: [
26   - FirmwaresComponent
  26 + OtaUpdateComponent
27 27 ],
28 28 imports: [
29 29 CommonModule,
30 30 SharedModule,
31 31 HomeComponentsModule,
32   - FirmwareRoutingModule
  32 + OtaUpdateRoutingModule
33 33 ]
34 34 })
35   -export class FirmwareModule { }
  35 +export class OtaUpdateModule { }
... ...
ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.html renamed from ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.html
... ... @@ -15,40 +15,41 @@
15 15 limitations under the License.
16 16
17 17 -->
18   -<mat-form-field [formGroup]="firmwareFormGroup" class="mat-block">
  18 +<mat-form-field [formGroup]="otaPackageFormGroup" class="mat-block">
19 19 <input matInput type="text" placeholder="{{ placeholderText | translate }}"
20   - #firmwareInput
21   - formControlName="firmwareId"
  20 + #packageInput
  21 + formControlName="packageId"
22 22 (focusin)="onFocus()"
23 23 [required]="required"
24   - [matAutocomplete]="firmwareAutocomplete">
25   - <button *ngIf="firmwareFormGroup.get('firmwareId').value && !disabled"
  24 + [matAutocomplete]="packageAutocomplete">
  25 + <button *ngIf="otaPackageFormGroup.get('packageId').value && !disabled"
26 26 type="button"
27 27 matSuffix mat-button mat-icon-button aria-label="Clear"
28 28 (click)="clear()">
29 29 <mat-icon class="material-icons">close</mat-icon>
30 30 </button>
31 31 <mat-autocomplete class="tb-autocomplete"
32   - #firmwareAutocomplete="matAutocomplete"
33   - [displayWith]="displayFirmwareFn">
34   - <mat-option *ngFor="let firmware of filteredFirmwares | async" [value]="firmware">
35   - <span [innerHTML]="this.firmwareTitleText(firmware) | highlight:searchText"></span>
  32 + #packageAutocomplete="matAutocomplete"
  33 + [displayWith]="displayPackageFn">
  34 + <mat-option *ngFor="let package of filteredPackages | async" [value]="package">
  35 + <span [innerHTML]="this.packageTitleText(package) | highlight:searchText"></span>
36 36 </mat-option>
37   - <mat-option *ngIf="!(filteredFirmwares | async)?.length" [value]="null" class="tb-not-found">
  37 + <mat-option *ngIf="!(filteredPackages | async)?.length" [value]="null" class="tb-not-found">
38 38 <div class="tb-not-found-content" (click)="$event.stopPropagation()">
39 39 <div *ngIf="!textIsNotEmpty(searchText); else searchNotEmpty">
40   - <span>{{ notFoundFirmware | translate }}</span>
  40 + <span>{{ notFoundPackage | translate }}</span>
41 41 </div>
42 42 <ng-template #searchNotEmpty>
43 43 <span>
44   - {{ translate.get(notMatchingFirmware,
  44 + {{ translate.get(notMatchingPackage,
45 45 {entity: truncate.transform(searchText, true, 6, &apos;...&apos;)}) | async }}
46 46 </span>
47 47 </ng-template>
48 48 </div>
49 49 </mat-option>
50 50 </mat-autocomplete>
51   - <mat-error *ngIf="firmwareFormGroup.get('firmwareId').hasError('required')">
  51 + <mat-error *ngIf="otaPackageFormGroup.get('packageId').hasError('required')">
52 52 {{ requiredErrorText | translate }}
53 53 </mat-error>
  54 + <mat-hint *ngIf="!disabled">{{ hintText | translate }}</mat-hint>
54 55 </mat-form-field>
... ...
ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.ts renamed from ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.ts
... ... @@ -28,29 +28,29 @@ import { BaseData } from '@shared/models/base-data';
28 28 import { EntityService } from '@core/http/entity.service';
29 29 import { TruncatePipe } from '@shared/pipe/truncate.pipe';
30 30 import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
31   -import { FirmwareInfo, FirmwareType } from '@shared/models/firmware.models';
32   -import { FirmwareService } from '@core/http/firmware.service';
  31 +import { OtaPackageInfo, OtaUpdateTranslation, OtaUpdateType } from '@shared/models/ota-package.models';
  32 +import { OtaPackageService } from '@core/http/ota-package.service';
33 33 import { PageLink } from '@shared/models/page/page-link';
34 34 import { Direction } from '@shared/models/page/sort-order';
35 35
36 36 @Component({
37   - selector: 'tb-firmware-autocomplete',
38   - templateUrl: './firmware-autocomplete.component.html',
  37 + selector: 'tb-ota-package-autocomplete',
  38 + templateUrl: './ota-package-autocomplete.component.html',
39 39 styleUrls: [],
40 40 providers: [{
41 41 provide: NG_VALUE_ACCESSOR,
42   - useExisting: forwardRef(() => FirmwareAutocompleteComponent),
  42 + useExisting: forwardRef(() => OtaPackageAutocompleteComponent),
43 43 multi: true
44 44 }]
45 45 })
46   -export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnInit {
  46 +export class OtaPackageAutocompleteComponent implements ControlValueAccessor, OnInit {
47 47
48   - firmwareFormGroup: FormGroup;
  48 + otaPackageFormGroup: FormGroup;
49 49
50 50 modelValue: string | EntityId | null;
51 51
52 52 @Input()
53   - type = FirmwareType.FIRMWARE;
  53 + type = OtaUpdateType.FIRMWARE;
54 54
55 55 @Input()
56 56 deviceProfileId: string;
... ... @@ -78,42 +78,24 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
78 78 @Input()
79 79 disabled: boolean;
80 80
81   - @ViewChild('firmwareInput', {static: true}) firmwareInput: ElementRef;
82   - @ViewChild('firmwareInput', {read: MatAutocompleteTrigger}) firmwareAutocomplete: MatAutocompleteTrigger;
  81 + @ViewChild('packageInput', {static: true}) packageInput: ElementRef;
83 82
84   - filteredFirmwares: Observable<Array<FirmwareInfo>>;
  83 + filteredPackages: Observable<Array<OtaPackageInfo>>;
85 84
86 85 searchText = '';
87 86
88 87 private dirty = false;
89 88
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   -
107 89 private propagateChange = (v: any) => { };
108 90
109 91 constructor(private store: Store<AppState>,
110 92 public translate: TranslateService,
111 93 public truncate: TruncatePipe,
112 94 private entityService: EntityService,
113   - private firmwareService: FirmwareService,
  95 + private otaPackageService: OtaPackageService,
114 96 private fb: FormBuilder) {
115   - this.firmwareFormGroup = this.fb.group({
116   - firmwareId: [null]
  97 + this.otaPackageFormGroup = this.fb.group({
  98 + packageId: [null]
117 99 });
118 100 }
119 101
... ... @@ -125,7 +107,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
125 107 }
126 108
127 109 ngOnInit() {
128   - this.filteredFirmwares = this.firmwareFormGroup.get('firmwareId').valueChanges
  110 + this.filteredPackages = this.otaPackageFormGroup.get('packageId').valueChanges
129 111 .pipe(
130 112 tap(value => {
131 113 let modelValue;
... ... @@ -140,7 +122,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
140 122 }
141 123 }),
142 124 map(value => value ? (typeof value === 'string' ? value : value.title) : ''),
143   - mergeMap(name => this.fetchFirmware(name)),
  125 + mergeMap(name => this.fetchPackages(name)),
144 126 share()
145 127 );
146 128 }
... ... @@ -149,7 +131,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
149 131 }
150 132
151 133 getCurrentEntity(): BaseData<EntityId> | null {
152   - const currentRuleChain = this.firmwareFormGroup.get('firmwareId').value;
  134 + const currentRuleChain = this.otaPackageFormGroup.get('packageId').value;
153 135 if (currentRuleChain && typeof currentRuleChain !== 'string') {
154 136 return currentRuleChain as BaseData<EntityId>;
155 137 } else {
... ... @@ -160,9 +142,9 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
160 142 setDisabledState(isDisabled: boolean): void {
161 143 this.disabled = isDisabled;
162 144 if (this.disabled) {
163   - this.firmwareFormGroup.disable({emitEvent: false});
  145 + this.otaPackageFormGroup.disable({emitEvent: false});
164 146 } else {
165   - this.firmwareFormGroup.enable({emitEvent: false});
  147 + this.otaPackageFormGroup.enable({emitEvent: false});
166 148 }
167 149 }
168 150
... ... @@ -173,21 +155,21 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
173 155 writeValue(value: string | EntityId | null): void {
174 156 this.searchText = '';
175 157 if (value != null && value !== '') {
176   - let firmwareId = '';
  158 + let packageId = '';
177 159 if (typeof value === 'string') {
178   - firmwareId = value;
  160 + packageId = value;
179 161 } else if (value.entityType && value.id) {
180   - firmwareId = value.id;
  162 + packageId = value.id;
181 163 }
182   - if (firmwareId !== '') {
183   - this.entityService.getEntity(EntityType.FIRMWARE, firmwareId, {ignoreLoading: true, ignoreErrors: true}).subscribe(
  164 + if (packageId !== '') {
  165 + this.entityService.getEntity(EntityType.OTA_PACKAGE, packageId, {ignoreLoading: true, ignoreErrors: true}).subscribe(
184 166 (entity) => {
185 167 this.modelValue = this.useFullEntityId ? entity.id : entity.id.id;
186   - this.firmwareFormGroup.get('firmwareId').patchValue(entity, {emitEvent: false});
  168 + this.otaPackageFormGroup.get('packageId').patchValue(entity, {emitEvent: false});
187 169 },
188 170 () => {
189 171 this.modelValue = null;
190   - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false});
  172 + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false});
191 173 if (value !== null) {
192 174 this.propagateChange(this.modelValue);
193 175 }
... ... @@ -195,25 +177,25 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
195 177 );
196 178 } else {
197 179 this.modelValue = null;
198   - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false});
  180 + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false});
199 181 this.propagateChange(null);
200 182 }
201 183 } else {
202 184 this.modelValue = null;
203   - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false});
  185 + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false});
204 186 }
205 187 this.dirty = true;
206 188 }
207 189
208 190 onFocus() {
209 191 if (this.dirty) {
210   - this.firmwareFormGroup.get('firmwareId').updateValueAndValidity({onlySelf: true, emitEvent: true});
  192 + this.otaPackageFormGroup.get('packageId').updateValueAndValidity({onlySelf: true, emitEvent: true});
211 193 this.dirty = false;
212 194 }
213 195 }
214 196
215 197 reset() {
216   - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false});
  198 + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false});
217 199 }
218 200
219 201 updateView(value: string | null) {
... ... @@ -223,47 +205,51 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn
223 205 }
224 206 }
225 207
226   - displayFirmwareFn(firmware?: FirmwareInfo): string | undefined {
227   - return firmware ? `${firmware.title} (${firmware.version})` : undefined;
  208 + displayPackageFn(packageInfo?: OtaPackageInfo): string | undefined {
  209 + return packageInfo ? `${packageInfo.title} (${packageInfo.version})` : undefined;
228 210 }
229 211
230   - fetchFirmware(searchText?: string): Observable<Array<FirmwareInfo>> {
  212 + fetchPackages(searchText?: string): Observable<Array<OtaPackageInfo>> {
231 213 this.searchText = searchText;
232 214 const pageLink = new PageLink(50, 0, searchText, {
233 215 property: 'title',
234 216 direction: Direction.ASC
235 217 });
236   - return this.firmwareService.getFirmwaresInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type,
  218 + return this.otaPackageService.getOtaPackagesInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type,
237 219 true, {ignoreLoading: true}).pipe(
238 220 map((data) => data && data.data.length ? data.data : null)
239 221 );
240 222 }
241 223
242 224 clear() {
243   - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: true});
  225 + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: true});
244 226 setTimeout(() => {
245   - this.firmwareInput.nativeElement.blur();
246   - this.firmwareInput.nativeElement.focus();
  227 + this.packageInput.nativeElement.blur();
  228 + this.packageInput.nativeElement.focus();
247 229 }, 0);
248 230 }
249 231
250 232 get placeholderText(): string {
251   - return this.labelText || this.firmwareTypeTranslation.get(this.type).label;
  233 + return this.labelText || OtaUpdateTranslation.get(this.type).label;
252 234 }
253 235
254 236 get requiredErrorText(): string {
255   - return this.requiredText || this.firmwareTypeTranslation.get(this.type).required;
  237 + return this.requiredText || OtaUpdateTranslation.get(this.type).required;
  238 + }
  239 +
  240 + get notFoundPackage(): string {
  241 + return OtaUpdateTranslation.get(this.type).noFound;
256 242 }
257 243
258   - get notFoundFirmware(): string {
259   - return this.firmwareTypeTranslation.get(this.type).noFound;
  244 + get notMatchingPackage(): string {
  245 + return OtaUpdateTranslation.get(this.type).noMatching;
260 246 }
261 247
262   - get notMatchingFirmware(): string {
263   - return this.firmwareTypeTranslation.get(this.type).noMatching;
  248 + get hintText(): string {
  249 + return OtaUpdateTranslation.get(this.type).hint;
264 250 }
265 251
266   - firmwareTitleText(firmware: FirmwareInfo): string {
267   - return `${firmware.title} (${firmware.version})`;
  252 + packageTitleText(firpackageInfomware: OtaPackageInfo): string {
  253 + return `${firpackageInfomware.title} (${firpackageInfomware.version})`;
268 254 }
269 255 }
... ...
... ... @@ -121,6 +121,7 @@ export const HelpLinks = {
121 121 entitiesImport: helpBaseUrl + '/docs/user-guide/bulk-provisioning',
122 122 rulechains: helpBaseUrl + '/docs/user-guide/ui/rule-chains',
123 123 dashboards: helpBaseUrl + '/docs/user-guide/ui/dashboards',
  124 + otaUpdates: helpBaseUrl + '/docs/user-guide/ui/ota-updates',
124 125 widgetsBundles: helpBaseUrl + '/docs/user-guide/ui/widget-library#bundles',
125 126 widgetsConfig: helpBaseUrl + '/docs/user-guide/ui/dashboards#widget-configuration',
126 127 widgetsConfigTimeseries: helpBaseUrl + '/docs/user-guide/ui/dashboards#timeseries',
... ...
... ... @@ -27,7 +27,7 @@ import { KeyFilter } from '@shared/models/query/query.models';
27 27 import { TimeUnit } from '@shared/models/time/time.models';
28 28 import * as _moment from 'moment';
29 29 import { AbstractControl, ValidationErrors } from '@angular/forms';
30   -import { FirmwareId } from '@shared/models/id/firmware-id';
  30 +import { OtaPackageId } from '@shared/models/id/ota-package-id';
31 31 import { DashboardId } from '@shared/models/id/dashboard-id';
32 32
33 33 export enum DeviceProfileType {
... ... @@ -500,8 +500,8 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> {
500 500 defaultRuleChainId?: RuleChainId;
501 501 defaultDashboardId?: DashboardId;
502 502 defaultQueueName?: string;
503   - firmwareId?: FirmwareId;
504   - softwareId?: FirmwareId;
  503 + firmwareId?: OtaPackageId;
  504 + softwareId?: OtaPackageId;
505 505 profileData: DeviceProfileData;
506 506 }
507 507
... ... @@ -563,8 +563,8 @@ export interface Device extends BaseData<DeviceId> {
563 563 name: string;
564 564 type: string;
565 565 label: string;
566   - firmwareId?: FirmwareId;
567   - softwareId?: FirmwareId;
  566 + firmwareId?: OtaPackageId;
  567 + softwareId?: OtaPackageId;
568 568 deviceProfileId?: DeviceProfileId;
569 569 deviceData?: DeviceData;
570 570 additionalInfo?: any;
... ...
... ... @@ -35,7 +35,7 @@ export enum EntityType {
35 35 WIDGET_TYPE = 'WIDGET_TYPE',
36 36 API_USAGE_STATE = 'API_USAGE_STATE',
37 37 TB_RESOURCE = 'TB_RESOURCE',
38   - FIRMWARE = 'FIRMWARE'
  38 + OTA_PACKAGE = 'OTA_PACKAGE'
39 39 }
40 40
41 41 export enum AliasEntityType {
... ... @@ -296,14 +296,14 @@ export const entityTypeTranslations = new Map<EntityType | AliasEntityType, Enti
296 296 }
297 297 ],
298 298 [
299   - EntityType.FIRMWARE,
  299 + EntityType.OTA_PACKAGE,
300 300 {
301   - type: 'entity.type-firmware',
302   - details: 'firmware.firmware-details',
303   - add: 'firmware.add',
304   - noEntities: 'firmware.no-firmware-text',
305   - search: 'firmware.search',
306   - selectedEntities: 'firmware.selected-firmware'
  301 + type: 'entity.type-ota-package',
  302 + details: 'ota-update.ota-update-details',
  303 + add: 'ota-update.add',
  304 + noEntities: 'ota-update.no-packages-text',
  305 + search: 'ota-update.search',
  306 + selectedEntities: 'ota-update.selected-package'
307 307 }
308 308 ]
309 309 ]
... ... @@ -390,9 +390,9 @@ export const entityTypeResources = new Map<EntityType, EntityTypeResource<BaseDa
390 390 }
391 391 ],
392 392 [
393   - EntityType.FIRMWARE,
  393 + EntityType.OTA_PACKAGE,
394 394 {
395   - helpLinkId: 'firmware'
  395 + helpLinkId: 'otaUpdates'
396 396 }
397 397 ]
398 398 ]
... ...
ui-ngx/src/app/shared/models/id/ota-package-id.ts renamed from ui-ngx/src/app/shared/models/id/firmware-id.ts
... ... @@ -17,8 +17,8 @@
17 17 import { EntityId } from '@shared/models/id/entity-id';
18 18 import { EntityType } from '@shared/models/entity-type.models';
19 19
20   -export class FirmwareId implements EntityId {
21   - entityType = EntityType.FIRMWARE;
  20 +export class OtaPackageId implements EntityId {
  21 + entityType = EntityType.OTA_PACKAGE;
22 22 id: string;
23 23 constructor(id: string) {
24 24 this.id = id;
... ...
ui-ngx/src/app/shared/models/ota-package.models.ts renamed from ui-ngx/src/app/shared/models/firmware.models.ts
... ... @@ -16,7 +16,7 @@
16 16
17 17 import { BaseData } from '@shared/models/base-data';
18 18 import { TenantId } from '@shared/models/id/tenant-id';
19   -import { FirmwareId } from '@shared/models/id/firmware-id';
  19 +import { OtaPackageId } from '@shared/models/id/ota-package-id';
20 20 import { DeviceProfileId } from '@shared/models/id/device-profile-id';
21 21
22 22 export enum ChecksumAlgorithm {
... ... @@ -41,21 +41,48 @@ export const ChecksumAlgorithmTranslationMap = new Map<ChecksumAlgorithm, string
41 41 ]
42 42 );
43 43
44   -export enum FirmwareType {
  44 +export enum OtaUpdateType {
45 45 FIRMWARE = 'FIRMWARE',
46 46 SOFTWARE = 'SOFTWARE'
47 47 }
48 48
49   -export const FirmwareTypeTranslationMap = new Map<FirmwareType, string>(
  49 +export const OtaUpdateTypeTranslationMap = new Map<OtaUpdateType, string>(
50 50 [
51   - [FirmwareType.FIRMWARE, 'firmware.types.firmware'],
52   - [FirmwareType.SOFTWARE, 'firmware.types.software']
  51 + [OtaUpdateType.FIRMWARE, 'ota-update.types.firmware'],
  52 + [OtaUpdateType.SOFTWARE, 'ota-update.types.software']
53 53 ]
54 54 );
55 55
56   -export interface FirmwareInfo extends BaseData<FirmwareId> {
  56 +export interface OtaUpdateTranslation {
  57 + label: string;
  58 + required: string;
  59 + noFound: string;
  60 + noMatching: string;
  61 + hint: string;
  62 +}
  63 +
  64 +export const OtaUpdateTranslation = new Map<OtaUpdateType, OtaUpdateTranslation>(
  65 + [
  66 + [OtaUpdateType.FIRMWARE, {
  67 + label: 'ota-update.assign-firmware',
  68 + required: 'ota-update.assign-firmware-required',
  69 + noFound: 'ota-update.no-firmware-text',
  70 + noMatching: 'ota-update.no-firmware-matching',
  71 + hint: 'ota-update.chose-firmware-distributed-device'
  72 + }],
  73 + [OtaUpdateType.SOFTWARE, {
  74 + label: 'ota-update.assign-software',
  75 + required: 'ota-update.assign-software-required',
  76 + noFound: 'ota-update.no-software-text',
  77 + noMatching: 'ota-update.no-software-matching',
  78 + hint: 'ota-update.chose-software-distributed-device'
  79 + }]
  80 + ]
  81 +);
  82 +
  83 +export interface OtaPackageInfo extends BaseData<OtaPackageId> {
57 84 tenantId?: TenantId;
58   - type: FirmwareType;
  85 + type: OtaUpdateType;
59 86 deviceProfileId?: DeviceProfileId;
60 87 title?: string;
61 88 version?: string;
... ... @@ -68,7 +95,7 @@ export interface FirmwareInfo extends BaseData<FirmwareId> {
68 95 additionalInfo?: any;
69 96 }
70 97
71   -export interface Firmware extends FirmwareInfo {
  98 +export interface OtaPackage extends OtaPackageInfo {
72 99 file?: File;
73 100 data: string;
74 101 }
... ...
... ... @@ -141,7 +141,7 @@ import { FileSizePipe } from '@shared/pipe/file-size.pipe';
141 141 import { WidgetsBundleSearchComponent } from '@shared/components/widgets-bundle-search.component';
142 142 import { SelectableColumnsPipe } from '@shared/pipe/selectable-columns.pipe';
143 143 import { QuickTimeIntervalComponent } from '@shared/components/time/quick-time-interval.component';
144   -import { FirmwareAutocompleteComponent } from '@shared/components/firmware/firmware-autocomplete.component';
  144 +import { OtaPackageAutocompleteComponent } from '@shared/components/ota-package/ota-package-autocomplete.component';
145 145 import { MAT_DATE_LOCALE } from '@angular/material/core';
146 146
147 147 @NgModule({
... ... @@ -239,7 +239,7 @@ import { MAT_DATE_LOCALE } from '@angular/material/core';
239 239 HistorySelectorComponent,
240 240 EntityGatewaySelectComponent,
241 241 ContactComponent,
242   - FirmwareAutocompleteComponent,
  242 + OtaPackageAutocompleteComponent,
243 243 WidgetsBundleSearchComponent
244 244 ],
245 245 imports: [
... ... @@ -411,7 +411,7 @@ import { MAT_DATE_LOCALE } from '@angular/material/core';
411 411 HistorySelectorComponent,
412 412 EntityGatewaySelectComponent,
413 413 ContactComponent,
414   - FirmwareAutocompleteComponent,
  414 + OtaPackageAutocompleteComponent,
415 415 WidgetsBundleSearchComponent
416 416 ]
417 417 })
... ...
... ... @@ -1516,7 +1516,7 @@
1516 1516 "list-of-edges": "{ count, plural, 1 {One edge} other {List of # edges} }",
1517 1517 "edge-name-starts-with": "Edges whose names start with '{{prefix}}'",
1518 1518 "type-tb-resource": "Resource",
1519   - "type-firmware": "Firmware"
  1519 + "type-ota-package": "OTA package"
1520 1520 },
1521 1521 "entity-field": {
1522 1522 "created-time": "Created time",
... ... @@ -1927,51 +1927,6 @@
1927 1927 "inherit-owner": "Inherit from owner",
1928 1928 "source-attribute-not-set": "If source attribute isn't set"
1929 1929 },
1930   - "firmware": {
1931   - "add": "Add firmware",
1932   - "checksum": "Checksum",
1933   - "checksum-copied-message": "Firmware checksum has been copied to clipboard",
1934   - "checksum-required": "Checksum is required.",
1935   - "checksum-algorithm": "Checksum algorithm",
1936   - "content-type": "Content type",
1937   - "copy-checksum": "Copy checksum",
1938   - "copyId": "Copy firmware Id",
1939   - "description": "Description",
1940   - "delete": "Delete firmware",
1941   - "delete-firmware-text": "Be careful, after the confirmation the firmware will become unrecoverable.",
1942   - "delete-firmware-title": "Are you sure you want to delete the firmware '{{firmwareTitle}}'?",
1943   - "delete-firmwares-action-title": "Delete { count, plural, 1 {1 firmware} other {# firmwares} }",
1944   - "delete-firmwares-text": "Be careful, after the confirmation all selected resources will be removed.",
1945   - "delete-firmwares-title": "Are you sure you want to delete { count, plural, 1 {1 firmware} other {# firmwares} }?",
1946   - "download": "Download firmware",
1947   - "drop-file": "Drop a firmware file or click to select a file to upload.",
1948   - "empty": "Firmware is empty",
1949   - "idCopiedMessage": "Firmware Id has been copied to clipboard",
1950   - "no-firmware-matching": "No firmware matching '{{entity}}' were found.",
1951   - "no-firmware-text": "No firmwares found",
1952   - "no-software-matching": "No sowtware matching '{{entity}}' were found.",
1953   - "no-software-text": "No software found",
1954   - "file-name": "File name",
1955   - "file-size": "File size",
1956   - "file-size-bytes": "File size in bytes",
1957   - "firmware": "Firmware",
1958   - "firmware-details": "Firmware details",
1959   - "firmware-required": "Firmware is required.",
1960   - "search": "Search firmwares",
1961   - "selected-firmware": "{ count, plural, 1 {1 firmware} other {# firmwares} } selected",
1962   - "software": "Software",
1963   - "software-required": "Software is required.",
1964   - "title": "Title",
1965   - "title-required": "Title is required.",
1966   - "type": "Firmware type",
1967   - "types": {
1968   - "firmware": "Firmware",
1969   - "software": "Software"
1970   - },
1971   - "version": "Version",
1972   - "version-required": "Version is required.",
1973   - "warning-after-save-no-edit": "Once the firmware is saved, it will not be possible to change the title and version fields."
1974   - },
1975 1930 "fullscreen": {
1976 1931 "expand": "Expand to fullscreen",
1977 1932 "exit": "Exit fullscreen",
... ... @@ -2191,6 +2146,55 @@
2191 2146 "or": "or",
2192 2147 "error": "Login error"
2193 2148 },
  2149 + "ota-update": {
  2150 + "add": "Add package",
  2151 + "assign-firmware": "Assigned firmware",
  2152 + "assign-firmware-required": "Assigned firmware is required",
  2153 + "assign-software": "Assigned software",
  2154 + "assign-software-required": "Assigned software is required",
  2155 + "checksum": "Checksum",
  2156 + "checksum-algorithm": "Checksum algorithm",
  2157 + "checksum-copied-message": "Package checksum has been copied to clipboard",
  2158 + "chose-compatible-device-profile": "Choose compatible device profile",
  2159 + "chose-firmware-distributed-device": "Choose firmware that will be distributed to the devices",
  2160 + "chose-software-distributed-device": "Choose software that will be distributed to the devices",
  2161 + "content-type": "Content type",
  2162 + "copy-checksum": "Copy checksum",
  2163 + "copyId": "Copy package Id",
  2164 + "idCopiedMessage": "Package Id has been copied to clipboard",
  2165 + "description": "Description",
  2166 + "delete": "Delete package",
  2167 + "delete-ota-update-text": "Be careful, after the confirmation the OTA update will become unrecoverable.",
  2168 + "delete-ota-update-title": "Are you sure you want to delete the OTA update '{{title}}'?",
  2169 + "delete-ota-updates-text": "Be careful, after the confirmation all selected OTA updates will be removed.",
  2170 + "delete-ota-updates-title": "Are you sure you want to delete { count, plural, 1 {1 OTA update} other {# OTA updates} }?",
  2171 + "drop-file": "Drop a package file or click to select a file to upload.",
  2172 + "download": "Download package",
  2173 + "file-name": "File name",
  2174 + "file-size": "File size",
  2175 + "file-size-bytes": "File size in bytes",
  2176 + "no-packages-text": "No packages found",
  2177 + "no-firmware-text": "No compatible Firmware OTA Update packages provisioned.",
  2178 + "no-firmware-matching": "No compatible Firmware OTA Update packages matching '{{entity}}' were found.",
  2179 + "no-software-text": "No compatible Software OTA Update packages provisioned.",
  2180 + "no-software-matching": "No compatible Software OTA Update packages matching '{{entity}}' were found.",
  2181 + "search": "Search packages",
  2182 + "selected-package": "{ count, plural, 1 {1 package} other {# packages} } selected",
  2183 + "ota-update": "OTA update",
  2184 + "ota-update-details": "OTA update details",
  2185 + "ota-updates": "OTA updates",
  2186 + "package-type": "Package type",
  2187 + "packages-repository": "Packages repository",
  2188 + "title": "Title",
  2189 + "title-required": "Title is required.",
  2190 + "types": {
  2191 + "firmware": "Firmware",
  2192 + "software": "Software"
  2193 + },
  2194 + "version": "Version",
  2195 + "version-required": "Version is required.",
  2196 + "warning-after-save-no-edit": "Once the package is uploaded, you will not be able to modify title, version, device profile and package type."
  2197 + },
2194 2198 "position": {
2195 2199 "top": "Top",
2196 2200 "bottom": "Bottom",
... ...