Commit c8814f7cfa28ea84145d11b1a422df833381a881

Authored by Vladyslav_Prykhodko
1 parent cfa9a577

UI: Refactoring lwm2m

Showing 16 changed files with 168 additions and 275 deletions
... ... @@ -307,7 +307,6 @@ import { Lwm2mProfileComponentsModule } from '@home/components/profile/device/lw
307 307 EditAlarmDetailsDialogComponent,
308 308 DeviceProfileProvisionConfigurationComponent,
309 309 AlarmScheduleComponent,
310   - // Lwm2mProfileComponentsModule,
311 310 SmsProviderConfigurationComponent,
312 311 AwsSnsProviderConfigurationComponent,
313 312 TwilioSmsProviderConfigurationComponent
... ...
... ... @@ -15,19 +15,18 @@
15 15 ///
16 16
17 17 import { Component, forwardRef, Inject, Input, OnInit } from '@angular/core';
18   -
19   -import {
20   - ControlValueAccessor,
21   - FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators
22   -} from '@angular/forms';
  18 +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
23 19 import {
24   - SECURITY_CONFIG_MODE,
25   - SECURITY_CONFIG_MODE_NAMES,
26   - ServerSecurityConfig,
  20 + DEFAULT_CLIENT_HOLD_OFF_TIME,
  21 + DEFAULT_ID_SERVER,
27 22 DEFAULT_PORT_BOOTSTRAP_NO_SEC,
28 23 DEFAULT_PORT_SERVER_NO_SEC,
29   - DEFAULT_CLIENT_HOLD_OFF_TIME,
30   - DEFAULT_ID_SERVER, LEN_MAX_PUBLIC_KEY_RPK, LEN_MAX_PUBLIC_KEY_X509, KEY_REGEXP_HEX_DEC
  24 + KEY_REGEXP_HEX_DEC,
  25 + LEN_MAX_PUBLIC_KEY_RPK,
  26 + LEN_MAX_PUBLIC_KEY_X509,
  27 + SECURITY_CONFIG_MODE,
  28 + SECURITY_CONFIG_MODE_NAMES,
  29 + ServerSecurityConfig
31 30 } from './profile-config.models';
32 31 import { Store } from '@ngrx/store';
33 32 import { AppState } from '@core/core.state';
... ...
... ... @@ -46,50 +46,52 @@
46 46 <div class="tb-panel-title">{{ 'device-profile.lwm2m.servers' | translate | uppercase }}</div>
47 47 </mat-panel-title>
48 48 </mat-expansion-panel-header>
49   - <div fxLayout="column">
50   - <div fxLayout="row" fxLayoutGap="8px">
51   - <mat-form-field fxFlex>
52   - <mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
53   - <input matInput type="number" formControlName="shortId" required>
54   - <mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('shortId').hasError('required')">
55   - {{ 'device-profile.lwm2m.short-id' | translate }}
56   - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
57   - </mat-error>
58   - </mat-form-field>
59   - <mat-form-field fxFlex>
60   - <mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label>
61   - <input matInput type="number" formControlName="lifetime" required>
62   - <mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('lifetime').hasError('required')">
63   - {{ 'device-profile.lwm2m.lifetime' | translate }}
64   - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
65   - </mat-error>
66   - </mat-form-field>
  49 + <ng-template matExpansionPanelContent>
  50 + <div fxLayout="column">
  51 + <div fxLayout="row" fxLayoutGap="8px">
  52 + <mat-form-field fxFlex>
  53 + <mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
  54 + <input matInput type="number" formControlName="shortId" required>
  55 + <mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('shortId').hasError('required')">
  56 + {{ 'device-profile.lwm2m.short-id' | translate }}
  57 + <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
  58 + </mat-error>
  59 + </mat-form-field>
  60 + <mat-form-field fxFlex>
  61 + <mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label>
  62 + <input matInput type="number" formControlName="lifetime" required>
  63 + <mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('lifetime').hasError('required')">
  64 + {{ 'device-profile.lwm2m.lifetime' | translate }}
  65 + <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
  66 + </mat-error>
  67 + </mat-form-field>
  68 + </div>
  69 + <div fxLayout="row" fxLayoutGap="8px">
  70 + <mat-form-field fxFlex>
  71 + <mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label>
  72 + <input matInput type="number" formControlName="defaultMinPeriod" required>
  73 + <mat-error
  74 + *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('defaultMinPeriod').hasError('required')">
  75 + {{ 'device-profile.lwm2m.default-min-period' | translate }}
  76 + <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
  77 + </mat-error>
  78 + </mat-form-field>
  79 + <mat-form-field fxFlex>
  80 + <mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label>
  81 + <input matInput type="text" formControlName="binding" required>
  82 + <mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('binding').hasError('required')">
  83 + {{ 'device-profile.lwm2m.binding' | translate }}
  84 + <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
  85 + </mat-error>
  86 + </mat-form-field>
  87 + </div>
  88 + <div>
  89 + <mat-checkbox formControlName="notifIfDisabled" color="primary">
  90 + {{ 'device-profile.lwm2m.notif-if-disabled' | translate }}
  91 + </mat-checkbox>
  92 + </div>
67 93 </div>
68   - <div fxLayout="row" fxLayoutGap="8px">
69   - <mat-form-field fxFlex>
70   - <mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label>
71   - <input matInput type="number" formControlName="defaultMinPeriod" required>
72   - <mat-error
73   - *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('defaultMinPeriod').hasError('required')">
74   - {{ 'device-profile.lwm2m.default-min-period' | translate }}
75   - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
76   - </mat-error>
77   - </mat-form-field>
78   - <mat-form-field fxFlex>
79   - <mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label>
80   - <input matInput type="text" formControlName="binding" required>
81   - <mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('binding').hasError('required')">
82   - {{ 'device-profile.lwm2m.binding' | translate }}
83   - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
84   - </mat-error>
85   - </mat-form-field>
86   - </div>
87   - <div>
88   - <mat-checkbox formControlName="notifIfDisabled" color="primary">
89   - {{ 'device-profile.lwm2m.notif-if-disabled' | translate }}
90   - </mat-checkbox>
91   - </div>
92   - </div>
  94 + </ng-template>
93 95 </mat-expansion-panel>
94 96 </mat-accordion>
95 97 <mat-accordion multi="true" class="mat-body-1">
... ...
... ... @@ -14,26 +14,23 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import {
18   - DeviceProfileTransportConfiguration,
19   - DeviceTransportType
20   -} from '@shared/models/device.models';
21   -import {
22   - Component,
23   - forwardRef, Inject,
24   - Input,
25   - OnInit
26   -} from '@angular/core';
  17 +import { DeviceProfileTransportConfiguration, DeviceTransportType } from '@shared/models/device.models';
  18 +import { Component, forwardRef, Inject, Input, OnInit } from '@angular/core';
27 19 import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
28 20 import { Store } from '@ngrx/store';
29 21 import { AppState } from '@app/core/core.state';
30 22 import { coerceBooleanProperty } from '@angular/cdk/coercion';
31 23 import {
32 24 ATTR,
  25 + getDefaultProfileConfig,
  26 + Instance,
  27 + KEY_NAME,
  28 + ObjectLwM2M,
33 29 OBSERVE,
34 30 OBSERVE_ATTR,
35   - TELEMETRY,
36   - ObjectLwM2M, getDefaultProfileConfig, KEY_NAME, Instance, ProfileConfigModels, ResourceLwM2M
  31 + ProfileConfigModels,
  32 + ResourceLwM2M,
  33 + TELEMETRY
37 34 } from './profile-config.models';
38 35 import { DeviceProfileService } from '@core/http/device-profile.service';
39 36 import { deepClone, isUndefined } from '@core/utils';
... ... @@ -50,7 +47,7 @@ import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined';
50 47 multi: true
51 48 }]
52 49 })
53   -export class Lwm2mDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, OnInit, Validators {
  50 +export class Lwm2mDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, Validators {
54 51
55 52 private configurationValue: ProfileConfigModels;
56 53 private requiredValue: boolean;
... ... @@ -65,7 +62,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
65 62 bootstrapServers: string;
66 63 bootstrapServer: string;
67 64 lwm2mServer: string;
68   - sortFunction: {};
  65 + sortFunction: (key: string, value: object) => object;
69 66
70 67 get required(): boolean {
71 68 return this.requiredValue;
... ... @@ -99,6 +96,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
99 96 this.updateModel();
100 97 }
101 98 });
  99 + this.sortFunction = this.sortObjectKeyPathJson;
102 100 }
103 101
104 102 registerOnChange(fn: any): void {
... ... @@ -108,10 +106,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
108 106 registerOnTouched(fn: any): void {
109 107 }
110 108
111   - ngOnInit() {
112   - this.sortFunction = this.sortObjectKeyPathJson;
113   - }
114   -
115 109 setDisabledState(isDisabled: boolean): void {
116 110 this.disabled = isDisabled;
117 111 if (isDisabled) {
... ...
... ... @@ -49,7 +49,7 @@ import { DeviceProfileService } from '@core/http/device-profile.service';
49 49 multi: true
50 50 }]
51 51 })
52   -export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccessor, OnInit, Validators {
  52 +export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccessor {
53 53
54 54 private requiredValue: boolean;
55 55 private disabled = false as boolean;
... ... @@ -103,12 +103,6 @@ export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccesso
103 103 registerOnTouched(fn: any): void {
104 104 }
105 105
106   - ngOnInit() {
107   - }
108   -
109   - ngAfterViewInit(): void {
110   - }
111   -
112 106 setDisabledState(isDisabled: boolean): void {
113 107 this.disabled = isDisabled;
114 108 if (isDisabled) {
... ...
... ... @@ -15,7 +15,7 @@
15 15 limitations under the License.
16 16
17 17 -->
18   -<form [formGroup]="jsonFormGroup" (ngSubmit)="add()" style="min-width: 400px;">
  18 +<form [formGroup]="instancesFormGroup" (ngSubmit)="add()" style="min-width: 400px;">
19 19 <mat-toolbar fxLayout="row" color="primary">
20 20 <b><i>{{data.objectName}}</i></b> &nbsp;&nbsp; (object&nbsp;[<b>{{data.objectId}}</b>])
21 21 <span fxFlex></span>
... ... @@ -38,16 +38,15 @@
38 38 </fieldset>
39 39 </div>
40 40 <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center">
41   - <span fxFlex></span>
42 41 <button mat-button color="primary"
43 42 type="button"
44 43 [disabled]="(isLoading$ | async)"
45 44 (click)="cancel()">
46 45 {{ 'action.cancel' | translate }}
47 46 </button>
48   - <button mat-button mat-raised-button color="primary"
  47 + <button mat-raised-button color="primary"
49 48 type="submit"
50   - [disabled]="(isLoading$ | async) || jsonFormGroup.invalid || !jsonFormGroup.dirty">
  49 + [disabled]="(isLoading$ | async) || instancesFormGroup.invalid || !instancesFormGroup.dirty">
51 50 {{ 'action.save' | translate }}
52 51 </button>
53 52 </div>
... ...
... ... @@ -35,7 +35,7 @@ export interface Lwm2mObjectAddInstancesData {
35 35 })
36 36 export class Lwm2mObjectAddInstancesComponent extends DialogComponent<Lwm2mObjectAddInstancesComponent, object> implements OnInit {
37 37
38   - jsonFormGroup: FormGroup;
  38 + instancesFormGroup: FormGroup;
39 39 submitted = false;
40 40
41 41 constructor(protected store: Store<AppState>,
... ... @@ -46,9 +46,8 @@ export class Lwm2mObjectAddInstancesComponent extends DialogComponent<Lwm2mObjec
46 46 super(store, router, dialogRef);
47 47 }
48 48
49   -
50 49 ngOnInit(): void {
51   - this.jsonFormGroup = this.fb.group({
  50 + this.instancesFormGroup = this.fb.group({
52 51 instancesIds: this.data.instancesIds
53 52 });
54 53 }
... ... @@ -58,7 +57,7 @@ export class Lwm2mObjectAddInstancesComponent extends DialogComponent<Lwm2mObjec
58 57 }
59 58
60 59 add(): void {
61   - this.data.instancesIds = this.jsonFormGroup.get('instancesIds').value;
  60 + this.data.instancesIds = this.instancesFormGroup.get('instancesIds').value;
62 61 this.dialogRef.close(this.data);
63 62 }
64 63 }
... ...
... ... @@ -14,34 +14,20 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import {
18   - Component,
19   - forwardRef,
20   - Input,
21   - OnInit,
22   - ViewChild,
23   - ElementRef,
24   - Output,
25   - EventEmitter
26   -} from '@angular/core';
27   -import {
28   - ControlValueAccessor,
29   - FormBuilder,
30   - FormGroup,
31   - NG_VALUE_ACCESSOR, Validators
32   -} from '@angular/forms';
33   -import {coerceBooleanProperty} from '@angular/cdk/coercion';
34   -import {Store} from '@ngrx/store';
35   -import {AppState} from '@core/core.state';
36   -import {MatChipList} from '@angular/material/chips';
37   -import {MatAutocomplete} from '@angular/material/autocomplete';
38   -import {Observable} from 'rxjs';
39   -import {filter, map, mergeMap, share, tap} from 'rxjs/operators';
40   -import {ObjectLwM2M} from './profile-config.models';
41   -import {TranslateService} from '@ngx-translate/core';
42   -import {DeviceProfileService} from '@core/http/device-profile.service';
43   -import {PageLink} from '@shared/models/page/page-link';
44   -import {Direction} from '@shared/models/page/sort-order';
  17 +import { Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core';
  18 +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  19 +import { coerceBooleanProperty } from '@angular/cdk/coercion';
  20 +import { Store } from '@ngrx/store';
  21 +import { AppState } from '@core/core.state';
  22 +import { MatChipList } from '@angular/material/chips';
  23 +import { MatAutocomplete } from '@angular/material/autocomplete';
  24 +import { Observable } from 'rxjs';
  25 +import { filter, map, mergeMap, share, tap } from 'rxjs/operators';
  26 +import { ObjectLwM2M } from './profile-config.models';
  27 +import { TranslateService } from '@ngx-translate/core';
  28 +import { DeviceProfileService } from '@core/http/device-profile.service';
  29 +import { PageLink } from '@shared/models/page/page-link';
  30 +import { Direction } from '@shared/models/page/sort-order';
45 31
46 32 @Component({
47 33 selector: 'tb-profile-lwm2m-object-list',
... ... @@ -63,8 +49,8 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
63 49 modelValue: Array<number> | null;
64 50 objectsList: Array<ObjectLwM2M> = [];
65 51 filteredObjectsList: Observable<Array<ObjectLwM2M>>;
66   - disabled = false as boolean;
67   - searchText = '' as string;
  52 + disabled = false;
  53 + searchText = '';
68 54
69 55 get required(): boolean {
70 56 return this.requiredValue;
... ... @@ -210,9 +196,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
210 196 direction: Direction.ASC
211 197 });
212 198 return this.deviceProfileService.getLwm2mObjectsPage(pageLink, {ignoreLoading: true}).pipe(
213   - map(pageData => {
214   - return pageData.data;
215   - })
  199 + map(pageData => pageData.data)
216 200 );
217 201 }
218 202
... ...
... ... @@ -17,12 +17,10 @@
17 17 -->
18 18 <section [formGroup]="resourceFormGroup" class="mat-padding">
19 19 <div fxLayout="row" fxFill formArrayName="resources"
20   - *ngFor="let resourceLwM2M of resourceLwm2mFormArray(resourceFormGroup).controls; let z = index; trackBy: trackByParams">
21   - <div class="vertical-padding" fxLayout="column" fxFill [formGroupName]="z">
22   - <div fxLayout="row" fxFill [fxShow]="!z">
23   - <div fxFlex="55">
24   - <!-- <mat-label translate>device-profile.lwm2m.resource-label</mat-label>-->
25   - </div>
  20 + *ngFor="let resourceLwM2M of resourceFormArray.controls; let i = index; trackBy: trackByParams">
  21 + <div class="vertical-padding" fxLayout="column" fxFill [formGroupName]="i">
  22 + <div fxLayout="row" fxFill [fxShow]="!i">
  23 + <div fxFlex="55"></div>
26 24 <div fxFlex="10" fxLayoutAlign="start center">
27 25 <b>
28 26 <mat-label translate>device-profile.lwm2m.observe-label</mat-label>
... ... @@ -72,10 +70,9 @@
72 70 {{ 'device-profile.lwm2m.key-name_label' | translate }}</mat-label>
73 71 <input matInput type="text" formControlName="keyName" required
74 72 matTooltip="{{'device-profile.lwm2m.key-name-tip' | translate}}"
75   - (input)="updateValueKeyName($event, z)"
  73 + (input)="updateValueKeyName($event, i)"
76 74 matTooltipPosition="above">
77 75 <mat-error *ngIf="resourceLwM2M.get('keyName').hasError('required')">
78   -
79 76 {{ 'device-profile.lwm2m.key-name' | translate }}
80 77 <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
81 78 </mat-error>
... ...
... ... @@ -14,20 +14,12 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import { Component, forwardRef, Input, OnInit } from '@angular/core';
18   -import {
19   - ControlValueAccessor,
20   - FormArray, FormBuilder,
21   - FormGroup,
22   - NG_VALUE_ACCESSOR, Validators
23   -} from '@angular/forms';
24   -import {
25   - CAMEL_CASE_REGEXP,
26   - ResourceLwM2M
27   -} from '@home/components/profile/device/lwm2m/profile-config.models';
  17 +import { Component, forwardRef, Input } from '@angular/core';
  18 +import { ControlValueAccessor, FormArray, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  19 +import { ResourceLwM2M } from '@home/components/profile/device/lwm2m/profile-config.models';
28 20 import { Store } from '@ngrx/store';
29 21 import { AppState } from '@core/core.state';
30   -import { deepClone } from '@core/utils';
  22 +import _ from 'lodash';
31 23 import { coerceBooleanProperty } from '@angular/cdk/coercion';
32 24
33 25 @Component({
... ... @@ -43,12 +35,12 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
43 35 ]
44 36 })
45 37
46   -export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueAccessor, OnInit, Validators {
  38 +export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueAccessor {
47 39
48 40 private requiredValue: boolean;
49 41
50 42 resourceFormGroup: FormGroup;
51   - disabled = false as boolean;
  43 + disabled = false;
52 44
53 45 get required(): boolean {
54 46 return this.requiredValue;
... ... @@ -61,9 +53,12 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
61 53 this.requiredValue = newVal;
62 54 }
63 55 }
  56 +
64 57 constructor(private store: Store<AppState>,
65 58 private fb: FormBuilder) {
66   - this.resourceFormGroup = this.fb.group({resources: this.fb.array([])});
  59 + this.resourceFormGroup = this.fb.group({
  60 + resources: this.fb.array([])
  61 + });
67 62 this.resourceFormGroup.valueChanges.subscribe(value => {
68 63 if (!this.disabled) {
69 64 this.propagateChangeState(value.resources);
... ... @@ -71,9 +66,6 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
71 66 });
72 67 }
73 68
74   - ngOnInit(): void {
75   - }
76   -
77 69 registerOnTouched(fn: any): void {
78 70 }
79 71
... ... @@ -85,10 +77,6 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
85 77 return this.resourceFormGroup.get('resources') as FormArray;
86 78 }
87 79
88   - resourceLwm2mFormArray = (instance: FormGroup): FormArray => {
89   - return instance.get('resources') as FormArray;
90   - }
91   -
92 80 setDisabledState(isDisabled: boolean): void {
93 81 this.disabled = isDisabled;
94 82 if (isDisabled) {
... ... @@ -98,31 +86,16 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
98 86 }
99 87 }
100 88
101   - getDisabledState = (): boolean => {
102   - return this.disabled;
103   - }
104   -
105   - updateValueKeyName = (event: any, z: number): void => {
106   - this.resourceFormArray.at(z).patchValue( {keyName: this.keysToCamel(deepClone(event.target.value))} );
107   - }
108   -
109   - private keysToCamel = (o: any): string => {
110   - const val = o.split(' ');
111   - const playStore = [];
112   - val.forEach((item, k) => {
113   - item = item.replace(CAMEL_CASE_REGEXP, '');
114   - item = (k === 0) ? item.charAt(0).toLowerCase() + item.substr(1) : item.charAt(0).toUpperCase() + item.substr(1);
115   - playStore.push(item);
116   - });
117   - return playStore.join('');
  89 + updateValueKeyName = (event: Event, index: number): void => {
  90 + this.resourceFormArray.at(index).patchValue({keyName: _.camelCase((event.target as HTMLInputElement).value)});
118 91 }
119 92
120   - private createResourceLwM2M = (resourcesLwM2MJson: ResourceLwM2M []): void => {
121   - if (resourcesLwM2MJson.length === this.resourceFormArray.length) {
122   - this.resourceFormArray.patchValue(resourcesLwM2MJson, {emitEvent: false});
  93 + createResourceLwM2M(resourcesLwM2M: ResourceLwM2M[]): void {
  94 + if (resourcesLwM2M.length === this.resourceFormArray.length) {
  95 + this.resourceFormArray.patchValue(resourcesLwM2M, {emitEvent: false});
123 96 } else {
124 97 this.resourceFormArray.clear();
125   - resourcesLwM2MJson.forEach(resourceLwM2M => {
  98 + resourcesLwM2M.forEach(resourceLwM2M => {
126 99 this.resourceFormArray.push(this.fb.group({
127 100 id: resourceLwM2M.id,
128 101 name: resourceLwM2M.name,
... ...
... ... @@ -19,7 +19,7 @@
19 19 <section [formGroup]="observeAttrTelemetryFormGroup" class="mat-padding">
20 20 <mat-accordion multi="true" class="mat-body-1" formArrayName="clientLwM2M">
21 21 <mat-expansion-panel
22   - *ngFor="let objectLwM2M of clientLwM2MFormArray(observeAttrTelemetryFormGroup).controls; let i = index; trackBy: trackByParams"
  22 + *ngFor="let objectLwM2M of clientLwM2MFormArray.controls; let i = index; trackBy: trackByParams"
23 23 [formGroupName]="i">
24 24 <mat-expansion-panel-header>
25 25 <mat-panel-title fxLayoutAlign="space-between">
... ... @@ -34,8 +34,8 @@
34 34 </button>
35 35 </mat-panel-title>
36 36 </mat-expansion-panel-header>
37   - <div fxLayout="column" fxLayoutGap="8px" formArrayName="instances">
38   - <ng-template matExpansionPanelContent>
  37 + <ng-template matExpansionPanelContent>
  38 + <div fxLayout="column" fxLayoutGap="8px" formArrayName="instances">
39 39 <mat-expansion-panel
40 40 *ngFor="let instances of instancesLwm2mFormArray(objectLwM2M).controls; let y = index;"
41 41 [formGroupName]="y"
... ... @@ -50,7 +50,7 @@
50 50 </div>
51 51 <div class="checkbox-padding" fxFlex="10">
52 52 <mat-checkbox color="primary"
53   - [formControlName]="observe"
  53 + [disabled]="this.disabled"
54 54 [checked]="getChecked(instances, 'observe')"
55 55 (click)="$event.stopPropagation()"
56 56 (change)="changeInstanceResourcesCheckBox($event.checked, instances, 'observe')"
... ... @@ -61,7 +61,8 @@
61 61 </mat-checkbox>
62 62 </div>
63 63 <div class="checkbox-padding" fxFlex="10">
64   - <mat-checkbox [formControlName]="attribute" color="warn"
  64 + <mat-checkbox color="warn"
  65 + [disabled]="this.disabled"
65 66 [checked]="getChecked(instances, 'attribute')"
66 67 (click)="$event.stopPropagation()"
67 68 (change)="changeInstanceResourcesCheckBox($event.checked, instances, 'attribute')"
... ... @@ -72,7 +73,8 @@
72 73 </mat-checkbox>
73 74 </div>
74 75 <div class="checkbox-padding" fxFlex="10">
75   - <mat-checkbox [formControlName]="telemetry" color="primary"
  76 + <mat-checkbox color="primary"
  77 + [disabled]="this.disabled"
76 78 [checked]="getChecked(instances, 'telemetry')"
77 79 (click)="$event.stopPropagation()"
78 80 (change)="changeInstanceResourcesCheckBox($event.checked, instances, 'telemetry')"
... ... @@ -95,8 +97,8 @@
95 97 </tb-profile-lwm2m-observe-attr-telemetry-resource>
96 98 </ng-template>
97 99 </mat-expansion-panel>
98   - </ng-template>
99   - </div>
  100 + </div>
  101 + </ng-template>
100 102 </mat-expansion-panel>
101 103 </mat-accordion>
102 104 </section>
... ...
... ... @@ -15,7 +15,7 @@
15 15 ///
16 16
17 17
18   -import { Component, forwardRef, Input, OnInit } from '@angular/core';
  18 +import { Component, forwardRef, Input } from '@angular/core';
19 19 import {
20 20 AbstractControl,
21 21 ControlValueAccessor,
... ... @@ -28,16 +28,8 @@ import {
28 28 import { Store } from '@ngrx/store';
29 29 import { AppState } from '@core/core.state';
30 30 import { coerceBooleanProperty } from '@angular/cdk/coercion';
31   -import {
32   - ATTR,
33   - Instance,
34   - ObjectLwM2M,
35   - OBSERVE,
36   - ResourceLwM2M,
37   - TELEMETRY
38   -} from './profile-config.models';
39   -import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined';
40   -import { deepClone, isUndefined } from '@core/utils';
  31 +import { Instance, ObjectLwM2M, ResourceLwM2M } from './profile-config.models';
  32 +import { deepClone, isDefinedAndNotNull, isEqual, isUndefined } from '@core/utils';
41 33 import { MatDialog } from '@angular/material/dialog';
42 34 import { TranslateService } from '@ngx-translate/core';
43 35 import {
... ... @@ -58,25 +50,18 @@ import {
58 50 ]
59 51 })
60 52
61   -export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor, OnInit, Validators {
  53 +export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor {
62 54
63 55 private requiredValue: boolean;
64 56
65 57 valuePrev = null as any;
66 58 observeAttrTelemetryFormGroup: FormGroup;
67   - observe = OBSERVE as string;
68   - attribute = ATTR as string;
69   - telemetry = TELEMETRY as string;
70 59
71 60 get required(): boolean {
72 61 return this.requiredValue;
73 62 }
74 63
75 64 @Input()
76   - disabled: boolean;
77   -
78   - // tslint:disable-next-line:adjacent-overload-signatures
79   - @Input()
80 65 set required(value: boolean) {
81 66 const newVal = coerceBooleanProperty(value);
82 67 if (this.requiredValue !== newVal) {
... ... @@ -85,6 +70,9 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
85 70 }
86 71 }
87 72
  73 + @Input()
  74 + disabled: boolean;
  75 +
88 76 constructor(private store: Store<AppState>,
89 77 private fb: FormBuilder,
90 78 private dialog: MatDialog,
... ... @@ -99,9 +87,6 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
99 87 });
100 88 }
101 89
102   - ngOnInit(): void {
103   - }
104   -
105 90 private propagateChange = (v: any) => { };
106 91
107 92
... ... @@ -139,10 +124,6 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
139 124 }
140 125 }
141 126
142   - getDisabledState = (): boolean => {
143   - return this.disabled;
144   - }
145   -
146 127 writeValue(value: any): void {
147 128 this.buildClientObjectsLwM2M(value.clientLwM2M);
148 129 }
... ... @@ -153,8 +134,8 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
153 134 );
154 135 }
155 136
156   - private createObjectsLwM2M = (objectsLwM2MJson: ObjectLwM2M []): FormArray => {
157   - return this.fb.array(objectsLwM2MJson.map((objectLwM2M) => {
  137 + private createObjectsLwM2M = (objectsLwM2M: ObjectLwM2M[]): FormArray => {
  138 + return this.fb.array(objectsLwM2M.map((objectLwM2M) => {
158 139 return this.fb.group({
159 140 id: objectLwM2M.id,
160 141 name: objectLwM2M.name,
... ... @@ -165,20 +146,17 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
165 146 }));
166 147 }
167 148
168   - private createInstanceLwM2M = (instanceLwM2MJson: Instance []): FormArray => {
169   - return this.fb.array(instanceLwM2MJson.map((instanceLwM2M) => {
  149 + private createInstanceLwM2M = (instancesLwM2M: Instance[]): FormArray => {
  150 + return this.fb.array(instancesLwM2M.map((instanceLwM2M) => {
170 151 return this.fb.group({
171 152 id: instanceLwM2M.id,
172   - [this.observe]: {value: false, disabled: this.disabled},
173   - [this.attribute]: {value: false, disabled: this.disabled},
174   - [this.telemetry]: {value: false, disabled: this.disabled},
175 153 resources: {value: instanceLwM2M.resources, disabled: this.disabled}
176 154 });
177 155 }));
178 156 }
179 157
180   - clientLwM2MFormArray = (formGroup: FormGroup): FormArray => {
181   - return formGroup.get('clientLwM2M') as FormArray;
  158 + get clientLwM2MFormArray(): FormArray {
  159 + return this.observeAttrTelemetryFormGroup.get('clientLwM2M') as FormArray;
182 160 }
183 161
184 162 instancesLwm2mFormArray = (objectLwM2M: AbstractControl): FormArray => {
... ... @@ -186,7 +164,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
186 164 }
187 165
188 166 changeInstanceResourcesCheckBox = (value: boolean, instance: AbstractControl, type: string): void => {
189   - const resources = instance.get('resources').value as ResourceLwM2M [];
  167 + const resources = instance.get('resources').value as ResourceLwM2M[];
190 168 resources.forEach(resource => resource[type] = value);
191 169 instance.get('resources').patchValue(resources);
192 170 this.propagateChange(this.observeAttrTelemetryFormGroup.value);
... ... @@ -202,26 +180,18 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
202 180 }
203 181
204 182 getIndeterminate = (instance: AbstractControl, type: string): boolean => {
205   - const resources = instance.get('resources').value as ResourceLwM2M [];
206   - if (isNotNullOrUndefined(resources)) {
207   - const isType = (element) => element[type] === true;
208   - const checkedResource = resources.filter(isType);
209   - if (checkedResource.length === 0) { return false; }
210   - else if (checkedResource.length === resources.length) {
211   - instance.patchValue({[type]: true});
212   - return false;
213   - } else { return true; }
  183 + const resources = instance.get('resources').value as ResourceLwM2M[];
  184 + if (isDefinedAndNotNull(resources)) {
  185 + const checkedResource = resources.filter(resource => resource[type]);
  186 + return checkedResource.length !== 0 && checkedResource.length !== resources.length;
214 187 }
215 188 return false;
216 189 }
217 190
218 191
219 192 getChecked = (instance: AbstractControl, type: string): boolean => {
220   - const resources = instance.get('resources').value as ResourceLwM2M [];
221   - if (isNotNullOrUndefined(resources)) {
222   - return resources.some(resource => resource[type]);
223   - }
224   - return false;
  193 + const resources = instance.get('resources').value as ResourceLwM2M[];
  194 + return isDefinedAndNotNull(resources) && resources.every(resource => resource[type]);
225 195 }
226 196
227 197 getExpended = (objectLwM2M: AbstractControl): boolean => {
... ... @@ -265,7 +235,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
265 235 }
266 236 }).afterClosed().subscribe(
267 237 (res: Lwm2mObjectAddInstancesData | undefined) => {
268   - if (isNotNullOrUndefined(res)) {
  238 + if (isDefinedAndNotNull(res)) {
269 239 this.updateInstancesIds(res);
270 240 }
271 241 }
... ... @@ -278,43 +248,41 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
278 248 data.instancesIds.forEach(value => {
279 249 valueNew.add(value);
280 250 });
281   - const oldInstances = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M []).
282   - find(e => e.id === data.objectId).instances;
  251 + const oldInstances = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M [])
  252 + .find(e => e.id === data.objectId).instances;
283 253 oldInstances.forEach(inst => {
284 254 valueOld.add(inst.id);
285 255 });
286   - if (JSON.stringify(Array.from(valueOld)) !== JSON.stringify(Array.from(valueNew))) {
287   - const idsDel = this.diffBetweenSet(valueNew, this.deepCloneSet(valueOld));
288   - const idsAdd = this.diffBetweenSet(valueOld, this.deepCloneSet(valueNew));
  256 + if (!isEqual(valueOld, valueNew)) {
  257 + const idsDel = this.diffBetweenSet(valueOld, valueNew);
  258 + const idsAdd = this.diffBetweenSet(valueNew, valueOld);
289 259 if (idsAdd.size) {
290 260 this.addInstancesNew(data.objectId, idsAdd);
291 261 }
292 262 if (idsDel.size) {
293   - this.delInstances(data.objectId, idsDel);
  263 + this.deleteInstances(data.objectId, idsDel);
294 264 }
295 265 }
296 266 }
297 267
298   - private delInstances = (objectId: number, idsDel: Set<number>): void => {
299   - let isIdIndex = (element) => element.id === objectId;
300   - const objectIndex = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M []).findIndex(isIdIndex);
  268 + private deleteInstances = (objectId: number, idsDel: Set<number>): void => {
  269 + const objectIndex = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M[])
  270 + .findIndex(element => element.id === objectId);
301 271 idsDel.forEach(x => {
302   - isIdIndex = (element) => element.value.id === x;
303 272 const instancesFormArray = ((this.observeAttrTelemetryFormGroup.get('clientLwM2M') as FormArray)
304   - .controls[objectIndex].get('instances') as FormArray);
305   - const instanceIndex = instancesFormArray.controls.findIndex(isIdIndex);
  273 + .at(objectIndex).get('instances') as FormArray);
  274 + const instanceIndex = instancesFormArray.value.findIndex(element => element.id === x);
306 275 instancesFormArray.removeAt(instanceIndex);
307 276 });
308 277 }
309 278
310 279 private addInstancesNew = (objectId: number, idsAdd: Set<number>): void => {
311 280 const instancesValue = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M [])
312   - .find(e => e.id === objectId).instances;
  281 + .find(objectLwM2M => objectLwM2M.id === objectId).instances;
313 282 const instancesFormArray = ((this.observeAttrTelemetryFormGroup.get('clientLwM2M') as FormArray).controls
314 283 .find(e => e.value.id === objectId).get('instances') as FormArray) as FormArray;
315 284 idsAdd.forEach(x => {
316 285 const instanceNew = deepClone(instancesValue[0]) as Instance;
317   - instanceNew.id = x;
318 286 instanceNew.resources.forEach(r => {
319 287 r.attribute = false;
320 288 r.telemetry = false;
... ... @@ -322,28 +290,14 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
322 290 });
323 291 instancesFormArray.push(this.fb.group({
324 292 id: x,
325   - [this.observe]: {value: false, disabled: this.disabled},
326   - [this.attribute]: {value: false, disabled: this.disabled},
327   - [this.telemetry]: {value: false, disabled: this.disabled},
328 293 resources: {value: instanceNew.resources, disabled: this.disabled}
329 294 }));
330 295 });
331 296 (instancesFormArray.controls as FormGroup[]).sort((a, b) => a.value.id - b.value.id);
332 297 }
333 298
334   - private deepCloneSet = (oldSet: Set<any>): Set<any> => {
335   - const newSet = new Set<number>();
336   - oldSet.forEach(p => {
337   - newSet.add(p);
338   - });
339   - return newSet;
340   - }
341   -
342 299 private diffBetweenSet = (firstSet: Set<any>, secondSet: Set<any>): Set<any> => {
343   - firstSet.forEach(p => {
344   - secondSet.delete(p);
345   - });
346   - return secondSet;
  300 + return new Set([...Array.from(firstSet)].filter(x => !secondSet.has(x)));
347 301 }
348 302
349 303 private setInstancesIds = (instances: Instance []): Set<number> => {
... ...
... ... @@ -33,7 +33,6 @@ export const DEFAULT_BOOTSTRAP_SERVER_ACCOUNT_TIME_OUT = 0;
33 33 export const LEN_MAX_PUBLIC_KEY_RPK = 182;
34 34 export const LEN_MAX_PUBLIC_KEY_X509 = 3000;
35 35 export const KEY_REGEXP_HEX_DEC = /^[-+]?[0-9A-Fa-f]+\.?[0-9A-Fa-f]*?$/;
36   -export const CAMEL_CASE_REGEXP = /[-_&@.,*+!?^${}()|[\]\\]/g;
37 36 export const INSTANCES_ID_VALUE_MIN = 0;
38 37 export const INSTANCES_ID_VALUE_MAX = 65535;
39 38
... ... @@ -82,12 +81,14 @@ interface BootstrapSecurityConfig {
82 81
83 82 export interface ProfileConfigModels {
84 83 bootstrap: BootstrapSecurityConfig;
85   - observeAttr: {
86   - observe: string [],
87   - attribute: string [],
88   - telemetry: string [],
89   - keyName: []
90   - };
  84 + observeAttr: ObservableAttributes;
  85 +}
  86 +
  87 +export interface ObservableAttributes {
  88 + observe: string[];
  89 + attribute: string[];
  90 + telemetry: string[];
  91 + keyName: string[];
91 92 }
92 93
93 94 export function getDefaultBootstrapServersSecurityConfig(): BootstrapServersSecurityConfig {
... ...
... ... @@ -35,7 +35,7 @@
35 35 required
36 36 >
37 37 </tb-entity-gateway-select>
38   - <div fxLayout="column">profile-tab
  38 + <div fxLayout="column">
39 39 <mat-form-field fxFlex>
40 40 <mat-label>{{'gateway.security-type' | translate }}</mat-label>
41 41 <mat-select formControlName="securityType" >
... ...
... ... @@ -61,8 +61,7 @@ export class JsonObjectEditComponent implements OnInit, ControlValueAccessor, Va
61 61
62 62 @Input() editorStyle: { [klass: string]: any };
63 63
64   - // tslint:disable-next-line:ban-types
65   - @Input() sort: Function;
  64 + @Input() sort: (key: string, value: any) => any;
66 65
67 66 private requiredValue: boolean;
68 67
... ... @@ -227,10 +226,9 @@ export class JsonObjectEditComponent implements OnInit, ControlValueAccessor, Va
227 226 try {
228 227
229 228 if (this.modelValue) {
230   - this.contentValue = JSON.stringify(this.modelValue, isUndefined(this.sort) ? null :
231   - // tslint:disable-next-line:no-shadowed-variable
232   - (key, value) => {
233   - return this.sort(key, value);
  229 + this.contentValue = JSON.stringify(this.modelValue, isUndefined(this.sort) ? undefined :
  230 + (key, objectValue) => {
  231 + return this.sort(key, objectValue);
234 232 }, 2);
235 233 this.objectValid = true;
236 234 } else {
... ...
... ... @@ -454,8 +454,6 @@ export interface DeviceCredentials extends BaseData<DeviceCredentialsId> {
454 454 credentialsType: DeviceCredentialsType;
455 455 credentialsId: string;
456 456 credentialsValue: string;
457   - credentialsLwKey: string;
458   - credentialsLwValue: string;
459 457 }
460 458
461 459 export interface DeviceCredentialMQTTBasic {
... ...