Commit 52d07fe080c99765b8844d87c292df013f1052ba
Merge branch 'feature/ota-tag' of github.com:YevhenBondarenko/thingsboard into feature/ota-tag
Showing
7 changed files
with
52 additions
and
23 deletions
... | ... | @@ -62,6 +62,7 @@ public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackage |
62 | 62 | this.type = otaPackageInfo.getType(); |
63 | 63 | this.title = otaPackageInfo.getTitle(); |
64 | 64 | this.version = otaPackageInfo.getVersion(); |
65 | + this.tag = otaPackageInfo.getTag(); | |
65 | 66 | this.url = otaPackageInfo.getUrl(); |
66 | 67 | this.hasData = otaPackageInfo.isHasData(); |
67 | 68 | this.fileName = otaPackageInfo.getFileName(); | ... | ... |
... | ... | @@ -145,6 +145,7 @@ public class OtaPackageInfoEntity extends BaseSqlEntity<OtaPackageInfo> implemen |
145 | 145 | this.type = type; |
146 | 146 | this.title = title; |
147 | 147 | this.version = version; |
148 | + this.tag = tag; | |
148 | 149 | this.url = url; |
149 | 150 | this.fileName = fileName; |
150 | 151 | this.contentType = contentType; | ... | ... |
... | ... | @@ -59,9 +59,10 @@ export class OtaUpdateTableConfigResolve implements Resolve<EntityTableConfig<Ot |
59 | 59 | |
60 | 60 | this.config.columns.push( |
61 | 61 | new DateEntityTableColumn<OtaPackageInfo>('createdTime', 'common.created-time', this.datePipe, '150px'), |
62 | - new EntityTableColumn<OtaPackageInfo>('title', 'ota-update.title', '20%'), | |
63 | - new EntityTableColumn<OtaPackageInfo>('version', 'ota-update.version', '20%'), | |
64 | - new EntityTableColumn<OtaPackageInfo>('type', 'ota-update.package-type', '20%', entity => { | |
62 | + new EntityTableColumn<OtaPackageInfo>('title', 'ota-update.title', '15%'), | |
63 | + new EntityTableColumn<OtaPackageInfo>('version', 'ota-update.version', '15%'), | |
64 | + new EntityTableColumn<OtaPackageInfo>('tag', 'ota-update.version-tag', '15%'), | |
65 | + new EntityTableColumn<OtaPackageInfo>('type', 'ota-update.package-type', '15%', entity => { | |
65 | 66 | return this.translate.instant(OtaUpdateTypeTranslationMap.get(entity.type)); |
66 | 67 | }), |
67 | 68 | new EntityTableColumn<OtaPackageInfo>('url', 'ota-update.direct-url', '20%', entity => { | ... | ... |
... | ... | @@ -74,6 +74,11 @@ |
74 | 74 | </mat-error> |
75 | 75 | </mat-form-field> |
76 | 76 | </div> |
77 | + <mat-form-field class="mat-block" fxFlex style="margin-bottom: 8px"> | |
78 | + <mat-label translate>ota-update.version-tag</mat-label> | |
79 | + <input matInput formControlName="tag" type="text" [readonly]="!isAdd"> | |
80 | + <mat-hint *ngIf="isAdd" translate>ota-update.version-tag-hint</mat-hint> | |
81 | + </mat-form-field> | |
77 | 82 | <tb-device-profile-autocomplete |
78 | 83 | formControlName="deviceProfileId" |
79 | 84 | required |
... | ... | @@ -94,8 +99,8 @@ |
94 | 99 | <section *ngIf="isAdd"> |
95 | 100 | <div class="mat-caption" style="margin: -8px 0 8px;" translate>ota-update.warning-after-save-no-edit</div> |
96 | 101 | <mat-radio-group formControlName="isURL" fxLayoutGap="16px"> |
97 | - <mat-radio-button [value]="false">Upload binary file</mat-radio-button> | |
98 | - <mat-radio-button [value]="true">Use external URL</mat-radio-button> | |
102 | + <mat-radio-button [value]="false">{{ "ota-update.upload-binary-file" | translate }}</mat-radio-button> | |
103 | + <mat-radio-button [value]="true">{{ "ota-update.use-external-url" | translate }}</mat-radio-button> | |
99 | 104 | </mat-radio-group> |
100 | 105 | </section> |
101 | 106 | <section *ngIf="!entityForm.get('isURL').value"> | ... | ... |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | /// |
16 | 16 | |
17 | 17 | import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; |
18 | -import { Subject } from 'rxjs'; | |
18 | +import { combineLatest, Subject } from 'rxjs'; | |
19 | 19 | import { Store } from '@ngrx/store'; |
20 | 20 | import { AppState } from '@core/core.state'; |
21 | 21 | import { TranslateService } from '@ngx-translate/core'; |
... | ... | @@ -30,7 +30,7 @@ import { |
30 | 30 | OtaUpdateTypeTranslationMap |
31 | 31 | } from '@shared/models/ota-package.models'; |
32 | 32 | import { ActionNotificationShow } from '@core/notification/notification.actions'; |
33 | -import { filter, takeUntil } from 'rxjs/operators'; | |
33 | +import { filter, startWith, takeUntil } from 'rxjs/operators'; | |
34 | 34 | import { isNotEmptyStr } from '@core/utils'; |
35 | 35 | |
36 | 36 | @Component({ |
... | ... | @@ -56,22 +56,36 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O |
56 | 56 | |
57 | 57 | ngOnInit() { |
58 | 58 | super.ngOnInit(); |
59 | - this.entityForm.get('isURL').valueChanges.pipe( | |
60 | - filter(() => this.isAdd), | |
61 | - takeUntil(this.destroy$) | |
62 | - ).subscribe((isURL) => { | |
63 | - if (isURL === false) { | |
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, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]); | |
71 | - this.entityForm.get('file').updateValueAndValidity({emitEvent: false}); | |
72 | - this.entityForm.get('url').updateValueAndValidity({emitEvent: false}); | |
73 | - } | |
74 | - }); | |
59 | + if (this.isAdd) { | |
60 | + this.entityForm.get('isURL').valueChanges.pipe( | |
61 | + takeUntil(this.destroy$) | |
62 | + ).subscribe((isURL) => { | |
63 | + if (isURL === false) { | |
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, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]); | |
71 | + this.entityForm.get('file').updateValueAndValidity({emitEvent: false}); | |
72 | + this.entityForm.get('url').updateValueAndValidity({emitEvent: false}); | |
73 | + } | |
74 | + }); | |
75 | + combineLatest([ | |
76 | + this.entityForm.get('title').valueChanges.pipe(startWith(''), takeUntil(this.destroy$)), | |
77 | + this.entityForm.get('version').valueChanges.pipe(startWith(''), takeUntil(this.destroy$)) | |
78 | + ]).pipe( | |
79 | + filter(() => this.entityForm.get('tag').pristine), | |
80 | + takeUntil(this.destroy$) | |
81 | + ).subscribe(([title, version]) => { | |
82 | + let tag = `${title} ${version}`.trim(); | |
83 | + if (tag === '') { | |
84 | + tag = ''; | |
85 | + } | |
86 | + this.entityForm.get('tag').patchValue(tag); | |
87 | + }); | |
88 | + } | |
75 | 89 | } |
76 | 90 | |
77 | 91 | ngOnDestroy() { |
... | ... | @@ -92,6 +106,7 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O |
92 | 106 | const form = this.fb.group({ |
93 | 107 | title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], |
94 | 108 | version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], |
109 | + tag: [entity ? entity.tag : '', [Validators.maxLength(255)]], | |
95 | 110 | type: [entity?.type ? entity.type : OtaUpdateType.FIRMWARE, Validators.required], |
96 | 111 | deviceProfileId: [entity ? entity.deviceProfileId : null, Validators.required], |
97 | 112 | checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256], |
... | ... | @@ -119,6 +134,7 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O |
119 | 134 | this.entityForm.patchValue({ |
120 | 135 | title: entity.title, |
121 | 136 | version: entity.version, |
137 | + tag: entity.tag, | |
122 | 138 | type: entity.type, |
123 | 139 | deviceProfileId: entity.deviceProfileId, |
124 | 140 | checksumAlgorithm: entity.checksumAlgorithm, | ... | ... |
... | ... | @@ -2342,8 +2342,12 @@ |
2342 | 2342 | "firmware": "Firmware", |
2343 | 2343 | "software": "Software" |
2344 | 2344 | }, |
2345 | + "upload-binary-file": "Upload binary file", | |
2346 | + "use-external-url": "Use external URL", | |
2345 | 2347 | "version": "Version", |
2346 | 2348 | "version-required": "Version is required.", |
2349 | + "version-tag": "Version Tag", | |
2350 | + "version-tag-hint": "Custom tag should match the package version reported by your device.", | |
2347 | 2351 | "warning-after-save-no-edit": "Once the package is uploaded, you will not be able to modify title, version, device profile and package type." |
2348 | 2352 | }, |
2349 | 2353 | "position": { | ... | ... |