Commit 52d07fe080c99765b8844d87c292df013f1052ba

Authored by YevhenBondarenko
2 parents c9fbe743 5a880346

Merge branch 'feature/ota-tag' of github.com:YevhenBondarenko/thingsboard into feature/ota-tag

... ... @@ -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,
... ...
... ... @@ -91,6 +91,7 @@ export interface OtaPackageInfo extends BaseData<OtaPackageId> {
91 91 deviceProfileId?: DeviceProfileId;
92 92 title?: string;
93 93 version?: string;
  94 + tag?: string;
94 95 hasData?: boolean;
95 96 url?: string;
96 97 fileName: string;
... ...
... ... @@ -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": {
... ...