diff options
author | JvD_Ericsson <jeff.van.dam@est.tech> | 2022-10-27 12:47:28 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-11-30 13:26:41 +0000 |
commit | 0d708e3bb2502abe50e1ed4069b43536b538ceef (patch) | |
tree | a36c57ddeb12207af60c6c5cfc5311246ca4c126 /catalog-ui | |
parent | 15f3f0bb8e0cec965a9714e3681fbdee4b19b3c4 (diff) |
Support addition of scalar type constraints
this also supports the addition of
the in_range and the valid_values constraints,
and supports delete and editing of current and
added constraints
Issue-ID: SDC-4223
Change-Id: I5ffb4d17d9f8c2730f650153fb4ff89eccfdd474
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
Diffstat (limited to 'catalog-ui')
9 files changed, 179 insertions, 47 deletions
diff --git a/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.html b/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.html index 139f1f4220..d84ec821de 100644 --- a/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.html +++ b/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.html @@ -15,7 +15,7 @@ --> -<div> +<div class="type-map"> <div data-ng-repeat="i in getNumber(mapKeys.length) track by $index" class="map-item" data-ng-class="{'primitive-value-map':!isSchemaTypeDataType}"> <div class="i-sdc-form-item map-item-field" data-ng-class="{error:(parentFormObj['mapKey'+fieldsPrefixName+$index].$dirty && parentFormObj['mapKey'+fieldsPrefixName+$index].$invalid)}"> <label class="i-sdc-form-label required">Key</label> diff --git a/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.less b/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.less index 6dc481dd26..9c2984e3ce 100644 --- a/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.less +++ b/catalog-ui/src/app/directives/property-types/type-map/type-map-directive.less @@ -86,3 +86,7 @@ } } } + +.type-map { + display: inline-block; +} diff --git a/catalog-ui/src/app/models/properties.ts b/catalog-ui/src/app/models/properties.ts index e292a6ceef..91245967b0 100644 --- a/catalog-ui/src/app/models/properties.ts +++ b/catalog-ui/src/app/models/properties.ts @@ -61,6 +61,7 @@ export class PropertyModel extends PropertyBEModel implements IPropertyModel { uniqueId:string; name:string; constraints:Array<Object>; + propertyConstraints:Array<string>; defaultValue:string; description:string; password:boolean; diff --git a/catalog-ui/src/app/modules/directive-module.ts b/catalog-ui/src/app/modules/directive-module.ts index e339b5d471..adc88cbc6d 100644 --- a/catalog-ui/src/app/modules/directive-module.ts +++ b/catalog-ui/src/app/modules/directive-module.ts @@ -327,7 +327,7 @@ directiveModule.directive('toscaFunction', downgradeComponent({ directiveModule.directive('appConstraints', downgradeComponent({ component: ConstraintsComponent, - inputs: ['property', 'isViewOnly'], + inputs: ['propertyConstraints', 'isViewOnly', 'propertyType'], outputs: ['onConstraintChange'] }) as angular.IDirectiveFactory); 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 301d196d41..6272a4529f 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 @@ -21,7 +21,7 @@ <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"> + <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" @@ -31,7 +31,9 @@ hidden selected> {{ConstraintTypesMapping[constraint.type]}} </option> - <option *ngFor="let constraintType of constraintTypes" [value]="constraintType"> + <option *ngFor="let constraintType of constraintTypes" + [value]="constraintType" + [disabled]="disableConstraint(constraintType, constraint.type)"> {{ConstraintTypesMapping[constraintType]}} </option> </select> @@ -44,13 +46,13 @@ <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" - (change)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, 0)" + (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" - (change)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, 1)" + (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, 1)" [disabled]="isViewOnly" [value]="getInRangeValue(constraintIndex, 1)"/> </div> @@ -62,11 +64,11 @@ [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"> + <div class="w-sdc-form-columns-wrapper" *ngFor="let value of constraint.value; let valueIndex = index; trackBy:trackByFn"> <div class="w-sdc-form-column"> <input type="text" class="i-sdc-form-input" [value]="value" [disabled]="isViewOnly" - (change)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, valueIndex)"/> + (input)="onChangeConstrainValueIndex(constraintIndex, $event.target.value, valueIndex)"/> </div> <div class="w-sdc-form-column"> <span class="sprite-new delete-btn" [ngClass]="{'disabled': isViewOnly}" (click)="removeFromList(constraintIndex, valueIndex)"></span> @@ -76,7 +78,7 @@ <div *ngIf="constraint.type != 'inRange' && constraint.type != 'validValues'"> <input type="text" class="i-sdc-form-input myClass" - (change)="onChangeConstraintValue(constraintIndex, $event.target.value)" + (input)="onChangeConstraintValue(constraintIndex, $event.target.value)" [value]="constraint.value"/> </div> </div> @@ -89,9 +91,8 @@ </div> <div class="w-sdc-form-columns-wrapper-small" *ngIf="!isViewOnly"> - <div class="add-btn add-list-item w-sdc-form-column-small" *ngIf="!isViewOnly" [ngClass]="{'disabled': isViewOnly}" - (click)="addConstraint()"> Add Constraint </div> - </div> - + <div class="add-btn add-list-item w-sdc-form-column-small" *ngIf="!isViewOnly" [ngClass]="{'disabled': isViewOnly}" + (click)="addConstraint()"> Add Constraint </div> + </div> </form> </div> 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 ef4d6fd954..2e56ce1580 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,7 @@ */ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { PropertyBEModel } from "app/models"; +import { PROPERTY_DATA, PROPERTY_TYPES } from "app/utils/constants" @Component({ selector: 'app-constraints', @@ -27,24 +27,31 @@ import { PropertyBEModel } from "app/models"; }) export class ConstraintsComponent implements OnInit { - @Input() set property(property: PropertyBEModel) { + @Input() set propertyConstraints(propertyConstraints: any[]) { this.constraints = new Array(); - if(property.constraints) { - this._property = property; - property.constraints.forEach((constraint: any) => { + if(propertyConstraints) { + propertyConstraints.forEach((constraint: any) => { this.constraints.push(this.getConstraintFromPropertyBEModel(constraint)); }); } } + @Input() set propertyType(propertyType: string) { + if (!this._propertyType || propertyType == this._propertyType) { + this._propertyType = propertyType; + return; + } + this.constraints = new Array(); + this._propertyType = propertyType; + this.emitOnConstraintChange(); + } @Input() isViewOnly: boolean = false; - @Output() onConstraintChange: EventEmitter<any[]> = new EventEmitter<any[]>(); + @Output() onConstraintChange: EventEmitter<any> = new EventEmitter<any>(); - constraints: Constraint[]; + constraints: Constraint[] = new Array(); constraintTypes: string[]; ConstraintTypesMapping = ConstraintTypesMapping; - newConstraintType: any = ConstraintTypes.equal; - newConstraintValue: any = null; - _property: PropertyBEModel; + valid: boolean = true; + _propertyType: string; ngOnInit() { this.constraintTypes = Object.keys(ConstraintTypes).map(key => ConstraintTypes[key]); @@ -53,37 +60,43 @@ export class ConstraintsComponent implements OnInit { private getConstraintFromPropertyBEModel(constraint: any):Constraint { let constraintType: ConstraintTypes; let constraintValue: any; - if(constraint.validValues){ + if (!constraint) { + constraintType = ConstraintTypes.null; + constraintValue = ""; + } else if(constraint.hasOwnProperty(ConstraintTypes.valid_values)){ constraintType = ConstraintTypes.valid_values; constraintValue = constraint.validValues; - } else if(constraint.equal) { + } else if(constraint.hasOwnProperty(ConstraintTypes.equal)) { constraintType = ConstraintTypes.equal; constraintValue = constraint.equal; - } else if(constraint.greaterThan) { + } else if(constraint.hasOwnProperty(ConstraintTypes.greater_than)) { constraintType = ConstraintTypes.greater_than; constraintValue = constraint.greaterThan; - } else if(constraint.greaterOrEqual) { + } else if(constraint.hasOwnProperty(ConstraintTypes.greater_or_equal)) { constraintType = ConstraintTypes.greater_or_equal; constraintValue = constraint.greaterOrEqual; - } else if(constraint.lessThan) { + } else if(constraint.hasOwnProperty(ConstraintTypes.less_than)) { constraintType = ConstraintTypes.less_than; constraintValue = constraint.lessThan; - } else if(constraint.lessOrEqual) { + } else if(constraint.hasOwnProperty(ConstraintTypes.less_or_equal)) { constraintType = ConstraintTypes.less_or_equal; constraintValue = constraint.lessOrEqual; - } else if(constraint.rangeMinValue && constraint.rangeMaxValue) { + } 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) { constraintType = ConstraintTypes.in_range; constraintValue = new Array(constraint.rangeMinValue, constraint.rangeMaxValue); - } else if(constraint.length) { + } else if(constraint.hasOwnProperty(ConstraintTypes.length)) { constraintType = ConstraintTypes.length; constraintValue = constraint.length; - } else if(constraint.minLength) { + } else if(constraint.hasOwnProperty(ConstraintTypes.min_length)) { constraintType = ConstraintTypes.min_length; constraintValue = constraint.minLength; - } else if(constraint.maxLength) { + } else if(constraint.hasOwnProperty(ConstraintTypes.max_length)) { constraintType = ConstraintTypes.max_length; constraintValue = constraint.maxLength; - } else if(constraint.pattern) { + } else if(constraint.hasOwnProperty(ConstraintTypes.pattern)) { constraintType = ConstraintTypes.pattern; constraintValue = constraint.pattern; } @@ -101,7 +114,7 @@ export class ConstraintsComponent implements OnInit { return constraintArray; } - private getConstraintFormat(constraint: Constraint) { + private getConstraintFormat(constraint: Constraint): any { switch (constraint.type) { case ConstraintTypes.equal: return { @@ -152,8 +165,34 @@ export class ConstraintsComponent implements OnInit { } } + private validateConstraints(): void { + this.valid = this.constraints.every((constraint: Constraint) => { + if (Array.isArray(constraint.value)) { + return !(constraint.value.length == 0 || this.doesArrayContaintEmptyValues(constraint.value)); + } + return constraint.value && constraint.type != ConstraintTypes.null + }); + } + + private doesArrayContaintEmptyValues(arr) { + for(const element of arr) { + if(element === "") return true; + } + return false; + } + + private emitOnConstraintChange(): void { + this.validateConstraints(); + const newConstraints = this.getConstraintsFormat(); + 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){ @@ -161,6 +200,7 @@ export class ConstraintsComponent implements OnInit { this.constraints[constraintIndex].value = new Array(); } this.constraints[constraintIndex].value.push(""); + this.emitOnConstraintChange() } onChangeConstraintType(constraintIndex: number, newType: ConstraintTypes) { @@ -168,10 +208,12 @@ export class ConstraintsComponent implements OnInit { 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) { @@ -179,21 +221,21 @@ export class ConstraintsComponent implements OnInit { this.constraints[constraintIndex].value = new Array(); } this.constraints[constraintIndex].value[valueIndex] = newValue; + this.emitOnConstraintChange(); } removeConstraint(constraintIndex: number) { this.constraints.splice(constraintIndex, 1); - this.onConstraintChange.emit(this.getConstraintsFormat()); + this.emitOnConstraintChange(); } addConstraint() { let newConstraint: Constraint = { - type:this.newConstraintType, - value: this.newConstraintValue + type: ConstraintTypes.null, + value: "" } this.constraints.push(newConstraint); - this.newConstraintValue = null; - this.onConstraintChange.emit(this.getConstraintsFormat()); + this.emitOnConstraintChange(); } getInRangeValue(constraintIndex: number, valueIndex: number): string { @@ -203,9 +245,62 @@ export class ConstraintsComponent implements OnInit { 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; + } + + getConstraintTypeIfPresent(constraintType: ConstraintTypes): Constraint { + return this.constraints.find((constraint) => { + return constraint.type == constraintType ? true : false; + }) + } + + trackByFn(index) { + return index; + } + + isComparable(propType: string): boolean { + if (PROPERTY_DATA.COMPARABLE_TYPES.indexOf(propType) >= 0) { + return true; + } + return false; + } + } export enum ConstraintTypes { + null = "", equal= "equal", greater_than = "greaterThan", greater_or_equal = "greaterOrEqual", @@ -236,5 +331,4 @@ export const ConstraintTypesMapping = { export interface Constraint { type:ConstraintTypes, value:any - }
\ No newline at end of file diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts index c8fb1966b4..173486c2f0 100644 --- a/catalog-ui/src/app/utils/constants.ts +++ b/catalog-ui/src/app/utils/constants.ts @@ -162,6 +162,7 @@ export class PROPERTY_DATA { public static OPENECOMP_ROOT = "org.openecomp.datatypes.Root"; public static SUPPLEMENTAL_DATA = "supplemental_data"; public static SOURCES = [SOURCES.A_AND_AI, SOURCES.ORDER, SOURCES.RUNTIME]; + public static COMPARABLE_TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.TIMESTAMP, PROPERTY_TYPES.SCALAR, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME]; } export class PROPERTY_VALUE_CONSTRAINTS { 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 614f1583cb..eda5efcd49 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 @@ -69,6 +69,7 @@ interface IPropertyFormViewModelScope extends ng.IScope { constraints:string[]; modelNameFilter:string; isGetFunctionValueType: boolean; + invalidMandatoryFields: boolean; validateJson(json:string):boolean; save(doNotCloseModal?:boolean):void; @@ -404,17 +405,21 @@ export class PropertyFormViewModel { this.$scope.$watch("forms.editForm.$invalid", (newVal) => { if (this.$scope.editPropertyModel.hasGetFunctionValue) { - this.$scope.footerButtons[0].disabled = newVal || !this.$scope.editPropertyModel.property.toscaFunction || this.isViewOnly; + this.$scope.invalidMandatoryFields = !newVal || !this.$scope.editPropertyModel.property.toscaFunction || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; } else { - this.$scope.footerButtons[0].disabled = newVal || this.isViewOnly; + this.$scope.invalidMandatoryFields = !newVal || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; } }); this.$scope.$watch("forms.editForm.$valid", (newVal) => { if (this.$scope.editPropertyModel.hasGetFunctionValue) { - this.$scope.footerButtons[0].disabled = !newVal || !this.$scope.editPropertyModel.property.toscaFunction || this.isViewOnly; + this.$scope.invalidMandatoryFields = !newVal || !this.$scope.editPropertyModel.property.toscaFunction || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; } else { - this.$scope.footerButtons[0].disabled = !newVal || this.isViewOnly; + this.$scope.invalidMandatoryFields = !newVal || this.isViewOnly; + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; } }); @@ -460,6 +465,21 @@ export class PropertyFormViewModel { } } + this.$scope.onConstraintChange = (constraints: any): void => { + if (!this.$scope.invalidMandatoryFields) { + this.$scope.footerButtons[0].disabled = !constraints.valid; + } else { + this.$scope.footerButtons[0].disabled = this.$scope.invalidMandatoryFields; + } + if (!constraints.constraints || constraints.constraints.length == 0) { + this.$scope.editPropertyModel.property.propertyConstraints = null; + this.$scope.editPropertyModel.property.constraints = null; + return; + } + this.$scope.editPropertyModel.property.propertyConstraints = this.serializePropertyConstraints(constraints.constraints); + this.$scope.editPropertyModel.property.constraints = constraints.constraints; + } + this.$scope.onGetFunctionValidFunction = (toscaGetFunction: ToscaGetFunction): void => { this.$scope.editPropertyModel.property.toscaFunction = toscaGetFunction; } @@ -471,9 +491,19 @@ export class PropertyFormViewModel { } this.$scope.editPropertyModel.isGetFunctionValid = undefined; } - }; + private serializePropertyConstraints(constraints: any[]): string[] { + if (constraints) { + let stringConstrsints = new Array(); + constraints.forEach((constraint) => { + stringConstrsints.push(JSON.stringify(constraint)); + }) + return stringConstrsints; + } + return null; + } + private setEmptyValue() { const property1 = this.$scope.editPropertyModel.property; property1.value = undefined; diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html index 35e3932586..2f67474d4f 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html +++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html @@ -264,8 +264,9 @@ <div class="constraints-section i-sdc-form-item" data-ng-if="editPropertyModel.property.constraints || !(isViewOnly || componentMetadata.isService)"> <label class="i-sdc-form-label">Constraints</label> <ng-container> - <app-constraints [property]="editPropertyModel.property" + <app-constraints [property-constraints]="editPropertyModel.property.constraints" [is-view-only]="isViewOnly || componentMetadata.isService" + [property-type]="editPropertyModel.property.type" (on-constraint-change)="onConstraintChange($event)"> </app-constraints> </ng-container> |