From ce1a3ea56713b327a3b5c23dc4ceb5880a4415c4 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 3 Jun 2021 18:58:31 +0300 Subject: [PATCH] UI: OTA updates add support external URL --- .../app/core/http/device-profile.service.ts | 4 +- .../ota-update-table-config.resolve.ts | 42 +++++++- .../ota-update/ota-update.component.html | 96 ++++++++++++------- .../pages/ota-update/ota-update.component.ts | 42 +++++--- .../app/shared/models/ota-package.models.ts | 1 + .../assets/locale/locale.constant-en_US.json | 13 ++- 6 files changed, 141 insertions(+), 57 deletions(-) diff --git a/ui-ngx/src/app/core/http/device-profile.service.ts b/ui-ngx/src/app/core/http/device-profile.service.ts index f5c5625ba2..729ba7869b 100644 --- a/ui-ngx/src/app/core/http/device-profile.service.ts +++ b/ui-ngx/src/app/core/http/device-profile.service.ts @@ -98,10 +98,10 @@ export class DeviceProfileService { text += this.translate.instant('ota-update.change-firmware', {count: deviceFirmwareUpdate}); } if (deviceSoftwareUpdate > 0) { - text += text.length ? '
' : ''; + text += text.length ? ' ' : ''; text += this.translate.instant('ota-update.change-software', {count: deviceSoftwareUpdate}); } - return text !== '' ? this.dialogService.confirm('', text) : of(true); + return text !== '' ? this.dialogService.confirm('', text, null, this.translate.instant('common.proceed')) : of(true); }), mergeMap((update) => update ? this.saveDeviceProfile(deviceProfile, config) : throwError('Canceled saving device profiles'))); } diff --git a/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts index b22d43da46..d56b4e4541 100644 --- a/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts +++ b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts @@ -35,6 +35,10 @@ import { PageLink } from '@shared/models/page/page-link'; import { OtaUpdateComponent } from '@home/pages/ota-update/ota-update.component'; import { EntityAction } from '@home/models/entity/entity-component.models'; import { FileSizePipe } from '@shared/pipe/file-size.pipe'; +import { ClipboardService } from 'ngx-clipboard'; +import { ActionNotificationShow } from '@core/notification/notification.actions'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; @Injectable() export class OtaUpdateTableConfigResolve implements Resolve> { @@ -44,8 +48,10 @@ export class OtaUpdateTableConfigResolve implements Resolve, private otaPackageService: OtaPackageService, - private fileSize: FileSizePipe) { + private fileSize: FileSizePipe, + private clipboardService: ClipboardService) { this.config.entityType = EntityType.OTA_PACKAGE; this.config.entityComponent = OtaUpdateComponent; this.config.entityTranslations = entityTypeTranslations.get(EntityType.OTA_PACKAGE); @@ -62,14 +68,20 @@ export class OtaUpdateTableConfigResolve implements Resolve('fileName', 'ota-update.file-name', '25%'), new EntityTableColumn('dataSize', 'ota-update.file-size', '70px', entity => { - return this.fileSize.transform(entity.dataSize || 0); + return entity.dataSize ? this.fileSize.transform(entity.dataSize) : ''; }), new EntityTableColumn('checksum', 'ota-update.checksum', '540px', entity => { - return `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}`; + return entity.checksum ? `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}` : ''; }, () => ({}), false) ); this.config.cellActionDescriptors.push( + { + name: this.translate.instant('ota-update.copy-checksum'), + icon: 'content_copy', + isEnabled: (otaPackage) => !!otaPackage.checksum, + onAction: ($event, entity) => this.copyPackageChecksum($event, entity) + }, { name: this.translate.instant('ota-update.download'), icon: 'file_download', @@ -101,7 +113,26 @@ export class OtaUpdateTableConfigResolve implements Resolve): boolean { @@ -109,6 +140,9 @@ export class OtaUpdateTableConfigResolve implements Resolve @@ -49,7 +49,7 @@
-
+
ota-update.title @@ -83,44 +83,68 @@ -
ota-update.warning-after-save-no-edit
-
- - ota-update.checksum-algorithm - - - {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} - - - - - ota-update.checksum - - -
- - +
ota-update.warning-after-save-no-edit
+ + Upload binary file + Use external URL +
-
-
+
+
+ + + + {{ 'ota-update.auto-generate-checksum' | translate }} + +
+
- ota-update.file-name - + ota-update.checksum-algorithm + + + {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} + + - ota-update.file-size-bytes - - - - ota-update.content-type - + ota-update.checksum + + ota-update.checksum-hint
+
+
+ + ota-update.file-name + + + + ota-update.file-size-bytes + + + + ota-update.content-type + + +
+
+
+
+ + ota-update.url + + + ota-update.url-required + +
diff --git a/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts index fd4cd7ae27..42e0ffc33c 100644 --- a/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts +++ b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts @@ -30,6 +30,8 @@ import { OtaUpdateTypeTranslationMap } from '@shared/models/ota-package.models'; import { ActionNotificationShow } from '@core/notification/notification.actions'; +import { filter, takeUntil } from 'rxjs/operators'; +import { isNotEmptyStr } from '@core/utils'; @Component({ selector: 'tb-ota-update', @@ -52,6 +54,26 @@ export class OtaUpdateComponent extends EntityComponent implements O super(store, fb, entityValue, entitiesTableConfigValue); } + ngOnInit() { + super.ngOnInit(); + this.entityForm.get('resource').valueChanges.pipe( + filter(() => this.isAdd), + takeUntil(this.destroy$) + ).subscribe((resource) => { + if (resource === 'file') { + this.entityForm.get('url').clearValidators(); + this.entityForm.get('file').setValidators(Validators.required); + this.entityForm.get('url').updateValueAndValidity({emitEvent: false}); + this.entityForm.get('file').updateValueAndValidity({emitEvent: false}); + } else { + this.entityForm.get('file').clearValidators(); + this.entityForm.get('url').setValidators(Validators.required); + this.entityForm.get('file').updateValueAndValidity({emitEvent: false}); + this.entityForm.get('url').updateValueAndValidity({emitEvent: false}); + } + }); + } + ngOnDestroy() { super.ngOnDestroy(); this.destroy$.next(); @@ -74,6 +96,8 @@ export class OtaUpdateComponent extends EntityComponent implements O deviceProfileId: [entity ? entity.deviceProfileId : null, Validators.required], checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256], checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], + url: [entity ? entity.url : ''], + resource: ['file'], additionalInfo: this.fb.group( { description: [entity && entity.additionalInfo ? entity.additionalInfo.description : ''], @@ -82,6 +106,7 @@ export class OtaUpdateComponent extends EntityComponent implements O }); if (this.isAdd) { form.addControl('file', this.fb.control(null, Validators.required)); + form.addControl('generateChecksum', this.fb.control(true)); } else { form.addControl('fileName', this.fb.control(null)); form.addControl('dataSize', this.fb.control(null)); @@ -101,6 +126,8 @@ export class OtaUpdateComponent extends EntityComponent implements O fileName: entity.fileName, dataSize: entity.dataSize, contentType: entity.contentType, + url: entity.url, + resource: isNotEmptyStr(entity.url) ? 'url' : 'file', additionalInfo: { description: entity.additionalInfo ? entity.additionalInfo.description : '' } @@ -108,8 +135,6 @@ export class OtaUpdateComponent extends EntityComponent implements O if (!this.isAdd && this.entityForm.enabled) { this.entityForm.disable({emitEvent: false}); this.entityForm.get('additionalInfo').enable({emitEvent: false}); - // this.entityForm.get('dataSize').disable({emitEvent: false}); - // this.entityForm.get('contentType').disable({emitEvent: false}); } } @@ -124,14 +149,9 @@ export class OtaUpdateComponent extends EntityComponent implements O })); } - onPackageChecksumCopied() { - this.store.dispatch(new ActionNotificationShow( - { - message: this.translate.instant('ota-update.checksum-copied-message'), - type: 'success', - duration: 750, - verticalPosition: 'bottom', - horizontalPosition: 'right' - })); + prepareFormValue(formValue: any): any { + delete formValue.resource; + delete formValue.generateChecksum; + return super.prepareFormValue(formValue); } } diff --git a/ui-ngx/src/app/shared/models/ota-package.models.ts b/ui-ngx/src/app/shared/models/ota-package.models.ts index 22efc881b0..b6fecfc2c5 100644 --- a/ui-ngx/src/app/shared/models/ota-package.models.ts +++ b/ui-ngx/src/app/shared/models/ota-package.models.ts @@ -87,6 +87,7 @@ export interface OtaPackageInfo extends BaseData { title?: string; version?: string; hasData?: boolean; + url?: string; fileName: string; checksum?: string; checksumAlgorithm?: ChecksumAlgorithm; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index b4f8c32101..732535dafe 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -575,7 +575,8 @@ "enter-password": "Enter password", "enter-search": "Enter search", "created-time": "Created time", - "loading": "Loading..." + "loading": "Loading...", + "proceed": "Proceed" }, "content-type": { "json": "Json", @@ -2152,12 +2153,14 @@ "assign-firmware-required": "Assigned firmware is required", "assign-software": "Assigned software", "assign-software-required": "Assigned software is required", + "auto-generate-checksum": "Auto-generate checksum", "checksum": "Checksum", + "checksum-hint": "If checksum is empty, it will be generated automatically", "checksum-algorithm": "Checksum algorithm", "checksum-copied-message": "Package checksum has been copied to clipboard", - "change-firmware": "You have changed the firmware. This may cause update of the { count, plural, 1 {1 device} other {# devices} }.", - "change-software": "You have changed the software. This may cause update of the { count, plural, 1 {1 device} other {# devices} }.", - "chose-compatible-device-profile": "Choose compatible device profile. The uploaded package will be available only for devices with the chosen profile.", + "change-firmware": "Change of the firmware may cause update of { count, plural, 1 {1 device} other {# devices} }.", + "change-software": "Change of the software may cause update of { count, plural, 1 {1 device} other {# devices} }.", + "chose-compatible-device-profile": "The uploaded package will be available only for devices with the chosen profile.", "chose-firmware-distributed-device": "Choose firmware that will be distributed to the devices", "chose-software-distributed-device": "Choose software that will be distributed to the devices", "content-type": "Content type", @@ -2193,6 +2196,8 @@ "firmware": "Firmware", "software": "Software" }, + "url": "Direct URL", + "url-required": "Direct URL is required", "version": "Version", "version-required": "Version is required.", "warning-after-save-no-edit": "Once the package is uploaded, you will not be able to modify title, version, device profile and package type."