diff options
10 files changed, 134 insertions, 33 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java index 9734a0acdb..150007408a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java @@ -1374,6 +1374,7 @@ public class YamlTemplateParsingHandler { @SuppressWarnings("unchecked") private void fillInputsListRecursively(UploadPropInfo propertyDef, List<Object> propValueList) { + int index = 0; for (Object objValue : propValueList) { if (objValue instanceof Map) { Map<String, Object> objMap = (Map<String, Object>) objValue; @@ -1383,10 +1384,24 @@ public class YamlTemplateParsingHandler { Set<String> keys = objMap.keySet(); findAndFillInputsListRecursively(propertyDef, objMap, keys); } + if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(objValue)) { + Map<String, Object> propValueMap = new HashMap<String, Object>(); + propValueMap.put(String.valueOf(index),objValue); + final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>()); + if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) { + Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions(); + if (existingSubPropertyToscaFunctions == null) { + propertyDef.setSubPropertyToscaFunctions(subPropertyToscaFunctions); + } else { + propertyDef.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions); + } + } + } } else if (objValue instanceof List) { List<Object> propSubValueList = (List<Object>) objValue; fillInputsListRecursively(propertyDef, propSubValueList); } + index++; } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index e867d0639e..3797fb9fae 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -43,6 +43,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.json.JSONArray; import org.json.JSONObject; import org.onap.sdc.tosca.datatypes.model.PropertyType; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; @@ -1979,13 +1980,20 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { toscaFunctionValidator.validate(property, containerComponent); property.setValue(property.getToscaFunction().getValue()); } - - if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())){ - final JSONObject jObject = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue()); - property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> { - setJsonObjectForSubProperty(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue()); - }); - property.setValue(jObject.toString()); + if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) { + if (StringUtils.isNumeric(property.getSubPropertyToscaFunctions().iterator().next().getSubPropertyPath().get(0))) { + final JSONArray jsonArray = property.getValue() == null ? new JSONArray() : new JSONArray(property.getValue()); + property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> { + addE(jsonArray, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue()); + }); + property.setValue(jsonArray.toString()); + } else { + final JSONObject jObject = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue()); + property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> { + addE(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue()); + }); + property.setValue(jObject.toString()); + } } Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel()); if (updatedPropertyValue.isRight()) { @@ -2031,7 +2039,60 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType()); } } - + + private void addE(JSONArray jsonArray, List<String> path, String value) { + Object objectForPath = jsonArray.opt(Integer.parseInt(path.get(0))); + if (objectForPath == null) { + if (path.size() > 1) { + if (StringUtils.isNumeric(path.get(1))) { + objectForPath = new JSONArray(); + } else { + objectForPath = new JSONObject(); + } + jsonArray.put(Integer.parseInt(path.get(0)), objectForPath); + } + } + + if (path.size() == 1) { + Object valueAsObject = new Yaml().loadAs(value, Object.class); + jsonArray.put(Integer.parseInt(path.get(0)), valueAsObject); + } else { + if (objectForPath instanceof JSONObject) { + addE((JSONObject)objectForPath, path.subList(1, path.size()), value); + } else { + addE((JSONArray)objectForPath, path.subList(1, path.size()), value); + } + } + } + + private void addE(JSONObject jsonObject, List<String> path, String value) { + + Object objectForPath = null; + if (jsonObject.has(path.get(0))) { + objectForPath = jsonObject.get(path.get(0)); + } else { + if (path.size() > 1) { + if (StringUtils.isNumeric(path.get(1))) { + objectForPath = new JSONArray(); + } else { + objectForPath = new JSONObject(); + } + jsonObject.put(path.get(0), objectForPath); + } + } + + if (path.size() == 1) { + Object valueAsObject = new Yaml().loadAs(value, Object.class); + jsonObject.put(path.get(0), valueAsObject); + } else { + if (objectForPath instanceof JSONObject) { + addE((JSONObject)objectForPath, path.subList(1, path.size()), value); + } else { + addE((JSONArray)objectForPath, path.subList(1, path.size()), value); + } + } + } + private void setJsonObjectForSubProperty(final JSONObject jObject, final List<String> path, String value) { if (path.size() == 1) { Object valueAsObject = new Yaml().loadAs(value, Object.class); diff --git a/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts b/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts index 7d832c5193..60d2726575 100644 --- a/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts +++ b/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts @@ -55,7 +55,7 @@ export class DerivedFEProperty extends PropertyBEModel { this.canBeDeclared = true; //defaults to true } else { //creating a direct child of list or map (ie. Item that can be deleted, with UUID instead of name) super(null); - if(property.type === PROPERTY_TYPES.MAP && property.subPropertyToscaFunctions != null){ + if(property.subPropertyToscaFunctions != null){ property.subPropertyToscaFunctions.forEach((item : SubPropertyToscaFunction) => { if(item.subPropertyPath[0] === key){ this.toscaFunction = item.toscaFunction; @@ -69,7 +69,17 @@ export class DerivedFEProperty extends PropertyBEModel { this.propertiesName = parentName + '#' + this.name; if (property.type == PROPERTY_TYPES.LIST) { - this.mapKey = property.schema.property.type.split('.').pop(); + if(property.value != null) { + const valueJson = JSON.parse(property.value); + if (key != '') { + this.mapKey = key; + }else{ + let indexNumber = Number(Object.keys(valueJson).sort().reverse()[0]) + 1; + this.mapKey = indexNumber.toString(); + } + }else { + this.mapKey = "0"; + } this.mapKeyError = null; this.type = property.schema.property.type; if (this.type == PROPERTY_TYPES.MAP){ diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html index 2431a70536..d79c6dbb08 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html @@ -43,7 +43,7 @@ <!-- RIGHT CELL OR FULL WIDTH CELL--> <ng-container *ngIf="propType == derivedPropertyTypes.SIMPLE || property.isDeclared || property.isToscaFunction() || (property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)"> <div class="table-cell"> - <checkbox class="inline-checkBox" *ngIf="(nestedLevel == 1 && property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)" [(checked)]="property.isSelected" [disabled]="property.isDisabled || readonly || property.mapKey == ''" (checkedChange)="toggleTosca.emit(property)" ></checkbox> + <checkbox class="{{propType == derivedPropertyTypes.MAP ? 'inline-checkBox' : 'inline-checkBox-List'}}" *ngIf="(nestedLevel == 1 && property.isChildOfListOrMap && property.schema.property.isSimpleType)" [(checked)]="property.isSelected" [disabled]="property.isDisabled || readonly || property.mapKey == ''" (checkedChange)="toggleTosca.emit(property)" ></checkbox> <dynamic-element class="value-input" pattern="validationUtils.getValidationPattern(property.type)" [value]="(property.isDeclared || property.isToscaFunction()) ? property.value : property.valueObj" @@ -66,7 +66,7 @@ <div class="table-cell empty"></div> </ng-container> <!-- ICONS: add, delete, and expand --> - <ng-container *ngIf="(!property.isDeclared && !property.isToscaFunction()) || (property.isToscaFunction() && property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)"> + <ng-container *ngIf="(!property.isDeclared && !property.isToscaFunction()) || (property.isToscaFunction() && property.isChildOfListOrMap && property.schema.property.isSimpleType)"> <a *ngIf="(propType == derivedPropertyTypes.LIST) && (!property.isChildOfListOrMap || property.mapInlist)" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}" [attr.data-tests-id]="'add-to-list-' + propertyTestsId">Add value to list</a> <a *ngIf="(propType == derivedPropertyTypes.MAP) && (!property.isChildOfListOrMap || property.mapInlist)" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}" [attr.data-tests-id]="'add-to-list-' + propertyTestsId">Add value to map</a> <span *ngIf="property.isChildOfListOrMap" (click)="deleteItem.emit(property);" class="property-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'delete-from-list-' + propertyTestsId"></span> diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.less b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.less index 4d2cc89dfe..6b0f445006 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.less +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.less @@ -83,7 +83,13 @@ } .inline-checkBox { float: left; - width: 7%; + width: 9%; margin-left: -5px; margin-top: 4px; } +.inline-checkBox-List { + float: left; + width: 5%; + margin-left: 0; + margin-top: 4px; +} diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts index 57b991bf70..edcbd43e27 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts @@ -171,7 +171,6 @@ export class DynamicPropertyComponent { this.expandChildById(newProps[0].propertiesName); this.updateMapKeyValueOnMainParent(newProps); - this.emitter.emit(); } } @@ -219,23 +218,22 @@ export class DynamicPropertyComponent { if (!itemParent) { return; } - + const oldKey = item.getActualMapKey(); + if (this.property.subPropertyToscaFunctions !== null) { + let tempSubToscaFunction: SubPropertyToscaFunction[] = []; + this.property.subPropertyToscaFunctions.forEach((item : SubPropertyToscaFunction, index) => { + if(item.subPropertyPath[0] != oldKey){ + tempSubToscaFunction.push(item); + } + }); + this.property.subPropertyToscaFunctions = tempSubToscaFunction; + } if (item.derivedDataType == DerivedPropertyType.MAP && !item.mapInlist) { - const oldKey = item.getActualMapKey(); delete itemParent.valueObj[oldKey]; if (itemParent instanceof PropertyFEModel) { delete itemParent.valueObjValidation[oldKey]; itemParent.valueObjIsValid = itemParent.calculateValueObjIsValid(); } - if (this.property.subPropertyToscaFunctions !== null) { - let tempSubToscaFunction: SubPropertyToscaFunction[] = []; - this.property.subPropertyToscaFunctions.forEach((item : SubPropertyToscaFunction, index) => { - if(item.subPropertyPath[0] != oldKey){ - tempSubToscaFunction.push(item); - } - }); - this.property.subPropertyToscaFunctions = tempSubToscaFunction; - } this.property.childPropMapKeyUpdated(item, null); // remove map key } else { const itemIndex: number = this.property.flattenedChildren.filter(prop => prop.parentName == item.parentName).map(prop => prop.propertiesName).indexOf(item.propertiesName); diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less index 8c2c6ce940..b5abcb3451 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less @@ -2,7 +2,7 @@ @import '../../../../../assets/styles/sprite'; @smaller-screen: ~"only screen and (max-width: 1580px)"; -:host /deep/ input { width:100%;} +:host /deep/ input { width:96%;} .properties-table { display:flex; diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts index 767acb41a7..2bf1b1076b 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts @@ -580,22 +580,33 @@ export class PropertiesAssignmentComponent { private clearCheckedInstancePropertyValue() { const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty(); - let currentValue = checkedInstanceProperty.value; + const currentValue : any = checkedInstanceProperty.value; checkedInstanceProperty.getInputValues = null; checkedInstanceProperty.value = null; checkedInstanceProperty.toscaFunction = null; if (checkedInstanceProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName){ const propertiesNameArray = (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName; const parts = propertiesNameArray.split("#"); - const currentKey = checkedInstanceProperty.type === PROPERTY_TYPES.MAP ? (<DerivedFEProperty>checkedInstanceProperty.input).mapKey : null; + const currentKey = (checkedInstanceProperty.type == PROPERTY_TYPES.MAP || checkedInstanceProperty.type == PROPERTY_TYPES.LIST) ? (<DerivedFEProperty>checkedInstanceProperty.input).mapKey : null; if (propertiesNameArray.length > 1){ const index = checkedInstanceProperty.subPropertyToscaFunctions.findIndex(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey != null ? [currentKey] : parts.slice(1))); checkedInstanceProperty.subPropertyToscaFunctions.splice(index, 1); } if(currentValue !== null && currentKey !== null){ let valueJson = JSON.parse(currentValue); + let tempValue = valueJson[currentKey]; delete valueJson[currentKey]; - checkedInstanceProperty.value = JSON.stringify(valueJson); + if (checkedInstanceProperty.type == PROPERTY_TYPES.LIST) { + let listValue = []; + valueJson.forEach(item => { + if (item != null && item != '' && item != tempValue) { + listValue.push(item); + } + }); + checkedInstanceProperty.value = JSON.stringify(listValue); + } else { + checkedInstanceProperty.value = JSON.stringify(valueJson); + } } } if (this.selectedInstanceData instanceof ComponentInstance) { @@ -612,7 +623,7 @@ export class PropertiesAssignmentComponent { if (checkedProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedProperty).propertiesName){ const propertiesName = (<PropertyDeclareAPIModel>checkedProperty).propertiesName; const parts = propertiesName.split("#"); - const currentKey = checkedProperty.type === PROPERTY_TYPES.MAP ? (<DerivedFEProperty>checkedProperty.input).mapKey : null; + const currentKey = (checkedProperty.type == PROPERTY_TYPES.MAP || checkedProperty.type == PROPERTY_TYPES.LIST) ? (<DerivedFEProperty>checkedProperty.input).mapKey : null; if (checkedProperty.subPropertyToscaFunctions == null){ checkedProperty.subPropertyToscaFunctions = []; } diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts index bc73796672..0198dfd760 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts @@ -101,7 +101,7 @@ export class ToscaFunctionComponent implements OnInit, OnChanges { if (this.property instanceof PropertyDeclareAPIModel && this.property.subPropertyToscaFunctions && (<PropertyDeclareAPIModel> this.property).propertiesName){ let propertiesPath = (<PropertyDeclareAPIModel> this.property).propertiesName.split("#"); if (propertiesPath.length > 1){ - let keyToFind = this.property.type === PROPERTY_TYPES.MAP ? [(<DerivedFEProperty>this.property.input).mapKey] : propertiesPath.slice(1); + let keyToFind = (this.property.type == PROPERTY_TYPES.MAP || this.property.type == PROPERTY_TYPES.LIST) ? [(<DerivedFEProperty>this.property.input).mapKey] : propertiesPath.slice(1); let subPropertyToscaFunction = this.property.subPropertyToscaFunctions.find(subPropertyToscaFunction => this.areEqual(subPropertyToscaFunction.subPropertyPath, keyToFind !== null ? keyToFind : propertiesPath.slice(1))); if (subPropertyToscaFunction){ diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts index 0757e3d361..46541cf355 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts @@ -261,7 +261,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { } private propertyTypeToString() { - if (this.isSubProperty() && this.property.type != PROPERTY_TYPES.MAP){ + if (this.isSubProperty() && this.property.type != PROPERTY_TYPES.MAP && this.property.type != PROPERTY_TYPES.LIST){ return this.getType((<PropertyDeclareAPIModel>this.property).propertiesName.split("#").slice(1), this.property.type); } if (this.property.schemaType) { @@ -367,7 +367,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { private hasSameType(property: PropertyBEModel | AttributeBEModel): boolean { if (this.typeHasSchema(this.property.type)) { - if(this.property.type === PROPERTY_TYPES.MAP && this.property instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty){ + if ((this.property.type === PROPERTY_TYPES.MAP || this.property.type === PROPERTY_TYPES.LIST) && this.property instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty) { return property.type === this.property.schema.property.type; } if (!property.schema || !property.schema.property) { |