Provide tosca function as list primitive type entry values in composition view 26/132926/2
authorimamSidero <imam.hussain@est.tech>
Tue, 17 Jan 2023 10:59:29 +0000 (10:59 +0000)
committerMichael Morris <michael.morris@est.tech>
Fri, 20 Jan 2023 10:58:07 +0000 (10:58 +0000)
Providing the capability to add tosca function as the primitive type entry values of list in composition view

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

catalog-ui/src/app/directives/property-types/type-list/type-list-directive.html
catalog-ui/src/app/directives/property-types/type-list/type-list-directive.less
catalog-ui/src/app/directives/property-types/type-list/type-list-directive.ts
catalog-ui/src/app/directives/select-property-types/select-type-list/select-type-list-directive.less
catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html

index 48e4415..842b890 100644 (file)
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<div>
-    <div data-ng-if="!isSchemaTypeDataType">
-        <div class="i-sdc-form-item list-new-item" data-ng-class="{error:(parentFormObj['listNewItem'+fieldsPrefixName].$dirty && parentFormObj['listNewItem'+fieldsPrefixName].$invalid)}"
-             ng-if="schemaProperty.type !== 'map'">
-            <input class="i-sdc-form-input"
-                   data-tests-id="listNewItem{{fieldsPrefixName}}"
-                   ng-if="!constraints && !((schemaProperty.simpleType||schemaProperty.type) == 'boolean')"
-                   data-ng-disabled="readOnly"
-                   data-ng-model="listNewItem.value"
-                   type="text"
-                   name="listNewItem{{fieldsPrefixName}}"
-                   data-ng-pattern="getValidationPattern((schemaProperty.simpleType||schemaProperty.type))"
-                   data-ng-model-options="{ debounce: 200 }"
-                   placeholder="Type a value and then click ADD"
-                   data-ng-maxlength="maxLength"
-                   maxlength="{{maxLength}}"
-                   sdc-keyboard-events="" key-enter="schemaProperty.type && !parentFormObj['listNewItem'+fieldsPrefixName].$invalid && listNewItem.value && addListItem"
-                   autofocus />
-            <select class="i-sdc-form-select"
+    
+<div class="dt-list">
+    <div data-ng-repeat="i in getNumber(valueObjRef.length) track by $index" class="dt-list-item">
+        <span class="delete-dt-list-item" data-ng-click="deleteListItem($index)"></span>
+        <div data-ng-if="isSchemaTypeDataType">
+            <fields-structure value-obj-ref="valueObjRef[$index]"
+                            type-name="schemaProperty.type"
+                            parent-form-obj="parentFormObj"
+                            fields-prefix-name="fieldsPrefixName+''+$index"
+                            read-only="readOnly"></fields-structure>
+        </div>
+        <div data-ng-if="!isSchemaTypeDataType">
+            <div class="i-sdc-form-item list-new-item" data-ng-class="{error:(parentFormObj['listNewItem'+fieldsPrefixName].$dirty && parentFormObj['listNewItem'+fieldsPrefixName].$invalid)}"
+                ng-if="schemaProperty.type !== 'map'">
+                <form class="temp-form">
+                    <input type="radio" name="hasToscaFunction-{{fieldsPrefixName}}-{{$index}}" data-ng-checked="{{showToscaFunction[$index] == false}}" data-ng-click="onEnableTosca(false,$index)"/> 
+                    Value
+                    <input type="radio" name="hasToscaFunction-{{fieldsPrefixName}}-{{$index}}" data-ng-checked="{{showToscaFunction[$index]}}" data-ng-click="onEnableTosca(true,$index)" /> 
+                    {{'TOSCA_FUNCTION_LABEL' | translate}}
+                </form>
+                <input class="i-sdc-form-input"
                     data-tests-id="listNewItem{{fieldsPrefixName}}"
-                    ng-if="!constraints && (schemaProperty.simpleType||schemaProperty.type) == 'boolean'"
+                    ng-if="!constraints && !((schemaProperty.simpleType||schemaProperty.type) == 'boolean') && !showToscaFunction[$index]"
                     data-ng-disabled="readOnly"
+                    data-ng-model="valueObjRef[$index]"
+                    type="text"
                     name="listNewItem{{fieldsPrefixName}}"
-                    data-ng-model="listNewItem.value">
-                <option value="true">true</option>
-                <option value="false">false</option>
-            </select>
-
-
-            <select class="i-sdc-form-select"
-                data-tests-id="constraints"
-                ng-if="constraints"
-                data-ng-disabled="readOnly"
-                data-ng-model="listNewItem.value">
-                <!-- Get the default value in case exist -->
-                <option value = "{{listNewItem.value}" name = "{{listNewItem.value}}" hidden selected>
-                        {{listNewItem.value}}
-                </option> 
-                <!-- add all constratint to Select list -->
-                <option ng-repeat='value in constraints' value="{{value}}" name="{{value}}">
-                    {{value}}
-                </option>
-                
-                
-            </select>
+                    data-ng-pattern="getValidationPattern((schemaProperty.simpleType||schemaProperty.type))"
+                    data-ng-change="addValueToList(valueObjRef[$index], $index);$event.stopPropagation();"
+                    data-ng-model-options="{ debounce: 200 }"
+                    data-ng-maxlength="maxLength"
+                    maxlength="{{maxLength}}"
+                    data-required
+                    autofocus />
+                <select class="i-sdc-form-select"
+                        data-tests-id="listNewItem{{fieldsPrefixName}}"
+                        ng-if="!constraints && (schemaProperty.simpleType||schemaProperty.type) == 'boolean' && !showToscaFunction[$index]"
+                        data-ng-disabled="readOnly"
+                        name="listNewItem{{fieldsPrefixName}}"
+                        data-ng-model="valueObjRef[$index]">
+                    <option value="true">true</option>
+                    <option value="false">false</option>
+                </select>
 
-            <div class="input-error" data-ng-show="parentFormObj['listNewItem'+fieldsPrefixName].$dirty && parentFormObj['listNewItem'+fieldsPrefixName].$invalid">
-                <span ng-show="parentFormObj['listNewItem'+fieldsPrefixName].$error.pattern" translate="PROPERTY_EDIT_PATTERN"></span>
-                <span ng-show="parentFormObj['listNewItem'+fieldsPrefixName].$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '{{maxLength}}' }"></span>
-            </div>
-        </div>
-        <div class="add-btn add-list-item" data-tests-id="add-list-item{{fieldsPrefixName}}"
-             data-ng-class="{'disabled': readOnly || !schemaProperty.type || parentFormObj['listNewItem'+fieldsPrefixName].$invalid || (!listNewItem.value && schemaProperty.type !== 'map')}" data-ng-click="addListItem()">Add</div>
-        <div class="list-value-items">
-            <span class="list-value-item" data-ng-repeat="value in valueObjRef track by $index">
-                <span ng-if="!readOnly" class="delete-list-item sprite-new small-x-button" data-ng-click="deleteListItem($index)"
-                      title="{{'PROPERTY_EDIT_LIST_DELETE_ITEM' | translate}}"></span>
-                <div ng-if="schemaProperty.type === 'map'">
-                    <type-map value-obj-ref="value"
-                              schema-property="stringSchema"
-                              parent-form-obj="parentFormObj"
-                              fields-prefix-name="fieldsPrefixName+''+$index"
-                              read-only="readOnly"
-                              default-value="{{undefined}}"
-                              max-length="maxLength"
-                              show-add-btn="true"
-                              constraints="constraints">
-                    </type-map>
+                <div data-ng-if="showToscaFunction[$index]" class="div-tosca-function">
+                    <tosca-function [property]="parentProperty"
+                                    [component-instance-map]="componentInstanceMap"
+                                    [allow-clear]="false"
+                                    [composition-map]="true"
+                                    [composition-map-key]="$index+''"
+                                    (on-valid-function)="onGetToscaFunction($event,$index)"
+                    >
+                    </tosca-function>
                 </div>
-                <div ng-if="schemaProperty.type !== 'map'">
-                    {{value}}
+    
+                <select class="i-sdc-form-select"
+                    data-tests-id="constraints"
+                    ng-if="constraints"
+                    data-ng-disabled="readOnly"
+                    data-ng-model="valueObjRef[$index]">
+                    <!-- Get the default value in case exist -->
+                    <option value = "{{listNewItem.value}" name = "{{listNewItem.value}}" hidden selected>
+                            {{listNewItem.value}}
+                    </option> 
+                    <!-- add all constratint to Select list -->
+                    <option ng-repeat='value in constraints' value="{{value}}" name="{{value}}">
+                        {{value}}
+                    </option>
+                    
+                    
+                </select>
+    
+                <div class="input-error" data-ng-show="parentFormObj['listNewItem'+fieldsPrefixName].$dirty && parentFormObj['listNewItem'+fieldsPrefixName].$invalid">
+                    <span ng-show="parentFormObj['listNewItem'+fieldsPrefixName].$error.pattern" translate="PROPERTY_EDIT_PATTERN"></span>
+                    <span ng-show="parentFormObj['listNewItem'+fieldsPrefixName].$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '{{maxLength}}' }"></span>
                 </div>
-            </span>
-        </div>
-    </div>
-    <div data-ng-if="isSchemaTypeDataType">
-        <div class="dt-list">
-            <div data-ng-repeat="value in valueObjRef track by $index" class="dt-list-item">
-                <span class="delete-dt-list-item" data-ng-click="deleteListItem($index)"></span>
-                <fields-structure value-obj-ref="valueObjRef[$index]"
-                                  type-name="schemaProperty.type"
-                                  parent-form-obj="parentFormObj"
-                                  fields-prefix-name="fieldsPrefixName+''+$index"
-                                  read-only="readOnly"></fields-structure>
             </div>
-            <div class="add-btn add-list-item" data-tests-id="add-list-item"
-                       data-ng-class="{'disabled': readOnly}" data-ng-click="listNewItem.value='{}';addListItem();">Add</div>
+            <div ng-if="schemaProperty.type === 'map'">
+                <type-map value-obj-ref="value"
+                            schema-property="stringSchema"
+                            parent-form-obj="parentFormObj"
+                            fields-prefix-name="fieldsPrefixName+''+$index"
+                            read-only="readOnly"
+                            default-value="{{undefined}}"
+                            max-length="maxLength"
+                            show-add-btn="true"
+                            constraints="constraints">
+                </type-map>
+            </div>
         </div>
-
     </div>
+    <div class="add-btn add-list-item" data-tests-id="add-list-item"
+                data-ng-class="{'disabled': readOnly}" data-ng-click="listNewItem.value='';addListItem();">Add</div>
 </div>
+
index 99d8005..971ef3b 100644 (file)
@@ -1,13 +1,3 @@
-.list-new-item{
-    float: left;
-    width: 50%;
-    min-width: 221px;
-    margin-right: 15px;
-    input{
-        min-width: 221px;
-    }
-}
-
 .list-value-items{
     -webkit-border-radius: 2px;
     -moz-border-radius: 2px;
 
 }
 
-.dt-list{
-    display: table-caption;
-    .dt-list-item {
-        border-radius: 3px;
-        background-color: @tlv_color_v;
-        display: inline-block;
-        .delete-dt-list-item{
-            float: right;
-            position: relative;
-            top: 5px;
-            right: 5px;
-            .sprite-new;
-            .delete-icon;
-            &:hover{
-                .delete-icon-hover;
-            }
-        }
-        .data-type-name{
-            margin-right: 16px;
+.dt-list-item {
+    min-width: 300px;
+    min-height: 65px;
+    background-color: @tlv_color_v;
+    border-radius: 3px;
+    margin: 8px;
+    float: left;
+    display: flex;
+    .delete-dt-list-item{
+        float: right;
+        position: relative;
+        top: 5px;
+        right: 5px;
+        .sprite-new;
+        .delete-icon;
+        &:hover{
+            .delete-icon-hover;
         }
     }
+    .list-new-item{
+        margin: 7px 12px !important;
+            float: left;
+            min-height: 50px;
+            select{
+                width:171px;
+            }
+            input[type="text"]{
+                width: 170px;
+            }
+            &>.data-type-fields-structure{
+                padding: 0;
+            }
+    
+            .i-sdc-form-input:read-only{
+                opacity: 0.4;
+                cursor: auto;
+            }
+    }
+    .data-type-name{
+        margin-right: 16px;
+    }
+}
+
+.dt-list{
+    display: inline-block;
     &>.add-list-item{
         float:none;
     }
 }
 
+.tosca-function {
+    max-width: 165px;
+}
+
+.tosca-error {
+    max-width: 165px;
+}
+
+.temp-form {
+    all: unset;
+}
+
index 857c62c..fe50941 100644 (file)
  * Created by rcohen on 9/15/2016.
  */
 'use strict';
-import {SchemaProperty} from "app/models";
+import {SchemaProperty, PropertyModel} from "app/models";
 import {ValidationUtils, PROPERTY_TYPES} from "app/utils";
 import {DataTypesService} from "app/services";
+import {InstanceFeDetails} from "app/models/instance-fe-details";
+import {ToscaGetFunction} from "app/models/tosca-get-function";
+import {SubPropertyToscaFunction} from "app/models/sub-property-tosca-function";
 
 export interface ITypeListScope extends ng.IScope {
     parentFormObj:ng.IFormController;
     schemaProperty:SchemaProperty;
+    parentProperty:PropertyModel;
+    componentInstanceMap: Map<string, InstanceFeDetails>;
     isSchemaTypeDataType:boolean;
     valueObjRef:any;
     propertyNameValidationPattern:RegExp;
@@ -38,14 +43,18 @@ export interface ITypeListScope extends ng.IScope {
     listNewItem:any;
     maxLength:number;
     stringSchema: SchemaProperty;
-
+    showToscaFunction: Array<boolean>;
     constraints:string[];
 
     getValidationPattern(type:string):RegExp;
     validateIntRange(value:string):boolean;
     addListItem():void;
+    addValueToList(value:string,index:number);
     deleteListItem(listItemIndex:number):void;
     getStringSchemaProperty():SchemaProperty;
+    getNumber(num:number):Array<any>;
+    onEnableTosca(toscaFlag:boolean,index:number);
+    onGetToscaFunction(toscaGetFunction: ToscaGetFunction, index:number);
 }
 
 
@@ -65,6 +74,8 @@ export class TypeListDirective implements ng.IDirective {
     scope = {
         valueObjRef: '=',//ref to list object in the parent value object
         schemaProperty: '=',//get the schema.property object
+        componentInstanceMap: '=',
+        parentProperty: '=',
         parentFormObj: '=',//ref to parent form (get angular form object)
         fieldsPrefixName: '=',//prefix for form fields names
         readOnly: '=',//is form read only
@@ -82,7 +93,21 @@ export class TypeListDirective implements ng.IDirective {
     link = (scope:ITypeListScope, element:any, $attr:any) => {
         scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
         scope.stringSchema = this.stringSchema;
-
+        if (scope.valueObjRef.length == 0) {
+            scope.valueObjRef.push("");
+        }
+        scope.showToscaFunction = new Array(scope.valueObjRef.length);
+        scope.valueObjRef.forEach((value, index) => {
+            scope.showToscaFunction[index] = false;
+            let key : string = index.toString();
+            if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                scope.parentProperty.subPropertyToscaFunctions.forEach(SubPropertyToscaFunction => {
+                    if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) != -1) {
+                        scope.showToscaFunction[index] = true;
+                    }
+                });
+            }
+        });
         //reset valueObjRef when schema type is changed
         scope.$watchCollection('schemaProperty.type', (newData:any):void => {
             scope.isSchemaTypeDataType = this.DataTypesService.isDataTypeForSchemaType(scope.schemaProperty);
@@ -113,18 +138,80 @@ export class TypeListDirective implements ng.IDirective {
             } else if ((scope.schemaProperty.simpleType || scope.schemaProperty.type) == PROPERTY_TYPES.STRING) {
                 newVal = scope.listNewItem.value;
             } else {
-                newVal = JSON.parse(scope.listNewItem.value);
+                if (scope.listNewItem.value != "") {
+                    newVal = JSON.parse(scope.listNewItem.value);
+                }
             }
             scope.valueObjRef.push(newVal);
+            scope.showToscaFunction.push(false);
             scope.listNewItem.value = "";
         };
 
+        //return dummy array in order to prevent rendering map-keys ng-repeat again when a map key is changed
+        scope.getNumber = (num:number):Array<any> => {
+            return new Array(num);
+        };
+
+        scope.addValueToList = (value:string,index:number):void => {
+            console.log("value : "+value+" , index : "+index);
+            scope.valueObjRef[index] = value;
+            scope.parentProperty.value = scope.valueObjRef;
+        }
+
         scope.deleteListItem = (listItemIndex: number): void => {
             scope.valueObjRef.splice(listItemIndex, 1);
+            let key : string = listItemIndex.toString();
+            if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                let subToscaFunctionList : Array<SubPropertyToscaFunction> = [];
+                scope.parentProperty.subPropertyToscaFunctions.forEach((SubPropertyToscaFunction, index) => {
+                    if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) == -1) {
+                        subToscaFunctionList.push(SubPropertyToscaFunction);
+                    }
+                });
+                scope.parentProperty.subPropertyToscaFunctions = subToscaFunctionList;
+            }
             if (!scope.valueObjRef.length && scope.listDefaultValue) {
                 angular.copy(scope.listDefaultValue, scope.valueObjRef);
             }
         };
+
+        scope.onEnableTosca = (toscaFlag:boolean,flagIndex:number):void => {
+            scope.showToscaFunction[flagIndex] = toscaFlag;
+            scope.valueObjRef[flagIndex] = "";
+            let key:string = flagIndex.toString();
+            if (!toscaFlag) {
+                if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                    let subToscaFunctionList : Array<SubPropertyToscaFunction> = [];
+                    scope.parentProperty.subPropertyToscaFunctions.forEach((SubPropertyToscaFunction, index) => {
+                        if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) == -1) {
+                            subToscaFunctionList.push(SubPropertyToscaFunction);
+                        }
+                    });
+                    scope.parentProperty.subPropertyToscaFunctions = subToscaFunctionList;
+                }
+            }
+        };
+
+        scope.onGetToscaFunction = (toscaGetFunction: ToscaGetFunction, index:number): void => {
+            let key:string = index.toString();
+            if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                scope.parentProperty.subPropertyToscaFunctions.forEach(SubPropertyToscaFunction => {
+                    if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) != -1) {
+                        SubPropertyToscaFunction.toscaFunction = toscaGetFunction;
+                        return;
+                    }
+                });
+
+            }
+            if (scope.parentProperty.subPropertyToscaFunctions == null){
+                scope.parentProperty.subPropertyToscaFunctions = [];
+            }
+            let subPropertyToscaFunction = new SubPropertyToscaFunction();
+            subPropertyToscaFunction.toscaFunction = toscaGetFunction;
+            subPropertyToscaFunction.subPropertyPath = [key];
+            scope.parentProperty.subPropertyToscaFunctions.push(subPropertyToscaFunction);
+        }
+
     };
 
     public static factory = (DataTypesService:DataTypesService,
index 99d8005..9111aca 100644 (file)
@@ -3,9 +3,6 @@
     width: 50%;
     min-width: 221px;
     margin-right: 15px;
-    input{
-        min-width: 221px;
-    }
 }
 
 .list-value-items{
@@ -57,7 +54,7 @@
 }
 
 .dt-list{
-    display: table-caption;
+    display: inline-block;
     .dt-list-item {
         border-radius: 3px;
         background-color: @tlv_color_v;
index 48a85e4..6a9013c 100644 (file)
                         <input type="radio" name="hasGetFunctionValue"
                                ng-model="editPropertyModel.hasGetFunctionValue"
                                ng-value="false"
-                               ng-change="onValueTypeChange()"/> Entries
+                               ng-change="onValueTypeChange()"/> {{(editPropertyModel.property.type == 'map' || editPropertyModel.property.type == 'list') ? 'Entries' : 'Value'}}
                         <input type="radio" name="hasGetFunctionValue"
                                ng-model="editPropertyModel.hasGetFunctionValue"
                                ng-value="true"
                             <div ng-switch-when="list">
                                 <type-list value-obj-ref="myValue"
                                            schema-property="editPropertyModel.property.schema.property"
+                                           parent-property="editPropertyModel.property"
+                                           component-instance-map="componentInstanceMap"
                                            parent-form-obj="forms.editForm"
                                            fields-prefix-name="currentPropertyIndex"
                                            read-only="editPropertyModel.property.readonly && !isPropertyValueOwner"