aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreschcam <cameron.scholes@est.tech>2023-01-06 12:17:56 +0000
committerMichael Morris <michael.morris@est.tech>2023-02-28 12:24:57 +0000
commite546c7283de4abf182545cea1aa07a8de0233d3b (patch)
tree2966cf125ef7d089ca02ccb41aac3243bbf8ac7a
parent1f589435d0213865e6d82b3441e1c3d18a263aaf (diff)
Add validation for int and float constraints
Issue-ID: SDC-4316 Signed-off-by: eschcam <cameron.scholes@est.tech> Change-Id: I6d6172743779291597305583f2a7f4f2145f57fb
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.html170
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.spec.ts4
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.ts573
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.module.ts11
-rw-r--r--catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base.less1
-rw-r--r--catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts2
-rw-r--r--catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal.less1
7 files changed, 493 insertions, 269 deletions
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.html
index 46d4114250..3bbdaff2cb 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.html
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.html
@@ -20,99 +20,113 @@
-->
<div class="app-constraints">
- <form novalidate class="w-sdc-form two-columns">
- <div class="w-sdc-form-columns-wrapper" *ngFor="let constraint of constraints; let constraintIndex = index; trackBy:trackByFn">
- <div class="w-sdc-form-column-small">
- <select class="i-sdc-form-select"
- data-tests-id="constraints"
- [disabled]="isViewOnly"
- (change)="onChangeConstraintType(constraintIndex, $event.target.value)">
- <option *ngIf="constraint" [value]="constraint.type"
- hidden selected>
- {{ConstraintTypesMapping[constraint.type]}}
- </option>
- <option *ngFor="let constraintType of constraintTypes"
- [value]="constraintType"
- [disabled]="disableConstraint(constraintType, constraint.type)">
- {{ConstraintTypesMapping[constraintType]}}
- </option>
- </select>
- </div>
+ <form novalidate class="w-sdc-form two-columns" [formGroup]="constraintForm">
+ <div *ngFor="let constraint of constraintsArray.controls; let constraintIndex = index; trackBy:trackByFn">
- <div class="w-sdc-form-columns-wrapper">
+ <div formArrayName="constraint">
+ <div class="w-sdc-form-columns-wrapper" [formGroupName]="constraintIndex">
+ <div class="w-sdc-form-column-small">
+ <select class="i-sdc-form-select"
+ data-tests-id="constraints"
+ formControlName="type"
+ [value]="constraintsArray.at(constraintIndex).get('type').value"
+ (change)="onChangeConstraintType(constraintIndex, $event.target.value)">
+ <option *ngIf="constraint" [value]="constraint.value.type"
+ hidden selected>
+ {{ConstraintTypesMapping[constraint.value.type]}}
+ </option>
+ <option *ngFor="let constraintType of constraintTypes"
+ [value]="constraintType"
+ [disabled]="disableConstraint(constraintType, constraint.value.type)">
+ {{ConstraintTypesMapping[constraintType]}}
+ </option>
+ </select>
- <div class="w-sdc-form-column">
- <!-- ConstraintTypes.in_range-->
- <div class="w-sdc-form-columns-wrapper" *ngIf="constraint.type == 'inRange'">
- <div class="w-sdc-form-column">
- <input type="text" class="i-sdc-form-input myClass"
- (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, 0)"
- [disabled]="isViewOnly"
- [value]="getInRangeValue(constraintIndex, 0)"/>
- </div>
- <div class="w-sdc-form-column">
- <input type="text" class="i-sdc-form-input myClass"
- (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, 1)"
- [disabled]="isViewOnly"
- [value]="getInRangeValue(constraintIndex, 1)"/>
- </div>
+ <div class="validation-errors">
+ <ng-container *ngFor="let validation of validationMessages.type">
+ <div class="input-error" *ngIf="constraintsArray.at(constraintIndex).get('type').hasError(validation.type);">
+ {{ validation.message }}
+ </div>
+ </ng-container>
</div>
+ </div>
- <!-- ConstraintTypes.valid_values-->
- <div *ngIf="constraint.type == 'validValues'">
- <div class="w-sdc-form-columns-wrapper-block">
- <div class="add-btn add-list-item w-sdc-form-column-block"
- [ngClass]="{'disabled': isViewOnly}"
- (click)="addToList(constraintIndex)">Add to List</div>
- </div>
- <div class="w-sdc-form-columns-wrapper" *ngFor="let value of constraint.value; let valueIndex = index; trackBy:trackByFn">
+
+ <div class="w-sdc-form-columns-wrapper">
+
+ <div class="w-sdc-form-column">
+ <div class="w-sdc-form-columns-wrapper" *ngIf="constraint.value.type == 'inRange'">
<div class="w-sdc-form-column">
- <input type="text" class="i-sdc-form-input" *ngIf="propertyType !== 'boolean'"
- [disabled]="isViewOnly"
- [value]="value"
- (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, valueIndex)"/>
- <select class="i-sdc-form-select" *ngIf="propertyType == 'boolean'"
- [disabled]="isViewOnly"
- [value]="value"
- (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, valueIndex)">
- <option ngValue="true">true</option>
- <option ngValue="false">false</option>
- </select>
+ <input type="text" class="i-sdc-form-input myClass" required
+ (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, 0)"
+ [value]="getInRangeValue(constraintIndex, 0)"/>
+
+ <ng-container *ngFor="let validation of validationMessages.constraint">
+ <div class="input-error" *ngIf="constraintValuesArray(constraintIndex).controls[0].hasError(validation.type);">
+ {{ validation.message }}
+ </div>
+ </ng-container>
</div>
<div class="w-sdc-form-column">
- <span class="sprite-new delete-btn" [ngClass]="{'disabled': isViewOnly}" (click)="removeFromList(constraintIndex, valueIndex)"></span>
+ <input type="text" class="i-sdc-form-input myClass" required
+ (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, 1)"
+ [value]="getInRangeValue(constraintIndex, 1)"/>
+
+ <ng-container *ngFor="let validation of validationMessages.constraint">
+ <div class="input-error" *ngIf="constraintValuesArray(constraintIndex).controls[1].hasError(validation.type);">
+ {{ validation.message }}
+ </div>
+ </ng-container>
</div>
</div>
- </div>
- <!-- ConstraintTypes.equal-->
- <div *ngIf="constraint.type == 'equal'">
- <input type="text" class="i-sdc-form-input" *ngIf="propertyType !== 'boolean'"
- [disabled]="isViewOnly"
- (input)="onChangeConstraintValue(constraintIndex, $event.target.value)"
- [value]="constraint.value"/>
- <select class="i-sdc-form-select" *ngIf="propertyType == 'boolean'"
- [disabled]="isViewOnly"
- [value]="constraint.value"
- (input)="onChangeConstraintValue(constraintIndex, $event.target.value)">
- <option ngValue="true">true</option>
- <option ngValue="false">false</option>
- </select>
- </div>
+ <div *ngIf="constraint.value.type == 'validValues'">
+ <div class="w-sdc-form-columns-wrapper-block">
+ <div class="add-btn add-list-item w-sdc-form-column-block"
+ [ngClass]="{'disabled': isViewOnly}"
+ (click)="addToList(constraintIndex)">Add to List</div>
+ </div>
+ <div class="w-sdc-form-columns-wrapper" *ngFor="let value of constraintValuesArray(constraintIndex).controls; let valueIndex = index; trackBy:trackByFn">
+ <div class="w-sdc-form-column">
+ <input type="text" class="i-sdc-form-input" required
+ [value]="value.value"
+ (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, valueIndex)"/>
+ </div>
+
+ <ng-container *ngFor="let validation of validationMessages.constraint">
+ <div class="input-error" *ngIf="constraintValuesArray(constraintIndex).controls[valueIndex].hasError(validation.type);">
+ {{ validation.message }}
+ </div>
+ </ng-container>
+
+ <div class="w-sdc-form-column">
+ <span class="sprite-new delete-btn" [ngClass]="{'disabled': isViewOnly}" (click)="removeFromList(constraintIndex, valueIndex)"></span>
+ </div>
+ </div>
+ </div>
+
+ <div *ngIf="constraint.get('type').value != 'inRange' && constraint.get('type').value != 'validValues'">
+ <input type="text" class="i-sdc-form-input myClass required" required
+ formControlName="value"
+ [value]="constraintsArray.at(constraintIndex).get('value').value"
+ (input)="onChangeConstraintValue(constraintIndex, $event.target.value)"/>
- <!-- all other ConstraintTypes-->
- <div *ngIf="constraint.type != 'inRange' && constraint.type != 'validValues' && constraint.type != 'equal'">
- <input type="text" class="i-sdc-form-input myClass"
- [disabled]="isViewOnly"
- (input)="onChangeConstraintValue(constraintIndex, $event.target.value)"
- [value]="constraint.value"/>
+ <div class="validation-errors">
+ <ng-container *ngFor="let validation of validationMessages.constraint">
+ <div class="input-error" *ngIf="constraintsArray.at(constraintIndex).get('value').hasError(validation.type);">
+ {{ validation.message }}
+ </div>
+ </ng-container>
+ </div>
+ </div>
</div>
- </div>
- <div class="w-sdc-form-column-vsmall">
- <span class="sprite-new delete-btn" [ngClass]="{'disabled': isViewOnly}" (click)="removeConstraint(constraintIndex)"></span>
+ <div class="w-sdc-form-column-vsmall" *ngIf="!isViewOnly">
+ <span class="sprite-new delete-btn" [ngClass]="{'disabled': isViewOnly}" (click)="removeConstraint(constraintIndex)"></span>
+ </div>
</div>
</div>
+ </div>
</div>
<div class="w-sdc-form-columns-wrapper-small" *ngIf="!isViewOnly">
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.spec.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.spec.ts
index bfee76910e..06112e5830 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.spec.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.spec.ts
@@ -19,6 +19,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ConstraintsComponent } from './constraints.component';
describe('ConstraintsComponent', () => {
@@ -27,7 +28,8 @@ describe('ConstraintsComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
- declarations: [ ConstraintsComponent ]
+ declarations: [ ConstraintsComponent ],
+ imports: [FormsModule, ReactiveFormsModule]
})
.compileComponents();
}));
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.ts
index 2fb8b64e54..31dbeadd4e 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.component.ts
@@ -18,7 +18,15 @@
*/
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { PROPERTY_DATA, PROPERTY_TYPES } from "app/utils/constants"
+import {
+ AbstractControl, FormArray,
+ FormBuilder,
+ FormControl,
+ FormGroup, ValidationErrors,
+ ValidatorFn,
+ Validators
+} from '@angular/forms';
+import { PROPERTY_DATA, PROPERTY_TYPES } from 'app/utils/constants';
@Component({
selector: 'app-constraints',
@@ -32,88 +40,358 @@ export class ConstraintsComponent implements OnInit {
@Input() isViewOnly: boolean = false;
@Output() onConstraintChange: EventEmitter<any> = new EventEmitter<any>();
- constraints: Constraint[] = new Array();
constraintTypes: string[];
ConstraintTypesMapping = ConstraintTypesMapping;
- valid: boolean = true;
+ valid: boolean = false;
+ constraintForm: FormGroup;
+ validationMessages;
+ init: boolean = true;
+
+ constructor(private formBuilder: FormBuilder) {}
+
+ get constraintsArray() {
+ return this.constraintForm.get('constraint') as FormArray;
+ }
+
+ get constraintValidators(): ValidatorFn {
+ switch (this.propertyType) {
+ case PROPERTY_TYPES.INTEGER:
+ console.warn('Add int validator');
+ return Validators.compose([
+ Validators.required,
+ intValidator()
+ ]);
+ case PROPERTY_TYPES.FLOAT:
+ console.warn('Add float validator');
+ return Validators.compose([
+ Validators.required,
+ floatValidator()
+ ]);
+ default:
+ console.warn('Only required validator');
+ return Validators.compose([
+ Validators.required
+ ]);
+ }
+}
+
+ public constraintValuesArray(index: number): FormArray {
+ return this.constraintsArray.at(index).get('value') as FormArray;
+ }
ngOnInit() {
- this.constraintTypes = Object.keys(ConstraintTypes).map(key => ConstraintTypes[key]);
+ console.groupEnd();
+ this.constraintTypes = Object.keys(ConstraintTypes).map((key) => ConstraintTypes[key]);
+
+ // This is only used by the spec test
+ if (!this.constraintForm) {
+ this.constraintForm = this.formBuilder.group({
+ constraint: this.formBuilder.array([])
+ });
+ }
+
+ this.validationMessages = {
+ constraint: [
+ { type: 'required', message: 'Constraint value is required'},
+ { type: 'invalidInt', message: 'Constraint value is not a valid integer'},
+ { type: 'invalidFloat', message: 'Constraint value is not a valid floating point value'}
+ ],
+ type : [
+ { type: 'required', message: 'Constraint type is required'}
+ ]
+ };
+
+ this.init = false;
}
ngOnChanges(changes): void {
+ console.groupEnd();
+
+ // Changes fires before init so form has to be initialised here
+ if (this.init) {
+ this.constraintForm = this.formBuilder.group({
+ constraint: this.formBuilder.array([])
+ });
+
+ if (changes.propertyConstraints && changes.propertyConstraints.currentValue) {
+ changes.propertyConstraints.currentValue.forEach((constraint: any) => {
+ const prop = this.getConstraintFromPropertyBEModel(constraint);
+ console.log('constraint from BE model', prop);
+ this.constraintsArray.push(prop);
+ });
+ }
+ }
+
if (changes.propertyType) {
+ if (!this.init) {
+ // Reset constraints on property type change
+ console.warn('Property type changed. Resetting constraints');
+ this.constraintForm = this.formBuilder.group({
+ constraint: this.formBuilder.array([])
+ });
+ }
+
if (!this.propertyType || changes.propertyType.currentValue == this.propertyType) {
this.propertyType = changes.propertyType.currentValue;
} else {
- this.constraints = new Array();
this.propertyType = changes.propertyType;
this.emitOnConstraintChange();
}
+
+ this.constraintsArray.controls.forEach((control: AbstractControl) => {
+ control.get('value').setValidators(this.constraintValidators);
+ });
}
- this.constraints = new Array();
- if(changes.propertyConstraints) {
- if (changes.propertyConstraints.currentValue) {
- changes.propertyConstraints.currentValue.forEach((constraint: any) => {
- this.constraints.push(this.getConstraintFromPropertyBEModel(constraint));
- });
- }
+
+ console.log('constraints', this.constraintsArray);
+ }
+
+ removeFromList(constraintIndex: number, valueIndex: number) {
+ this.constraintsArray.at(constraintIndex).get('value').value.splice(valueIndex, 1);
+ this.emitOnConstraintChange();
+ }
+
+ addToList(constraintIndex: number) {
+ const newConstraint = new FormControl('', this.constraintValidators);
+
+ this.constraintValuesArray(constraintIndex).push(newConstraint);
+ console.log('constraintsArray', this.constraintsArray);
+ console.log('constraintValuesArray', this.constraintValuesArray(constraintIndex));
+ this.emitOnConstraintChange();
+ }
+
+ onChangeConstraintType(constraintIndex: number, newType: ConstraintTypes) {
+ if ((newType == ConstraintTypes.valid_values)) {
+ const newConstraint = this.formBuilder.group({
+ type: new FormControl({
+ value: newType,
+ disabled: this.isViewOnly
+ }, Validators.required),
+ value: this.formBuilder.array([])});
+
+ this.constraintsArray.removeAt(constraintIndex);
+ this.constraintsArray.push(newConstraint);
+ } else if (newType == ConstraintTypes.in_range) {
+ const newConstraint = this.formBuilder.group({
+ type: new FormControl({
+ value: newType,
+ disabled: this.isViewOnly
+ }, Validators.required),
+ value: this.formBuilder.array([])});
+
+ const valRef = newConstraint.get('value') as FormArray;
+ valRef.push(new FormControl('', this.constraintValidators));
+ valRef.push(new FormControl('', this.constraintValidators));
+
+ this.constraintsArray.removeAt(constraintIndex);
+ this.constraintsArray.push(newConstraint);
+ } else {
+ this.constraintsArray.at(constraintIndex).value.type = newType;
}
+ this.emitOnConstraintChange();
+ }
+
+ onChangeConstraintValue(constraintIndex: number, newValue: any) {
+ this.constraintsArray.at(constraintIndex).get('value').setValue(newValue);
+ this.emitOnConstraintChange();
+ }
+
+ onChangeConstrainValueIndex(constraintIndex: number, newValue: any, valueIndex: number) {
+ this.constraintValuesArray(constraintIndex).controls[valueIndex].setValue(newValue);
+ this.emitOnConstraintChange();
}
- private getConstraintFromPropertyBEModel(constraint: any):Constraint {
+ removeConstraint(constraintIndex: number) {
+ this.constraintsArray.removeAt(constraintIndex);
+ this.emitOnConstraintChange();
+}
+
+ addConstraint() {
+ const newConstraint = this.formBuilder.group({
+ type: new FormControl({
+ value: ConstraintTypes.null,
+ disabled: this.isViewOnly
+ }, Validators.required),
+ value: new FormControl({
+ value: '',
+ disabled: this.isViewOnly
+ }, this.constraintValidators)
+ });
+ this.constraintsArray.push(newConstraint);
+ this.valid = false;
+ this.emitOnConstraintChange();
+ }
+
+ getInRangeValue(constraintIndex: number, valueIndex: number): string {
+ const value = this.constraintsArray.at(constraintIndex).get('value').value;
+
+ if (!value || !value[valueIndex]) {
+ return '';
+ }
+
+ return value[valueIndex];
+ }
+
+ disableConstraint(optionConstraintType: ConstraintTypes): boolean {
+ const invalid = this.notAllowedConstraint(optionConstraintType);
+ return invalid ? invalid : this.getConstraintTypeIfPresent(optionConstraintType) ? true : false;
+ }
+
+ notAllowedConstraint(optionConstraintType: ConstraintTypes): boolean {
+ switch (optionConstraintType) {
+ case ConstraintTypes.less_or_equal:
+ case ConstraintTypes.less_than:
+ case ConstraintTypes.greater_or_equal:
+ case ConstraintTypes.greater_than:
+ case ConstraintTypes.in_range:
+ if (this.isComparable(this.propertyType)) {
+ return false;
+ }
+ break;
+ case ConstraintTypes.length:
+ case ConstraintTypes.max_length:
+ case ConstraintTypes.min_length:
+ if (this.propertyType == PROPERTY_TYPES.STRING || this.propertyType == PROPERTY_TYPES.MAP || this.propertyType == PROPERTY_TYPES.LIST) {
+ return false;
+ }
+ break;
+ case ConstraintTypes.pattern:
+ if (this.propertyType == PROPERTY_TYPES.STRING) {
+ return false;
+ }
+ break;
+ case ConstraintTypes.valid_values:
+ case ConstraintTypes.equal:
+ return false;
+ }
+ return true;
+ }
+
+ getConstraintTypeIfPresent(constraintType: ConstraintTypes): AbstractControl {
+ return this.constraintsArray.controls.find((control: AbstractControl) => {
+ const type = control.get('type').value;
+ return type == constraintType;
+ });
+ }
+
+ trackByFn(index) {
+ return index;
+ }
+
+ isComparable(propType: string): boolean {
+ if (PROPERTY_DATA.COMPARABLE_TYPES.indexOf(propType) >= 0) {
+ return true;
+ }
+ return false;
+ }
+
+ private getConstraintFromPropertyBEModel(constraint: any): AbstractControl {
+ console.log('be model constraints', constraint);
let constraintType: ConstraintTypes;
let constraintValue: any;
if (!constraint) {
constraintType = ConstraintTypes.null;
- constraintValue = "";
- } else if(constraint.hasOwnProperty(ConstraintTypes.valid_values)){
+ constraintValue = '';
+ } else if (constraint.hasOwnProperty(ConstraintTypes.valid_values)) {
constraintType = ConstraintTypes.valid_values;
- constraintValue = constraint.validValues;
- } else if(constraint.hasOwnProperty(ConstraintTypes.equal)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.equal)) {
constraintType = ConstraintTypes.equal;
constraintValue = constraint.equal;
- } else if(constraint.hasOwnProperty(ConstraintTypes.greater_than)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.greater_than)) {
constraintType = ConstraintTypes.greater_than;
constraintValue = constraint.greaterThan;
- } else if(constraint.hasOwnProperty(ConstraintTypes.greater_or_equal)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.greater_or_equal)) {
constraintType = ConstraintTypes.greater_or_equal;
constraintValue = constraint.greaterOrEqual;
- } else if(constraint.hasOwnProperty(ConstraintTypes.less_than)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.less_than)) {
constraintType = ConstraintTypes.less_than;
constraintValue = constraint.lessThan;
- } else if(constraint.hasOwnProperty(ConstraintTypes.less_or_equal)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.less_or_equal)) {
constraintType = ConstraintTypes.less_or_equal;
constraintValue = constraint.lessOrEqual;
- } else if(constraint.hasOwnProperty(ConstraintTypes.in_range)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.in_range)) {
constraintType = ConstraintTypes.in_range;
constraintValue = new Array(constraint.inRange[0], constraint.inRange[1]);
- } else if(constraint.rangeMaxValue || constraint.rangeMinValue) {
+ } else if (constraint.rangeMaxValue || constraint.rangeMinValue) {
constraintType = ConstraintTypes.in_range;
constraintValue = new Array(constraint.rangeMinValue, constraint.rangeMaxValue);
- } else if(constraint.hasOwnProperty(ConstraintTypes.length)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.length)) {
constraintType = ConstraintTypes.length;
constraintValue = constraint.length;
- } else if(constraint.hasOwnProperty(ConstraintTypes.min_length)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.min_length)) {
constraintType = ConstraintTypes.min_length;
constraintValue = constraint.minLength;
- } else if(constraint.hasOwnProperty(ConstraintTypes.max_length)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.max_length)) {
constraintType = ConstraintTypes.max_length;
constraintValue = constraint.maxLength;
- } else if(constraint.hasOwnProperty(ConstraintTypes.pattern)) {
+ } else if (constraint.hasOwnProperty(ConstraintTypes.pattern)) {
constraintType = ConstraintTypes.pattern;
constraintValue = constraint.pattern;
}
- return {
- type:constraintType,
- value:constraintValue
+
+ if (!constraint.hasOwnProperty(ConstraintTypes.valid_values) && !constraint.hasOwnProperty(ConstraintTypes.in_range)) {
+ return this.formBuilder.group({
+ type: new FormControl({
+ value: constraintType,
+ disabled: this.isViewOnly
+ }, Validators.required),
+ value: new FormControl({
+ value: constraintValue,
+ disabled: this.isViewOnly
+ }, this.constraintValidators)
+ });
+ } else {
+ const newForm = this.formBuilder.group({
+ type: new FormControl({
+ value: constraintType,
+ disabled: this.isViewOnly
+ }, Validators.required),
+ value: this.formBuilder.array([])
+ });
+
+ const valRef = newForm.get('value') as FormArray;
+
+ if (constraint.hasOwnProperty(ConstraintTypes.valid_values)) {
+ constraint.validValues.forEach((val) => {
+ valRef.push(new FormControl(val, this.constraintValidators));
+ });
+ } else {
+ constraint.inRange.forEach((val) => {
+ valRef.push(new FormControl(val, this.constraintValidators));
+ });
+ }
+
+ console.log('new form', newForm);
+ return newForm;
}
}
private getConstraintsFormat(): any[] {
- let constraintArray = new Array();
- this.constraints.forEach((constraint: Constraint) => {
- constraintArray.push(this.getConstraintFormat(constraint))
+ const constraintArray = new Array();
+ this.constraintsArray.controls.forEach((control: AbstractControl) => {
+ const type = control.get('type').value;
+ let constraint: Constraint;
+
+ if (type != ConstraintTypes.valid_values && type != ConstraintTypes.in_range) {
+ constraint = {
+ type,
+ value: control.get('value').value
+ };
+ } else {
+ const valArray = [];
+
+ control.get('value').value.forEach((val) => {
+ valArray.push(val);
+ });
+
+ constraint = {
+ type,
+ value: valArray
+ };
+ }
+
+ console.log('New constraint object', constraint);
+ constraintArray.push(this.getConstraintFormat(constraint));
});
return constraintArray;
}
@@ -123,224 +401,153 @@ export class ConstraintsComponent implements OnInit {
case ConstraintTypes.equal:
return {
[ConstraintTypes.equal]: constraint.value
- }
+ };
case ConstraintTypes.less_or_equal:
return {
[ConstraintTypes.less_or_equal]: constraint.value
- }
+ };
case ConstraintTypes.less_than:
return {
[ConstraintTypes.less_than]: constraint.value
- }
+ };
case ConstraintTypes.greater_or_equal:
return {
[ConstraintTypes.greater_or_equal]: constraint.value
- }
+ };
case ConstraintTypes.greater_than:
return {
[ConstraintTypes.greater_than]: constraint.value
- }
+ };
case ConstraintTypes.in_range:
return {
[ConstraintTypes.in_range]: constraint.value
- }
+ };
case ConstraintTypes.length:
return {
[ConstraintTypes.length]: constraint.value
- }
+ };
case ConstraintTypes.max_length:
return {
[ConstraintTypes.max_length]: constraint.value
- }
+ };
case ConstraintTypes.min_length:
return {
[ConstraintTypes.min_length]: constraint.value
- }
+ };
case ConstraintTypes.pattern:
return {
[ConstraintTypes.pattern]: constraint.value
- }
+ };
case ConstraintTypes.valid_values:
return {
[ConstraintTypes.valid_values]: constraint.value
- }
+ };
default:
return;
}
}
private validateConstraints(): void {
- this.valid = this.constraints.every((constraint: Constraint) => {
- if (Array.isArray(constraint.value)) {
- return !(constraint.value.length == 0 || this.doesArrayContaintEmptyValues(constraint.value));
+ this.valid = this.constraintsArray.controls.every((control: AbstractControl) => {
+ const value = control.get('value').value;
+ const type = control.get('type').value;
+ control.updateValueAndValidity();
+
+ if (Array.isArray(value)) {
+ return !(value.length == 0 || this.doesArrayContaintEmptyValues(value));
}
- if (constraint.type == ConstraintTypes.pattern) {
+ if (type == ConstraintTypes.pattern) {
try {
- new RegExp(constraint.value);
+ new RegExp(value);
this.valid = true;
- } catch(e) {
+ } catch (e) {
this.valid = false;
}
+ } else {
+ this.valid = this.constraintForm.valid;
}
- return constraint.value && constraint.type != ConstraintTypes.null
+
+ return value && type != ConstraintTypes.null;
});
}
private doesArrayContaintEmptyValues(arr) {
- for(const element of arr) {
- if(element === "") return true;
+ for (const element of arr) {
+ if (element === '') { return true; }
}
return false;
}
private emitOnConstraintChange(): void {
+ console.log('constraints', this.constraintsArray);
+
this.validateConstraints();
const newConstraints = this.getConstraintsFormat();
+
+ this.valid = this.constraintForm.valid;
+ console.log('emitOnConstraintChange.valid', this.valid);
+
this.onConstraintChange.emit({
constraints: newConstraints,
valid: this.valid
});
}
- removeFromList(constraintIndex: number, valueIndex: number){
- this.constraints[constraintIndex].value.splice(valueIndex, 1);
- this.emitOnConstraintChange()
- }
-
- addToList(constraintIndex: number){
- if (!this.constraints[constraintIndex].value) {
- this.constraints[constraintIndex].value = new Array();
- }
- this.constraints[constraintIndex].value.push("");
- this.emitOnConstraintChange()
- }
-
- onChangeConstraintType(constraintIndex: number, newType: ConstraintTypes) {
- this.constraints[constraintIndex].type = newType;
- if ((newType == ConstraintTypes.in_range || newType == ConstraintTypes.valid_values) && !Array.isArray(this.constraints[constraintIndex].value)) {
- this.constraints[constraintIndex].value = new Array()
- }
- this.emitOnConstraintChange();
- }
-
- onChangeConstraintValue(constraintIndex: number, newValue: any) {
- this.constraints[constraintIndex].value = newValue;
- this.emitOnConstraintChange();
- }
-
- onChangeConstrainValueIndex(constraintIndex: number, newValue: any, valueIndex: number) {
- if(!this.constraints[constraintIndex].value) {
- this.constraints[constraintIndex].value = new Array();
- }
- this.constraints[constraintIndex].value[valueIndex] = newValue;
- this.emitOnConstraintChange();
- }
-
- removeConstraint(constraintIndex: number) {
- this.constraints.splice(constraintIndex, 1);
- this.emitOnConstraintChange();
}
- addConstraint() {
- let newConstraint: Constraint = {
- type: ConstraintTypes.null,
- value: ""
- }
- this.constraints.push(newConstraint);
- this.emitOnConstraintChange();
- }
-
- getInRangeValue(constraintIndex: number, valueIndex: number): string {
- if(!this.constraints[constraintIndex].value || !this.constraints[constraintIndex].value[valueIndex]) {
- return "";
- }
- return this.constraints[constraintIndex].value[valueIndex];
- }
-
- disableConstraint(optionConstraintType: ConstraintTypes): boolean {
- const invalid = this.notAllowedConstraint(optionConstraintType);
- return invalid ? invalid : this.getConstraintTypeIfPresent(optionConstraintType) ? true : false;
- }
-
- notAllowedConstraint(optionConstraintType: ConstraintTypes): boolean {
- switch (optionConstraintType) {
- case ConstraintTypes.less_or_equal:
- case ConstraintTypes.less_than:
- case ConstraintTypes.greater_or_equal:
- case ConstraintTypes.greater_than:
- case ConstraintTypes.in_range:
- if (this.isComparable(this.propertyType)){
- return false;
- }
- break;
- case ConstraintTypes.length:
- case ConstraintTypes.max_length:
- case ConstraintTypes.min_length:
- if (this.propertyType == PROPERTY_TYPES.STRING || this.propertyType == PROPERTY_TYPES.MAP || this.propertyType == PROPERTY_TYPES.LIST){
- return false;
- }
- break;
- case ConstraintTypes.pattern:
- if (this.propertyType == PROPERTY_TYPES.STRING){
- return false;
- }
- break;
- case ConstraintTypes.valid_values:
- case ConstraintTypes.equal:
- return false;
- }
- return true;
- }
+export enum ConstraintTypes {
+ null = '',
+ equal= 'equal',
+ greater_than = 'greaterThan',
+ greater_or_equal = 'greaterOrEqual',
+ less_than = 'lessThan',
+ less_or_equal = 'lessOrEqual',
+ in_range = 'inRange',
+ valid_values = 'validValues',
+ length = 'length',
+ min_length = 'minLength',
+ max_length = 'maxLength',
+ pattern = 'pattern'
+}
- getConstraintTypeIfPresent(constraintType: ConstraintTypes): Constraint {
- return this.constraints.find((constraint) => {
- return constraint.type == constraintType ? true : false;
- })
- }
+export const ConstraintTypesMapping = {
+ [ConstraintTypes.equal]: 'equal',
+ [ConstraintTypes.greater_than]: 'greater_than',
+ [ConstraintTypes.greater_or_equal]: 'greater_or_equal',
+ [ConstraintTypes.less_than]: 'less_than',
+ [ConstraintTypes.less_or_equal]: 'less_or_equal',
+ [ConstraintTypes.in_range]: 'in_range',
+ [ConstraintTypes.valid_values]: 'valid_values',
+ [ConstraintTypes.length]: 'length',
+ [ConstraintTypes.min_length]: 'min_length',
+ [ConstraintTypes.max_length]: 'max_length',
+ [ConstraintTypes.pattern]: 'pattern'
+};
- trackByFn(index) {
- return index;
- }
+export interface Constraint {
+ type: ConstraintTypes;
+ value: any;
+}
- isComparable(propType: string): boolean {
- if (PROPERTY_DATA.COMPARABLE_TYPES.indexOf(propType) >= 0) {
- return true;
+export function intValidator(): ValidatorFn {
+ const intRegex = /^[-+]?\d+$/;
+ return (control: AbstractControl): ValidationErrors | null => {
+ if (control.value && !intRegex.test(control.value)) {
+ return {invalidInt: true};
}
- return false;
- }
+ return null;
+ };
}
-export enum ConstraintTypes {
- null = "",
- equal= "equal",
- greater_than = "greaterThan",
- greater_or_equal = "greaterOrEqual",
- less_than = "lessThan",
- less_or_equal = "lessOrEqual",
- in_range = "inRange",
- valid_values = "validValues",
- length = "length",
- min_length = "minLength",
- max_length = "maxLength",
- pattern = "pattern"
-}
+export function floatValidator(): ValidatorFn {
+ const floatRegex = /^[-+]?\d+(\.\d+)?$/;
-export const ConstraintTypesMapping = {
- [ConstraintTypes.equal]: "equal",
- [ConstraintTypes.greater_than]: "greater_than",
- [ConstraintTypes.greater_or_equal]: "greater_or_equal",
- [ConstraintTypes.less_than]: "less_than",
- [ConstraintTypes.less_or_equal]: "less_or_equal",
- [ConstraintTypes.in_range]: "in_range",
- [ConstraintTypes.valid_values]: "valid_values",
- [ConstraintTypes.length]: "length",
- [ConstraintTypes.min_length]: "min_length",
- [ConstraintTypes.max_length]: "max_length",
- [ConstraintTypes.pattern]: "pattern"
-};
+ return (control: AbstractControl): ValidationErrors | null => {
+ if (control.value && !floatRegex.test(control.value)) {
+ return {invalidFloat: true};
+ }
-export interface Constraint {
- type:ConstraintTypes,
- value:any
+ return null;
+ };
}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.module.ts
index 4f14e1f855..48ad24e112 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.module.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/constraints/constraints.module.ts
@@ -19,13 +19,14 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ConstraintsComponent } from './constraints.component';
-import { FormsModule } from '@angular/forms';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
@NgModule({
- imports: [
- CommonModule,
- FormsModule
- ],
+ imports: [
+ CommonModule,
+ FormsModule,
+ ReactiveFormsModule
+ ],
declarations: [ConstraintsComponent],
exports: [ConstraintsComponent],
entryComponents: [
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base.less b/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base.less
index 1c1c0c9c52..fabf883151 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base.less
+++ b/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base.less
@@ -6,7 +6,6 @@
}
form{
- width: 813px;
[name="description"]{
min-height:50px;
}
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts
index 05045c1529..52e8c0018a 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts
+++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts
@@ -507,6 +507,8 @@ export class PropertyFormViewModel {
}
this.$scope.onConstraintChange = (constraints: any): void => {
+ console.log('$scope.onConstraintChange', constraints);
+
if (!this.$scope.invalidMandatoryFields) {
this.$scope.footerButtons[0].disabled = !constraints.valid;
} else {
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal.less b/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal.less
index 02b7612671..1eb7a4649f 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal.less
+++ b/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal.less
@@ -6,7 +6,6 @@
}
form{
- width: 813px;
[name="description"]{
min-height:50px;
}