Merge pull request #11228 from rusikv/bug/device-profile-validation

Fixed device profile create/update form validation
This commit is contained in:
Igor Kulikov 2024-07-26 16:36:53 +03:00 committed by GitHub
commit f02df3e890
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 44 additions and 122 deletions

View File

@ -108,8 +108,7 @@
</mat-form-field> </mat-form-field>
<tb-device-profile-transport-configuration <tb-device-profile-transport-configuration
formControlName="transportConfiguration" formControlName="transportConfiguration"
isAdd="true" isAdd="true">
required>
</tb-device-profile-transport-configuration> </tb-device-profile-transport-configuration>
</form> </form>
</mat-step> </mat-step>

View File

@ -137,8 +137,7 @@
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<tb-device-profile-configuration <tb-device-profile-configuration
formControlName="configuration" formControlName="configuration">
required>
</tb-device-profile-configuration> </tb-device-profile-configuration>
</ng-template> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>
@ -151,8 +150,7 @@
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<tb-device-profile-transport-configuration <tb-device-profile-transport-configuration
formControlName="transportConfiguration" formControlName="transportConfiguration"
[isAdd] = "isTransportTypeChanged" [isAdd] = "isTransportTypeChanged">
required>
</tb-device-profile-transport-configuration> </tb-device-profile-transport-configuration>
</ng-template> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>

View File

@ -28,7 +28,6 @@ import {
} from '@angular/forms'; } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { import {
CoapDeviceProfileTransportConfiguration, CoapDeviceProfileTransportConfiguration,
coapDeviceTypeTranslationMap, coapDeviceTypeTranslationMap,
@ -74,7 +73,6 @@ export class CoapDeviceProfileTransportConfigurationComponent implements Control
coapTransportConfigurationFormGroup: UntypedFormGroup; coapTransportConfigurationFormGroup: UntypedFormGroup;
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
private requiredValue: boolean;
private transportPayloadTypeConfiguration = this.fb.group({ private transportPayloadTypeConfiguration = this.fb.group({
transportPayloadType: [TransportPayloadType.JSON, Validators.required], transportPayloadType: [TransportPayloadType.JSON, Validators.required],
@ -84,15 +82,6 @@ export class CoapDeviceProfileTransportConfigurationComponent implements Control
deviceRpcResponseProtoSchema: [defaultRpcResponseSchema, Validators.required] deviceRpcResponseProtoSchema: [defaultRpcResponseSchema, Validators.required]
}); });
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
disabled: boolean; disabled: boolean;

View File

@ -18,7 +18,6 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { import {
DefaultDeviceProfileConfiguration, DefaultDeviceProfileConfiguration,
DeviceProfileConfiguration, DeviceProfileConfiguration,
@ -39,15 +38,6 @@ export class DefaultDeviceProfileConfigurationComponent implements ControlValueA
defaultDeviceProfileConfigurationFormGroup: UntypedFormGroup; defaultDeviceProfileConfigurationFormGroup: UntypedFormGroup;
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
disabled: boolean; disabled: boolean;

View File

@ -15,39 +15,42 @@
/// ///
import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; import {
ControlValueAccessor,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
ValidationErrors,
Validator,
Validators
} from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { DefaultDeviceProfileTransportConfiguration, DeviceTransportType } from '@shared/models/device.models';
import {
DefaultDeviceProfileTransportConfiguration,
DeviceProfileTransportConfiguration,
DeviceTransportType
} from '@shared/models/device.models';
@Component({ @Component({
selector: 'tb-default-device-profile-transport-configuration', selector: 'tb-default-device-profile-transport-configuration',
templateUrl: './default-device-profile-transport-configuration.component.html', templateUrl: './default-device-profile-transport-configuration.component.html',
styleUrls: [], styleUrls: [],
providers: [{ providers: [
{
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DefaultDeviceProfileTransportConfigurationComponent), useExisting: forwardRef(() => DefaultDeviceProfileTransportConfigurationComponent),
multi: true multi: true
}] },
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => DefaultDeviceProfileTransportConfigurationComponent),
multi: true
}
]
}) })
export class DefaultDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, OnInit { export class DefaultDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, OnInit, Validator {
defaultDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup; defaultDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup;
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
disabled: boolean; disabled: boolean;
@ -86,12 +89,17 @@ export class DefaultDeviceProfileTransportConfigurationComponent implements Cont
this.defaultDeviceProfileTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false}); this.defaultDeviceProfileTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false});
} }
private updateModel() { validate(c: UntypedFormControl): ValidationErrors | null {
let configuration: DeviceProfileTransportConfiguration = null; return (this.defaultDeviceProfileTransportConfigurationFormGroup.valid) ? null : {
if (this.defaultDeviceProfileTransportConfigurationFormGroup.valid) { configuration: {
configuration = this.defaultDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration; valid: false
configuration.type = DeviceTransportType.DEFAULT;
} }
}
}
private updateModel() {
const configuration = this.defaultDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration;
configuration.type = DeviceTransportType.DEFAULT;
this.propagateChange(configuration); this.propagateChange(configuration);
} }
} }

View File

@ -19,7 +19,6 @@
<div [ngSwitch]="type"> <div [ngSwitch]="type">
<ng-template [ngSwitchCase]="deviceProfileType.DEFAULT"> <ng-template [ngSwitchCase]="deviceProfileType.DEFAULT">
<tb-default-device-profile-configuration <tb-default-device-profile-configuration
[required]="required"
formControlName="configuration"> formControlName="configuration">
</tb-default-device-profile-configuration> </tb-default-device-profile-configuration>
</ng-template> </ng-template>

View File

@ -18,7 +18,6 @@ import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core';
import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { DeviceProfileConfiguration, DeviceProfileType } from '@shared/models/device.models'; import { DeviceProfileConfiguration, DeviceProfileType } from '@shared/models/device.models';
import { deepClone } from '@core/utils'; import { deepClone } from '@core/utils';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
@ -42,15 +41,6 @@ export class DeviceProfileConfigurationComponent implements ControlValueAccessor
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
disabled: boolean; disabled: boolean;

View File

@ -19,32 +19,27 @@
<div [ngSwitch]="transportType"> <div [ngSwitch]="transportType">
<ng-template [ngSwitchCase]="deviceTransportType.DEFAULT"> <ng-template [ngSwitchCase]="deviceTransportType.DEFAULT">
<tb-default-device-profile-transport-configuration <tb-default-device-profile-transport-configuration
[required]="required"
formControlName="configuration"> formControlName="configuration">
</tb-default-device-profile-transport-configuration> </tb-default-device-profile-transport-configuration>
</ng-template> </ng-template>
<ng-template [ngSwitchCase]="deviceTransportType.MQTT"> <ng-template [ngSwitchCase]="deviceTransportType.MQTT">
<tb-mqtt-device-profile-transport-configuration <tb-mqtt-device-profile-transport-configuration
[required]="required"
formControlName="configuration"> formControlName="configuration">
</tb-mqtt-device-profile-transport-configuration> </tb-mqtt-device-profile-transport-configuration>
</ng-template> </ng-template>
<ng-template [ngSwitchCase]="deviceTransportType.COAP"> <ng-template [ngSwitchCase]="deviceTransportType.COAP">
<tb-coap-device-profile-transport-configuration <tb-coap-device-profile-transport-configuration
[required]="required"
formControlName="configuration"> formControlName="configuration">
</tb-coap-device-profile-transport-configuration> </tb-coap-device-profile-transport-configuration>
</ng-template> </ng-template>
<ng-template [ngSwitchCase]="deviceTransportType.LWM2M"> <ng-template [ngSwitchCase]="deviceTransportType.LWM2M">
<tb-profile-lwm2m-device-transport-configuration <tb-profile-lwm2m-device-transport-configuration
[isAdd]="isAdd" [isAdd]="isAdd"
[required]="required"
formControlName="configuration"> formControlName="configuration">
</tb-profile-lwm2m-device-transport-configuration> </tb-profile-lwm2m-device-transport-configuration>
</ng-template> </ng-template>
<ng-template [ngSwitchCase]="deviceTransportType.SNMP"> <ng-template [ngSwitchCase]="deviceTransportType.SNMP">
<tb-snmp-device-profile-transport-configuration <tb-snmp-device-profile-transport-configuration
[required]="required"
formControlName="configuration"> formControlName="configuration">
</tb-snmp-device-profile-transport-configuration> </tb-snmp-device-profile-transport-configuration>
</ng-template> </ng-template>

View File

@ -23,12 +23,10 @@ import {
UntypedFormControl, UntypedFormControl,
UntypedFormGroup, UntypedFormGroup,
ValidationErrors, ValidationErrors,
Validator, Validator
Validators
} from '@angular/forms'; } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { DeviceProfileTransportConfiguration, DeviceTransportType } from '@shared/models/device.models'; import { DeviceProfileTransportConfiguration, DeviceTransportType } from '@shared/models/device.models';
import { deepClone } from '@core/utils'; import { deepClone } from '@core/utils';
@ -55,15 +53,6 @@ export class DeviceProfileTransportConfigurationComponent implements ControlValu
deviceProfileTransportConfigurationFormGroup: UntypedFormGroup; deviceProfileTransportConfigurationFormGroup: UntypedFormGroup;
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
disabled: boolean; disabled: boolean;
@ -87,7 +76,7 @@ export class DeviceProfileTransportConfigurationComponent implements ControlValu
ngOnInit() { ngOnInit() {
this.deviceProfileTransportConfigurationFormGroup = this.fb.group({ this.deviceProfileTransportConfigurationFormGroup = this.fb.group({
configuration: [null, Validators.required] configuration: [null]
}); });
this.deviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => { this.deviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => {
this.updateModel(); this.updateModel();
@ -110,7 +99,7 @@ export class DeviceProfileTransportConfigurationComponent implements ControlValu
delete configuration.type; delete configuration.type;
} }
setTimeout(() => { setTimeout(() => {
this.deviceProfileTransportConfigurationFormGroup.patchValue({configuration}, {emitEvent: false}); this.deviceProfileTransportConfigurationFormGroup.patchValue({configuration});
}, 0); }, 0);
} }

View File

@ -25,7 +25,6 @@ import {
Validator, Validator,
Validators Validators
} from '@angular/forms'; } from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { import {
ATTRIBUTE, ATTRIBUTE,
DEFAULT_EDRX_CYCLE, DEFAULT_EDRX_CYCLE,
@ -47,7 +46,7 @@ import {
ObjectIDVerTranslationMap ObjectIDVerTranslationMap
} from './lwm2m-profile-config.models'; } from './lwm2m-profile-config.models';
import { DeviceProfileService } from '@core/http/device-profile.service'; import { DeviceProfileService } from '@core/http/device-profile.service';
import { deepClone, isDefinedAndNotNull, isEmpty, isUndefined } from '@core/utils'; import { deepClone, isDefinedAndNotNull, isEmpty } from '@core/utils';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import _ from 'lodash'; import _ from 'lodash';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
@ -77,7 +76,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
public disabled = false; public disabled = false;
public isTransportWasRunWithBootstrap = true; public isTransportWasRunWithBootstrap = true;
public isBootstrapServerUpdateEnable: boolean; public isBootstrapServerUpdateEnable: boolean;
private requiredValue: boolean;
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
lwm2mDeviceProfileFormGroup: UntypedFormGroup; lwm2mDeviceProfileFormGroup: UntypedFormGroup;
@ -88,15 +86,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
sortFunction: (key: string, value: object) => object; sortFunction: (key: string, value: object) => object;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
isAdd: boolean; isAdd: boolean;

View File

@ -29,7 +29,6 @@ import {
} from '@angular/forms'; } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { import {
defaultAttributesSchema, defaultAttributesSchema,
defaultRpcRequestSchema, defaultRpcRequestSchema,
@ -70,16 +69,6 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control
mqttDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup; mqttDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup;
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
disabled: boolean; disabled: boolean;

View File

@ -25,7 +25,6 @@ import {
Validator, Validator,
Validators Validators
} from '@angular/forms'; } from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { import {
DeviceTransportType, DeviceTransportType,
SnmpDeviceProfileTransportConfiguration SnmpDeviceProfileTransportConfiguration
@ -63,16 +62,6 @@ export class SnmpDeviceProfileTransportConfigurationComponent implements OnInit,
snmpDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup; snmpDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup;
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@Input() @Input()
disabled: boolean; disabled: boolean;

View File

@ -35,8 +35,7 @@
<div formGroupName="profileData"> <div formGroupName="profileData">
<tb-device-profile-transport-configuration <tb-device-profile-transport-configuration
formControlName="transportConfiguration" formControlName="transportConfiguration"
[isAdd] = "isTransportTypeChanged" [isAdd]="isTransportTypeChanged">
required>
</tb-device-profile-transport-configuration> </tb-device-profile-transport-configuration>
</div> </div>
</div> </div>
@ -65,8 +64,7 @@
<div class="mat-padding" [formGroup]="detailsForm"> <div class="mat-padding" [formGroup]="detailsForm">
<div formGroupName="profileData"> <div formGroupName="profileData">
<tb-device-profile-configuration <tb-device-profile-configuration
formControlName="configuration" formControlName="configuration">
required>
</tb-device-profile-configuration> </tb-device-profile-configuration>
</div> </div>
</div> </div>