Merge pull request #5558 from Terny22/bootstrap-server-configs
[3.3.3] UI: Bootstrap server configs refactoring for LwM2M transport
This commit is contained in:
commit
d56b5cd00f
@ -100,6 +100,7 @@
|
||||
</mat-form-field>
|
||||
<tb-device-profile-transport-configuration
|
||||
formControlName="transportConfiguration"
|
||||
isAdd="true"
|
||||
required>
|
||||
</tb-device-profile-transport-configuration>
|
||||
</form>
|
||||
|
||||
@ -34,9 +34,7 @@
|
||||
<div *ngIf="!disabled" style="padding-top: 16px;">
|
||||
<button mat-raised-button color="primary"
|
||||
type="button"
|
||||
(click)="addAlarm()"
|
||||
matTooltip="{{ 'device-profile.add-alarm-rule' | translate }}"
|
||||
matTooltipPosition="above">
|
||||
(click)="addAlarm()">
|
||||
<span translate>device-profile.add-alarm-rule</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -138,6 +138,7 @@
|
||||
<ng-template matExpansionPanelContent>
|
||||
<tb-device-profile-transport-configuration
|
||||
formControlName="transportConfiguration"
|
||||
[isAdd] = "isTransportTypeChanged"
|
||||
required>
|
||||
</tb-device-profile-transport-configuration>
|
||||
</ng-template>
|
||||
|
||||
@ -67,6 +67,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
|
||||
|
||||
displayTransportConfiguration: boolean;
|
||||
|
||||
isTransportTypeChanged = false;
|
||||
|
||||
serviceType = ServiceType.TB_RULE_ENGINE;
|
||||
|
||||
deviceProfileId: EntityId;
|
||||
@ -158,6 +160,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
|
||||
const deviceTransportType: DeviceTransportType = form.get('transportType').value;
|
||||
this.displayTransportConfiguration = deviceTransportType &&
|
||||
deviceTransportTypeConfigurationInfoMap.get(deviceTransportType).hasProfileConfiguration;
|
||||
this.isTransportTypeChanged = true;
|
||||
let profileData: DeviceProfileData = form.getRawValue().profileData;
|
||||
if (!profileData) {
|
||||
profileData = {
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
</ng-template>
|
||||
<ng-template [ngSwitchCase]="deviceTransportType.LWM2M">
|
||||
<tb-profile-lwm2m-device-transport-configuration
|
||||
[isAdd]="isAdd"
|
||||
[required]="required"
|
||||
formControlName="configuration">
|
||||
</tb-profile-lwm2m-device-transport-configuration>
|
||||
|
||||
@ -50,6 +50,9 @@ export class DeviceProfileTransportConfigurationComponent implements ControlValu
|
||||
@Input()
|
||||
disabled: boolean;
|
||||
|
||||
@Input()
|
||||
isAdd: boolean;
|
||||
|
||||
transportType: DeviceTransportType;
|
||||
|
||||
private propagateChange = (v: any) => { };
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<form [formGroup]="addConfigServerFormGroup" style="width: 400px;">
|
||||
<mat-toolbar fxLayout="row" color="primary">
|
||||
<h2 translate>device-profile.lwm2m.add-new-server-title</h2>
|
||||
<span fxFlex></span>
|
||||
<button mat-button mat-icon-button (click)="cancel()" type="button">
|
||||
<mat-icon class="material-icons">close</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
|
||||
</mat-progress-bar>
|
||||
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
|
||||
<div mat-dialog-content fxLayout="column">
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'device-profile.lwm2m.server-type' | translate }}</mat-label>
|
||||
<mat-select formControlName="serverType">
|
||||
<mat-option *ngFor="let serverType of serverTypes"
|
||||
[value]="serverType">
|
||||
{{ serverConfigTypeNamesMap.get(serverType) | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions fxLayout="row">
|
||||
<span fxFlex></span>
|
||||
<button mat-button color="primary"
|
||||
type="button"
|
||||
[disabled]="(isLoading$ | async)"
|
||||
(click)="cancel()" cdkFocusInitial>
|
||||
{{ 'action.cancel' | translate }}
|
||||
</button>
|
||||
<button mat-button mat-raised-button color="primary"
|
||||
type="button"
|
||||
[disabled]="(isLoading$ | async) || addConfigServerFormGroup.invalid"
|
||||
(click)="addServerConfig()">
|
||||
{{ 'action.add' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,60 @@
|
||||
///
|
||||
/// 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 } from '@angular/core';
|
||||
import { DialogComponent } from '@shared/components/dialog.component';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { Router } from '@angular/router';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import {
|
||||
ServerConfigType,
|
||||
ServerConfigTypeTranslationMap
|
||||
} from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-profile-lwm2m-bootstrap-add-config-server-dialog',
|
||||
templateUrl: './lwm2m-bootstrap-add-config-server-dialog.component.html'
|
||||
})
|
||||
export class Lwm2mBootstrapAddConfigServerDialogComponent extends DialogComponent<Lwm2mBootstrapAddConfigServerDialogComponent> {
|
||||
|
||||
addConfigServerFormGroup: FormGroup;
|
||||
|
||||
serverTypes = Object.values(ServerConfigType);
|
||||
serverConfigTypeNamesMap = ServerConfigTypeTranslationMap;
|
||||
|
||||
constructor(protected store: Store<AppState>,
|
||||
protected router: Router,
|
||||
private fb: FormBuilder,
|
||||
public dialogRef: MatDialogRef<Lwm2mBootstrapAddConfigServerDialogComponent, boolean>,
|
||||
) {
|
||||
super(store, router, dialogRef);
|
||||
this.addConfigServerFormGroup = this.fb.group({
|
||||
serverType: [ServerConfigType.LWM2M]
|
||||
});
|
||||
}
|
||||
|
||||
addServerConfig() {
|
||||
this.dialogRef.close(this.addConfigServerFormGroup.get('serverType').value === ServerConfigType.BOOTSTRAP);
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.dialogRef.close(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
|
||||
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 fxLayout="column">
|
||||
<mat-accordion multi="true">
|
||||
<div *ngFor="let serverConfig of serverConfigsFromArray().controls; trackBy: trackByParams; let $index = index;">
|
||||
<tb-profile-lwm2m-device-config-server
|
||||
[formControl]="serverConfig"
|
||||
(removeServer)="removeServerConfig($event, $index)">
|
||||
</tb-profile-lwm2m-device-config-server>
|
||||
</div>
|
||||
</mat-accordion>
|
||||
<div *ngIf="!serverConfigsFromArray().controls.length" style="margin:32px 0">
|
||||
<span translate fxLayoutAlign="center center"
|
||||
class="tb-prompt">device-profile.lwm2m.no-config-servers</span>
|
||||
</div>
|
||||
<div *ngIf="!disabled" style="padding-top: 16px;">
|
||||
<button mat-raised-button color="primary"
|
||||
type="button"
|
||||
(click)="addServerConfig()">
|
||||
<span>{{ (isBootstrapAdded() ? 'device-profile.lwm2m.add-lwm2m-server-config' :
|
||||
'device-profile.lwm2m.add-server-config') | translate}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,185 @@
|
||||
///
|
||||
/// 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, forwardRef, Input, OnInit } from '@angular/core';
|
||||
import {
|
||||
AbstractControl,
|
||||
ControlValueAccessor,
|
||||
FormArray,
|
||||
FormBuilder, FormControl,
|
||||
FormGroup,
|
||||
NG_VALIDATORS,
|
||||
NG_VALUE_ACCESSOR
|
||||
} from '@angular/forms';
|
||||
import { of, Subscription } from 'rxjs';
|
||||
import { ServerSecurityConfig } from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DialogService } from '@core/services/dialog.service';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Lwm2mBootstrapAddConfigServerDialogComponent } from '@home/components/profile/device/lwm2m/lwm2m-bootstrap-add-config-server-dialog.component';
|
||||
import { mergeMap } from 'rxjs/operators';
|
||||
import { DeviceProfileService } from '@core/http/device-profile.service';
|
||||
import { Lwm2mSecurityType } from '@shared/models/lwm2m-security-config.models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-profile-lwm2m-bootstrap-config-servers',
|
||||
templateUrl: './lwm2m-bootstrap-config-servers.component.html',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => Lwm2mBootstrapConfigServersComponent),
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: NG_VALIDATORS,
|
||||
useExisting: forwardRef(() => Lwm2mBootstrapConfigServersComponent),
|
||||
multi: true,
|
||||
}
|
||||
]
|
||||
})
|
||||
export class Lwm2mBootstrapConfigServersComponent implements OnInit, ControlValueAccessor {
|
||||
|
||||
bootstrapConfigServersFormGroup: FormGroup;
|
||||
|
||||
@Input()
|
||||
disabled: boolean;
|
||||
|
||||
private valueChangeSubscription: Subscription = null;
|
||||
|
||||
private propagateChange = (v: any) => { };
|
||||
|
||||
constructor(public translate: TranslateService,
|
||||
public matDialog: MatDialog,
|
||||
private dialogService: DialogService,
|
||||
private deviceProfileService: DeviceProfileService,
|
||||
private fb: FormBuilder) {
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any): void {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.bootstrapConfigServersFormGroup = this.fb.group({
|
||||
serverConfigs: this.fb.array([])
|
||||
});
|
||||
}
|
||||
|
||||
serverConfigsFromArray(): FormArray {
|
||||
return this.bootstrapConfigServersFormGroup.get('serverConfigs') as FormArray;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.disabled = isDisabled;
|
||||
if (this.disabled) {
|
||||
this.bootstrapConfigServersFormGroup.disable({emitEvent: false});
|
||||
} else {
|
||||
this.bootstrapConfigServersFormGroup.enable({emitEvent: false});
|
||||
}
|
||||
}
|
||||
|
||||
writeValue(serverConfigs: Array<ServerSecurityConfig> | null): void {
|
||||
if (this.valueChangeSubscription) {
|
||||
this.valueChangeSubscription.unsubscribe();
|
||||
}
|
||||
const serverConfigsControls: Array<AbstractControl> = [];
|
||||
if (serverConfigs) {
|
||||
serverConfigs.forEach((serverConfig) => {
|
||||
serverConfigsControls.push(this.fb.control(serverConfig));
|
||||
});
|
||||
}
|
||||
this.bootstrapConfigServersFormGroup.setControl('serverConfigs', this.fb.array(serverConfigsControls));
|
||||
if (this.disabled) {
|
||||
this.bootstrapConfigServersFormGroup.disable({emitEvent: false});
|
||||
} else {
|
||||
this.bootstrapConfigServersFormGroup.enable({emitEvent: false});
|
||||
}
|
||||
this.valueChangeSubscription = this.bootstrapConfigServersFormGroup.valueChanges.subscribe(() => {
|
||||
this.updateModel();
|
||||
});
|
||||
}
|
||||
|
||||
trackByParams(index: number): number {
|
||||
return index;
|
||||
}
|
||||
|
||||
removeServerConfig($event: Event, index: number) {
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
}
|
||||
this.dialogService.confirm(
|
||||
this.translate.instant('device-profile.lwm2m.delete-server-title'),
|
||||
this.translate.instant('device-profile.lwm2m.delete-server-text'),
|
||||
this.translate.instant('action.no'),
|
||||
this.translate.instant('action.yes'),
|
||||
true
|
||||
).subscribe((result) => {
|
||||
if (result) {
|
||||
this.serverConfigsFromArray().removeAt(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addServerConfig(): void {
|
||||
const addDialogObs = this.isBootstrapAdded() ? of(false) :
|
||||
this.matDialog.open<Lwm2mBootstrapAddConfigServerDialogComponent>(Lwm2mBootstrapAddConfigServerDialogComponent, {
|
||||
disableClose: true,
|
||||
panelClass: ['tb-dialog', 'tb-fullscreen-dialog']
|
||||
}).afterClosed();
|
||||
const addServerConfigObs = addDialogObs.pipe(
|
||||
mergeMap((isBootstrap) => {
|
||||
if (isBootstrap === null) {
|
||||
return of(null);
|
||||
}
|
||||
return this.deviceProfileService.getLwm2mBootstrapSecurityInfoBySecurityType(isBootstrap, Lwm2mSecurityType.NO_SEC);
|
||||
})
|
||||
);
|
||||
addServerConfigObs.subscribe((serverConfig) => {
|
||||
if (serverConfig) {
|
||||
serverConfig.securityMode = Lwm2mSecurityType.NO_SEC;
|
||||
this.serverConfigsFromArray().push(this.fb.control(serverConfig));
|
||||
this.updateModel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public validate(c: FormControl) {
|
||||
return (this.bootstrapConfigServersFormGroup.valid) ? null : {
|
||||
serverConfigs: {
|
||||
valid: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public isBootstrapAdded() {
|
||||
const serverConfigsArray = this.serverConfigsFromArray().getRawValue();
|
||||
for (let i = 0; i < serverConfigsArray.length; i++) {
|
||||
if (serverConfigsArray[i].bootstrapServerIs) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private updateModel() {
|
||||
const serverConfigs: Array<ServerSecurityConfig> = this.serverConfigsFromArray().value;
|
||||
this.propagateChange(serverConfigs);
|
||||
}
|
||||
}
|
||||
@ -15,99 +15,170 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<section [formGroup]="serverFormGroup">
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.mode' | translate }}</mat-label>
|
||||
<mat-select formControlName="securityMode">
|
||||
<mat-option *ngFor="let securityMode of securityConfigLwM2MTypes"
|
||||
[value]="securityMode">
|
||||
{{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityMode]) }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.server-host' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="host" required>
|
||||
<mat-error *ngIf="serverFormGroup.get('host').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.server-host-required' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.server-port' | translate }}</mat-label>
|
||||
<input matInput type="number" formControlName="port" required min="0" max="65535">
|
||||
<mat-error *ngIf="serverFormGroup.get('port').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.server-port-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('port').hasError('pattern')">
|
||||
{{ 'device-profile.lwm2m.server-port-pattern' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('port').hasError('min') ||
|
||||
<mat-expansion-panel [formGroup]="serverFormGroup" #serverPanel>
|
||||
<mat-expansion-panel-header>
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-panel-title>
|
||||
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
|
||||
<div style="min-width:150px">{{ (serverFormGroup.get('bootstrapServerIs').value ?
|
||||
'device-profile.lwm2m.bootstrap-server' : 'device-profile.lwm2m.lwm2m-server') | translate }}</div>
|
||||
<div *ngIf="!serverPanel.expanded" fxLayout="row" style="font-size:14px">
|
||||
<div style="margin-left:32px">{{ ('device-profile.lwm2m.short-id' | translate) + ': ' }}
|
||||
<span style="font-style: italic">{{ serverFormGroup.get('shortServerId').value }}</span>
|
||||
</div>
|
||||
<div style="margin-left:32px">{{ ('device-profile.lwm2m.mode' | translate) + ': ' }}
|
||||
<span style="font-style: italic">{{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[serverFormGroup.get('securityMode').value]) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-panel-title>
|
||||
<span fxFlex></span>
|
||||
<button *ngIf="!disabled" mat-icon-button style="min-width: 40px;"
|
||||
type="button"
|
||||
(click)="removeServer.emit($event)"
|
||||
matTooltip="{{ 'action.remove' | translate }}"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-expansion-panel-header>
|
||||
<ng-template matExpansionPanelContent>
|
||||
<section>
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.mode' | translate }}</mat-label>
|
||||
<mat-select formControlName="securityMode">
|
||||
<mat-option *ngFor="let securityMode of securityConfigLwM2MTypes"
|
||||
[value]="securityMode">
|
||||
{{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityMode]) }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.short-id-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" min="1" max="65534" formControlName="shortServerId" required>
|
||||
<mat-error *ngIf="serverFormGroup.get('shortServerId').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.short-id-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('shortServerId').hasError('pattern')">
|
||||
{{ 'device-profile.lwm2m.short-id-pattern' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('shortServerId').hasError('min') ||
|
||||
serverFormGroup.get('shortServerId').hasError('max')">
|
||||
{{ 'device-profile.lwm2m.short-id-range' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.server-host' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="host" required>
|
||||
<mat-error *ngIf="serverFormGroup.get('host').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.server-host-required' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.server-port' | translate }}</mat-label>
|
||||
<input matInput type="number" formControlName="port" required min="0" max="65535" readonly>
|
||||
<mat-error *ngIf="serverFormGroup.get('port').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.server-port-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('port').hasError('pattern')">
|
||||
{{ 'device-profile.lwm2m.server-port-pattern' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('port').hasError('min') ||
|
||||
serverFormGroup.get('port').hasError('max')">
|
||||
{{ 'device-profile.lwm2m.server-port-range' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.short-id-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" min="1" max="65534" formControlName="serverId" required>
|
||||
<mat-error *ngIf="serverFormGroup.get('serverId').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.short-id-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('serverId').hasError('pattern')">
|
||||
{{ 'device-profile.lwm2m.short-id-pattern' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('serverId').hasError('min') ||
|
||||
serverFormGroup.get('serverId').hasError('max')">
|
||||
{{ 'device-profile.lwm2m.short-id-range' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.client-hold-off-time' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.client-hold-off-time-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" formControlName="clientHoldOffTime" required min="0">
|
||||
<mat-error *ngIf="serverFormGroup.get('clientHoldOffTime').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.client-hold-off-time-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('clientHoldOffTime').hasError('min') ||
|
||||
{{ 'device-profile.lwm2m.server-port-range' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.client-hold-off-time' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.client-hold-off-time-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" formControlName="clientHoldOffTime" required min="0">
|
||||
<mat-error *ngIf="serverFormGroup.get('clientHoldOffTime').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.client-hold-off-time-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('clientHoldOffTime').hasError('min') ||
|
||||
serverFormGroup.get('clientHoldOffTime').hasError('pattern')">
|
||||
{{ 'device-profile.lwm2m.client-hold-off-time-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.account-after-timeout' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.account-after-timeout-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" formControlName="bootstrapServerAccountTimeout" required min="0">
|
||||
<mat-error *ngIf="serverFormGroup.get('bootstrapServerAccountTimeout').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.account-after-timeout-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('bootstrapServerAccountTimeout').hasError('min') ||
|
||||
{{ 'device-profile.lwm2m.client-hold-off-time-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.account-after-timeout' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.account-after-timeout-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" formControlName="bootstrapServerAccountTimeout" required min="0">
|
||||
<mat-error *ngIf="serverFormGroup.get('bootstrapServerAccountTimeout').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.account-after-timeout-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('bootstrapServerAccountTimeout').hasError('min') ||
|
||||
serverFormGroup.get('bootstrapServerAccountTimeout').hasError('pattern')">
|
||||
{{ 'device-profile.lwm2m.account-after-timeout-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div *ngIf="serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK ||
|
||||
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509">
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label>{{ 'device-profile.lwm2m.server-public-key' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{ publicKeyOrIdTooltipNamesMap.get(serverFormGroup.get('securityMode').value) | translate }}">help</mat-icon>
|
||||
<textarea matInput
|
||||
cdkTextareaAutosize
|
||||
cdkAutosizeMinRows="1"
|
||||
cols="1" required
|
||||
formControlName="serverPublicKey"
|
||||
required>
|
||||
</textarea>
|
||||
<mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.server-public-key-required' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</section>
|
||||
{{ 'device-profile.lwm2m.account-after-timeout-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div *ngIf="serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK ||
|
||||
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509">
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label>{{ 'device-profile.lwm2m.server-public-key' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{ publicKeyOrIdTooltipNamesMap.get(serverFormGroup.get('securityMode').value) | translate }}">help</mat-icon>
|
||||
<textarea matInput
|
||||
cdkTextareaAutosize
|
||||
cdkAutosizeMinRows="1"
|
||||
cols="1" required
|
||||
formControlName="serverPublicKey"
|
||||
required>
|
||||
</textarea>
|
||||
<mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.server-public-key-required' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label>
|
||||
<input matInput type="number" min="0" formControlName="lifetime" required>
|
||||
<mat-error *ngIf="serverFormGroup.get('lifetime').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.lifetime-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('lifetime').hasError('pattern') ||
|
||||
serverFormGroup.get('lifetime').hasError('min')">
|
||||
{{ 'device-profile.lwm2m.lifetime-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.default-min-period-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" min="0" formControlName="defaultMinPeriod" required>
|
||||
<mat-error *ngIf="serverFormGroup.get('defaultMinPeriod').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.default-min-period-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="serverFormGroup.get('defaultMinPeriod').hasError('pattern') ||
|
||||
serverFormGroup.get('defaultMinPeriod').hasError('min')">
|
||||
{{ 'device-profile.lwm2m.default-min-period-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.binding-tooltip' | translate }}">help</mat-icon>
|
||||
<mat-select formControlName="binding">
|
||||
<mat-option *ngFor="let bindingMode of bindingModeTypes" [value]="bindingMode">
|
||||
{{ bindingModeTypeNamesMap.get(bindingMode) | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-checkbox formControlName="notifIfDisabled" color="primary">
|
||||
{{ 'device-profile.lwm2m.notification-storing' | translate }}
|
||||
</mat-checkbox>
|
||||
</section>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Component, EventEmitter, forwardRef, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import {
|
||||
ControlValueAccessor,
|
||||
FormBuilder,
|
||||
@ -26,8 +26,7 @@ import {
|
||||
Validators
|
||||
} from '@angular/forms';
|
||||
import {
|
||||
DEFAULT_PORT_BOOTSTRAP_NO_SEC,
|
||||
DEFAULT_PORT_SERVER_NO_SEC,
|
||||
BingingMode, BingingModeTranslationsMap,
|
||||
ServerSecurityConfig
|
||||
} from './lwm2m-profile-config.models';
|
||||
import { DeviceProfileService } from '@core/http/device-profile.service';
|
||||
@ -65,14 +64,16 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
|
||||
private isDataLoadedIntoCache = false;
|
||||
|
||||
serverFormGroup: FormGroup;
|
||||
bindingModeTypes = Object.values(BingingMode);
|
||||
bindingModeTypeNamesMap = BingingModeTranslationsMap;
|
||||
securityConfigLwM2MType = Lwm2mSecurityType;
|
||||
securityConfigLwM2MTypes = Object.keys(Lwm2mSecurityType);
|
||||
credentialTypeLwM2MNamesMap = Lwm2mSecurityTypeTranslationMap;
|
||||
publicKeyOrIdTooltipNamesMap = Lwm2mPublicKeyOrIdTooltipTranslationsMap;
|
||||
currentSecurityMode = null;
|
||||
|
||||
@Input()
|
||||
isBootstrapServer = false;
|
||||
@Output()
|
||||
removeServer = new EventEmitter();
|
||||
|
||||
private propagateChange = (v: any) => { };
|
||||
|
||||
@ -83,19 +84,29 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
|
||||
ngOnInit(): void {
|
||||
this.serverFormGroup = this.fb.group({
|
||||
host: ['', Validators.required],
|
||||
port: [this.isBootstrapServer ? DEFAULT_PORT_BOOTSTRAP_NO_SEC : DEFAULT_PORT_SERVER_NO_SEC,
|
||||
[Validators.required, Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]],
|
||||
port: ['', [Validators.required, Validators.min(1), Validators.max(65535), Validators.pattern('[0-9]*')]],
|
||||
securityMode: [Lwm2mSecurityType.NO_SEC],
|
||||
serverPublicKey: [''],
|
||||
clientHoldOffTime: ['', [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
|
||||
serverId: ['', [Validators.required, Validators.min(1), Validators.max(65534), Validators.pattern('[0-9]*')]],
|
||||
shortServerId: ['', [Validators.required, Validators.min(1), Validators.max(65534), Validators.pattern('[0-9]*')]],
|
||||
bootstrapServerAccountTimeout: ['', [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
|
||||
binding: [''],
|
||||
lifetime: [null, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
|
||||
notifIfDisabled: [],
|
||||
defaultMinPeriod: [null, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
|
||||
bootstrapServerIs: []
|
||||
});
|
||||
this.serverFormGroup.get('securityMode').valueChanges.pipe(
|
||||
tap(securityMode => this.updateValidate(securityMode)),
|
||||
tap((securityMode) => {
|
||||
this.currentSecurityMode = securityMode;
|
||||
this.updateValidate(securityMode);
|
||||
}),
|
||||
mergeMap(securityMode => this.getLwm2mBootstrapSecurityInfo(securityMode)),
|
||||
takeUntil(this.destroy$)
|
||||
).subscribe(serverSecurityConfig => {
|
||||
if (this.currentSecurityMode !== Lwm2mSecurityType.NO_SEC) {
|
||||
this.changeSecurityHostPortFields(serverSecurityConfig);
|
||||
}
|
||||
this.serverFormGroup.patchValue(serverSecurityConfig, {emitEvent: false});
|
||||
});
|
||||
this.serverFormGroup.valueChanges.pipe(
|
||||
@ -114,8 +125,13 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
|
||||
if (serverData) {
|
||||
this.serverFormGroup.patchValue(serverData, {emitEvent: false});
|
||||
this.updateValidate(serverData.securityMode);
|
||||
if (serverData.securityHost && serverData.securityPort) {
|
||||
delete serverData.securityHost;
|
||||
delete serverData.securityPort;
|
||||
this.propagateChangeState(this.serverFormGroup.getRawValue());
|
||||
}
|
||||
}
|
||||
if (!this.isDataLoadedIntoCache){
|
||||
if (!this.isDataLoadedIntoCache) {
|
||||
this.getLwm2mBootstrapSecurityInfo().subscribe(value => {
|
||||
if (!serverData) {
|
||||
this.serverFormGroup.patchValue(value);
|
||||
@ -171,11 +187,17 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
|
||||
}
|
||||
|
||||
private getLwm2mBootstrapSecurityInfo(securityMode = Lwm2mSecurityType.NO_SEC): Observable<ServerSecurityConfig> {
|
||||
return this.deviceProfileService.getLwm2mBootstrapSecurityInfoBySecurityType(this.isBootstrapServer, securityMode).pipe(
|
||||
return this.deviceProfileService.getLwm2mBootstrapSecurityInfoBySecurityType(
|
||||
this.serverFormGroup.get('bootstrapServerIs').value, securityMode).pipe(
|
||||
tap(() => this.isDataLoadedIntoCache = true)
|
||||
);
|
||||
}
|
||||
|
||||
private changeSecurityHostPortFields(serverData: ServerSecurityConfig): void {
|
||||
serverData.port = serverData.securityPort;
|
||||
serverData.host = serverData.securityHost;
|
||||
}
|
||||
|
||||
validate(): ValidationErrors | null {
|
||||
return this.serverFormGroup.valid ? null : {
|
||||
serverFormGroup: true
|
||||
|
||||
@ -33,93 +33,9 @@
|
||||
</mat-tab>
|
||||
<mat-tab label="{{ 'device-profile.lwm2m.bootstrap-tab' | translate }}">
|
||||
<section [formGroup]="lwm2mDeviceProfileFormGroup">
|
||||
<section formGroupName="bootstrap" style="padding: 20px 2px">
|
||||
<mat-accordion multi="true">
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>{{ 'device-profile.lwm2m.server' | translate }}</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<ng-template matExpansionPanelContent formGroupName="servers">
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.short-id-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" min="1" max="65534" formControlName="shortId" required>
|
||||
<mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('bootstrap.servers.shortId').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.short-id-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('bootstrap.servers.shortId').hasError('min') ||
|
||||
lwm2mDeviceProfileFormGroup.get('bootstrap.servers.shortId').hasError('max')">
|
||||
{{ 'device-profile.lwm2m.short-id-range' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('bootstrap.servers.shortId').hasError('pattern')">
|
||||
{{ 'device-profile.lwm2m.short-id-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label>
|
||||
<input matInput type="number" min="0" formControlName="lifetime" required>
|
||||
<mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('bootstrap.servers.lifetime').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.lifetime-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('bootstrap.servers.lifetime').hasError('pattern') ||
|
||||
lwm2mDeviceProfileFormGroup.get('bootstrap.servers.lifetime').hasError('min')">
|
||||
{{ 'device-profile.lwm2m.lifetime-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.default-min-period-tooltip' | translate }}">help</mat-icon>
|
||||
<input matInput type="number" min="0" formControlName="defaultMinPeriod" required>
|
||||
<mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('bootstrap.servers.defaultMinPeriod').hasError('required')">
|
||||
{{ 'device-profile.lwm2m.default-min-period-required' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('bootstrap.servers.defaultMinPeriod').hasError('pattern') ||
|
||||
lwm2mDeviceProfileFormGroup.get('bootstrap.servers.defaultMinPeriod').hasError('min')">
|
||||
{{ 'device-profile.lwm2m.default-min-period-pattern' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label>
|
||||
<mat-icon *ngIf="!disabled" class="mat-primary" aria-hidden="false" aria-label="help-icon" matSuffix style="cursor:pointer;"
|
||||
matTooltip="{{'device-profile.lwm2m.binding-tooltip' | translate }}">help</mat-icon>
|
||||
<mat-select formControlName="binding">
|
||||
<mat-option *ngFor="let bindingMode of bindingModeTypes" [value]="bindingMode">
|
||||
{{ bindingModeTypeNamesMap.get(bindingMode) | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-checkbox formControlName="notifIfDisabled" color="primary">
|
||||
{{ 'device-profile.lwm2m.notification-storing' | translate }}
|
||||
</mat-checkbox>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>{{ 'device-profile.lwm2m.bootstrap-server' | translate }}</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<ng-template matExpansionPanelContent>
|
||||
<tb-profile-lwm2m-device-config-server
|
||||
formControlName="bootstrapServer"
|
||||
[isBootstrapServer]="true">
|
||||
</tb-profile-lwm2m-device-config-server>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>{{ 'device-profile.lwm2m.lwm2m-server' | translate }}</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<ng-template matExpansionPanelContent>
|
||||
<tb-profile-lwm2m-device-config-server
|
||||
formControlName="lwm2mServer"
|
||||
[isBootstrapServer]="false">
|
||||
</tb-profile-lwm2m-device-config-server>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
<section style="padding: 20px 2px">
|
||||
<tb-profile-lwm2m-bootstrap-config-servers formControlName="bootstrap">
|
||||
</tb-profile-lwm2m-bootstrap-config-servers>
|
||||
</section>
|
||||
</section>
|
||||
</mat-tab>
|
||||
|
||||
@ -28,20 +28,11 @@ import {
|
||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||
import {
|
||||
ATTRIBUTE,
|
||||
BingingMode,
|
||||
BingingModeTranslationsMap,
|
||||
DEFAULT_BINDING,
|
||||
DEFAULT_EDRX_CYCLE,
|
||||
DEFAULT_FW_UPDATE_RESOURCE,
|
||||
DEFAULT_ID_SERVER,
|
||||
DEFAULT_LIFE_TIME,
|
||||
DEFAULT_MIN_PERIOD,
|
||||
DEFAULT_NOTIF_IF_DESIBLED,
|
||||
DEFAULT_PAGING_TRANSMISSION_WINDOW,
|
||||
DEFAULT_PSM_ACTIVITY_TIMER,
|
||||
DEFAULT_SW_UPDATE_RESOURCE,
|
||||
getDefaultBootstrapServerSecurityConfig,
|
||||
getDefaultLwM2MServerSecurityConfig,
|
||||
Instance,
|
||||
INSTANCES,
|
||||
KEY_NAME,
|
||||
@ -60,6 +51,7 @@ import { Direction } from '@shared/models/page/sort-order';
|
||||
import _ from 'lodash';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Lwm2mSecurityType } from '@shared/models/lwm2m-security-config.models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-profile-lwm2m-device-transport-configuration',
|
||||
@ -83,8 +75,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
|
||||
private requiredValue: boolean;
|
||||
private destroy$ = new Subject();
|
||||
|
||||
bindingModeTypes = Object.values(BingingMode);
|
||||
bindingModeTypeNamesMap = BingingModeTranslationsMap;
|
||||
lwm2mDeviceProfileFormGroup: FormGroup;
|
||||
configurationValue: Lwm2mProfileConfigModels;
|
||||
sortFunction: (key: string, value: object) => object;
|
||||
@ -98,6 +88,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
|
||||
this.requiredValue = coerceBooleanProperty(value);
|
||||
}
|
||||
|
||||
@Input()
|
||||
isAdd: boolean;
|
||||
|
||||
private propagateChange = (v: any) => {
|
||||
}
|
||||
|
||||
@ -106,17 +99,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
|
||||
this.lwm2mDeviceProfileFormGroup = this.fb.group({
|
||||
objectIds: [null],
|
||||
observeAttrTelemetry: [null],
|
||||
bootstrap: this.fb.group({
|
||||
servers: this.fb.group({
|
||||
binding: [DEFAULT_BINDING],
|
||||
shortId: [DEFAULT_ID_SERVER, [Validators.required, Validators.min(1), Validators.max(65534), Validators.pattern('[0-9]*')]],
|
||||
lifetime: [DEFAULT_LIFE_TIME, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
|
||||
notifIfDisabled: [DEFAULT_NOTIF_IF_DESIBLED, []],
|
||||
defaultMinPeriod: [DEFAULT_MIN_PERIOD, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
|
||||
}),
|
||||
bootstrapServer: [null, Validators.required],
|
||||
lwm2mServer: [null, Validators.required]
|
||||
}),
|
||||
bootstrap: [[]],
|
||||
clientLwM2mSettings: this.fb.group({
|
||||
clientOnlyObserveAfterConnect: [1, []],
|
||||
fwUpdateStrategy: [1, []],
|
||||
@ -187,9 +170,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
|
||||
async writeValue(value: Lwm2mProfileConfigModels | null) {
|
||||
if (isDefinedAndNotNull(value) && (value?.clientLwM2mSettings || value?.observeAttr || value?.bootstrap)) {
|
||||
this.configurationValue = value;
|
||||
const defaultFormSettings = value.clientLwM2mSettings.fwUpdateStrategy === 1 &&
|
||||
isUndefined(value.clientLwM2mSettings.fwUpdateResource);
|
||||
if (defaultFormSettings) {
|
||||
if (this.isAdd) {
|
||||
await this.defaultProfileConfig();
|
||||
}
|
||||
this.initWriteValue();
|
||||
@ -203,23 +184,14 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
|
||||
}
|
||||
|
||||
private async defaultProfileConfig(): Promise<void> {
|
||||
let bootstrap: ServerSecurityConfig;
|
||||
let lwm2m: ServerSecurityConfig;
|
||||
try {
|
||||
[bootstrap, lwm2m] = await Promise.all([
|
||||
this.deviceProfileService.getLwm2mBootstrapSecurityInfoBySecurityType(true).toPromise(),
|
||||
this.deviceProfileService.getLwm2mBootstrapSecurityInfoBySecurityType(false).toPromise()
|
||||
]);
|
||||
} catch (e) {
|
||||
bootstrap = getDefaultBootstrapServerSecurityConfig();
|
||||
lwm2m = getDefaultLwM2MServerSecurityConfig();
|
||||
const lwm2m: ServerSecurityConfig = await this.deviceProfileService.getLwm2mBootstrapSecurityInfoBySecurityType(false).toPromise();
|
||||
if (lwm2m) {
|
||||
lwm2m.securityMode = Lwm2mSecurityType.NO_SEC;
|
||||
}
|
||||
|
||||
this.configurationValue.bootstrap.bootstrapServer = bootstrap;
|
||||
this.configurationValue.bootstrap.lwm2mServer = lwm2m;
|
||||
this.configurationValue.bootstrap = [lwm2m];
|
||||
this.lwm2mDeviceProfileFormGroup.patchValue({
|
||||
bootstrap: this.configurationValue.bootstrap
|
||||
}, {emitEvent: false});
|
||||
}, {emitEvent: true});
|
||||
}
|
||||
|
||||
private initWriteValue = (): void => {
|
||||
@ -282,12 +254,10 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
|
||||
}
|
||||
|
||||
private updateDeviceProfileValue(config): void {
|
||||
if (this.lwm2mDeviceProfileFormGroup.valid) {
|
||||
if (this.lwm2mDeviceProfileFormGroup.valid && config.observeAttrTelemetry) {
|
||||
this.updateObserveAttrTelemetryFromGroupToJson(config.observeAttrTelemetry);
|
||||
}
|
||||
this.configurationValue.bootstrap.bootstrapServer = config.bootstrap.bootstrapServer;
|
||||
this.configurationValue.bootstrap.lwm2mServer = config.bootstrap.lwm2mServer;
|
||||
this.configurationValue.bootstrap.servers = config.bootstrap.servers;
|
||||
this.configurationValue.bootstrap = config.bootstrap;
|
||||
this.configurationValue.clientLwM2mSettings = config.clientLwM2mSettings;
|
||||
this.updateModel();
|
||||
}
|
||||
|
||||
@ -22,7 +22,9 @@ import { Lwm2mObserveAttrTelemetryResourcesComponent } from './lwm2m-observe-att
|
||||
import { Lwm2mAttributesDialogComponent } from './lwm2m-attributes-dialog.component';
|
||||
import { Lwm2mAttributesComponent } from './lwm2m-attributes.component';
|
||||
import { Lwm2mAttributesKeyListComponent } from './lwm2m-attributes-key-list.component';
|
||||
import { Lwm2mBootstrapConfigServersComponent } from '@home/components/profile/device/lwm2m/lwm2m-bootstrap-config-servers.component';
|
||||
import { Lwm2mDeviceConfigServerComponent } from './lwm2m-device-config-server.component';
|
||||
import { Lwm2mBootstrapAddConfigServerDialogComponent } from '@home/components/profile/device/lwm2m/lwm2m-bootstrap-add-config-server-dialog.component';
|
||||
import { Lwm2mObjectAddInstancesDialogComponent } from './lwm2m-object-add-instances-dialog.component';
|
||||
import { Lwm2mObjectAddInstancesListComponent } from './lwm2m-object-add-instances-list.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@ -40,7 +42,9 @@ import { DeviceProfileCommonModule } from '@home/components/profile/device/commo
|
||||
Lwm2mAttributesDialogComponent,
|
||||
Lwm2mAttributesComponent,
|
||||
Lwm2mAttributesKeyListComponent,
|
||||
Lwm2mBootstrapConfigServersComponent,
|
||||
Lwm2mDeviceConfigServerComponent,
|
||||
Lwm2mBootstrapAddConfigServerDialogComponent,
|
||||
Lwm2mObjectAddInstancesDialogComponent,
|
||||
Lwm2mObjectAddInstancesListComponent,
|
||||
Lwm2mObserveAttrTelemetryInstancesComponent
|
||||
@ -58,7 +62,9 @@ import { DeviceProfileCommonModule } from '@home/components/profile/device/commo
|
||||
Lwm2mAttributesDialogComponent,
|
||||
Lwm2mAttributesComponent,
|
||||
Lwm2mAttributesKeyListComponent,
|
||||
Lwm2mBootstrapConfigServersComponent,
|
||||
Lwm2mDeviceConfigServerComponent,
|
||||
Lwm2mBootstrapAddConfigServerDialogComponent,
|
||||
Lwm2mObjectAddInstancesDialogComponent,
|
||||
Lwm2mObjectAddInstancesListComponent,
|
||||
Lwm2mObserveAttrTelemetryInstancesComponent
|
||||
|
||||
@ -96,6 +96,18 @@ export const AttributeNameTranslationMap = new Map<AttributeName, string>(
|
||||
]
|
||||
);
|
||||
|
||||
export enum ServerConfigType {
|
||||
LWM2M = 'LWM2M',
|
||||
BOOTSTRAP = 'BOOTSTRAP'
|
||||
}
|
||||
|
||||
export const ServerConfigTypeTranslationMap = new Map<ServerConfigType, string>(
|
||||
[
|
||||
[ServerConfigType.LWM2M, 'device-profile.lwm2m.lwm2m-server'],
|
||||
[ServerConfigType.BOOTSTRAP, 'device-profile.lwm2m.bootstrap-server']
|
||||
]
|
||||
);
|
||||
|
||||
export enum PowerMode {
|
||||
PSM = 'PSM',
|
||||
DRX = 'DRX',
|
||||
@ -110,22 +122,21 @@ export const PowerModeTranslationMap = new Map<PowerMode, string>(
|
||||
]
|
||||
);
|
||||
|
||||
export interface BootstrapServersSecurityConfig {
|
||||
shortId: number;
|
||||
lifetime: number;
|
||||
defaultMinPeriod: number;
|
||||
notifIfDisabled: boolean;
|
||||
binding: string;
|
||||
}
|
||||
|
||||
export interface ServerSecurityConfig {
|
||||
host?: string;
|
||||
port?: number;
|
||||
securityMode: Lwm2mSecurityType;
|
||||
securityHost?: string;
|
||||
securityPort?: number;
|
||||
serverPublicKey?: string;
|
||||
clientHoldOffTime?: number;
|
||||
serverId?: number;
|
||||
shortServerId?: number;
|
||||
bootstrapServerAccountTimeout: number;
|
||||
lifetime: number;
|
||||
defaultMinPeriod: number;
|
||||
notifIfDisabled: boolean;
|
||||
binding: string;
|
||||
bootstrapServerIs: boolean;
|
||||
}
|
||||
|
||||
export interface ServerSecurityConfigInfo extends ServerSecurityConfig {
|
||||
@ -134,16 +145,10 @@ export interface ServerSecurityConfigInfo extends ServerSecurityConfig {
|
||||
bootstrapServerIs: boolean;
|
||||
}
|
||||
|
||||
interface BootstrapSecurityConfig {
|
||||
servers: BootstrapServersSecurityConfig;
|
||||
bootstrapServer: ServerSecurityConfig;
|
||||
lwm2mServer: ServerSecurityConfig;
|
||||
}
|
||||
|
||||
export interface Lwm2mProfileConfigModels {
|
||||
clientLwM2mSettings: ClientLwM2mSettings;
|
||||
observeAttr: ObservableAttributes;
|
||||
bootstrap: BootstrapSecurityConfig;
|
||||
bootstrap: Array<ServerSecurityConfig>;
|
||||
}
|
||||
|
||||
export interface ClientLwM2mSettings {
|
||||
@ -167,35 +172,6 @@ export interface ObservableAttributes {
|
||||
attributeLwm2m: AttributesNameValueMap;
|
||||
}
|
||||
|
||||
export function getDefaultBootstrapServersSecurityConfig(): BootstrapServersSecurityConfig {
|
||||
return {
|
||||
shortId: DEFAULT_ID_SERVER,
|
||||
lifetime: DEFAULT_LIFE_TIME,
|
||||
defaultMinPeriod: DEFAULT_MIN_PERIOD,
|
||||
notifIfDisabled: DEFAULT_NOTIF_IF_DESIBLED,
|
||||
binding: DEFAULT_BINDING
|
||||
};
|
||||
}
|
||||
|
||||
export function getDefaultBootstrapServerSecurityConfig(): ServerSecurityConfig {
|
||||
return {
|
||||
bootstrapServerAccountTimeout: DEFAULT_BOOTSTRAP_SERVER_ACCOUNT_TIME_OUT,
|
||||
clientHoldOffTime: DEFAULT_CLIENT_HOLD_OFF_TIME,
|
||||
host: DEFAULT_LOCAL_HOST_NAME,
|
||||
port: DEFAULT_PORT_BOOTSTRAP_NO_SEC,
|
||||
securityMode: Lwm2mSecurityType.NO_SEC,
|
||||
serverId: DEFAULT_ID_BOOTSTRAP,
|
||||
serverPublicKey: ''
|
||||
};
|
||||
}
|
||||
|
||||
export function getDefaultLwM2MServerSecurityConfig(): ServerSecurityConfig {
|
||||
const DefaultLwM2MServerSecurityConfig = getDefaultBootstrapServerSecurityConfig();
|
||||
DefaultLwM2MServerSecurityConfig.port = DEFAULT_PORT_SERVER_NO_SEC;
|
||||
DefaultLwM2MServerSecurityConfig.serverId = DEFAULT_ID_SERVER;
|
||||
return DefaultLwM2MServerSecurityConfig;
|
||||
}
|
||||
|
||||
export function getDefaultProfileObserveAttrConfig(): ObservableAttributes {
|
||||
return {
|
||||
observe: [],
|
||||
|
||||
@ -133,6 +133,7 @@
|
||||
</mat-form-field>
|
||||
<tb-device-profile-transport-configuration
|
||||
formControlName="transportConfiguration"
|
||||
isAdd="true"
|
||||
required>
|
||||
</tb-device-profile-transport-configuration>
|
||||
</form>
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
<div formGroupName="profileData">
|
||||
<tb-device-profile-transport-configuration
|
||||
formControlName="transportConfiguration"
|
||||
[isAdd] = "isTransportTypeChanged"
|
||||
required>
|
||||
</tb-device-profile-transport-configuration>
|
||||
</div>
|
||||
|
||||
@ -38,12 +38,17 @@ export class DeviceProfileTabsComponent extends EntityTabsComponent<DeviceProfil
|
||||
|
||||
deviceTransportTypeHints = deviceTransportTypeHintMap;
|
||||
|
||||
isTransportTypeChanged = false;
|
||||
|
||||
constructor(protected store: Store<AppState>) {
|
||||
super(store);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.detailsForm.get('transportType').valueChanges.subscribe(() => {
|
||||
this.isTransportTypeChanged = true;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -31,9 +31,6 @@ import { OtaPackageId } from '@shared/models/id/ota-package-id';
|
||||
import { DashboardId } from '@shared/models/id/dashboard-id';
|
||||
import { DataType } from '@shared/models/constants';
|
||||
import {
|
||||
getDefaultBootstrapServerSecurityConfig,
|
||||
getDefaultBootstrapServersSecurityConfig,
|
||||
getDefaultLwM2MServerSecurityConfig,
|
||||
getDefaultProfileClientLwM2mSettingsConfig,
|
||||
getDefaultProfileObserveAttrConfig,
|
||||
PowerMode
|
||||
@ -384,11 +381,7 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT
|
||||
case DeviceTransportType.LWM2M:
|
||||
const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = {
|
||||
observeAttr: getDefaultProfileObserveAttrConfig(),
|
||||
bootstrap: {
|
||||
servers: getDefaultBootstrapServersSecurityConfig(),
|
||||
bootstrapServer: getDefaultBootstrapServerSecurityConfig(),
|
||||
lwm2mServer: getDefaultLwM2MServerSecurityConfig()
|
||||
},
|
||||
bootstrap: [],
|
||||
clientLwM2mSettings: getDefaultProfileClientLwM2mSettingsConfig()
|
||||
};
|
||||
transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M};
|
||||
|
||||
@ -67,14 +67,9 @@ export interface ServerSecurityConfig {
|
||||
clientSecretKey?: string;
|
||||
}
|
||||
|
||||
interface BootstrapSecurityConfig {
|
||||
bootstrapServer: ServerSecurityConfig;
|
||||
lwm2mServer: ServerSecurityConfig;
|
||||
}
|
||||
|
||||
export interface Lwm2mSecurityConfigModels {
|
||||
client: ClientSecurityConfig;
|
||||
bootstrap: BootstrapSecurityConfig;
|
||||
bootstrap: Array<ServerSecurityConfig>;
|
||||
}
|
||||
|
||||
|
||||
@ -84,10 +79,9 @@ export function getLwm2mSecurityConfigModelsDefault(): Lwm2mSecurityConfigModels
|
||||
securityConfigClientMode: Lwm2mSecurityType.NO_SEC,
|
||||
endpoint: ''
|
||||
},
|
||||
bootstrap: {
|
||||
bootstrapServer: getDefaultServerSecurityConfig(),
|
||||
lwm2mServer: getDefaultServerSecurityConfig()
|
||||
}
|
||||
bootstrap: [
|
||||
getDefaultServerSecurityConfig()
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1310,16 +1310,18 @@
|
||||
"edit-attribute": "Edit attribute",
|
||||
"view-attribute": "View attribute",
|
||||
"remove-attribute": "Remove attribute",
|
||||
"delete-server-text": "Be careful, after the confirmation the server configuration will become unrecoverable.",
|
||||
"delete-server-title": "Are you sure you want to delete the server?",
|
||||
"mode": "Security config mode",
|
||||
"bootstrap-tab": "Bootstrap",
|
||||
"bootstrap-server-legend": "Bootstrap Server (ShortId...)",
|
||||
"lwm2m-server-legend": "LwM2M Server (ShortId...)",
|
||||
"server": "Server",
|
||||
"short-id": "Short ID",
|
||||
"short-id-tooltip": "Server ShortID must be equal Security ShortID ",
|
||||
"short-id-required": "Short ID is required.",
|
||||
"short-id-range": "Short ID should be in a range from 1 to 65534.",
|
||||
"short-id-pattern": "Short ID must be a positive integer.",
|
||||
"short-id": "Short server ID",
|
||||
"short-id-tooltip": "Server short Id. Used as link to associate server Object Instance.\nThis identifier uniquely identifies each LwM2M Server configured for the LwM2M Client.\nResource MUST be set when the Bootstrap-Server Resource has a value of 'false'.\nThe values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.",
|
||||
"short-id-required": "Short server ID is required.",
|
||||
"short-id-range": "Short server ID should be in a range from 1 to 65534.",
|
||||
"short-id-pattern": "Short server ID must be a positive integer.",
|
||||
"lifetime": "Client registration lifetime",
|
||||
"lifetime-required": "Client registration lifetime is required.",
|
||||
"lifetime-pattern": "Client registration lifetime must be a positive integer.",
|
||||
@ -1361,6 +1363,11 @@
|
||||
"account-after-timeout-required": "Account after the timeout is required.",
|
||||
"account-after-timeout-pattern": "Account after the timeout must be a positive integer.",
|
||||
"account-after-timeout-tooltip": "Bootstrap-Server Account after the timeout value given by this resource.",
|
||||
"server-type": "Server type",
|
||||
"add-new-server-title": "Add new server config",
|
||||
"add-server-config": "Add server config",
|
||||
"add-lwm2m-server-config": "Add LwM2M server",
|
||||
"no-config-servers": "No servers configured",
|
||||
"others-tab": "Other settings",
|
||||
"client-strategy": "Client strategy when connecting",
|
||||
"client-strategy-label": "Strategy",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user