Merge pull request #11228 from rusikv/bug/device-profile-validation
Fixed device profile create/update form validation
This commit is contained in:
		
						commit
						f02df3e890
					
				@ -108,8 +108,7 @@
 | 
			
		||||
        </mat-form-field>
 | 
			
		||||
        <tb-device-profile-transport-configuration
 | 
			
		||||
          formControlName="transportConfiguration"
 | 
			
		||||
          isAdd="true"
 | 
			
		||||
          required>
 | 
			
		||||
          isAdd="true">
 | 
			
		||||
        </tb-device-profile-transport-configuration>
 | 
			
		||||
      </form>
 | 
			
		||||
    </mat-step>
 | 
			
		||||
 | 
			
		||||
@ -137,8 +137,7 @@
 | 
			
		||||
            </mat-expansion-panel-header>
 | 
			
		||||
            <ng-template matExpansionPanelContent>
 | 
			
		||||
              <tb-device-profile-configuration
 | 
			
		||||
                formControlName="configuration"
 | 
			
		||||
                required>
 | 
			
		||||
                formControlName="configuration">
 | 
			
		||||
              </tb-device-profile-configuration>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
@ -151,8 +150,7 @@
 | 
			
		||||
            <ng-template matExpansionPanelContent>
 | 
			
		||||
              <tb-device-profile-transport-configuration
 | 
			
		||||
                formControlName="transportConfiguration"
 | 
			
		||||
                [isAdd] = "isTransportTypeChanged"
 | 
			
		||||
                required>
 | 
			
		||||
                [isAdd] = "isTransportTypeChanged">
 | 
			
		||||
              </tb-device-profile-transport-configuration>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </mat-expansion-panel>
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,6 @@ import {
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@app/core/core.state';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import {
 | 
			
		||||
  CoapDeviceProfileTransportConfiguration,
 | 
			
		||||
  coapDeviceTypeTranslationMap,
 | 
			
		||||
@ -74,7 +73,6 @@ export class CoapDeviceProfileTransportConfigurationComponent implements Control
 | 
			
		||||
  coapTransportConfigurationFormGroup: UntypedFormGroup;
 | 
			
		||||
 | 
			
		||||
  private destroy$ = new Subject<void>();
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
 | 
			
		||||
  private transportPayloadTypeConfiguration = this.fb.group({
 | 
			
		||||
    transportPayloadType: [TransportPayloadType.JSON, Validators.required],
 | 
			
		||||
@ -84,15 +82,6 @@ export class CoapDeviceProfileTransportConfigurationComponent implements Control
 | 
			
		||||
    deviceRpcResponseProtoSchema: [defaultRpcResponseSchema, Validators.required]
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,6 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core';
 | 
			
		||||
import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@app/core/core.state';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import {
 | 
			
		||||
  DefaultDeviceProfileConfiguration,
 | 
			
		||||
  DeviceProfileConfiguration,
 | 
			
		||||
@ -39,15 +38,6 @@ export class DefaultDeviceProfileConfigurationComponent implements ControlValueA
 | 
			
		||||
 | 
			
		||||
  defaultDeviceProfileConfigurationFormGroup: UntypedFormGroup;
 | 
			
		||||
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,39 +15,42 @@
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
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 { AppState } from '@app/core/core.state';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import {
 | 
			
		||||
  DefaultDeviceProfileTransportConfiguration,
 | 
			
		||||
  DeviceProfileTransportConfiguration,
 | 
			
		||||
  DeviceTransportType
 | 
			
		||||
} from '@shared/models/device.models';
 | 
			
		||||
import { DefaultDeviceProfileTransportConfiguration, DeviceTransportType } from '@shared/models/device.models';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'tb-default-device-profile-transport-configuration',
 | 
			
		||||
  templateUrl: './default-device-profile-transport-configuration.component.html',
 | 
			
		||||
  styleUrls: [],
 | 
			
		||||
  providers: [{
 | 
			
		||||
    provide: NG_VALUE_ACCESSOR,
 | 
			
		||||
    useExisting: forwardRef(() => DefaultDeviceProfileTransportConfigurationComponent),
 | 
			
		||||
    multi: true
 | 
			
		||||
  }]
 | 
			
		||||
  providers: [
 | 
			
		||||
    {
 | 
			
		||||
      provide: NG_VALUE_ACCESSOR,
 | 
			
		||||
      useExisting: forwardRef(() => DefaultDeviceProfileTransportConfigurationComponent),
 | 
			
		||||
      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;
 | 
			
		||||
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
@ -86,12 +89,17 @@ export class DefaultDeviceProfileTransportConfigurationComponent implements Cont
 | 
			
		||||
    this.defaultDeviceProfileTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateModel() {
 | 
			
		||||
    let configuration: DeviceProfileTransportConfiguration = null;
 | 
			
		||||
    if (this.defaultDeviceProfileTransportConfigurationFormGroup.valid) {
 | 
			
		||||
      configuration = this.defaultDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration;
 | 
			
		||||
      configuration.type = DeviceTransportType.DEFAULT;
 | 
			
		||||
  validate(c: UntypedFormControl): ValidationErrors | null {
 | 
			
		||||
    return (this.defaultDeviceProfileTransportConfigurationFormGroup.valid) ? null : {
 | 
			
		||||
      configuration: {
 | 
			
		||||
        valid: false
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateModel() {
 | 
			
		||||
    const configuration = this.defaultDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration;
 | 
			
		||||
    configuration.type = DeviceTransportType.DEFAULT;
 | 
			
		||||
    this.propagateChange(configuration);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,6 @@
 | 
			
		||||
  <div [ngSwitch]="type">
 | 
			
		||||
    <ng-template [ngSwitchCase]="deviceProfileType.DEFAULT">
 | 
			
		||||
      <tb-default-device-profile-configuration
 | 
			
		||||
        [required]="required"
 | 
			
		||||
        formControlName="configuration">
 | 
			
		||||
      </tb-default-device-profile-configuration>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
 | 
			
		||||
@ -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 { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@app/core/core.state';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import { DeviceProfileConfiguration, DeviceProfileType } from '@shared/models/device.models';
 | 
			
		||||
import { deepClone } from '@core/utils';
 | 
			
		||||
import { Subject } from 'rxjs';
 | 
			
		||||
@ -42,15 +41,6 @@ export class DeviceProfileConfigurationComponent implements ControlValueAccessor
 | 
			
		||||
 | 
			
		||||
  private destroy$ = new Subject<void>();
 | 
			
		||||
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,32 +19,27 @@
 | 
			
		||||
  <div [ngSwitch]="transportType">
 | 
			
		||||
    <ng-template [ngSwitchCase]="deviceTransportType.DEFAULT">
 | 
			
		||||
      <tb-default-device-profile-transport-configuration
 | 
			
		||||
        [required]="required"
 | 
			
		||||
        formControlName="configuration">
 | 
			
		||||
      </tb-default-device-profile-transport-configuration>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
    <ng-template [ngSwitchCase]="deviceTransportType.MQTT">
 | 
			
		||||
      <tb-mqtt-device-profile-transport-configuration
 | 
			
		||||
        [required]="required"
 | 
			
		||||
        formControlName="configuration">
 | 
			
		||||
      </tb-mqtt-device-profile-transport-configuration>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
    <ng-template [ngSwitchCase]="deviceTransportType.COAP">
 | 
			
		||||
      <tb-coap-device-profile-transport-configuration
 | 
			
		||||
        [required]="required"
 | 
			
		||||
        formControlName="configuration">
 | 
			
		||||
      </tb-coap-device-profile-transport-configuration>
 | 
			
		||||
    </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>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
    <ng-template [ngSwitchCase]="deviceTransportType.SNMP">
 | 
			
		||||
      <tb-snmp-device-profile-transport-configuration
 | 
			
		||||
        [required]="required"
 | 
			
		||||
        formControlName="configuration">
 | 
			
		||||
      </tb-snmp-device-profile-transport-configuration>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
 | 
			
		||||
@ -23,12 +23,10 @@ import {
 | 
			
		||||
  UntypedFormControl,
 | 
			
		||||
  UntypedFormGroup,
 | 
			
		||||
  ValidationErrors,
 | 
			
		||||
  Validator,
 | 
			
		||||
  Validators
 | 
			
		||||
  Validator
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@app/core/core.state';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import { DeviceProfileTransportConfiguration, DeviceTransportType } from '@shared/models/device.models';
 | 
			
		||||
import { deepClone } from '@core/utils';
 | 
			
		||||
 | 
			
		||||
@ -55,15 +53,6 @@ export class DeviceProfileTransportConfigurationComponent implements ControlValu
 | 
			
		||||
 | 
			
		||||
  deviceProfileTransportConfigurationFormGroup: UntypedFormGroup;
 | 
			
		||||
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
@ -87,7 +76,7 @@ export class DeviceProfileTransportConfigurationComponent implements ControlValu
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    this.deviceProfileTransportConfigurationFormGroup = this.fb.group({
 | 
			
		||||
      configuration: [null, Validators.required]
 | 
			
		||||
      configuration: [null]
 | 
			
		||||
    });
 | 
			
		||||
    this.deviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => {
 | 
			
		||||
      this.updateModel();
 | 
			
		||||
@ -110,7 +99,7 @@ export class DeviceProfileTransportConfigurationComponent implements ControlValu
 | 
			
		||||
      delete configuration.type;
 | 
			
		||||
    }
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      this.deviceProfileTransportConfigurationFormGroup.patchValue({configuration}, {emitEvent: false});
 | 
			
		||||
      this.deviceProfileTransportConfigurationFormGroup.patchValue({configuration});
 | 
			
		||||
    }, 0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,6 @@ import {
 | 
			
		||||
  Validator,
 | 
			
		||||
  Validators
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import {
 | 
			
		||||
  ATTRIBUTE,
 | 
			
		||||
  DEFAULT_EDRX_CYCLE,
 | 
			
		||||
@ -47,7 +46,7 @@ import {
 | 
			
		||||
  ObjectIDVerTranslationMap
 | 
			
		||||
} from './lwm2m-profile-config.models';
 | 
			
		||||
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 _ from 'lodash';
 | 
			
		||||
import { Subject } from 'rxjs';
 | 
			
		||||
@ -77,7 +76,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
 | 
			
		||||
  public disabled = false;
 | 
			
		||||
  public isTransportWasRunWithBootstrap = true;
 | 
			
		||||
  public isBootstrapServerUpdateEnable: boolean;
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
  private destroy$ = new Subject<void>();
 | 
			
		||||
 | 
			
		||||
  lwm2mDeviceProfileFormGroup: UntypedFormGroup;
 | 
			
		||||
@ -88,15 +86,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
 | 
			
		||||
 | 
			
		||||
  sortFunction: (key: string, value: object) => object;
 | 
			
		||||
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  isAdd: boolean;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,6 @@ import {
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@app/core/core.state';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import {
 | 
			
		||||
  defaultAttributesSchema,
 | 
			
		||||
  defaultRpcRequestSchema,
 | 
			
		||||
@ -70,16 +69,6 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control
 | 
			
		||||
  mqttDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup;
 | 
			
		||||
 | 
			
		||||
  private destroy$ = new Subject<void>();
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,6 @@ import {
 | 
			
		||||
  Validator,
 | 
			
		||||
  Validators
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
 | 
			
		||||
import {
 | 
			
		||||
  DeviceTransportType,
 | 
			
		||||
  SnmpDeviceProfileTransportConfiguration
 | 
			
		||||
@ -63,16 +62,6 @@ export class SnmpDeviceProfileTransportConfigurationComponent implements OnInit,
 | 
			
		||||
  snmpDeviceProfileTransportConfigurationFormGroup: UntypedFormGroup;
 | 
			
		||||
 | 
			
		||||
  private destroy$ = new Subject<void>();
 | 
			
		||||
  private requiredValue: boolean;
 | 
			
		||||
 | 
			
		||||
  get required(): boolean {
 | 
			
		||||
    return this.requiredValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  set required(value: boolean) {
 | 
			
		||||
    this.requiredValue = coerceBooleanProperty(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  disabled: boolean;
 | 
			
		||||
 | 
			
		||||
@ -35,8 +35,7 @@
 | 
			
		||||
    <div formGroupName="profileData">
 | 
			
		||||
      <tb-device-profile-transport-configuration
 | 
			
		||||
        formControlName="transportConfiguration"
 | 
			
		||||
        [isAdd] = "isTransportTypeChanged"
 | 
			
		||||
        required>
 | 
			
		||||
        [isAdd]="isTransportTypeChanged">
 | 
			
		||||
      </tb-device-profile-transport-configuration>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
@ -65,8 +64,7 @@
 | 
			
		||||
  <div class="mat-padding" [formGroup]="detailsForm">
 | 
			
		||||
    <div formGroupName="profileData">
 | 
			
		||||
      <tb-device-profile-configuration
 | 
			
		||||
        formControlName="configuration"
 | 
			
		||||
        required>
 | 
			
		||||
        formControlName="configuration">
 | 
			
		||||
      </tb-device-profile-configuration>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user