diff options
5 files changed, 235 insertions, 121 deletions
diff --git a/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.html b/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.html index 48e441599f..842b890d6e 100644 --- a/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.html +++ b/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.html @@ -13,96 +13,98 @@ ~ 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> + diff --git a/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.less b/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.less index 99d8005fb1..971ef3b007 100644 --- a/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.less +++ b/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.less @@ -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; @@ -56,29 +46,65 @@ } -.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; +} + diff --git a/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.ts b/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.ts index 857c62cc92..fe509416fa 100644 --- a/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.ts +++ b/catalog-ui/src/app/directives/property-types/type-list/type-list-directive.ts @@ -22,13 +22,18 @@ * 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, diff --git a/catalog-ui/src/app/directives/select-property-types/select-type-list/select-type-list-directive.less b/catalog-ui/src/app/directives/select-property-types/select-type-list/select-type-list-directive.less index 99d8005fb1..9111acabf8 100644 --- a/catalog-ui/src/app/directives/select-property-types/select-type-list/select-type-list-directive.less +++ b/catalog-ui/src/app/directives/select-property-types/select-type-list/select-type-list-directive.less @@ -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; 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 48a85e4fcc..6a9013cce6 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 @@ -146,7 +146,7 @@ <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" @@ -190,6 +190,8 @@ <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" |