Provide add/edit constraints capability to inputs in properties page 06/133006/11
authorimamSidero <imam.hussain@est.tech>
Tue, 24 Jan 2023 16:03:54 +0000 (16:03 +0000)
committerMichael Morris <michael.morris@est.tech>
Fri, 27 Jan 2023 18:22:19 +0000 (18:22 +0000)
Providing the capability to add or edit constraints to inputs in properies of a service

Issue-ID: SDC-4346
Signed-off-by: Imam hussain <imam.hussain@est.tech>
Change-Id: I56261441022751a191fe057aafa4c681c8db96c5

12 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
catalog-ui/src/app/models/properties.ts
catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
catalog-ui/src/app/utils/modals-handler.ts
catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts
catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesAssignmentInputTab.java

index 21327ea..44fecb3 100644 (file)
@@ -308,6 +308,9 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
                 currInput.setDefaultValue(updateInputObjectValue);
                 currInput.setOwnerId(userId);
                 currInput.setMetadata(newInput.getMetadata());
+                if (newInput.getConstraints() != null) {
+                    currInput.setConstraints(newInput.getConstraints());
+                }
                 if (newInput.isRequired() != null) {
                     currInput.setRequired(newInput.isRequired());
                 }
index 2cccc31..f5db6be 100644 (file)
@@ -2113,7 +2113,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         }
         Service service = serviceResultEither.left().value();
         if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
-            ListUtils.emptyIfNull(service.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
+            ListUtils.emptyIfNull(service.getInputs()).stream().filter(input -> CollectionUtils.isEmpty(input.getConstraints()))
+                .forEach(input -> input.setConstraints(setInputConstraint(input)));
         }
         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
         return Either.left(dataTransfer);
index 65158de..80575c4 100644 (file)
@@ -89,12 +89,12 @@ export class PropertyModel extends PropertyBEModel implements IPropertyModel {
     filterTerm:string;
     isAlreadySelected:boolean;
     addOn:string;
-
+    propertyView: boolean = false;
 
     constructor(property?:PropertyModel) {
         super(property);
         if (property) {
-            // this.constraints = property.constraints;
+            this.constraints = property.constraints;
             this.source = property.source;
             this.valueUniqueUid = property.valueUniqueUid;
             this.path = property.path;
@@ -105,6 +105,7 @@ export class PropertyModel extends PropertyBEModel implements IPropertyModel {
             this.componentInstanceId = property.componentInstanceId;
             this.parentValue = property.parentValue;
             this.ownerId = property.ownerId;
+            this.propertyView = property.propertyView;
         }
 
         if (!this.schema || !this.schema.property) {
index 7c83c55..1389c21 100644 (file)
@@ -44,7 +44,7 @@
                 <!-- Property Name -->
                 <div class="table-cell col1">
                     <div class="inner-cell-div">
-                        <span class="property-name" tooltip="{{input.name}}">{{input.name}}</span>
+                        <a class="property-name" (click)="updateProperty(input)" tooltip="{{input.name}}">{{input.name}}</a>
                     </div>
                     <span *ngIf="input.description"
                           class="property-description-icon sprite-new show-desc"
index 822d8c9..ec18767 100644 (file)
@@ -23,7 +23,8 @@
  * Created by rc2122 on 5/4/2017.
  */
 import { Component, Input, Output, EventEmitter, ViewChildren, QueryList } from "@angular/core";
-import { InputFEModel } from "app/models";
+import { InputFEModel, PropertyModel, PropertiesGroup, Component as ComponentData } from "app/models";
+import { ModalsHandler } from 'app/utils';
 import { ModalService } from "../../../services/modal.service";
 import { InstanceFeDetails } from "app/models/instance-fe-details";
 import { InstanceFePropertiesMap } from "../../../../models/properties-inputs/property-fe-map";
@@ -48,6 +49,8 @@ export class InputsTableComponent {
     @Output() deleteInput: EventEmitter<any> = new EventEmitter<any>();
 
     @Input() fePropertiesMap: InstanceFePropertiesMap;
+    @Input() componentInstancePropertyMap: PropertiesGroup;
+    @Input() parentComponent: ComponentData;
 
     @ViewChildren('metadataViewChildren') public metadataViewChildren: QueryList<DynamicElementComponent>;
 
@@ -84,7 +87,7 @@ export class InputsTableComponent {
     };
 
 
-    constructor(private modalService: ModalService, private dataTypeService: DataTypeService){
+    constructor(private modalService: ModalService, private dataTypeService: DataTypeService, private modalsHandler: ModalsHandler){
         var x = 5
     }
 
@@ -175,6 +178,43 @@ export class InputsTableComponent {
         return false;
     }
 
+    public updateProperty = (inputProperty: InputFEModel): void => {
+        let modelProperty : PropertyModel = this.createPropertyModel(inputProperty);
+        if (inputProperty.instanceUniqueId != null && this.componentInstancePropertyMap != null && modelProperty.constraints == null) {
+            this.componentInstancePropertyMap[inputProperty.instanceUniqueId].forEach(tempProperty => {
+                modelProperty.constraints = tempProperty.constraints;
+            });
+        }
+        this.modalsHandler.newOpenEditPropertyModal(modelProperty, [],true, 'component', modelProperty.resourceInstanceUniqueId, this.parentComponent, inputProperty);     
+    }
+
+    private createPropertyModel(inputproperty: InputFEModel){
+        let propertyModel = new PropertyModel();
+        propertyModel.constraints = inputproperty.constraints;
+        propertyModel.defaultValue = inputproperty.defaultValue;
+        propertyModel.definition = inputproperty.definition;
+        propertyModel.description = inputproperty.description;
+        propertyModel.name = inputproperty.name;
+        propertyModel.parentUniqueId = inputproperty.parentUniqueId;
+        propertyModel.password = inputproperty.password;
+        propertyModel.required = inputproperty.required;
+        propertyModel.schema = inputproperty.schema;
+        propertyModel.schemaType = inputproperty.schemaType;
+        propertyModel.type = inputproperty.type;
+        propertyModel.uniqueId = inputproperty.uniqueId;
+        propertyModel.value = inputproperty.value;
+        propertyModel.getInputValues = inputproperty.getInputValues;
+        propertyModel.parentPropertyType = inputproperty.parentPropertyType;
+        propertyModel.subPropertyInputPath = inputproperty.subPropertyInputPath;
+        propertyModel.getPolicyValues = inputproperty.getPolicyValues;
+        propertyModel.inputPath = inputproperty.inputPath;
+        propertyModel.metadata = inputproperty.metadata;
+        propertyModel.subPropertyToscaFunctions = inputproperty.subPropertyToscaFunctions;
+        propertyModel.ownerId = inputproperty.ownerId;
+        propertyModel.propertyView = true;
+        return propertyModel;
+    }
+
 }
 
 
index 04bed37..d25daf2 100644 (file)
@@ -230,7 +230,7 @@ export class PropertiesTabComponent implements OnInit {
             (this.isPropertyOwner() ?
                 this.properties[property.parentUniqueId] :
                 this.properties[property.resourceInstanceUniqueId]) || [],
-            this.isPropertyValueOwner(), 'component', property.resourceInstanceUniqueId).then((updatedProperty: PropertyModel) => {
+            this.isPropertyValueOwner(), 'component', property.resourceInstanceUniqueId, null, null).then((updatedProperty: PropertyModel) => {
                 if (updatedProperty) {
                     const oldProp = _.find(this.properties[updatedProperty.resourceInstanceUniqueId],
                                  (prop: PropertyModel) => prop.uniqueId === updatedProperty.uniqueId);
index 1be3495..1eed6df 100644 (file)
                             [showDelete]="!isReadOnly && isSelf()"
                             [inputs]="inputs | searchFilter:'name':searchQuery"
                             [instanceNamesMap]="componentInstanceNamesMap"
+                            [componentInstancePropertyMap]="componentInstancePropertyMap"
                             [isLoading]="loadingInputs"
                             [componentType]="component.componentType"
+                            [parentComponent]="component"
                             (deleteInput)="deleteInput($event)"
                             (inputChanged)="dataChanged($event)">
                         </inputs-table>
index a347779..e66de41 100644 (file)
@@ -39,7 +39,8 @@ import {
     PropertyFEModel,
     Service,
     SimpleFlatProperty,
-    PropertyDeclareAPIModel
+    PropertyDeclareAPIModel,
+    PropertiesGroup
 } from "app/models";
 import {ResourceType} from "app/utils";
 import {ComponentServiceNg2} from "../../services/component-services/component.service";
@@ -121,6 +122,7 @@ export class PropertiesAssignmentComponent {
     serviceBePropertiesMap: InstanceBePropertiesMap;
     serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
     selectedInstance_FlattenCapabilitiesList: Capability[];
+    componentInstancePropertyMap : PropertiesGroup;
 
     @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
     @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
@@ -170,6 +172,7 @@ export class PropertiesAssignmentComponent {
                 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
                 this.inputs.push(newInput); //only push items that were declared via SDC
             });
+            this.componentInstancePropertyMap = response.componentInstancesProperties;
             this.loadingInputs = false;
 
         }, error => {
index cbbab45..43f9637 100644 (file)
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-import {  Component, DisplayModule , PropertyModel } from '../models';
+import {  Component, DisplayModule , PropertyModel, InputFEModel } from '../models';
 import { ComponentMetadata } from '../models/component-metadata';
 
 export interface IModalsHandler {
@@ -97,6 +97,9 @@ export class ModalsHandler implements IModalsHandler {
                 },
                 isViewOnly: (): boolean => {
                     return isViewOnly;
+                },
+                inputProperty: (): InputFEModel => {
+                    return null;
                 }
             }
         };
@@ -115,7 +118,7 @@ export class ModalsHandler implements IModalsHandler {
      * @param isPropertyValueOwner - boolean telling if the component is eligible of editing the property
      * @returns {IPromise<T>} - Promise telling if the modal has opened or not
      */
-    newOpenEditPropertyModal = (property: PropertyModel, filteredProperties: PropertyModel[], isPropertyValueOwner: boolean, propertyOwnerType: string, propertyOwnerId: string): ng.IPromise<any> => {
+    newOpenEditPropertyModal = (property: PropertyModel, filteredProperties: PropertyModel[], isPropertyValueOwner: boolean, propertyOwnerType: string, propertyOwnerId: string, component: Component, inputProperty: InputFEModel): ng.IPromise<any> => {
         const deferred = this.$q.defer();
 
         const modalOptions: ng.ui.bootstrap.IModalSettings = {
@@ -142,6 +145,12 @@ export class ModalsHandler implements IModalsHandler {
                 },
                 isViewOnly: (): boolean => {
                     return false;
+                },
+                component: (): Component => {
+                    return component as Component;
+                },
+                inputProperty: (): InputFEModel => {
+                    return inputProperty;
                 }
             }
         };
index 151c34f..c20d9fc 100644 (file)
 import * as _ from "lodash";
 import {FormState, PROPERTY_DATA, PROPERTY_TYPES, PROPERTY_VALUE_CONSTRAINTS, ValidationUtils} from "app/utils";
 import {DataTypesService} from "app/services";
-import {DataTypesMap, PropertyModel} from "app/models";
+import {DataTypesMap, PropertyModel, InputBEModel, Component, InputFEModel} from "app/models";
 import {ComponentInstance} from "../../../../models/componentsInstances/componentInstance";
 import {ComponentInstanceServiceNg2} from "app/ng2/services/component-instance-services/component-instance.service";
+import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service";
 import {SdcUiCommon, SdcUiComponents, SdcUiServices} from "onap-ui-angular";
 import {CompositionService} from "app/ng2/pages/composition/composition.service";
 import {WorkspaceService} from "app/ng2/pages/workspace/workspace.service";
@@ -99,7 +100,7 @@ export class PropertyFormViewModel {
         'PropertyNameValidationPattern',
         'CommentValidationPattern',
         'ValidationUtils',
-        // 'component',
+        'component',
         '$filter',
         'ModalServiceSdcUI',
         'filteredProperties',
@@ -109,9 +110,11 @@ export class PropertyFormViewModel {
         'propertyOwnerType',
         'propertyOwnerId',
         'ComponentInstanceServiceNg2',
+        'ComponentServiceNg2',
         'TopologyTemplateService',
         'CompositionService',
-        'workspaceService'
+        'workspaceService',
+        'inputProperty'
     ];
 
     private formState:FormState;
@@ -124,7 +127,7 @@ export class PropertyFormViewModel {
                 private PropertyNameValidationPattern:RegExp,
                 private CommentValidationPattern:RegExp,
                 private ValidationUtils:ValidationUtils,
-                // private component:Component,
+                private component:Component,
                 private $filter:ng.IFilterService,
                 private modalService:SdcUiServices.ModalService,
                 private filteredProperties:Array<PropertyModel>,
@@ -134,9 +137,11 @@ export class PropertyFormViewModel {
                 private propertyOwnerType:string,
                 private propertyOwnerId:string,
                 private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2,
+                private ComponentServiceNg2: ComponentServiceNg2,
                 private topologyTemplateService: TopologyTemplateService,
                 private compositionService: CompositionService,
-                private workspaceService: WorkspaceService) {
+                private workspaceService: WorkspaceService,
+                private inputProperty : InputFEModel) {
 
         this.formState = angular.isDefined(property.name) ? FormState.UPDATE : FormState.CREATE;
         this.initScope();
@@ -322,6 +327,25 @@ export class PropertyFormViewModel {
         //scope methods
         this.$scope.save = (doNotCloseModal?:boolean):void => {
             let property:PropertyModel = this.$scope.editPropertyModel.property;
+            this.$scope.isLoading = true;
+            if (property.propertyView){
+                if (property.constraints.length == 0) {
+                    return;
+                }
+                let input : InputBEModel = this.inputProperty;
+                input.constraints = property.constraints;
+                this.ComponentServiceNg2.updateComponentInputs(this.component, [input]).subscribe(
+                    (response) => {
+                        console.debug("Input property updated");
+                        this.$uibModalInstance.close();
+                    },
+                    (error) => {
+                        console.debug("Failed to update input property");
+                        this.$uibModalInstance.close();
+                    }
+                );
+                return;
+            }
             this.$scope.editPropertyModel.property.description = this.ValidationUtils.stripAndSanitize(this.$scope.editPropertyModel.property.description);
             //if read only - or no changes made - just closes the modal
             //need to check for property.value changes manually to detect if map properties deleted
index dc26d1f..6e6c29b 100644 (file)
@@ -15,7 +15,7 @@
 -->
 <ng1-modal modal="modalInstanceProperty" type="classic" class="sdc-edit-property-container" buttons="footerButtons" header="{{isNew ? 'Add' : 'Update' }} Property" show-close-button="true" data-tests-id="sdc-edit-property-container">
     <loader data-display="isLoading" relative="false" size="medium"></loader>
-    <div class="sdc-modal-top-bar" data-ng-if="!isNew">
+    <div class="sdc-modal-top-bar" data-ng-if="!isNew && !editPropertyModel.property.propertyView">
         <div class="sdc-modal-top-bar-buttons">
             <span ng-click="delete(editPropertyModel.property)" data-ng-class="{'disabled' : isPropertyValueOwner || editPropertyModel.property.readonly || propertyOwnerType == 'group' || propertyOwnerType == 'policy'}" class="sprite-new delete-btn" data-tests-id="delete_property"  sdc-smart-tooltip="">Delete</span>
             <span class="delimiter"></span>
                 </div>
                 <!-- Default value -->
 
-                <div class="default-value-section i-sdc-form-item">
+                <div class="default-value-section i-sdc-form-item" data-ng-if="!editPropertyModel.property.propertyView">
                     <label class="i-sdc-form-label">Default Value</label>
                     <ng-container ng-if="!componentMetadata.isVfc">
                         <input type="hidden" ng-model="editPropertyModel.isGetFunctionValid" required="required"/>
                         </div>
                     </div>
                 </div>
-                <div class="constraints-section i-sdc-form-item" data-ng-if="editPropertyModel.property.constraints || !(isViewOnly || componentMetadata.isService)">
+                <div class="constraints-section i-sdc-form-item" data-ng-if="editPropertyModel.property.propertyView || editPropertyModel.property.constraints || !(isViewOnly || componentMetadata.isService)">
                     <label class="i-sdc-form-label">Constraints</label>
                     <ng-container>
                         <app-constraints [property-constraints]="editPropertyModel.property.constraints"
-                                         [is-view-only]="isViewOnly || componentMetadata.isService"
+                                         [is-view-only]="editPropertyModel.property.propertyView? !editPropertyModel.property.propertyView :(isViewOnly || componentMetadata.isService)"
                                          [property-type]="editPropertyModel.property.type"
                                          (on-constraint-change)="onConstraintChange($event)">
                         </app-constraints>
index a46e9a9..b83be25 100644 (file)
@@ -157,7 +157,7 @@ public class ResourcePropertiesAssignmentInputTab extends AbstractPageObject {
         PROPERTY_SAVE_MESSAGE("//div[contains(text(), 'Successfully saved')]"),
         INPUT_PROPERTY_NAME("//*[contains(@class, 'property-name')]"),
         INPUT_PROPERTY_TABLE_ROW("//div[contains(@class, 'table-row') and descendant::*[text() = '%s']]"),
-        INPUT_PROPERTY_ADD_METADATA_BUTTON(INPUT_PROPERTY_TABLE_ROW.getXpath().concat("//a")),
+        INPUT_PROPERTY_ADD_METADATA_BUTTON(INPUT_PROPERTY_TABLE_ROW.getXpath().concat("//a[contains(@class, 'add-item')]")),
         INPUT_PROPERTY_METADATA_KEY_VALUE_PAIR(INPUT_PROPERTY_TABLE_ROW.getXpath().concat("//input")),
         INPUT_ADD_BTN("//div[contains(@class,'add-btn')]"),
         MODAL_BACKGROUND("//div[@class='modal-background']");