18 changed files with 697 additions and 32 deletions
@ -0,0 +1,123 @@ |
|||
///
|
|||
/// Copyright © 2016-2021 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Injectable } from '@angular/core'; |
|||
import { HttpClient } from '@angular/common/http'; |
|||
import { PageLink } from '@shared/models/page/page-link'; |
|||
import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils'; |
|||
import { Observable } from 'rxjs'; |
|||
import { PageData } from '@shared/models/page/page-data'; |
|||
import { Firmware, FirmwareInfo } from '@shared/models/firmware.models'; |
|||
import { catchError, map, mergeMap } from 'rxjs/operators'; |
|||
import { deepClone, isDefinedAndNotNull } from '@core/utils'; |
|||
import { InterceptorHttpParams } from '@core/interceptors/interceptor-http-params'; |
|||
import { InterceptorConfig } from '@core/interceptors/interceptor-config'; |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root' |
|||
}) |
|||
export class FirmwareService { |
|||
constructor( |
|||
private http: HttpClient |
|||
) { |
|||
|
|||
} |
|||
|
|||
public getFirmwares(pageLink: PageLink, hasData?: boolean, config?: RequestConfig): Observable<PageData<FirmwareInfo>> { |
|||
let url = `/api/firmwares${pageLink.toQuery()}`; |
|||
if (isDefinedAndNotNull(hasData)) { |
|||
url += `&hasData=${hasData}`; |
|||
} |
|||
return this.http.get<PageData<FirmwareInfo>>(url, defaultHttpOptionsFromConfig(config)); |
|||
} |
|||
|
|||
public getFirmware(firmwareId: string, config?: RequestConfig): Observable<Firmware> { |
|||
return this.http.get<Firmware>(`/api/firmware/${firmwareId}`, defaultHttpOptionsFromConfig(config)); |
|||
} |
|||
|
|||
public getFirmwareInfo(firmwareId: string, config?: RequestConfig): Observable<FirmwareInfo> { |
|||
return this.http.get<FirmwareInfo>(`/api/firmware/info/${firmwareId}`, defaultHttpOptionsFromConfig(config)); |
|||
} |
|||
|
|||
public downloadFirmware(firmwareId: string): Observable<any> { |
|||
return this.http.get(`/api/firmware/${firmwareId}/download`, { responseType: 'arraybuffer', observe: 'response' }).pipe( |
|||
map((response) => { |
|||
const headers = response.headers; |
|||
const filename = headers.get('x-filename'); |
|||
const contentType = headers.get('content-type'); |
|||
const linkElement = document.createElement('a'); |
|||
try { |
|||
const blob = new Blob([response.body], { type: contentType }); |
|||
const url = URL.createObjectURL(blob); |
|||
linkElement.setAttribute('href', url); |
|||
linkElement.setAttribute('download', filename); |
|||
const clickEvent = new MouseEvent('click', |
|||
{ |
|||
view: window, |
|||
bubbles: true, |
|||
cancelable: false |
|||
} |
|||
); |
|||
linkElement.dispatchEvent(clickEvent); |
|||
return null; |
|||
} catch (e) { |
|||
throw e; |
|||
} |
|||
}) |
|||
); |
|||
} |
|||
|
|||
public saveFirmware(firmware: Firmware, config?: RequestConfig): Observable<Firmware> { |
|||
if (!firmware.file) { |
|||
return this.saveFirmwareInfo(firmware, config); |
|||
} |
|||
const firmwareInfo = deepClone(firmware); |
|||
delete firmwareInfo.file; |
|||
delete firmwareInfo.checksum; |
|||
delete firmwareInfo.checksumAlgorithm; |
|||
return this.saveFirmwareInfo(firmwareInfo, config).pipe( |
|||
mergeMap(res => { |
|||
return this.uploadFirmwareFile(res.id.id, firmware.file, firmware.checksumAlgorithm, firmware.checksum).pipe( |
|||
catchError(() => this.deleteFirmware(res.id.id)) |
|||
); |
|||
}) |
|||
); |
|||
} |
|||
|
|||
public saveFirmwareInfo(firmware: FirmwareInfo, config?: RequestConfig): Observable<Firmware> { |
|||
return this.http.post<Firmware>('/api/firmware', firmware, defaultHttpOptionsFromConfig(config)); |
|||
} |
|||
|
|||
public uploadFirmwareFile(firmwareId: string, file: File, checksumAlgorithm?: string, |
|||
checksum?: string, config?: RequestConfig): Observable<any> { |
|||
if (!config) { |
|||
config = {}; |
|||
} |
|||
const formData = new FormData(); |
|||
formData.append('file', file); |
|||
let url = `/api/firmware/${firmwareId}`; |
|||
if (checksumAlgorithm && checksum) { |
|||
url += `?checksumAlgorithm=${checksumAlgorithm}&checksum=${checksum}`; |
|||
} |
|||
return this.http.post(url, formData, |
|||
defaultHttpUploadOptions(config.ignoreLoading, config.ignoreErrors, config.resendRequest)); |
|||
} |
|||
|
|||
public deleteFirmware(firmwareId: string, config?: RequestConfig) { |
|||
return this.http.delete(`/api/firmware/${firmwareId}`, defaultHttpOptionsFromConfig(config)); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
///
|
|||
/// Copyright © 2016-2021 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { RouterModule, Routes } from '@angular/router'; |
|||
import { EntitiesTableComponent } from '@home/components/entity/entities-table.component'; |
|||
import { Authority } from '@shared/models/authority.enum'; |
|||
import { NgModule } from '@angular/core'; |
|||
import { FirmwareTableConfigResolve } from '@home/pages/firmware/firmware-table-config.resolve'; |
|||
|
|||
const routes: Routes = [ |
|||
{ |
|||
path: 'firmwares', |
|||
component: EntitiesTableComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN], |
|||
title: 'firmware.firmware', |
|||
breadcrumb: { |
|||
label: 'firmware.firmware', |
|||
icon: 'memory' |
|||
} |
|||
}, |
|||
resolve: { |
|||
entitiesTableConfig: FirmwareTableConfigResolve |
|||
} |
|||
} |
|||
]; |
|||
|
|||
@NgModule({ |
|||
imports: [RouterModule.forChild(routes)], |
|||
exports: [RouterModule], |
|||
providers: [ |
|||
FirmwareTableConfigResolve |
|||
] |
|||
}) |
|||
export class FirmwareRoutingModule{ } |
|||
@ -0,0 +1,99 @@ |
|||
///
|
|||
/// Copyright © 2016-2021 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Injectable } from '@angular/core'; |
|||
import { Resolve } from '@angular/router'; |
|||
import { |
|||
DateEntityTableColumn, |
|||
EntityTableColumn, |
|||
EntityTableConfig |
|||
} from '@home/models/entity/entities-table-config.models'; |
|||
import { Firmware, FirmwareInfo } from '@shared/models/firmware.models'; |
|||
import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; |
|||
import { TranslateService } from '@ngx-translate/core'; |
|||
import { DatePipe } from '@angular/common'; |
|||
import { FirmwareService } from '@core/http/firmware.service'; |
|||
import { PageLink } from '@shared/models/page/page-link'; |
|||
import { FirmwaresComponent } from '@home/pages/firmware/firmwares.component'; |
|||
import { EntityAction } from '@home/models/entity/entity-component.models'; |
|||
import { DeviceInfo } from '@shared/models/device.models'; |
|||
|
|||
@Injectable() |
|||
export class FirmwareTableConfigResolve implements Resolve<EntityTableConfig<Firmware, PageLink, FirmwareInfo>> { |
|||
|
|||
private readonly config: EntityTableConfig<Firmware, PageLink, FirmwareInfo> = new EntityTableConfig<Firmware, PageLink, FirmwareInfo>(); |
|||
|
|||
constructor(private translate: TranslateService, |
|||
private datePipe: DatePipe, |
|||
private firmwareService: FirmwareService) { |
|||
this.config.entityType = EntityType.FIRMWARE; |
|||
this.config.entityComponent = FirmwaresComponent; |
|||
this.config.entityTranslations = entityTypeTranslations.get(EntityType.FIRMWARE); |
|||
this.config.entityResources = entityTypeResources.get(EntityType.FIRMWARE); |
|||
|
|||
this.config.entityTitle = (firmware) => firmware ? firmware.title : ''; |
|||
|
|||
this.config.columns.push( |
|||
new DateEntityTableColumn<FirmwareInfo>('createdTime', 'common.created-time', this.datePipe, '150px'), |
|||
new EntityTableColumn<FirmwareInfo>('title', 'firmware.title', '50%'), |
|||
new EntityTableColumn<FirmwareInfo>('version', 'firmware.version', '50%') |
|||
); |
|||
|
|||
this.config.cellActionDescriptors.push( |
|||
{ |
|||
name: this.translate.instant('firmware.export'), |
|||
icon: 'file_download', |
|||
isEnabled: (firmware) => firmware.hasData, |
|||
onAction: ($event, entity) => this.exportFirmware($event, entity) |
|||
} |
|||
); |
|||
|
|||
this.config.deleteEntityTitle = firmware => this.translate.instant('firmware.delete-firmware-title', |
|||
{ firmwareTitle: firmware.title }); |
|||
this.config.deleteEntityContent = () => this.translate.instant('firmware.delete-firmware-text'); |
|||
this.config.deleteEntitiesTitle = count => this.translate.instant('firmware.delete-firmwares-title', {count}); |
|||
this.config.deleteEntitiesContent = () => this.translate.instant('firmware.delete-firmwares-text'); |
|||
|
|||
this.config.entitiesFetchFunction = pageLink => this.firmwareService.getFirmwares(pageLink); |
|||
this.config.loadEntity = id => this.firmwareService.getFirmwareInfo(id.id); |
|||
this.config.saveEntity = firmware => this.firmwareService.saveFirmware(firmware); |
|||
this.config.deleteEntity = id => this.firmwareService.deleteFirmware(id.id); |
|||
|
|||
this.config.onEntityAction = action => this.onFirmwareAction(action); |
|||
} |
|||
|
|||
resolve(): EntityTableConfig<Firmware, PageLink, FirmwareInfo> { |
|||
this.config.tableTitle = this.translate.instant('firmware.firmware'); |
|||
return this.config; |
|||
} |
|||
|
|||
exportFirmware($event: Event, firmware: FirmwareInfo) { |
|||
if ($event) { |
|||
$event.stopPropagation(); |
|||
} |
|||
this.firmwareService.downloadFirmware(firmware.id.id).subscribe(); |
|||
} |
|||
|
|||
onFirmwareAction(action: EntityAction<FirmwareInfo>): boolean { |
|||
switch (action.action) { |
|||
case 'uploadFirmware': |
|||
this.exportFirmware(action.event, action.entity); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
///
|
|||
/// Copyright © 2016-2021 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { SharedModule } from '@shared/shared.module'; |
|||
import { HomeComponentsModule } from '@home/components/home-components.module'; |
|||
import { FirmwareRoutingModule } from '@home/pages/firmware/firmware-routing.module'; |
|||
import { FirmwaresComponent } from '@home/pages/firmware/firmwares.component'; |
|||
|
|||
@NgModule({ |
|||
declarations: [ |
|||
FirmwaresComponent |
|||
], |
|||
imports: [ |
|||
CommonModule, |
|||
SharedModule, |
|||
HomeComponentsModule, |
|||
FirmwareRoutingModule |
|||
] |
|||
}) |
|||
export class FirmwareModule { } |
|||
@ -0,0 +1,87 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2021 The Thingsboard Authors |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
|
|||
--> |
|||
<div class="tb-details-buttons" fxLayout.xs="column"> |
|||
<button mat-raised-button color="primary" fxFlex.xs |
|||
[disabled]="(isLoading$ | async) || !entity?.hasData" |
|||
(click)="onEntityAction($event, 'uploadFirmware')" |
|||
[fxShow]="!isEdit"> |
|||
{{'firmware.export' | translate }} |
|||
</button> |
|||
<button mat-raised-button color="primary" fxFlex.xs |
|||
[disabled]="(isLoading$ | async)" |
|||
(click)="onEntityAction($event, 'delete')" |
|||
[fxShow]="!hideDelete() && !isEdit"> |
|||
{{'resource.delete' | translate }} |
|||
</button> |
|||
</div> |
|||
<div class="mat-padding" fxLayout="column"> |
|||
<form [formGroup]="entityForm"> |
|||
<fieldset [disabled]="(isLoading$ | async) || !isEdit"> |
|||
<mat-hint class="tb-hint" translate *ngIf="isAdd">firmware.warning-after-save-no-edit</mat-hint> |
|||
<div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayout.xs="column"> |
|||
<mat-form-field class="mat-block" fxFlex="45"> |
|||
<mat-label translate>firmware.title</mat-label> |
|||
<input matInput formControlName="title" type="text" required> |
|||
<mat-error *ngIf="entityForm.get('title').hasError('required')"> |
|||
{{ 'firmware.title-required' | translate }} |
|||
</mat-error> |
|||
</mat-form-field> |
|||
<mat-form-field class="mat-block" fxFlex> |
|||
<mat-label translate>firmware.version</mat-label> |
|||
<input matInput formControlName="version" type="text" required> |
|||
<mat-error *ngIf="entityForm.get('version').hasError('required')"> |
|||
{{ 'firmware.version-required' | translate }} |
|||
</mat-error> |
|||
</mat-form-field> |
|||
</div> |
|||
<section *ngIf="isAdd" style="padding-bottom: 8px"> |
|||
<div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayout.xs="column"> |
|||
<mat-form-field class="mat-block" fxFlex="45"> |
|||
<mat-label translate>firmware.checksum-algorithm</mat-label> |
|||
<mat-select formControlName="checksumAlgorithm"> |
|||
<mat-option [value]=null></mat-option> |
|||
<mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm"> |
|||
{{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} |
|||
</mat-option> |
|||
</mat-select> |
|||
</mat-form-field> |
|||
<mat-form-field class="mat-block" fxFlex> |
|||
<mat-label translate>firmware.checksum</mat-label> |
|||
<input matInput formControlName="checksum" type="text" |
|||
[required]="entityForm.get('checksumAlgorithm').value != null"> |
|||
<mat-error *ngIf="entityForm.get('checksumAlgorithm').hasError('required')"> |
|||
{{ 'firmware.checksum-required' | translate }} |
|||
</mat-error> |
|||
</mat-form-field> |
|||
</div> |
|||
<tb-file-input |
|||
formControlName="file" |
|||
workFromFileObj="true" |
|||
required |
|||
dropLabel="{{'resource.drop-file' | translate}}"> |
|||
</tb-file-input> |
|||
</section> |
|||
<div formGroupName="additionalInfo"> |
|||
<mat-form-field class="mat-block"> |
|||
<mat-label translate>firmware.description</mat-label> |
|||
<textarea matInput formControlName="description" rows="2"></textarea> |
|||
</mat-form-field> |
|||
</div> |
|||
</fieldset> |
|||
</form> |
|||
</div> |
|||
@ -0,0 +1,112 @@ |
|||
///
|
|||
/// Copyright © 2016-2021 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; |
|||
import { Subject } from 'rxjs'; |
|||
import { Store } from '@ngrx/store'; |
|||
import { AppState } from '@core/core.state'; |
|||
import { TranslateService } from '@ngx-translate/core'; |
|||
import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; |
|||
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; |
|||
import { EntityComponent } from '@home/components/entity/entity.component'; |
|||
import { ChecksumAlgorithm, ChecksumAlgorithmTranslationMap, Firmware } from '@shared/models/firmware.models'; |
|||
import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; |
|||
|
|||
@Component({ |
|||
selector: 'tb-firmware', |
|||
templateUrl: './firmwares.component.html' |
|||
}) |
|||
export class FirmwaresComponent extends EntityComponent<Firmware> implements OnInit, OnDestroy { |
|||
|
|||
private destroy$ = new Subject(); |
|||
|
|||
checksumAlgorithms = Object.values(ChecksumAlgorithm); |
|||
checksumAlgorithmTranslationMap = ChecksumAlgorithmTranslationMap; |
|||
|
|||
constructor(protected store: Store<AppState>, |
|||
protected translate: TranslateService, |
|||
@Inject('entity') protected entityValue: Firmware, |
|||
@Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<Firmware>, |
|||
public fb: FormBuilder) { |
|||
super(store, fb, entityValue, entitiesTableConfigValue); |
|||
} |
|||
|
|||
ngOnInit() { |
|||
super.ngOnInit(); |
|||
if (this.isAdd) { |
|||
this.entityForm.get('checksumAlgorithm').valueChanges.pipe( |
|||
map(algorithm => !!algorithm), |
|||
distinctUntilChanged(), |
|||
takeUntil(this.destroy$) |
|||
).subscribe( |
|||
setAlgorithm => { |
|||
if (setAlgorithm) { |
|||
this.entityForm.get('checksum').setValidators([Validators.maxLength(1020), Validators.required]); |
|||
} else { |
|||
this.entityForm.get('checksum').clearValidators(); |
|||
} |
|||
this.entityForm.get('checksum').updateValueAndValidity({emitEvent: false}); |
|||
} |
|||
); |
|||
} |
|||
} |
|||
|
|||
ngOnDestroy() { |
|||
super.ngOnDestroy(); |
|||
this.destroy$.next(); |
|||
this.destroy$.complete(); |
|||
} |
|||
|
|||
hideDelete() { |
|||
if (this.entitiesTableConfig) { |
|||
return !this.entitiesTableConfig.deleteEnabled(this.entity); |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
buildForm(entity: Firmware): FormGroup { |
|||
const form = this.fb.group({ |
|||
title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], |
|||
version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], |
|||
additionalInfo: this.fb.group( |
|||
{ |
|||
description: [entity && entity.additionalInfo ? entity.additionalInfo.description : ''], |
|||
} |
|||
) |
|||
}); |
|||
if (this.isAdd) { |
|||
form.addControl('checksumAlgorithm', this.fb.control(null)); |
|||
form.addControl('checksum', this.fb.control('', Validators.maxLength(1020))); |
|||
form.addControl('file', this.fb.control(null, Validators.required)); |
|||
} |
|||
return form; |
|||
} |
|||
|
|||
updateForm(entity: Firmware) { |
|||
if (this.isEdit) { |
|||
this.entityForm.get('title').disable({emitEvent: false}); |
|||
this.entityForm.get('version').disable({emitEvent: false}); |
|||
} |
|||
this.entityForm.patchValue({ |
|||
title: entity.title, |
|||
version: entity.version, |
|||
additionalInfo: { |
|||
description: entity.additionalInfo ? entity.additionalInfo.description : '' |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
///
|
|||
/// Copyright © 2016-2021 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { BaseData } from '@shared/models/base-data'; |
|||
import { TenantId } from '@shared/models/id/tenant-id'; |
|||
import { FirmwareId } from '@shared/models/id/firmware-id'; |
|||
|
|||
export enum ChecksumAlgorithm { |
|||
MD5 = 'md5', |
|||
SHA256 = 'sha256', |
|||
CRC32 = 'crc32' |
|||
} |
|||
|
|||
export const ChecksumAlgorithmTranslationMap = new Map<ChecksumAlgorithm, string>( |
|||
[ |
|||
[ChecksumAlgorithm.MD5, 'MD5'], |
|||
[ChecksumAlgorithm.SHA256, 'SHA-256'], |
|||
[ChecksumAlgorithm.CRC32, 'CRC-32'] |
|||
] |
|||
); |
|||
|
|||
export interface FirmwareInfo extends BaseData<FirmwareId> { |
|||
tenantId?: TenantId; |
|||
title?: string; |
|||
version?: string; |
|||
hasData?: boolean; |
|||
additionalInfo?: any; |
|||
} |
|||
|
|||
export interface Firmware extends FirmwareInfo { |
|||
file?: File; |
|||
data: string; |
|||
fileName: string; |
|||
checksum?: ChecksumAlgorithm; |
|||
checksumAlgorithm?: string; |
|||
contentType: string; |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
///
|
|||
/// Copyright © 2016-2021 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { EntityId } from '@shared/models/id/entity-id'; |
|||
import { EntityType } from '@shared/models/entity-type.models'; |
|||
|
|||
export class FirmwareId implements EntityId { |
|||
entityType = EntityType.FIRMWARE; |
|||
id: string; |
|||
constructor(id: string) { |
|||
this.id = id; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue