Commit ce1a3ea56713b327a3b5c23dc4ceb5880a4415c4
1 parent
fa3bbb28
UI: OTA updates add support external URL
Showing
6 changed files
with
141 additions
and
57 deletions
@@ -98,10 +98,10 @@ export class DeviceProfileService { | @@ -98,10 +98,10 @@ export class DeviceProfileService { | ||
98 | text += this.translate.instant('ota-update.change-firmware', {count: deviceFirmwareUpdate}); | 98 | text += this.translate.instant('ota-update.change-firmware', {count: deviceFirmwareUpdate}); |
99 | } | 99 | } |
100 | if (deviceSoftwareUpdate > 0) { | 100 | if (deviceSoftwareUpdate > 0) { |
101 | - text += text.length ? '<br/>' : ''; | 101 | + text += text.length ? ' ' : ''; |
102 | text += this.translate.instant('ota-update.change-software', {count: deviceSoftwareUpdate}); | 102 | text += this.translate.instant('ota-update.change-software', {count: deviceSoftwareUpdate}); |
103 | } | 103 | } |
104 | - return text !== '' ? this.dialogService.confirm('', text) : of(true); | 104 | + return text !== '' ? this.dialogService.confirm('', text, null, this.translate.instant('common.proceed')) : of(true); |
105 | }), | 105 | }), |
106 | mergeMap((update) => update ? this.saveDeviceProfile(deviceProfile, config) : throwError('Canceled saving device profiles'))); | 106 | mergeMap((update) => update ? this.saveDeviceProfile(deviceProfile, config) : throwError('Canceled saving device profiles'))); |
107 | } | 107 | } |
@@ -35,6 +35,10 @@ import { PageLink } from '@shared/models/page/page-link'; | @@ -35,6 +35,10 @@ import { PageLink } from '@shared/models/page/page-link'; | ||
35 | import { OtaUpdateComponent } from '@home/pages/ota-update/ota-update.component'; | 35 | import { OtaUpdateComponent } from '@home/pages/ota-update/ota-update.component'; |
36 | import { EntityAction } from '@home/models/entity/entity-component.models'; | 36 | import { EntityAction } from '@home/models/entity/entity-component.models'; |
37 | import { FileSizePipe } from '@shared/pipe/file-size.pipe'; | 37 | import { FileSizePipe } from '@shared/pipe/file-size.pipe'; |
38 | +import { ClipboardService } from 'ngx-clipboard'; | ||
39 | +import { ActionNotificationShow } from '@core/notification/notification.actions'; | ||
40 | +import { Store } from '@ngrx/store'; | ||
41 | +import { AppState } from '@core/core.state'; | ||
38 | 42 | ||
39 | @Injectable() | 43 | @Injectable() |
40 | export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<OtaPackage, PageLink, OtaPackageInfo>> { | 44 | export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<OtaPackage, PageLink, OtaPackageInfo>> { |
@@ -44,8 +48,10 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | @@ -44,8 +48,10 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | ||
44 | 48 | ||
45 | constructor(private translate: TranslateService, | 49 | constructor(private translate: TranslateService, |
46 | private datePipe: DatePipe, | 50 | private datePipe: DatePipe, |
51 | + private store: Store<AppState>, | ||
47 | private otaPackageService: OtaPackageService, | 52 | private otaPackageService: OtaPackageService, |
48 | - private fileSize: FileSizePipe) { | 53 | + private fileSize: FileSizePipe, |
54 | + private clipboardService: ClipboardService) { | ||
49 | this.config.entityType = EntityType.OTA_PACKAGE; | 55 | this.config.entityType = EntityType.OTA_PACKAGE; |
50 | this.config.entityComponent = OtaUpdateComponent; | 56 | this.config.entityComponent = OtaUpdateComponent; |
51 | this.config.entityTranslations = entityTypeTranslations.get(EntityType.OTA_PACKAGE); | 57 | this.config.entityTranslations = entityTypeTranslations.get(EntityType.OTA_PACKAGE); |
@@ -62,15 +68,21 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | @@ -62,15 +68,21 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | ||
62 | }), | 68 | }), |
63 | new EntityTableColumn<OtaPackageInfo>('fileName', 'ota-update.file-name', '25%'), | 69 | new EntityTableColumn<OtaPackageInfo>('fileName', 'ota-update.file-name', '25%'), |
64 | new EntityTableColumn<OtaPackageInfo>('dataSize', 'ota-update.file-size', '70px', entity => { | 70 | new EntityTableColumn<OtaPackageInfo>('dataSize', 'ota-update.file-size', '70px', entity => { |
65 | - return this.fileSize.transform(entity.dataSize || 0); | 71 | + return entity.dataSize ? this.fileSize.transform(entity.dataSize) : ''; |
66 | }), | 72 | }), |
67 | new EntityTableColumn<OtaPackageInfo>('checksum', 'ota-update.checksum', '540px', entity => { | 73 | new EntityTableColumn<OtaPackageInfo>('checksum', 'ota-update.checksum', '540px', entity => { |
68 | - return `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}`; | 74 | + return entity.checksum ? `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}` : ''; |
69 | }, () => ({}), false) | 75 | }, () => ({}), false) |
70 | ); | 76 | ); |
71 | 77 | ||
72 | this.config.cellActionDescriptors.push( | 78 | this.config.cellActionDescriptors.push( |
73 | { | 79 | { |
80 | + name: this.translate.instant('ota-update.copy-checksum'), | ||
81 | + icon: 'content_copy', | ||
82 | + isEnabled: (otaPackage) => !!otaPackage.checksum, | ||
83 | + onAction: ($event, entity) => this.copyPackageChecksum($event, entity) | ||
84 | + }, | ||
85 | + { | ||
74 | name: this.translate.instant('ota-update.download'), | 86 | name: this.translate.instant('ota-update.download'), |
75 | icon: 'file_download', | 87 | icon: 'file_download', |
76 | isEnabled: (otaPackage) => otaPackage.hasData, | 88 | isEnabled: (otaPackage) => otaPackage.hasData, |
@@ -101,7 +113,26 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | @@ -101,7 +113,26 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | ||
101 | if ($event) { | 113 | if ($event) { |
102 | $event.stopPropagation(); | 114 | $event.stopPropagation(); |
103 | } | 115 | } |
104 | - this.otaPackageService.downloadOtaPackage(otaPackageInfo.id.id).subscribe(); | 116 | + if (otaPackageInfo.url) { |
117 | + window.open(otaPackageInfo.url, '_blank'); | ||
118 | + } else { | ||
119 | + this.otaPackageService.downloadOtaPackage(otaPackageInfo.id.id).subscribe(); | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + copyPackageChecksum($event: Event, otaPackageInfo: OtaPackageInfo) { | ||
124 | + if ($event) { | ||
125 | + $event.stopPropagation(); | ||
126 | + } | ||
127 | + this.clipboardService.copy(otaPackageInfo?.checksum); | ||
128 | + this.store.dispatch(new ActionNotificationShow( | ||
129 | + { | ||
130 | + message: this.translate.instant('ota-update.checksum-copied-message'), | ||
131 | + type: 'success', | ||
132 | + duration: 750, | ||
133 | + verticalPosition: 'bottom', | ||
134 | + horizontalPosition: 'right' | ||
135 | + })); | ||
105 | } | 136 | } |
106 | 137 | ||
107 | onPackageAction(action: EntityAction<OtaPackageInfo>): boolean { | 138 | onPackageAction(action: EntityAction<OtaPackageInfo>): boolean { |
@@ -109,6 +140,9 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | @@ -109,6 +140,9 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot | ||
109 | case 'uploadPackage': | 140 | case 'uploadPackage': |
110 | this.exportPackage(action.event, action.entity); | 141 | this.exportPackage(action.event, action.entity); |
111 | return true; | 142 | return true; |
143 | + case 'copyChecksum': | ||
144 | + this.copyPackageChecksum(action.event, action.entity); | ||
145 | + return true; | ||
112 | } | 146 | } |
113 | return false; | 147 | return false; |
114 | } | 148 | } |
@@ -31,6 +31,7 @@ | @@ -31,6 +31,7 @@ | ||
31 | <div fxLayout="row" fxLayout.xs="column"> | 31 | <div fxLayout="row" fxLayout.xs="column"> |
32 | <button mat-raised-button | 32 | <button mat-raised-button |
33 | ngxClipboard | 33 | ngxClipboard |
34 | + [disabled]="(isLoading$ | async)" | ||
34 | (cbOnSuccess)="onPackageIdCopied()" | 35 | (cbOnSuccess)="onPackageIdCopied()" |
35 | [cbContent]="entity?.id?.id" | 36 | [cbContent]="entity?.id?.id" |
36 | [fxShow]="!isEdit"> | 37 | [fxShow]="!isEdit"> |
@@ -38,10 +39,9 @@ | @@ -38,10 +39,9 @@ | ||
38 | <span translate>ota-update.copyId</span> | 39 | <span translate>ota-update.copyId</span> |
39 | </button> | 40 | </button> |
40 | <button mat-raised-button | 41 | <button mat-raised-button |
41 | - ngxClipboard | ||
42 | - (cbOnSuccess)="onPackageChecksumCopied()" | ||
43 | - [cbContent]="entity?.checksum" | ||
44 | - [fxShow]="!isEdit"> | 42 | + [disabled]="(isLoading$ | async)" |
43 | + (click)="onEntityAction($event, 'copyChecksum')" | ||
44 | + [fxShow]="!isEdit && entity?.checksum"> | ||
45 | <mat-icon svgIcon="mdi:clipboard-arrow-left"></mat-icon> | 45 | <mat-icon svgIcon="mdi:clipboard-arrow-left"></mat-icon> |
46 | <span translate>ota-update.copy-checksum</span> | 46 | <span translate>ota-update.copy-checksum</span> |
47 | </button> | 47 | </button> |
@@ -49,7 +49,7 @@ | @@ -49,7 +49,7 @@ | ||
49 | </div> | 49 | </div> |
50 | <div class="mat-padding" fxLayout="column" fxLayoutGap="8px"> | 50 | <div class="mat-padding" fxLayout="column" fxLayoutGap="8px"> |
51 | <form [formGroup]="entityForm"> | 51 | <form [formGroup]="entityForm"> |
52 | - <fieldset [disabled]="(isLoading$ | async) || !isEdit" fxLayout="column" fxLayoutGap="8px"> | 52 | + <fieldset [disabled]="(isLoading$ | async) || !isEdit" fxLayout="column"> |
53 | <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayout.xs="column"> | 53 | <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayout.xs="column"> |
54 | <mat-form-field class="mat-block" fxFlex="45"> | 54 | <mat-form-field class="mat-block" fxFlex="45"> |
55 | <mat-label translate>ota-update.title</mat-label> | 55 | <mat-label translate>ota-update.title</mat-label> |
@@ -83,44 +83,68 @@ | @@ -83,44 +83,68 @@ | ||
83 | </mat-option> | 83 | </mat-option> |
84 | </mat-select> | 84 | </mat-select> |
85 | </mat-form-field> | 85 | </mat-form-field> |
86 | - <div class="mat-caption" translate *ngIf="isAdd">ota-update.warning-after-save-no-edit</div> | ||
87 | - <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column"> | ||
88 | - <mat-form-field class="mat-block" fxFlex="33"> | ||
89 | - <mat-label translate>ota-update.checksum-algorithm</mat-label> | ||
90 | - <mat-select formControlName="checksumAlgorithm"> | ||
91 | - <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm"> | ||
92 | - {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} | ||
93 | - </mat-option> | ||
94 | - </mat-select> | ||
95 | - </mat-form-field> | ||
96 | - <mat-form-field class="mat-block" fxFlex> | ||
97 | - <mat-label translate>ota-update.checksum</mat-label> | ||
98 | - <input matInput formControlName="checksum" type="text" [readonly]="!isAdd"> | ||
99 | - </mat-form-field> | ||
100 | - </div> | ||
101 | <section *ngIf="isAdd"> | 86 | <section *ngIf="isAdd"> |
102 | - <tb-file-input | ||
103 | - formControlName="file" | ||
104 | - workFromFileObj="true" | ||
105 | - required | ||
106 | - dropLabel="{{'ota-update.drop-file' | translate}}"> | ||
107 | - </tb-file-input> | 87 | + <div class="mat-caption" style="margin: -8px 0 8px;" translate>ota-update.warning-after-save-no-edit</div> |
88 | + <mat-radio-group formControlName="resource" fxLayoutGap="16px"> | ||
89 | + <mat-radio-button value="file">Upload binary file</mat-radio-button> | ||
90 | + <mat-radio-button value="url">Use external URL</mat-radio-button> | ||
91 | + </mat-radio-group> | ||
108 | </section> | 92 | </section> |
109 | - <section *ngIf="!isAdd"> | ||
110 | - <div fxLayout="row" fxLayoutGap.gt-md="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column"> | 93 | + <section *ngIf="entityForm.get('resource').value === 'file'"> |
94 | + <section *ngIf="isAdd"> | ||
95 | + <tb-file-input | ||
96 | + formControlName="file" | ||
97 | + workFromFileObj="true" | ||
98 | + [required]="entityForm.get('resource').value === 'file'" | ||
99 | + dropLabel="{{'ota-update.drop-file' | translate}}"> | ||
100 | + </tb-file-input> | ||
101 | + <mat-checkbox formControlName="generateChecksum" style="margin-top: 16px"> | ||
102 | + {{ 'ota-update.auto-generate-checksum' | translate }} | ||
103 | + </mat-checkbox> | ||
104 | + </section> | ||
105 | + <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayoutGap.sm="8px" | ||
106 | + fxLayout.xs="column" fxLayout.md="column" *ngIf="!(isAdd && this.entityForm.get('generateChecksum').value)"> | ||
111 | <mat-form-field class="mat-block" fxFlex="33"> | 107 | <mat-form-field class="mat-block" fxFlex="33"> |
112 | - <mat-label translate>ota-update.file-name</mat-label> | ||
113 | - <input matInput formControlName="fileName" type="text" readonly> | 108 | + <mat-label translate>ota-update.checksum-algorithm</mat-label> |
109 | + <mat-select formControlName="checksumAlgorithm"> | ||
110 | + <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm"> | ||
111 | + {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} | ||
112 | + </mat-option> | ||
113 | + </mat-select> | ||
114 | </mat-form-field> | 114 | </mat-form-field> |
115 | <mat-form-field class="mat-block" fxFlex> | 115 | <mat-form-field class="mat-block" fxFlex> |
116 | - <mat-label translate>ota-update.file-size-bytes</mat-label> | ||
117 | - <input matInput formControlName="dataSize" type="text" readonly> | ||
118 | - </mat-form-field> | ||
119 | - <mat-form-field class="mat-block" fxFlex> | ||
120 | - <mat-label translate>ota-update.content-type</mat-label> | ||
121 | - <input matInput formControlName="contentType" type="text" readonly> | 116 | + <mat-label translate>ota-update.checksum</mat-label> |
117 | + <input matInput formControlName="checksum" type="text"> | ||
118 | + <mat-hint *ngIf="isAdd" translate>ota-update.checksum-hint</mat-hint> | ||
122 | </mat-form-field> | 119 | </mat-form-field> |
123 | </div> | 120 | </div> |
121 | + <section *ngIf="!isAdd"> | ||
122 | + <div fxLayout="row" fxLayoutGap.gt-md="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column"> | ||
123 | + <mat-form-field class="mat-block" fxFlex="33"> | ||
124 | + <mat-label translate>ota-update.file-name</mat-label> | ||
125 | + <input matInput formControlName="fileName" type="text"> | ||
126 | + </mat-form-field> | ||
127 | + <mat-form-field class="mat-block" fxFlex> | ||
128 | + <mat-label translate>ota-update.file-size-bytes</mat-label> | ||
129 | + <input matInput formControlName="dataSize" type="text"> | ||
130 | + </mat-form-field> | ||
131 | + <mat-form-field class="mat-block" fxFlex> | ||
132 | + <mat-label translate>ota-update.content-type</mat-label> | ||
133 | + <input matInput formControlName="contentType" type="text"> | ||
134 | + </mat-form-field> | ||
135 | + </div> | ||
136 | + </section> | ||
137 | + </section> | ||
138 | + <section *ngIf="entityForm.get('resource').value === 'url'" style="margin-top: 8px"> | ||
139 | + <mat-form-field class="mat-block"> | ||
140 | + <mat-label translate>ota-update.url</mat-label> | ||
141 | + <input matInput formControlName="url" | ||
142 | + type="text" | ||
143 | + [required]="entityForm.get('resource').value === 'url'"> | ||
144 | + <mat-error *ngIf="entityForm.get('url').hasError('required')" translate> | ||
145 | + ota-update.url-required | ||
146 | + </mat-error> | ||
147 | + </mat-form-field> | ||
124 | </section> | 148 | </section> |
125 | <div formGroupName="additionalInfo"> | 149 | <div formGroupName="additionalInfo"> |
126 | <mat-form-field class="mat-block"> | 150 | <mat-form-field class="mat-block"> |
@@ -30,6 +30,8 @@ import { | @@ -30,6 +30,8 @@ import { | ||
30 | OtaUpdateTypeTranslationMap | 30 | OtaUpdateTypeTranslationMap |
31 | } from '@shared/models/ota-package.models'; | 31 | } from '@shared/models/ota-package.models'; |
32 | import { ActionNotificationShow } from '@core/notification/notification.actions'; | 32 | import { ActionNotificationShow } from '@core/notification/notification.actions'; |
33 | +import { filter, takeUntil } from 'rxjs/operators'; | ||
34 | +import { isNotEmptyStr } from '@core/utils'; | ||
33 | 35 | ||
34 | @Component({ | 36 | @Component({ |
35 | selector: 'tb-ota-update', | 37 | selector: 'tb-ota-update', |
@@ -52,6 +54,26 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | @@ -52,6 +54,26 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | ||
52 | super(store, fb, entityValue, entitiesTableConfigValue); | 54 | super(store, fb, entityValue, entitiesTableConfigValue); |
53 | } | 55 | } |
54 | 56 | ||
57 | + ngOnInit() { | ||
58 | + super.ngOnInit(); | ||
59 | + this.entityForm.get('resource').valueChanges.pipe( | ||
60 | + filter(() => this.isAdd), | ||
61 | + takeUntil(this.destroy$) | ||
62 | + ).subscribe((resource) => { | ||
63 | + if (resource === 'file') { | ||
64 | + this.entityForm.get('url').clearValidators(); | ||
65 | + this.entityForm.get('file').setValidators(Validators.required); | ||
66 | + this.entityForm.get('url').updateValueAndValidity({emitEvent: false}); | ||
67 | + this.entityForm.get('file').updateValueAndValidity({emitEvent: false}); | ||
68 | + } else { | ||
69 | + this.entityForm.get('file').clearValidators(); | ||
70 | + this.entityForm.get('url').setValidators(Validators.required); | ||
71 | + this.entityForm.get('file').updateValueAndValidity({emitEvent: false}); | ||
72 | + this.entityForm.get('url').updateValueAndValidity({emitEvent: false}); | ||
73 | + } | ||
74 | + }); | ||
75 | + } | ||
76 | + | ||
55 | ngOnDestroy() { | 77 | ngOnDestroy() { |
56 | super.ngOnDestroy(); | 78 | super.ngOnDestroy(); |
57 | this.destroy$.next(); | 79 | this.destroy$.next(); |
@@ -74,6 +96,8 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | @@ -74,6 +96,8 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | ||
74 | deviceProfileId: [entity ? entity.deviceProfileId : null, Validators.required], | 96 | deviceProfileId: [entity ? entity.deviceProfileId : null, Validators.required], |
75 | checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256], | 97 | checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256], |
76 | checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], | 98 | checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], |
99 | + url: [entity ? entity.url : ''], | ||
100 | + resource: ['file'], | ||
77 | additionalInfo: this.fb.group( | 101 | additionalInfo: this.fb.group( |
78 | { | 102 | { |
79 | description: [entity && entity.additionalInfo ? entity.additionalInfo.description : ''], | 103 | description: [entity && entity.additionalInfo ? entity.additionalInfo.description : ''], |
@@ -82,6 +106,7 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | @@ -82,6 +106,7 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | ||
82 | }); | 106 | }); |
83 | if (this.isAdd) { | 107 | if (this.isAdd) { |
84 | form.addControl('file', this.fb.control(null, Validators.required)); | 108 | form.addControl('file', this.fb.control(null, Validators.required)); |
109 | + form.addControl('generateChecksum', this.fb.control(true)); | ||
85 | } else { | 110 | } else { |
86 | form.addControl('fileName', this.fb.control(null)); | 111 | form.addControl('fileName', this.fb.control(null)); |
87 | form.addControl('dataSize', this.fb.control(null)); | 112 | form.addControl('dataSize', this.fb.control(null)); |
@@ -101,6 +126,8 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | @@ -101,6 +126,8 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | ||
101 | fileName: entity.fileName, | 126 | fileName: entity.fileName, |
102 | dataSize: entity.dataSize, | 127 | dataSize: entity.dataSize, |
103 | contentType: entity.contentType, | 128 | contentType: entity.contentType, |
129 | + url: entity.url, | ||
130 | + resource: isNotEmptyStr(entity.url) ? 'url' : 'file', | ||
104 | additionalInfo: { | 131 | additionalInfo: { |
105 | description: entity.additionalInfo ? entity.additionalInfo.description : '' | 132 | description: entity.additionalInfo ? entity.additionalInfo.description : '' |
106 | } | 133 | } |
@@ -108,8 +135,6 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | @@ -108,8 +135,6 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | ||
108 | if (!this.isAdd && this.entityForm.enabled) { | 135 | if (!this.isAdd && this.entityForm.enabled) { |
109 | this.entityForm.disable({emitEvent: false}); | 136 | this.entityForm.disable({emitEvent: false}); |
110 | this.entityForm.get('additionalInfo').enable({emitEvent: false}); | 137 | this.entityForm.get('additionalInfo').enable({emitEvent: false}); |
111 | - // this.entityForm.get('dataSize').disable({emitEvent: false}); | ||
112 | - // this.entityForm.get('contentType').disable({emitEvent: false}); | ||
113 | } | 138 | } |
114 | } | 139 | } |
115 | 140 | ||
@@ -124,14 +149,9 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | @@ -124,14 +149,9 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O | ||
124 | })); | 149 | })); |
125 | } | 150 | } |
126 | 151 | ||
127 | - onPackageChecksumCopied() { | ||
128 | - this.store.dispatch(new ActionNotificationShow( | ||
129 | - { | ||
130 | - message: this.translate.instant('ota-update.checksum-copied-message'), | ||
131 | - type: 'success', | ||
132 | - duration: 750, | ||
133 | - verticalPosition: 'bottom', | ||
134 | - horizontalPosition: 'right' | ||
135 | - })); | 152 | + prepareFormValue(formValue: any): any { |
153 | + delete formValue.resource; | ||
154 | + delete formValue.generateChecksum; | ||
155 | + return super.prepareFormValue(formValue); | ||
136 | } | 156 | } |
137 | } | 157 | } |
@@ -87,6 +87,7 @@ export interface OtaPackageInfo extends BaseData<OtaPackageId> { | @@ -87,6 +87,7 @@ export interface OtaPackageInfo extends BaseData<OtaPackageId> { | ||
87 | title?: string; | 87 | title?: string; |
88 | version?: string; | 88 | version?: string; |
89 | hasData?: boolean; | 89 | hasData?: boolean; |
90 | + url?: string; | ||
90 | fileName: string; | 91 | fileName: string; |
91 | checksum?: string; | 92 | checksum?: string; |
92 | checksumAlgorithm?: ChecksumAlgorithm; | 93 | checksumAlgorithm?: ChecksumAlgorithm; |
@@ -575,7 +575,8 @@ | @@ -575,7 +575,8 @@ | ||
575 | "enter-password": "Enter password", | 575 | "enter-password": "Enter password", |
576 | "enter-search": "Enter search", | 576 | "enter-search": "Enter search", |
577 | "created-time": "Created time", | 577 | "created-time": "Created time", |
578 | - "loading": "Loading..." | 578 | + "loading": "Loading...", |
579 | + "proceed": "Proceed" | ||
579 | }, | 580 | }, |
580 | "content-type": { | 581 | "content-type": { |
581 | "json": "Json", | 582 | "json": "Json", |
@@ -2152,12 +2153,14 @@ | @@ -2152,12 +2153,14 @@ | ||
2152 | "assign-firmware-required": "Assigned firmware is required", | 2153 | "assign-firmware-required": "Assigned firmware is required", |
2153 | "assign-software": "Assigned software", | 2154 | "assign-software": "Assigned software", |
2154 | "assign-software-required": "Assigned software is required", | 2155 | "assign-software-required": "Assigned software is required", |
2156 | + "auto-generate-checksum": "Auto-generate checksum", | ||
2155 | "checksum": "Checksum", | 2157 | "checksum": "Checksum", |
2158 | + "checksum-hint": "If checksum is empty, it will be generated automatically", | ||
2156 | "checksum-algorithm": "Checksum algorithm", | 2159 | "checksum-algorithm": "Checksum algorithm", |
2157 | "checksum-copied-message": "Package checksum has been copied to clipboard", | 2160 | "checksum-copied-message": "Package checksum has been copied to clipboard", |
2158 | - "change-firmware": "You have changed the firmware. This may cause update of the { count, plural, 1 {1 device} other {# devices} }.", | ||
2159 | - "change-software": "You have changed the software. This may cause update of the { count, plural, 1 {1 device} other {# devices} }.", | ||
2160 | - "chose-compatible-device-profile": "Choose compatible device profile. The uploaded package will be available only for devices with the chosen profile.", | 2161 | + "change-firmware": "Change of the firmware may cause update of { count, plural, 1 {1 device} other {# devices} }.", |
2162 | + "change-software": "Change of the software may cause update of { count, plural, 1 {1 device} other {# devices} }.", | ||
2163 | + "chose-compatible-device-profile": "The uploaded package will be available only for devices with the chosen profile.", | ||
2161 | "chose-firmware-distributed-device": "Choose firmware that will be distributed to the devices", | 2164 | "chose-firmware-distributed-device": "Choose firmware that will be distributed to the devices", |
2162 | "chose-software-distributed-device": "Choose software that will be distributed to the devices", | 2165 | "chose-software-distributed-device": "Choose software that will be distributed to the devices", |
2163 | "content-type": "Content type", | 2166 | "content-type": "Content type", |
@@ -2193,6 +2196,8 @@ | @@ -2193,6 +2196,8 @@ | ||
2193 | "firmware": "Firmware", | 2196 | "firmware": "Firmware", |
2194 | "software": "Software" | 2197 | "software": "Software" |
2195 | }, | 2198 | }, |
2199 | + "url": "Direct URL", | ||
2200 | + "url-required": "Direct URL is required", | ||
2196 | "version": "Version", | 2201 | "version": "Version", |
2197 | "version-required": "Version is required.", | 2202 | "version-required": "Version is required.", |
2198 | "warning-after-save-no-edit": "Once the package is uploaded, you will not be able to modify title, version, device profile and package type." | 2203 | "warning-after-save-no-edit": "Once the package is uploaded, you will not be able to modify title, version, device profile and package type." |