aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandre.schmid <andre.schmid@est.tech>2022-02-09 19:00:35 +0000
committerMichael Morris <michael.morris@est.tech>2022-03-11 15:25:28 +0000
commitf13f58eb867c763e6ed1c3b674fd99b1081a0664 (patch)
treec0ccc70b8fdf4362bce26efa0a5bb1c435f98575
parent767b122ea026099e17a2ffde30e6718d2abf150f (diff)
Support complex types in interface operation inputs
Issue-ID: SDC-3897 Change-Id: Ieac2d74ad340de1d9f6e4cd3ac830e2ec8c35d5b Signed-off-by: andre.schmid <andre.schmid@est.tech> Signed-off-by: vasraz <vasyl.razinkov@est.tech> Signed-off-by: MichaelMorris <michael.morris@est.tech>
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java10
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java17
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java3
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java5
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java69
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java9
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java104
-rw-r--r--catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java87
-rw-r--r--catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverterTest.java95
-rw-r--r--catalog-ui/package.json4
-rw-r--r--catalog-ui/src/app/app.ts2
-rw-r--r--catalog-ui/src/app/models/data-types-map.ts10
-rw-r--r--catalog-ui/src/app/models/data-types.ts35
-rw-r--r--catalog-ui/src/app/models/interfaceOperation.ts28
-rw-r--r--catalog-ui/src/app/models/properties-inputs/property-be-model.ts56
-rw-r--r--catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html2
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts55
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.html69
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.less64
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.spec.ts67
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.ts210
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html119
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.less123
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.spec.ts55
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts245
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.html36
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.less36
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.spec.ts69
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.ts125
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html45
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.less72
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.ts48
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html41
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less13
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts109
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts26
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/panel-tab.component.ts16
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts49
-rw-r--r--catalog-ui/src/app/ng2/services/data-type.service.ts4
-rw-r--r--catalog-ui/src/app/services/data-types-service.ts33
-rw-r--r--catalog-ui/src/assets/languages/en_US.json1149
-rw-r--r--catalog-ui/src/main.ts29
-rw-r--r--common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java11
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java32
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java25
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java11
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java100
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java134
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java160
49 files changed, 2740 insertions, 1176 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java
index 8f580382d2..cbf14da3fd 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java
@@ -60,6 +60,7 @@ import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
import org.openecomp.sdc.be.user.UserBusinessLogic;
import org.openecomp.sdc.common.api.Constants;
import org.openecomp.sdc.common.datastructure.Wrapper;
+import org.openecomp.sdc.common.util.ValidationUtils;
import org.openecomp.sdc.exception.ResponseFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,7 +68,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Path("/v1/catalog/{componentType}/{componentId}/componentInstance/{componentInstanceId}/interfaceOperation")
-@Tags({@Tag(name = "SDCE-2 APIs")})
+@Tag(name = "SDCE-2 APIs")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Controller
@@ -104,11 +105,14 @@ public class ComponentInterfaceOperationServlet extends AbstractValidationsServl
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response updateComponentInstanceInterfaceOperation(
@Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
- ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType,
+ ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") String componentType,
@Parameter(description = "Component Id") @PathParam("componentId") String componentId,
@Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId,
@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
+ userId = ValidationUtils.sanitizeInputString(userId);
+ componentType = ValidationUtils.sanitizeInputString(componentType);
+ componentInstanceId = ValidationUtils.sanitizeInputString(componentInstanceId);
LOGGER.debug(MODIFIER_ID_IS, userId);
final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId);
final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
@@ -118,7 +122,7 @@ public class ComponentInterfaceOperationServlet extends AbstractValidationsServl
}
final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
if (bytes == null || bytes.length == 0) {
- LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID);
+ LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, "content is empty");
return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
}
final String data = new String(bytes);
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java
index 919a5bca00..64e61699ed 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java
@@ -155,9 +155,9 @@ public class InterfacesOperationsConverter {
return false;
}
- private static String getInputValue(String inputValue) {
- String toscaInputValue = inputValue;
- if (Objects.nonNull(inputValue) && inputValue.contains(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) {
+ private static String getInputValue(final OperationInputDefinition input) {
+ String inputValue = input.getValue() == null ? input.getToscaDefaultValue(): input.getValue();
+ if (inputValue != null && inputValue.contains(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) {
Gson gson = new Gson();
Map<String, List<String>> consumptionValue = gson.fromJson(inputValue, Map.class);
List<String> mappedOutputValue = consumptionValue.get(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName());
@@ -166,9 +166,9 @@ public class InterfacesOperationsConverter {
String interfaceName = interfaceType.substring(interfaceType.lastIndexOf('.') + 1);
mappedOutputValue.remove(1);
mappedOutputValue.add(1, interfaceName);
- toscaInputValue = gson.toJson(consumptionValue);
+ inputValue = gson.toJson(consumptionValue);
}
- return toscaInputValue;
+ return inputValue;
}
private static String getInterfaceType(Component component, String interfaceType) {
@@ -384,12 +384,7 @@ public class InterfacesOperationsConverter {
toscaInput.setDescription(input.getDescription());
toscaInput.setType(input.getType());
toscaInput.setRequired(input.isRequired());
- if (isServiceProxyInterface) {
- String inputValue = Objects.nonNull(input.getValue()) ? getInputValue(input.getValue()) : getInputValue(input.getToscaDefaultValue());
- toscaInput.setDefaultp(propertyConvertor.convertToToscaObject(input, inputValue, dataTypes, false));
- } else {
- toscaInput.setDefaultp(propertyConvertor.convertToToscaObject(input, getInputValue(input.getToscaDefaultValue()), dataTypes, false));
- }
+ toscaInput.setDefaultp(propertyConvertor.convertToToscaObject(input, getInputValue(input), dataTypes, false));
toscaInputs.put(input.getName(), toscaInput);
}
toscaOperation.setInputs(toscaInputs);
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java
index 89ff754933..5d3fe1bf77 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java
@@ -53,7 +53,6 @@ import org.springframework.stereotype.Service;
public class PropertyConvertor {
private static final Logger log = Logger.getLogger(PropertyConvertor.class);
- private JsonParser jsonParser = new JsonParser();
public Either<ToscaNodeType, ToscaError> convertProperties(Component component, ToscaNodeType toscaNodeType,
Map<String, DataTypeDefinition> dataTypes) {
@@ -145,7 +144,7 @@ public class PropertyConvertor {
StringReader reader = new StringReader(value);
JsonReader jsonReader = new JsonReader(reader);
jsonReader.setLenient(true);
- jsonElement = jsonParser.parse(jsonReader);
+ jsonElement = JsonParser.parseReader(jsonReader);
if (value.equals("")) {
return value;
}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java
index d20f1c0600..e55a92dd0b 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java
@@ -206,8 +206,7 @@ class InterfacesOperationsConverterTest {
ToscaNodeType nodeType = new ToscaNodeType();
interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
- ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
- interfacesOperationsConverter, null);
+ ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null, null, null);
ToscaTemplate template = new ToscaTemplate("testService");
Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
nodeTypes.put(NODE_TYPE_NAME, nodeType);
@@ -493,7 +492,7 @@ class InterfacesOperationsConverterTest {
private ListDataDefinition<OperationInputDefinition> createInputs(Component component, int numOfInputs) {
ListDataDefinition<OperationInputDefinition> operationInputDefinitionList = new ListDataDefinition<>();
for (int i = 0; i < numOfInputs; i++) {
- String mappedPropertyName = java.util.UUID.randomUUID().toString() + "." + MAPPED_PROPERTY_NAME + i;
+ String mappedPropertyName = java.util.UUID.randomUUID() + "." + MAPPED_PROPERTY_NAME + i;
operationInputDefinitionList.add(createMockOperationInputDefinition(
INPUT_NAME_PREFIX + inputTypes[i] + "_" + i, mappedPropertyName, i));
addMappedPropertyAsComponentInput(component, mappedPropertyName);
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java
index 05ff278fc0..36c9eb8288 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java
@@ -20,25 +20,21 @@
package org.openecomp.sdc.be.tosca;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import fj.data.Either;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.MockitoAnnotations;
import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
import org.openecomp.sdc.be.model.DataTypeDefinition;
@@ -48,16 +44,17 @@ import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
import org.openecomp.sdc.be.tosca.model.ToscaProperty;
-@RunWith(MockitoJUnitRunner.class)
-public class PropertyConvertorTest {
+class PropertyConvertorTest {
+
private PropertyDefinition property;
private Map<String, DataTypeDefinition> dataTypes;
@InjectMocks
private PropertyConvertor propertyConvertor;
- @Before
+ @BeforeEach
public void setUp(){
+ MockitoAnnotations.openMocks(this);
property = new PropertyDefinition();
property.setName("myProperty");
property.setType(ToscaPropertyType.INTEGER.getType());
@@ -66,7 +63,7 @@ public class PropertyConvertorTest {
}
@Test
- public void testConvertProperty() {
+ void testConvertProperty() {
SchemaDefinition schema = new SchemaDefinition();
schema.setProperty(property);
@@ -76,14 +73,14 @@ public class PropertyConvertorTest {
}
@Test
- public void convertPropertyWhenValueAndDefaultNull() {
+ void convertPropertyWhenValueAndDefaultNull() {
ToscaProperty prop = propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY);
assertNotNull(prop);
assertNull(prop.getDefaultp());
}
@Test
- public void convertPropertyWhenValueNullAndDefaultNotEmpty() {
+ void convertPropertyWhenValueNullAndDefaultNotEmpty() {
final String def = "1";
property.setDefaultValue(def);
ToscaProperty result = propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY);
@@ -92,7 +89,7 @@ public class PropertyConvertorTest {
}
@Test
- public void convertPropertyWithMetadata() {
+ void convertPropertyWithMetadata() {
Map<String, String> metadata = new HashMap<>();
metadata.put("key1", "value");
property.setMetadata(metadata);
@@ -102,7 +99,7 @@ public class PropertyConvertorTest {
}
@Test
- public void convertPropertiesWhenValueAndDefaultNullInOne() {
+ void convertPropertiesWhenValueAndDefaultNullInOne() {
PropertyDefinition property1 = new PropertyDefinition();
property1.setName("otherProperty");
property1.setType(ToscaPropertyType.INTEGER.getType());
@@ -126,7 +123,7 @@ public class PropertyConvertorTest {
}
@Test
- public void convertPropertiesWhenValueAndDefaultExist() {
+ void convertPropertiesWhenValueAndDefaultExist() {
PropertyDefinition property1 = new PropertyDefinition();
property1.setName("otherProperty");
property1.setType(ToscaPropertyType.INTEGER.getType());
@@ -147,7 +144,7 @@ public class PropertyConvertorTest {
}
@Test
- public void convertPropertiesWhenValueAndDefaultNullInAll() {
+ void convertPropertiesWhenValueAndDefaultNullInAll() {
PropertyDefinition property1 = new PropertyDefinition();
property1.setName("otherProperty");
property1.setType(ToscaPropertyType.INTEGER.getType());
@@ -166,23 +163,25 @@ public class PropertyConvertorTest {
}
@Test
- public void convertPropertyWhichStartsWithSemiColon() throws Exception {
- PropertyDefinition property1 = new PropertyDataDefinitionBuilder()
- .setDefaultValue("::")
- .setType(ToscaPropertyType.STRING.getType())
- .build();
- ToscaProperty toscaProperty = propertyConvertor.convertProperty(Collections.emptyMap(), property1, PropertyConvertor.PropertyType.PROPERTY);
- assertThat(toscaProperty.getDefaultp()).isEqualTo("::");
+ void convertPropertyWhichStartsWithSemiColon() {
+ final PropertyDefinition property = new PropertyDataDefinitionBuilder()
+ .setDefaultValue("::")
+ .setType(ToscaPropertyType.STRING.getType())
+ .build();
+ final ToscaProperty toscaProperty =
+ propertyConvertor.convertProperty(Collections.emptyMap(), property, PropertyConvertor.PropertyType.PROPERTY);
+ assertEquals("::", toscaProperty.getDefaultp());
}
@Test
- public void convertPropertyWhichStartsWithSlash() throws Exception {
- PropertyDefinition property1 = new PropertyDataDefinitionBuilder()
- .setDefaultValue("/")
- .setType(ToscaPropertyType.STRING.getType())
- .build();
- ToscaProperty toscaProperty = propertyConvertor.convertProperty(Collections.emptyMap(), property1, PropertyConvertor.PropertyType.PROPERTY);
- assertThat(toscaProperty.getDefaultp()).isEqualTo("/");
+ void convertPropertyWhichStartsWithSlash() {
+ final PropertyDefinition property = new PropertyDataDefinitionBuilder()
+ .setDefaultValue("/")
+ .setType(ToscaPropertyType.STRING.getType())
+ .build();
+ final ToscaProperty toscaProperty =
+ propertyConvertor.convertProperty(Collections.emptyMap(), property, PropertyConvertor.PropertyType.PROPERTY);
+ assertEquals("/", toscaProperty.getDefaultp());
}
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java
index 1d0354f749..9ee287b333 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java
@@ -43,8 +43,7 @@ import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
public class ToscaMapValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter {
private static final Logger log = Logger.getLogger(ToscaMapValueConverter.class.getName());
- private static ToscaMapValueConverter mapConverter = new ToscaMapValueConverter();
- private JsonParser jsonParser = new JsonParser();
+ private static final ToscaMapValueConverter mapConverter = new ToscaMapValueConverter();
private ToscaMapValueConverter() {
}
@@ -56,7 +55,7 @@ public class ToscaMapValueConverter extends ToscaValueBaseConverter implements T
@Override
public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
if (value == null) {
- return value;
+ return null;
}
try {
ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
@@ -85,12 +84,12 @@ public class ToscaMapValueConverter extends ToscaValueBaseConverter implements T
return value;
}
}
- JsonElement jsonElement = null;
+ JsonElement jsonElement;
try {
StringReader reader = new StringReader(value);
JsonReader jsonReader = new JsonReader(reader);
jsonReader.setLenient(true);
- jsonElement = jsonParser.parse(jsonReader);
+ jsonElement = JsonParser.parseReader(jsonReader);
} catch (JsonSyntaxException e) {
log.debug("convertToToscaValue failed to parse json value :", e);
return null;
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java
index b0598971df..ee254811b1 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java
@@ -26,11 +26,9 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
@@ -82,74 +80,54 @@ public class ToscaValueBaseConverter {
return result;
}
- public Object handleComplexJsonValue(JsonElement elementValue) {
- Object jsonValue = null;
- Map<String, Object> value = new HashMap<>();
- if (elementValue.isJsonObject()) {
- JsonObject jsonOb = elementValue.getAsJsonObject();
- Set<Entry<String, JsonElement>> entrySet = jsonOb.entrySet();
- Iterator<Entry<String, JsonElement>> iteratorEntry = entrySet.iterator();
- while (iteratorEntry.hasNext()) {
- Entry<String, JsonElement> entry = iteratorEntry.next();
- if (entry.getValue().isJsonArray()) {
- List<Object> array = handleJsonArray(entry.getValue());
- value.put(entry.getKey(), array);
- } else {
- Object object;
- if (entry.getValue().isJsonPrimitive()) {
- object = json2JavaPrimitive(entry.getValue().getAsJsonPrimitive());
- } else {
- object = handleComplexJsonValue(entry.getValue());
- }
- value.put(entry.getKey(), object);
- }
- }
- jsonValue = value;
- } else {
- if (elementValue.isJsonArray()) {
- jsonValue = handleJsonArray(elementValue);
- } else {
- if (elementValue.isJsonPrimitive()) {
- jsonValue = json2JavaPrimitive(elementValue.getAsJsonPrimitive());
- } else {
- log.debug("not supported json type ");
- }
- }
+ public Object handleComplexJsonValue(final JsonElement jsonElement) {
+ if (jsonElement.isJsonNull()) {
+ return null;
+ }
+ if (jsonElement.isJsonObject()) {
+ return handleJsonObject(jsonElement);
}
- return jsonValue;
+ if (jsonElement.isJsonArray()) {
+ return handleJsonArray(jsonElement);
+ }
+ if (jsonElement.isJsonPrimitive()) {
+ return json2JavaPrimitive(jsonElement.getAsJsonPrimitive());
+ }
+ log.debug("JSON type '{}' not supported", jsonElement);
+ return null;
}
- private List<Object> handleJsonArray(JsonElement entry) {
- List<Object> array = new ArrayList<>();
- JsonArray jsonArray = entry.getAsJsonArray();
- Iterator<JsonElement> iterator = jsonArray.iterator();
- while (iterator.hasNext()) {
- Object object;
- JsonElement element = iterator.next();
- if (element.isJsonPrimitive()) {
- object = json2JavaPrimitive(element.getAsJsonPrimitive());
- } else {
- object = handleComplexJsonValue(element);
- }
- array.add(object);
+ private Map<String, Object> handleJsonObject(final JsonElement jsonElement) {
+ final Map<String, Object> jsonObjectAsMap = new HashMap<>();
+ final JsonObject jsonObject = jsonElement.getAsJsonObject();
+ for (final Entry<String, JsonElement> entry : jsonObject.entrySet()) {
+ jsonObjectAsMap.put(entry.getKey(), handleComplexJsonValue(entry.getValue()));
}
- return array;
+ return jsonObjectAsMap;
}
- public Object json2JavaPrimitive(JsonPrimitive prim) {
- if (prim.isBoolean()) {
- return prim.getAsBoolean();
- } else if (prim.isString()) {
- return prim.getAsString();
- } else if (prim.isNumber()) {
- String strRepesentation = prim.getAsString();
- if (strRepesentation.contains(".")) {
- return prim.getAsDouble();
- } else {
- return prim.getAsInt();
+ private List<Object> handleJsonArray(final JsonElement entry) {
+ final List<Object> jsonAsArray = new ArrayList<>();
+ final JsonArray jsonArray = entry.getAsJsonArray();
+ for (final JsonElement jsonElement : jsonArray) {
+ jsonAsArray.add(handleComplexJsonValue(jsonElement));
+ }
+ return jsonAsArray;
+ }
+
+ public Object json2JavaPrimitive(final JsonPrimitive jsonPrimitive) {
+ if (jsonPrimitive.isBoolean()) {
+ return jsonPrimitive.getAsBoolean();
+ }
+ if (jsonPrimitive.isString()) {
+ return jsonPrimitive.getAsString();
+ }
+ if (jsonPrimitive.isNumber()) {
+ if (jsonPrimitive.getAsString().contains(".")) {
+ return jsonPrimitive.getAsDouble();
}
- } else {
- throw new IllegalStateException();
+ return jsonPrimitive.getAsInt();
}
+ throw new IllegalStateException(String.format("JSON primitive not supported: %s", jsonPrimitive));
}
}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java
index cf2172d2b0..5d933ea3f6 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java
@@ -20,31 +20,36 @@
package org.openecomp.sdc.be.model.tosca.converters;
-import com.google.gson.JsonObject;
-import org.junit.Before;
-import org.junit.Test;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import com.google.gson.JsonObject;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-public class DataTypePropertyConverterTest {
+class DataTypePropertyConverterTest {
- private static final String EMPTY_JSON_STR = "{}";
- public static final String PROPERTY2_DEFAULT = "{\"prop1\":\"def1\",\"prop3\":\"def3\"}";
- private DataTypePropertyConverter testInstance = DataTypePropertyConverter.getInstance();
- private Map<String, DataTypeDefinition> dataTypes;
- private DataTypeDefinition noDefaultValue, dataType1, dataType2, dataType3;
- private PropertyDefinition prop1, prop2, prop3, noDefaultProp;
+ private static final DataTypePropertyConverter dataTypePropertyConverter = DataTypePropertyConverter.getInstance();
+ private static final String PROPERTY2_DEFAULT = "{\"prop1\":\"def1\",\"prop3\":\"def3\"}";
- @Before
- public void setUp() throws Exception {
+ private Map<String, DataTypeDefinition> dataTypes;
+ private DataTypeDefinition noDefaultValue;
+ private DataTypeDefinition dataType2;
+ private DataTypeDefinition dataType3;
+ private PropertyDefinition prop1;
+ private PropertyDefinition prop2;
+ private PropertyDefinition prop3;
+ private PropertyDefinition noDefaultProp;
+
+ @BeforeEach
+ void setUp() {
dataTypes = new HashMap<>();
prop1 = new PropertyDefinition();
@@ -65,7 +70,7 @@ public class DataTypePropertyConverterTest {
noDefaultValue = new DataTypeDefinition();
noDefaultValue.setProperties(Collections.singletonList(noDefaultProp));
- dataType1 = new DataTypeDefinition();
+ DataTypeDefinition dataType1 = new DataTypeDefinition();
dataType1.setProperties(Arrays.asList(prop1, prop3));
dataType2 = new DataTypeDefinition();
@@ -82,51 +87,51 @@ public class DataTypePropertyConverterTest {
}
@Test
- public void testGetPropertyDefaultValuesRec_dataTypeNotExist() throws Exception {
- String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("someType", dataTypes);
+ void testGetPropertyDefaultValuesRec_dataTypeNotExist() {
+ String defaultValue = dataTypePropertyConverter.getDataTypePropertiesDefaultValuesRec("someType", dataTypes);
assertNull(defaultValue);
}
@Test
- public void testGetPropertyDefaultValuesRec_NoDefaultValue() throws Exception {
- String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("noDefault", dataTypes);
+ void testGetPropertyDefaultValuesRec_NoDefaultValue() {
+ String defaultValue = dataTypePropertyConverter.getDataTypePropertiesDefaultValuesRec("noDefault", dataTypes);
assertNull(defaultValue);
}
@Test
- public void testGetPropertyDefaultValuesRec() throws Exception {
- String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType1", dataTypes);
+ void testGetPropertyDefaultValuesRec() {
+ String defaultValue = dataTypePropertyConverter.getDataTypePropertiesDefaultValuesRec("dataType1", dataTypes);
assertEquals(PROPERTY2_DEFAULT, defaultValue);
}
@Test
- public void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType_derivedDataTypeHasNoDefaults() throws Exception {
+ void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType_derivedDataTypeHasNoDefaults() {
dataType2.setDerivedFrom(noDefaultValue);
- String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes);
+ String defaultValue = dataTypePropertyConverter.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes);
assertNull(defaultValue);
}
@Test
- public void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType() throws Exception {
- String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes);
+ void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType() {
+ String defaultValue = dataTypePropertyConverter.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes);
assertEquals(PROPERTY2_DEFAULT, defaultValue);
}
@Test
- public void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties_dataTypeOfPropertyHasNoDefault() throws Exception {
+ void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties_dataTypeOfPropertyHasNoDefault() {
dataType3.getProperties().get(0).setType(noDefaultValue.getName());
- String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes);
+ String defaultValue = dataTypePropertyConverter.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes);
assertNull(defaultValue);
}
@Test
- public void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties() throws Exception {
- String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes);
+ void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties() {
+ String defaultValue = dataTypePropertyConverter.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes);
assertEquals("{\"prop2\":" + PROPERTY2_DEFAULT + "}", defaultValue);//data type 3 has property prop2 which has a data type with property prop1 which has a default value
}
@Test
- public void testMergeDefaultValues_allDefaultValuesAreOverridden() throws Exception {
+ void testMergeDefaultValues_allDefaultValuesAreOverridden() {
JsonObject value = new JsonObject();
value.addProperty(noDefaultProp.getName(), "override1");
@@ -144,12 +149,12 @@ public class DataTypePropertyConverterTest {
String valBeforeMerge = value.toString();
- testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
+ dataTypePropertyConverter.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
assertEquals(valBeforeMerge, value.toString());
}
@Test
- public void testMergeDefaultValues() throws Exception {
+ void testMergeDefaultValues() {
JsonObject value = new JsonObject();
value.addProperty(noDefaultProp.getName(), "override1");
@@ -158,23 +163,23 @@ public class DataTypePropertyConverterTest {
value.add(prop2.getName(), prop1Val);
- testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
+ dataTypePropertyConverter.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
assertEquals("{\"noDefaultProp\":\"override1\",\"prop2\":{\"prop1\":\"prop1Override\",\"prop3\":\"def3\"}}",
value.toString());//expect to merge prop 3 default as it was not overridden
}
@Test
- public void testMergeDefaultValues_mergeAll() throws Exception {
+ void testMergeDefaultValues_mergeAll() {
JsonObject value = new JsonObject();
- testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
+ dataTypePropertyConverter.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
assertEquals("{\"prop2\":" + PROPERTY2_DEFAULT + "}",
value.toString());//expect to merge prop 3 default as it was not overridden
}
@Test
- public void testMergeDefaultValues_doNotAddDefaultsForGetInputValues() throws Exception {
+ void testMergeDefaultValues_doNotAddDefaultsForGetInputValues() {
JsonObject getInputValue = new JsonObject();
getInputValue.addProperty("get_input", "in1");
@@ -182,13 +187,13 @@ public class DataTypePropertyConverterTest {
JsonObject value = new JsonObject();
value.add(prop2.getName(), getInputValue);
- testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
+ dataTypePropertyConverter.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
assertEquals("{\"prop2\":{\"get_input\":\"in1\"}}", value.toString());
}
@Test
- public void testMergeDefaultValues_doNotAddDefaultsForGetInputInnerValues() throws Exception {
+ void testMergeDefaultValues_doNotAddDefaultsForGetInputInnerValues() {
JsonObject getInputValue = new JsonObject();
getInputValue.addProperty("get_input", "in1");
@@ -198,7 +203,7 @@ public class DataTypePropertyConverterTest {
JsonObject value = new JsonObject();
value.add(prop2.getName(), prop1Val);
- testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
+ dataTypePropertyConverter.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes);
assertEquals("{\"prop2\":{\"prop1\":{\"get_input\":\"in1\"},\"prop3\":\"def3\"}}", value.toString());
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverterTest.java
index 0923f8e49f..179d3cf7a1 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverterTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverterTest.java
@@ -20,41 +20,46 @@
package org.openecomp.sdc.be.model.tosca.converters;
-import com.google.gson.JsonPrimitive;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import org.junit.jupiter.api.Test;
-
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
-public class ToscaValueBaseConverterTest {
+class ToscaValueBaseConverterTest {
- private ToscaValueBaseConverter converter = new ToscaValueBaseConverter();
+ private final ToscaValueBaseConverter converter = new ToscaValueBaseConverter();
@Test
- public void testJson2JavaPrimitive() throws Exception {
+ void testJson2JavaPrimitive() {
JsonPrimitive prim1 = new JsonPrimitive(Boolean.FALSE);
Object res1 = converter.json2JavaPrimitive(prim1);
assertFalse((Boolean)res1);
JsonPrimitive prim2 = new JsonPrimitive("Test");
Object res2 = converter.json2JavaPrimitive(prim2);
- assertTrue(res2.equals("Test"));
+ assertEquals("Test", res2);
JsonPrimitive prim3 = new JsonPrimitive(3);
Object res3 = converter.json2JavaPrimitive(prim3);
- assertTrue((Integer)res3 == 3);
+ assertEquals(3, (int) (Integer) res3);
JsonPrimitive prim4 = new JsonPrimitive(3.6);
Object res4 = converter.json2JavaPrimitive(prim4);
- assertTrue((Double)res4 == 3.6);
+ assertEquals(3.6, (Double) res4);
}
@Test
- public void testIsEmptyObjectValue() throws Exception {
+ void testIsEmptyObjectValue() {
boolean res1 = ToscaValueBaseConverter.isEmptyObjectValue(null);
assertTrue(res1);
@@ -70,4 +75,74 @@ public class ToscaValueBaseConverterTest {
boolean res5 = ToscaValueBaseConverter.isEmptyObjectValue("test");
assertFalse(res5);
}
+
+ @Test
+ void testHandleComplexJsonValue() {
+ JsonObject innerObject = new JsonObject();
+ innerObject.addProperty("string", "stringValue");
+ innerObject.addProperty("int", 1);
+ innerObject.addProperty("float", 1.1);
+ innerObject.add("null", null);
+
+ JsonArray jsonArray1 = new JsonArray();
+ jsonArray1.add(innerObject);
+ jsonArray1.add(innerObject);
+ jsonArray1.add(innerObject);
+
+ JsonArray jsonArray2 = new JsonArray();
+ jsonArray2.add("value0");
+ jsonArray2.add("value1");
+ jsonArray2.add("value2");
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.add("objectProperty", innerObject);
+ jsonObject.add("arrayProperty1", jsonArray1);
+ jsonObject.add("arrayProperty2", jsonArray2);
+ jsonObject.addProperty("stringProperty", "stringPropertyValue");
+
+ final Object resultingObject = converter.handleComplexJsonValue(jsonObject);
+ assertTrue(resultingObject instanceof Map);
+ final Map<String, Object> jsonObjectAsMap = (Map<String, Object>) resultingObject;
+ assertEquals(4, jsonObjectAsMap.keySet().size());
+ assertTrue(jsonObjectAsMap.containsKey("objectProperty"));
+ assertTrue(jsonObjectAsMap.containsKey("arrayProperty1"));
+ assertTrue(jsonObjectAsMap.containsKey("arrayProperty2"));
+ assertTrue(jsonObjectAsMap.containsKey("stringProperty"));
+
+ final String stringProperty = (String) jsonObjectAsMap.get("stringProperty");
+ assertEquals(jsonObject.get("stringProperty").getAsString(), stringProperty);
+
+ final Object arrayProperty1 = jsonObjectAsMap.get("arrayProperty1");
+ assertTrue(arrayProperty1 instanceof List);
+ final List<Object> arrayProperty1AsList = (List<Object>) arrayProperty1;
+ assertEquals(3, arrayProperty1AsList.size());
+ for (int i = 0; i < arrayProperty1AsList.size(); i++) {
+ final Object actualElement = arrayProperty1AsList.get(i);
+ assertTrue(actualElement instanceof Map);
+ final Map<String, Object> actualElementAsMap = (Map<String, Object>) actualElement;
+ final JsonObject expectedJsonObject = jsonArray1.get(i).getAsJsonObject();
+ assertEquals(expectedJsonObject.get("string").getAsString(), actualElementAsMap.get("string"));
+ assertEquals(expectedJsonObject.get("int").getAsInt(), actualElementAsMap.get("int"));
+ assertEquals(expectedJsonObject.get("float").getAsDouble(), actualElementAsMap.get("float"));
+ assertNull(actualElementAsMap.get("null"));
+ }
+
+ final Object arrayProperty2 = jsonObjectAsMap.get("arrayProperty2");
+ assertTrue(arrayProperty2 instanceof List);
+ final List<String> arrayProperty2AsList = (List<String>) arrayProperty2;
+ assertEquals(3, arrayProperty2AsList.size());
+ for (int i = 0; i < arrayProperty2AsList.size(); i++) {
+ assertEquals("value" + i, arrayProperty2AsList.get(i));
+ }
+
+ final Object objectProperty = jsonObjectAsMap.get("objectProperty");
+ assertTrue(objectProperty instanceof Map);
+ final Map<String, Object> objectPropertyAsMap = (Map<String, Object>) objectProperty;
+ assertEquals(4, objectPropertyAsMap.keySet().size());
+ assertTrue(objectPropertyAsMap.containsKey("string"));
+ assertEquals(innerObject.get("string").getAsString(), objectPropertyAsMap.get("string"));
+ assertEquals(innerObject.get("int").getAsInt(), objectPropertyAsMap.get("int"));
+ assertEquals(innerObject.get("float").getAsDouble(), objectPropertyAsMap.get("float"));
+ assertNull(objectPropertyAsMap.get("null"));
+ }
}
diff --git a/catalog-ui/package.json b/catalog-ui/package.json
index 5f0b12deb6..92e6ef4e01 100644
--- a/catalog-ui/package.json
+++ b/catalog-ui/package.json
@@ -116,7 +116,7 @@
"angular-tooltips": "0.1.23",
"angular-translate": "^2.15.1",
"angular-translate-loader-static-files": "^2.15.1",
- "angular-ui-bootstrap": "1.3.3",
+ "angular-ui-bootstrap": "2.5.0",
"angular-ui-notification": "^0.3.6",
"angular-ui-router": "^0.4.2",
"angular-uuid4": "^0.3.1",
@@ -137,7 +137,7 @@
"lodash": "^4.17.2",
"ng-infinite-scroll": "^1.3.0",
"ngx-drag-drop": "v2.0.0-rc.4",
- "onap-ui-angular": "5.2.5",
+ "onap-ui-angular": "5.4.4",
"perfect-scrollbar": "^0.6.16",
"protractor": "7.0.0",
"qtip2": "^3.0.3",
diff --git a/catalog-ui/src/app/app.ts b/catalog-ui/src/app/app.ts
index ffa43895a7..e7e2828eb5 100644
--- a/catalog-ui/src/app/app.ts
+++ b/catalog-ui/src/app/app.ts
@@ -675,7 +675,7 @@ ng1appModule.run([
// $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';
$http.defaults.headers.common[cookieService.getUserIdSuffix()] = cookieService.getUserId();
- DataTypesService.fetchDataTypesByModel(null);
+ DataTypesService.loadDataTypesCache(null);
//handle stateChangeStart
let internalDeregisterStateChangeStartWatcher: Function = (): void => {
diff --git a/catalog-ui/src/app/models/data-types-map.ts b/catalog-ui/src/app/models/data-types-map.ts
index 3591bc2705..e7b1c6922a 100644
--- a/catalog-ui/src/app/models/data-types-map.ts
+++ b/catalog-ui/src/app/models/data-types-map.ts
@@ -25,13 +25,13 @@
import {DataTypeModel} from "./data-types";
export class DataTypesMapData {
- [dataTypeId:string]:Array<DataTypeModel>;
+ [dataTypeId: string]: Array<DataTypeModel>;
}
export class DataTypesMap {
- dataTypesMap:DataTypesMapData;
+ dataTypesMap: DataTypesMapData;
- constructor(dataTypesMap:DataTypesMapData) {
- this.dataTypesMap = dataTypesMap;
- }
+ constructor(dataTypesMap: DataTypesMapData) {
+ this.dataTypesMap = dataTypesMap;
+ }
}
diff --git a/catalog-ui/src/app/models/data-types.ts b/catalog-ui/src/app/models/data-types.ts
index 7004b43cbc..7fc788bf93 100644
--- a/catalog-ui/src/app/models/data-types.ts
+++ b/catalog-ui/src/app/models/data-types.ts
@@ -25,6 +25,7 @@
import {PropertyBEModel} from "./properties-inputs/property-be-model";
import {AttributeBEModel} from "./attributes-outputs/attribute-be-model";
import {Model} from "./model";
+import {PROPERTY_DATA} from "../utils/constants";
export class DataTypeModel {
@@ -39,16 +40,24 @@ export class DataTypeModel {
attributes: Array<AttributeBEModel>;
model: Model;
- constructor(dataType:DataTypeModel) {
+ constructor(dataType: DataTypeModel) {
if (dataType) {
this.uniqueId = dataType.uniqueId;
this.name = dataType.name;
this.derivedFromName = dataType.derivedFromName;
+ if (dataType.derivedFrom) {
+ this.derivedFrom = new DataTypeModel(dataType.derivedFrom);
+ }
this.creationTime = dataType.creationTime;
this.modificationTime = dataType.modificationTime;
- this.properties = dataType.properties;
+ if (dataType.properties) {
+ this.properties = [];
+ dataType.properties.forEach(property => {
+ this.properties.push(new PropertyBEModel(property));
+ });
+ }
this.attributes = dataType.attributes;
- this.model = this.model;
+ this.model = dataType.model;
}
}
@@ -56,5 +65,25 @@ export class DataTypeModel {
return this;
};
+
+ /**
+ * Parses the default value to JSON.
+ */
+ public parseDefaultValueToJson(): any {
+ if (PROPERTY_DATA.TYPES.indexOf(this.name) > -1) {
+ return undefined;
+ }
+ const defaultValue = {};
+ if (this.properties) {
+ this.properties.forEach(property => {
+ const propertyDefaultValue = property.parseDefaultValueToJson();
+ if (propertyDefaultValue != undefined) {
+ defaultValue[property.name] = propertyDefaultValue;
+ }
+ });
+ }
+
+ return defaultValue === {} ? undefined : defaultValue;
+ }
}
diff --git a/catalog-ui/src/app/models/interfaceOperation.ts b/catalog-ui/src/app/models/interfaceOperation.ts
index 109babb068..9d8ab366a2 100644
--- a/catalog-ui/src/app/models/interfaceOperation.ts
+++ b/catalog-ui/src/app/models/interfaceOperation.ts
@@ -20,21 +20,47 @@
'use strict';
import {ArtifactModel} from "./artifacts";
+import {SchemaPropertyGroupModel} from "./schema-property";
+import {PROPERTY_DATA, PROPERTY_TYPES} from "../utils/constants";
export class InputOperationParameter {
name: string;
type: string;
+ schema: SchemaPropertyGroupModel;
inputId: string;
toscaDefaultValue?: string;
+ value?: any;
constructor(param?: any) {
if (param) {
this.name = param.name;
this.type = param.type;
+ this.schema = param.schema;
this.inputId = param.inputId;
this.toscaDefaultValue = param.toscaDefaultValue;
+ this.value = param.value;
+ }
+ }
+
+ public getDefaultValue(): any {
+ if (this.isTypeNotSimple()) {
+ if (this.toscaDefaultValue) {
+ this.toscaDefaultValue = JSON.parse(this.toscaDefaultValue);
+ return JSON.parse(this.toscaDefaultValue);
+ }
+ switch (this.type) {
+ case PROPERTY_TYPES.LIST:
+ return [];
+ default:
+ return {};
+ }
}
- console.info("InputOperationParameter Constructor: ", param)
+
+ return this.toscaDefaultValue;
+ }
+
+ private isTypeNotSimple() {
+ return PROPERTY_DATA.SIMPLE_TYPES.indexOf(this.type) == -1;
}
}
diff --git a/catalog-ui/src/app/models/properties-inputs/property-be-model.ts b/catalog-ui/src/app/models/properties-inputs/property-be-model.ts
index bd65c3a70a..267a2adc71 100644
--- a/catalog-ui/src/app/models/properties-inputs/property-be-model.ts
+++ b/catalog-ui/src/app/models/properties-inputs/property-be-model.ts
@@ -109,15 +109,61 @@ export class PropertyBEModel {
return temp;
}
- public getDerivedPropertyType = () => {
+ public getDerivedPropertyType = (): DerivedPropertyType => {
if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(this.type) > -1) {
return DerivedPropertyType.SIMPLE;
- } else if (this.type === PROPERTY_TYPES.LIST) {
+ }
+ if (this.type === PROPERTY_TYPES.LIST) {
return DerivedPropertyType.LIST;
- } else if (this.type === PROPERTY_TYPES.MAP) {
+ }
+ if (this.type === PROPERTY_TYPES.MAP) {
return DerivedPropertyType.MAP;
- } else {
- return DerivedPropertyType.COMPLEX;
+ }
+ return DerivedPropertyType.COMPLEX;
+ }
+
+ /**
+ * Parses default value to JSON.
+ */
+ public parseDefaultValueToJson(): any {
+ if (this.defaultValue == undefined) {
+ return undefined;
+ }
+
+ const propertyType: DerivedPropertyType = this.getDerivedPropertyType();
+ if (propertyType == DerivedPropertyType.SIMPLE) {
+ return this.parseDefaultSimpleValue();
+ }
+
+ try {
+ return JSON.parse(this.defaultValue);
+ } catch (e) {
+ console.error(`Could not parse the property of type '${this.type}' default value to JSON '${this.defaultValue}'`, e);
+ }
+
+ return undefined;
+ }
+
+ private parseDefaultSimpleValue() {
+ switch (this.type) {
+ case PROPERTY_TYPES.INTEGER:
+ try {
+ return parseInt(this.defaultValue);
+ } catch (e) {
+ console.error(`Could not parse the property of type '${this.type}' default value to int '${this.defaultValue}'`, e);
+ }
+ return undefined;
+ case PROPERTY_TYPES.FLOAT:
+ try {
+ return parseFloat(this.defaultValue);
+ } catch (e) {
+ console.error(`Could not parse the property of type '${this.type}' default value to float '${this.defaultValue}'`, e);
+ }
+ return undefined;
+ case PROPERTY_TYPES.BOOLEAN:
+ return this.defaultValue === 'true';
+ default:
+ return this.defaultValue;
}
}
diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
index e1638fb00f..7c83c55ae6 100644
--- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
@@ -117,7 +117,7 @@
<!-- Value -->
<div class="table-cell valueCol" [class.inner-table-container]="input.childrenProperties || !input.isSimpleType">
<dynamic-element class="value-input"
- *ngIf="checkInstanceFePropertiesMapIsFilled() && input.isSimpleType"
+
pattern="validationUtils.getValidationPattern(input.type)"
[value]="input.defaultValueObj"
[type]="input.type"
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts
index 60d66788ac..b14d0dda65 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts
@@ -22,31 +22,17 @@
import {Component, ComponentRef, Inject, Input} from '@angular/core';
import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
import {TranslateService} from "../../../shared/translator/translate.service";
-import {ModalService } from 'app/ng2/services/modal.service';
-import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component';
-import {
- Component as TopologyTemplate
-} from "../../../../models/components/component";
+import {ModalService} from 'app/ng2/services/modal.service';
+import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
+import {Component as TopologyTemplate} from "../../../../models/components/component";
import {PluginsService} from "app/ng2/services/plugins.service";
import {SelectedComponentType} from "../common/store/graph.actions";
import {WorkspaceService} from "../../workspace/workspace.service";
-import {
- ComponentInstanceInterfaceModel,
- InterfaceOperationModel
-} from "../../../../models/interfaceOperation";
-import {
- InterfaceOperationHandlerComponent
-} from "./operation-creator/interface-operation-handler.component";
-
-import {
- ButtonModel,
- ComponentMetadata,
- InterfaceModel,
- InputBEModel,
- ModalModel,
- ComponentInstance, ArtifactModel
-} from 'app/models';
+import {ComponentInstanceInterfaceModel, InterfaceOperationModel} from "../../../../models/interfaceOperation";
+import {InterfaceOperationHandlerComponent} from "./operation-creator/interface-operation-handler.component";
+
+import {ArtifactModel, ButtonModel, ComponentInstance, ComponentMetadata, InputBEModel, InterfaceModel, ModalModel} from 'app/models';
import {ArtifactGroupType} from "../../../../utils/constants";
import {DropdownValue} from "../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
import {ToscaArtifactService} from "../../../services/tosca-artifact.service";
@@ -86,12 +72,14 @@ export class UIInterfaceOperationModel extends InterfaceOperationModel {
class ModalTranslation {
EDIT_TITLE: string;
CANCEL_BUTTON: string;
+ CLOSE_BUTTON: string;
SAVE_BUTTON: string;
constructor(private TranslateService: TranslateService) {
this.TranslateService.languageChangedObservable.subscribe(lang => {
this.EDIT_TITLE = this.TranslateService.translate('INTERFACE_EDIT_TITLE');
this.CANCEL_BUTTON = this.TranslateService.translate("INTERFACE_CANCEL_BUTTON");
+ this.CLOSE_BUTTON = this.TranslateService.translate("INTERFACE_CLOSE_BUTTON");
this.SAVE_BUTTON = this.TranslateService.translate("INTERFACE_SAVE_BUTTON");
});
}
@@ -135,7 +123,7 @@ export class InterfaceOperationsComponent {
toscaArtifactTypes: Array<DropdownValue> = [];
@Input() component: ComponentInstance;
- @Input() readonly: boolean;
+ @Input() isViewOnly: boolean;
@Input() enableMenuItems: Function;
@Input() disableMenuItems: Function;
@Input() componentType: SelectedComponentType;
@@ -209,14 +197,23 @@ export class InterfaceOperationsComponent {
}
private enableOrDisableSaveButton = (): boolean => {
- return this.modalInstance.instance.dynamicContent.instance.readonly;
+ return this.isViewOnly;
}
onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
- const cancelButton: ButtonModel = new ButtonModel(this.modalTranslation.CANCEL_BUTTON, 'outline white', this.cancelAndCloseModal);
- const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue', () =>
- this.updateInterfaceOperation(), this.enableOrDisableSaveButton);
- const modalModel: ModalModel = new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', [saveButton, cancelButton], 'custom');
+
+ const buttonList = [];
+ if (this.isViewOnly) {
+ const closeButton: ButtonModel = new ButtonModel(this.modalTranslation.CLOSE_BUTTON, 'outline white', this.cancelAndCloseModal);
+ buttonList.push(closeButton);
+ } else {
+ const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue', () =>
+ this.updateInterfaceOperation(), this.enableOrDisableSaveButton);
+ const cancelButton: ButtonModel = new ButtonModel(this.modalTranslation.CANCEL_BUTTON, 'outline white', this.cancelAndCloseModal);
+ buttonList.push(saveButton);
+ buttonList.push(cancelButton);
+ }
+ const modalModel: ModalModel = new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', buttonList, 'custom');
this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
this.modalServiceNg2.addDynamicContentToModal(
@@ -228,7 +225,7 @@ export class InterfaceOperationsComponent {
selectedInterface: interfaceModel,
selectedInterfaceOperation: operation,
validityChangedCallback: this.enableOrDisableSaveButton,
- isViewOnly: false
+ isViewOnly: this.isViewOnly
}
);
this.modalInstance.instance.open();
@@ -241,7 +238,7 @@ export class InterfaceOperationsComponent {
private updateInterfaceOperation() {
this.isLoading = true;
- let operationUpdated = this.modalInstance.instance.dynamicContent.instance.operationToUpdate;
+ const operationUpdated: InterfaceOperationModel = this.modalInstance.instance.dynamicContent.instance.operationToUpdate;
this.topologyTemplateService.updateComponentInstanceInterfaceOperation(
this.componentMetaData.uniqueId,
this.componentMetaData.componentType,
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.html
new file mode 100644
index 0000000000..6753b82167
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.html
@@ -0,0 +1,69 @@
+<!--
+ ~ -
+ ~ ============LICENSE_START=======================================================
+ ~ Copyright (C) 2022 Nordix Foundation.
+ ~ ================================================================================
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ ~ ============LICENSE_END=========================================================
+ -->
+
+<div>
+ <div *ngIf="!isView && showAddLink" class="add-button-container">
+ <a class="add-btn" data-tests-id="add-input.add-input-link"
+ (click)="showAddInput()">{{'OPERATION_ADD_INPUT' | translate}}
+ </a>
+ </div>
+ <form *ngIf="showForm" [formGroup]="inputForm" (ngSubmit)="onSubmit()">
+ <label class="occurrences-label">{{'ADD_INPUT_TITLE' | translate}}</label>
+ <div>
+ <label class="sdc-input-label" for="input-name">{{'OPERATION_INPUT_NAME' | translate}}</label>
+ <input id="input-name" class="sdc-input" type="text" formControlName="name" data-tests-id="add-input.input-name"/>
+ </div>
+ <div>
+ <label class="sdc-input-label" for="input-type">{{'OPERATION_INPUT_TYPE' | translate}}</label>
+ <sdc-combo-box
+ id="input-type"
+ [placeHolder]="inputToAdd.type != undefined ? inputToAdd.type : 'Select...'"
+ [data]="inputTypeOptions"
+ [selectedValue]="inputToAdd.type"
+ (itemSelected)="onChangeInputType($event)"
+ [testId]="'add-input.input-type'"
+ [disabled]="isView"
+ >
+ </sdc-combo-box>
+ </div>
+ <div *ngIf="showInputSchema">
+ <label class="sdc-input-label" for="input-schema">{{'OPERATION_INPUT_SCHEMA' | translate}}</label>
+ <sdc-combo-box
+ id="input-schema"
+ [placeHolder]="getSchemaPlaceholder()"
+ [data]="inputSchemaOptions"
+ [selectedValue]="getSchemaType()"
+ (itemSelected)="onChangeInputSchema($event)"
+ [testId]="'add-input.input-schema'"
+ [disabled]="isView"
+ >
+ </sdc-combo-box>
+ </div>
+ <div class="confirmation-button-container" *ngIf="!isView">
+ <button type="submit" class="tlv-btn blue" [disabled]="!inputForm.valid" data-tests-id="add-input.add-input-btn">
+ {{'OPERATION_ADD_INPUT' | translate}}
+ </button>
+ <button type="button" class="tlv-btn outline white" (click)="onCancel()" data-tests-id="add-input.cancel-btn">
+ {{'OPERATION_CANCEL' | translate}}
+ </button>
+ </div>
+ </form>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.less
new file mode 100644
index 0000000000..5eb4a7f5b1
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.less
@@ -0,0 +1,64 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+.add-button-container {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-end;
+ margin: 7px 5px 7px 0;
+}
+
+.confirmation-button-container {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-end;
+ margin: 7px 5px 7px 0;
+ button {
+ margin: 0 5px;
+ }
+}
+
+.sdc-input-label {
+ margin-bottom: 5px;
+ display: block;
+ font-family: OpenSans-Semibold, Arial, sans-serif;
+ font-style: normal;
+ font-weight: 600;
+ font-size: 12px;
+}
+
+.sdc-input {
+ box-sizing: border-box;
+ padding: 0 10px;
+ height: 38px;
+ width: 100%;
+ border: solid 1px #d2d2d2;
+ border-radius: 2px;
+ color: #5a5a5a;
+}
+
+.add-param-link {
+
+}
+
+.add-btn {
+
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.spec.ts
new file mode 100644
index 0000000000..2c6c1e6614
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.spec.ts
@@ -0,0 +1,67 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {AddInputComponent} from './add-input.component';
+import {TranslateModule} from '../../../../../shared/translator/translate.module';
+import {ReactiveFormsModule} from '@angular/forms';
+import {SdcUiComponentsModule} from 'onap-ui-angular/dist';
+import {Observable} from 'rxjs/Observable';
+import {DataTypesMap} from '../../../../../../models/data-types-map';
+import {TranslateService} from '../../../../../shared/translator/translate.service';
+
+const translateServiceMock: Partial<TranslateService> = {
+ translate: jest.fn((str: string) => {
+ })
+};
+
+describe('AddInputComponent', () => {
+ let component: AddInputComponent;
+ let fixture: ComponentFixture<AddInputComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AddInputComponent ],
+ imports: [
+ TranslateModule,
+ SdcUiComponentsModule,
+ ReactiveFormsModule
+ ],
+ providers: [
+ { provide: TranslateService, useValue: translateServiceMock }
+ ]
+ })
+ .compileComponents();
+
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AddInputComponent);
+ component = fixture.componentInstance;
+ component.dataTypeMap$ = new Observable<DataTypesMap>();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.ts
new file mode 100644
index 0000000000..6632d1a69e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.ts
@@ -0,0 +1,210 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {InputOperationParameter} from '../../../../../../models/interfaceOperation';
+import {IDropDownOption} from 'onap-ui-angular/dist/form-elements/dropdown/dropdown-models';
+import {Observable} from 'rxjs/Observable';
+import {AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators} from '@angular/forms';
+import {PROPERTY_TYPES} from '../../../../../../utils/constants';
+import {SchemaProperty, SchemaPropertyGroupModel} from '../../../../../../models/schema-property';
+import {DataTypeModel} from "../../../../../../models/data-types";
+
+@Component({
+ selector: 'app-add-input',
+ templateUrl: './add-input.component.html',
+ styleUrls: ['./add-input.component.less']
+})
+export class AddInputComponent implements OnInit {
+
+ @Input('dataTypeMap') dataTypeMap$: Observable<Map<string, DataTypeModel>>;
+ @Input('isView') isView: boolean;
+ @Input() existingInputNames: Array<string> = [];
+ @Output('onAddInput') onAddInputEvent: EventEmitter<InputOperationParameter>;
+
+ dataTypeMap: Map<string, DataTypeModel>;
+ inputToAdd: InputOperationParameter;
+ inputTypeOptions: Array<IDropDownOption>;
+ inputSchemaOptions: Array<IDropDownOption>;
+ showForm: boolean = false;
+ showAddLink: boolean = true;
+ showInputSchema: boolean = false;
+
+ inputForm: FormGroup;
+
+ constructor() {
+ this.onAddInputEvent = new EventEmitter<InputOperationParameter>();
+ this.inputTypeOptions = [];
+ this.inputSchemaOptions = [];
+ this.inputToAdd = new InputOperationParameter();
+ }
+
+ schemaValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
+ const type = control.get('type');
+ const schema = control.get('schema');
+ return (type.value === 'list' || type.value === 'map') && !schema.value ? { schemaRequired: true } : null;
+ };
+
+ uniqueNameValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
+ const name = control.get('name');
+ return this.existingInputNames.indexOf(name.value) === -1 ? null : { nameIsNotUnique: true };
+ };
+
+ ngOnInit() {
+ this.initForm();
+ this.initInputType();
+ }
+
+ private initForm() {
+ this.inputForm = new FormGroup({
+ name: new FormControl({value: '', disabled: this.isView}, [Validators.required, Validators.minLength(1)]),
+ type: new FormControl({value: '', disabled: this.isView}, [Validators.required, Validators.minLength(1)]),
+ schema: new FormControl({value: '', disabled: this.isView})
+ }, { validators: [this.schemaValidator, this.uniqueNameValidator] });
+ }
+
+ private initInputType() {
+ this.dataTypeMap$.subscribe((dataTypesMap: Map<string, DataTypeModel>) => {
+ this.dataTypeMap = dataTypesMap;
+ this.inputTypeOptions = [];
+ this.inputSchemaOptions = [];
+ dataTypesMap.forEach((value, key) => {
+ const entry = {label: key, value: key};
+ this.inputTypeOptions.push(entry);
+ if (key != PROPERTY_TYPES.LIST && key != PROPERTY_TYPES.MAP) {
+ this.inputSchemaOptions.push(entry);
+ }
+ });
+ });
+ }
+
+ onChangeInputType(inputType) {
+ const typeForm = this.inputForm.get('type');
+ if (!inputType) {
+ this.inputToAdd.type = undefined;
+ typeForm.setValue(undefined);
+ this.toggleInputSchema();
+ return;
+ }
+ typeForm.setValue(inputType);
+ this.inputToAdd.type = inputType;
+ this.toggleInputSchema();
+ }
+
+ onChangeInputSchema(inputSchema: string) {
+ const schemaForm = this.inputForm.get('schema');
+ if (!inputSchema) {
+ this.inputToAdd.schema = undefined;
+ schemaForm.setValue(undefined);
+ return;
+ }
+ schemaForm.setValue(inputSchema);
+ this.inputToAdd.schema = new SchemaPropertyGroupModel();
+ this.inputToAdd.schema.property = new SchemaProperty();
+ this.inputToAdd.schema.property.type = inputSchema;
+ }
+
+ onSubmit() {
+ this.trimForm();
+ if (this.inputForm.valid) {
+ const nameForm = this.inputForm.get('name');
+ const typeForm = this.inputForm.get('type');
+ const schemaForm = this.inputForm.get('schema');
+ const input = new InputOperationParameter();
+ input.name = nameForm.value;
+ input.type = typeForm.value;
+ if (this.typeHasSchema()) {
+ input.schema = new SchemaPropertyGroupModel();
+ input.schema.property = new SchemaProperty();
+ input.schema.property.type = schemaForm.value;
+ }
+ input.inputId = this.generateUniqueId();
+ this.onAddInputEvent.emit(input);
+ this.hideAddInput();
+ this.resetForm();
+ }
+ }
+
+ showAddInput() {
+ this.showForm = true;
+ this.showAddLink = false;
+ }
+
+ hideAddInput() {
+ this.showForm = false;
+ this.showAddLink = true;
+ }
+
+ onCancel() {
+ this.hideAddInput();
+ this.resetForm();
+ }
+
+ private generateUniqueId(): string {
+ let result = '';
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ const charactersLength = characters.length;
+ for (let i = 0; i < 36; i++ ) {
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
+ }
+ return result;
+ }
+
+ private resetForm() {
+ this.inputForm.reset();
+ this.showInputSchema = false;
+ this.inputToAdd = new InputOperationParameter();
+ }
+
+ getSchemaType() {
+ return this.inputToAdd.schema == undefined ? undefined : this.inputToAdd.schema.property.type;
+ }
+
+ getSchemaPlaceholder() {
+ const schemaType = this.getSchemaType();
+ return schemaType === undefined ? 'Select...' : schemaType;
+ }
+
+ private toggleInputSchema() {
+ this.showInputSchema = this.typeHasSchema();
+ }
+
+ private typeHasSchema() {
+ const typeForm = this.inputForm.get('type');
+ return typeForm.value == PROPERTY_TYPES.LIST || typeForm.value == PROPERTY_TYPES.MAP;
+ }
+
+ private trimForm() {
+ const nameForm = this.inputForm.get('name');
+ if (nameForm.value) {
+ nameForm.setValue(nameForm.value.trim());
+ }
+ const typeForm = this.inputForm.get('type');
+ if (typeForm.value) {
+ typeForm.setValue(typeForm.value.trim());
+ }
+ const schemaForm = this.inputForm.get('schema');
+ if (schemaForm.value) {
+ schemaForm.setValue(schemaForm.value.trim());
+ }
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html
new file mode 100644
index 0000000000..0449da7d05
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html
@@ -0,0 +1,119 @@
+<!--
+ ~ -
+ ~ ============LICENSE_START=======================================================
+ ~ Copyright (C) 2022 Nordix Foundation.
+ ~ ================================================================================
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ ~ ============LICENSE_END=========================================================
+ -->
+
+<li [class.root]="isRoot()">
+ <span class="input-info">
+ <em class="sprite-new round-expand-icon" [class.open]="isExpanded" (click)="expandAndCollapse()"></em>
+ <label class="input-label">{{name}}:</label> <em data-tests-id="input-type">{{resolveType()}}</em>
+ <span class="sprite-new delete-btn" *ngIf="showInputDelete()" (click)="onInputDelete()"></span>
+ <span class="sprite-new delete-btn" *ngIf="showListItemDelete()" (click)="onChildListItemDelete()"></span>
+ </span>
+ <ng-container *ngIf="isTypeSimple(type.name)">
+ <ul *ngIf="isExpanded">
+ <li class="input-value">
+ <ng-container *ngIf="isViewOnly">
+ {{valueObjRef}}<em class="empty-value" *ngIf="!valueObjRef">empty</em>
+ </ng-container>
+ <input *ngIf="!isViewOnly" [type]="getSimpleValueInputType()" name="value"
+ [(ngModel)]="valueObjRef"
+ (ngModelChange)="onValueChange($event)"
+ />
+ </li>
+ </ul>
+ </ng-container>
+ <ng-container *ngIf="isTypeComplex(type.name)" >
+ <ul *ngIf="isExpanded">
+ <ng-container *ngFor="let property of this.type.properties">
+ <app-input-list-item
+ [name]="property.name"
+ [type]="getDataType(property.type)"
+ [dataTypeMap]="dataTypeMap"
+ [valueObjRef]="valueObjRef[property.name]"
+ [schema]="property.schema"
+ [nestingLevel]="nestingLevel + 1"
+ [isViewOnly]="isViewOnly"
+ (onValueChange)="onPropertyValueChange($event)">
+ </app-input-list-item>
+ </ng-container>
+ </ul>
+ </ng-container>
+ <ng-container *ngIf="isTypeList(type.name)">
+ <ul *ngIf="isExpanded">
+ <ng-container *ngFor="let value1 of valueObjRef; index as i; trackBy: trackByIndex">
+ <li class="input-value" *ngIf="isTypeSimple(schema.property.type)">
+ <ng-container *ngIf="isViewOnly">
+ {{valueObjRef[i]}}
+ </ng-container>
+ <input type="text" *ngIf="!isViewOnly"
+ [(ngModel)]="valueObjRef[i]" (ngModelChange)="onListValueChange()" />
+ <span class="sprite-new delete-btn" *ngIf="!isViewOnly" (click)="onListItemDelete(i)"></span>
+ </li>
+ <app-input-list-item *ngIf="!isTypeSimple(schema.property.type)"
+ [name]="i+''"
+ [type]="getDataType(schema.property.type)"
+ [dataTypeMap]="dataTypeMap"
+ [valueObjRef]="valueObjRef[i]"
+ [schema]="schema"
+ [nestingLevel]="nestingLevel + 1"
+ [listIndex]="i"
+ [isListChild]="true"
+ [isViewOnly]="isViewOnly"
+ (onValueChange)="onPropertyValueChange($event)"
+ (onChildListItemDelete)="onListItemDelete($event)">
+ </app-input-list-item>
+ </ng-container>
+ <li class="input-value" *ngIf="!isViewOnly">
+ <a class="add-btn" (click)="addListElement()">{{'INPUT_LIST_ADD_LIST_ENTRY' | translate}}</a>
+ </li>
+ </ul>
+ </ng-container>
+ <ng-container *ngIf="isTypeMap(type.name)">
+ <ul *ngIf="isExpanded">
+ <ng-container *ngFor="let key of getObjectEntries(valueObjRef); index as i">
+ <li class="input-value" *ngIf="isTypeSimple(schema.property.type)">
+ <label class="input-label">{{key}}:</label>
+ <ng-container *ngIf="isViewOnly">
+ {{valueObjRef[key]}}
+ </ng-container>
+ <input type="text" *ngIf="!isViewOnly" [(ngModel)]="valueObjRef[key]" (ngModelChange)="onMapValueChange()"/>
+ <span class="sprite-new delete-btn" *ngIf="!isViewOnly" (click)="onMapKeyDelete(key)"></span>
+ </li>
+ <app-input-list-item
+ *ngIf="!isTypeSimple(schema.property.type)"
+ [name]="key"
+ [type]="getDataType(schema.property.type)"
+ [dataTypeMap]="dataTypeMap"
+ [valueObjRef]="valueObjRef[key]"
+ [schema]="schema"
+ [isMapChild]="true"
+ [nestingLevel]="nestingLevel + 1"
+ [isViewOnly]="isViewOnly"
+ (onValueChange)="onPropertyValueChange($event)"
+ (onDelete)="onMapKeyDelete($event)">
+ </app-input-list-item>
+ </ng-container>
+ <li class="input-value" *ngIf="!isViewOnly">
+ <input type="text" [(ngModel)]="mapEntryName" placeholder="{{ 'INPUT_LIST_MAP_KEY_PLACEHOLDER' | translate }}"/>
+ <a class="add-btn" (click)="addMapEntry()">{{ 'INPUT_LIST_ADD_MAP_ENTRY' | translate }}</a>
+ </li>
+ </ul>
+ </ng-container>
+</li> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.less
new file mode 100644
index 0000000000..cb7346e390
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.less
@@ -0,0 +1,123 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+* {
+ font-size: 0.875rem;
+}
+
+.input-info {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ gap: 10px;
+ font-family: OpenSans-Regular, sans-serif;
+ font-weight: 400;
+}
+
+.input-label {
+ margin: 0;
+ font-weight: bold;
+}
+
+.input-value {
+ display: flex;
+ flex-flow: row nowrap;
+ gap: 7px;
+
+ input {
+ min-width: 150px;
+ max-width: 250px;
+ }
+}
+
+.input-map-key {
+ input {
+ max-width: 150px;
+ }
+}
+
+.input-action-container {
+ flex-grow: 1;
+ margin-left: auto;
+}
+
+.input-action {
+ flex-grow: 2
+}
+
+ul {
+ margin: 0 0 0 20px;
+ list-style: none;
+ line-height: 2em;
+}
+
+li {
+ position: relative;
+
+ &:before {
+ position: absolute;
+ left: -15px;
+ top: 0;
+ content: '';
+ display: block;
+ border-left: 1px solid #ddd;
+ height: 1em;
+ border-bottom: 1px solid #ddd;
+ width: 10px;
+ }
+
+ &:after {
+ position: absolute;
+ left: -15px;
+ bottom: -7px;
+ content: '';
+ display: block;
+ border-left: 1px solid #ddd;
+ height: 100%;
+ }
+
+ &.root {
+ margin: 0 0 0 -20px;
+
+ &:before {
+ display: none;
+ }
+
+ &:after {
+ display: none;
+ }
+ }
+
+ &:last-child {
+ &:after {
+ display: none
+ }
+ }
+}
+
+label {
+ margin: 0;
+ font-weight: normal;
+}
+
+.empty-value {
+ color: #aaaaaa;
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.spec.ts
new file mode 100644
index 0000000000..b7e34e5c32
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.spec.ts
@@ -0,0 +1,55 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {InputListItemComponent} from './input-list-item.component';
+import {TranslateModule} from '../../../../../../shared/translator/translate.module';
+import {FormsModule} from '@angular/forms';
+import {DataTypeModel} from '../../../../../../../models/data-types';
+
+describe('InputListItemComponent', () => {
+ let component: InputListItemComponent;
+ let fixture: ComponentFixture<InputListItemComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ InputListItemComponent ],
+ imports: [
+ TranslateModule,
+ FormsModule
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(InputListItemComponent);
+ component = fixture.componentInstance;
+ component.valueObjRef = "";
+ component.type = new DataTypeModel(undefined);
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeDefined();
+ });
+});
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts
new file mode 100644
index 0000000000..cd75fe87e6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts
@@ -0,0 +1,245 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {DataTypeModel} from '../../../../../../../models/data-types';
+import {SchemaPropertyGroupModel} from '../../../../../../../models/schema-property';
+import {DerivedPropertyType, PropertyBEModel} from '../../../../../../../models/properties-inputs/property-be-model';
+import {PROPERTY_DATA, PROPERTY_TYPES} from '../../../../../../../utils/constants';
+
+@Component({
+ selector: 'app-input-list-item',
+ templateUrl: './input-list-item.component.html',
+ styleUrls: ['./input-list-item.component.less']
+})
+export class InputListItemComponent implements OnInit {
+
+ @Input() valueObjRef: any;
+ @Input() name: string;
+ @Input() dataTypeMap: Map<string, DataTypeModel>;
+ @Input() type: DataTypeModel;
+ @Input() schema: SchemaPropertyGroupModel;
+ @Input() nestingLevel: number;
+ @Input() isListChild: boolean = false;
+ @Input() isMapChild: boolean = false;
+ @Input() listIndex: number;
+ @Input() isViewOnly: boolean;
+ @Output('onValueChange') onValueChangeEvent: EventEmitter<any> = new EventEmitter<any>();
+ @Output('onDelete') onDeleteEvent: EventEmitter<string> = new EventEmitter<string>();
+ @Output('onChildListItemDelete') onChildListItemDeleteEvent: EventEmitter<number> = new EventEmitter<number>();
+
+ isExpanded: boolean = false;
+ mapEntryName: string;
+
+ ngOnInit() {
+ if (!this.nestingLevel) {
+ this.nestingLevel = 0;
+ }
+ if (this.type.properties) {
+ this.type.properties.forEach(property => {
+ this.initEmptyPropertyInValueObjRef(property);
+ });
+ }
+ }
+
+ private initEmptyPropertyInValueObjRef(property: PropertyBEModel) {
+ if (this.valueObjRef[property.name] == undefined) {
+ if (this.isTypeComplex(property.type) || this.isTypeMap(property.type)) {
+ this.valueObjRef[property.name] = {};
+ } else if (this.isTypeList(property.type)) {
+ this.valueObjRef[property.name] = [];
+ } else {
+ this.valueObjRef[property.name] = null;
+ }
+ }
+ }
+
+ getType(typeName: string): DerivedPropertyType {
+ if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(typeName) > -1) {
+ return DerivedPropertyType.SIMPLE;
+ } else if (typeName === PROPERTY_TYPES.LIST) {
+ return DerivedPropertyType.LIST;
+ } else if (typeName === PROPERTY_TYPES.MAP) {
+ return DerivedPropertyType.MAP;
+ } else {
+ return DerivedPropertyType.COMPLEX;
+ }
+ }
+
+ isTypeSimple(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.SIMPLE;
+ }
+
+ isTypeList(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.LIST;
+ }
+
+ isTypeMap(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.MAP;
+ }
+
+ isTypeComplex(typeName: string): boolean {
+ return !this.isTypeSimple(typeName) && !this.isTypeList(typeName) && !this.isTypeMap(typeName);
+ }
+
+ expandAndCollapse() {
+ this.isExpanded = !this.isExpanded;
+ }
+
+ getDataType(type: string) {
+ return this.dataTypeMap.get(type);
+ }
+
+ onValueChange(value: any): void {
+ if (this.type.name == PROPERTY_TYPES.INTEGER || this.type.name == PROPERTY_TYPES.FLOAT) {
+ this.emitValueChangeEvent(this.parseNumber(value));
+ return;
+ }
+ if (this.type.name == PROPERTY_TYPES.BOOLEAN) {
+ this.emitValueChangeEvent(this.parseBoolean(value));
+ return;
+ }
+ this.emitValueChangeEvent(value);
+ }
+
+ onListValueChange(): void {
+ this.emitValueChangeEvent(this.valueObjRef);
+ }
+
+ onPropertyValueChange($event: any) {
+ this.valueObjRef[$event.name] = $event.value;
+ this.emitValueChangeEvent(this.valueObjRef);
+ }
+
+ private emitValueChangeEvent(value: any) {
+ this.onValueChangeEvent.emit({
+ name: this.name,
+ value: value
+ });
+ }
+
+ isRoot(): boolean {
+ return this.nestingLevel === 0;
+ }
+
+ showListItemDelete(): boolean {
+ return !this.isViewOnly && (this.isListChild && this.nestingLevel > 0);
+ }
+
+ showInputDelete(): boolean {
+ return !this.isViewOnly && (this.isRoot() || this.isMapChild);
+ }
+
+ resolveType(): string {
+ if (this.isTypeList(this.type.name)) {
+ return `list of value type ${this.schema.property.type}`
+ }
+ if (this.isTypeMap(this.type.name)) {
+ return `map of 'string' keys and '${this.schema.property.type}' values`
+ }
+ return this.type.name;
+ }
+
+ onInputDelete() {
+ this.onDeleteEvent.emit(this.name);
+ }
+
+ onListItemDelete(index: number): void {
+ this.valueObjRef.splice(index, 1);
+ this.emitValueChangeEvent(this.valueObjRef);
+ }
+
+ addListElement() {
+ if (this.isTypeSimple(this.schema.property.type)) {
+ this.valueObjRef.push('');
+ } else if (this.isTypeComplex(this.schema.property.type) || this.isTypeMap(this.schema.property.type)) {
+ this.valueObjRef.push({});
+ } else if (this.isTypeList(this.schema.property.type)) {
+ this.valueObjRef.push([]);
+ }
+ }
+
+ trackByIndex(index: number, value: string): number {
+ return index;
+ }
+
+ onChildListItemDelete() {
+ this.onChildListItemDeleteEvent.emit(this.listIndex);
+ }
+
+ getObjectEntries(valueObjRef: object) {
+ return Object.keys(valueObjRef);
+ }
+
+ onMapValueChange() {
+ this.emitValueChangeEvent(this.valueObjRef);
+ }
+
+ onMapKeyDelete(key: string) {
+ delete this.valueObjRef[key]
+ this.emitValueChangeEvent(this.valueObjRef);
+ }
+
+ addMapEntry() {
+ let newKey;
+ if (this.mapEntryName) {
+ newKey = this.mapEntryName.trim();
+ }
+ if (!newKey) {
+ return;
+ }
+ if (Object.keys(this.valueObjRef).indexOf(newKey) !== -1) {
+ return;
+ }
+ this.mapEntryName = '';
+ if (this.isTypeSimple(this.schema.property.type)) {
+ this.valueObjRef[newKey] = '';
+ } else if (this.isTypeComplex(this.schema.property.type) || this.isTypeMap(this.schema.property.type)) {
+ this.valueObjRef[newKey] = {};
+ } else if (this.isTypeList(this.schema.property.type)) {
+ this.valueObjRef[newKey] = [];
+ }
+ this.emitValueChangeEvent(this.valueObjRef);
+ }
+
+ getSimpleValueInputType() {
+ if (this.type.name == PROPERTY_TYPES.INTEGER || this.type.name == PROPERTY_TYPES.FLOAT) {
+ return 'number';
+ }
+ return 'text';
+ }
+
+ private parseBoolean(value: any) {
+ if (value === 'true') {
+ return true;
+ }
+ if (value === 'false') {
+ return false;
+ }
+ return null;
+ }
+
+ private parseNumber(value: any) {
+ const number = parseInt(value);
+ return isNaN(number) ? null : number;
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.html
new file mode 100644
index 0000000000..802bd63838
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.html
@@ -0,0 +1,36 @@
+<!--
+ ~ -
+ ~ ============LICENSE_START=======================================================
+ ~ Copyright (C) 2022 Nordix Foundation.
+ ~ ================================================================================
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ ~ ============LICENSE_END=========================================================
+ -->
+
+<label>{{ 'INPUT_LIST_TITLE' | translate }}</label>
+<div class="input-tree">
+ <ul *ngFor="let input of _inputs">
+ <app-input-list-item
+ [name]="input.name"
+ [type]="getDataType(input.type)"
+ [dataTypeMap]="dataTypeMap"
+ [valueObjRef]="input.value"
+ [schema]="input.schema"
+ [isViewOnly]="isViewOnly"
+ (onValueChange)="onValueChange($event)"
+ (onDelete)="onDelete($event)">
+ </app-input-list-item>
+ </ul>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.less
new file mode 100644
index 0000000000..b9784f9564
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.less
@@ -0,0 +1,36 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+.input-tree {
+ overflow: scroll;
+ max-height: 300px;
+ max-width: 100%;
+
+ ul {
+ margin: 0 0 0 20px;
+ list-style: none;
+ line-height: 2em;
+ }
+}
+
+.input-tree::-webkit-scrollbar-track {
+ border: 0;
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.spec.ts
new file mode 100644
index 0000000000..b07a4bb55f
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.spec.ts
@@ -0,0 +1,69 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {InputListComponent} from './input-list.component';
+import {TranslateModule} from '../../../../../shared/translator/translate.module';
+import {Component, Input} from '@angular/core';
+import {DataTypeModel} from '../../../../../../models/data-types';
+import {TranslateService} from '../../../../../shared/translator/translate.service';
+
+@Component({selector: 'app-input-list-item', template: ''})
+class InputListItemStubComponent {
+ @Input() name: string;
+ @Input() type: DataTypeModel;
+ @Input() dataTypeMap: any;
+ @Input() valueObjRef: any;
+ @Input() schema: any;
+ @Input() isViewOnly: boolean;
+}
+
+const translateServiceMock: Partial<TranslateService> = {
+ translate: jest.fn((str: string) => {
+ })
+};
+
+describe('InputListComponent', () => {
+ let component: InputListComponent;
+ let fixture: ComponentFixture<InputListComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ InputListComponent, InputListItemStubComponent ],
+ imports: [ TranslateModule ],
+ providers: [
+ { provide: TranslateService, useValue: translateServiceMock }
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(InputListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeDefined();
+ });
+});
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.ts
new file mode 100644
index 0000000000..72812d810d
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list.component.ts
@@ -0,0 +1,125 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, EventEmitter, Input, Output} from '@angular/core';
+import {InputOperationParameter} from "../../../../../../models/interfaceOperation";
+import {DataTypeModel} from "../../../../../../models/data-types";
+import {DerivedPropertyType} from "../../../../../../models/properties-inputs/property-be-model";
+import {PROPERTY_DATA, PROPERTY_TYPES} from "../../../../../../utils/constants";
+
+@Component({
+ selector: 'input-list',
+ templateUrl: './input-list.component.html',
+ styleUrls: ['./input-list.component.less']
+})
+export class InputListComponent {
+
+ @Input() set inputs(inputs: Array<InputOperationParameter>) {
+ this._inputs = new Array<InputOperationParameter>();
+ if (inputs) {
+ inputs.forEach(input => {
+ const inputCopy = new InputOperationParameter(input);
+ this.initValue(inputCopy);
+
+ this._inputs.push(inputCopy);
+ });
+ }
+ }
+ @Input() dataTypeMap: Map<string, DataTypeModel>;
+ @Input() isViewOnly: boolean;
+ @Output('onValueChange') inputValueChangeEvent: EventEmitter<InputOperationParameter> = new EventEmitter<InputOperationParameter>();
+ @Output('onDelete') inputDeleteEvent: EventEmitter<string> = new EventEmitter<string>();
+
+ _inputs: Array<InputOperationParameter>;
+
+ getDataType(type: string): DataTypeModel {
+ return this.dataTypeMap.get(type);
+ }
+
+ private initValue(input: InputOperationParameter): void {
+ if (input.value) {
+ try {
+ input.value = JSON.parse(input.value);
+ } catch (e) {
+ console.debug('Could not parse value', input.value, e);
+ }
+ return;
+ }
+
+ if (input.toscaDefaultValue) {
+ try {
+ input.value = JSON.parse(input.toscaDefaultValue);
+ return;
+ } catch (e) {
+ console.debug('Could not parse value', input.value, e);
+ }
+ }
+
+ if (this.isTypeComplex(input.type) || this.isTypeMap(input.type)) {
+ input.value = {};
+ } else if (this.isTypeList(input.type)) {
+ input.value = [];
+ } else {
+ input.value = undefined;
+ }
+ }
+
+ getType(typeName: string): DerivedPropertyType {
+ if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(typeName) > -1) {
+ return DerivedPropertyType.SIMPLE;
+ } else if (typeName === PROPERTY_TYPES.LIST) {
+ return DerivedPropertyType.LIST;
+ } else if (typeName === PROPERTY_TYPES.MAP) {
+ return DerivedPropertyType.MAP;
+ } else {
+ return DerivedPropertyType.COMPLEX;
+ }
+ }
+
+ isTypeSimple(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.SIMPLE;
+ }
+
+ isTypeList(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.LIST;
+ }
+
+ isTypeMap(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.MAP;
+ }
+
+ isTypeComplex(typeName: string): boolean {
+ return !this.isTypeSimple(typeName) && !this.isTypeList(typeName) && !this.isTypeMap(typeName);
+ }
+
+ onValueChange($event: any) {
+ const inputOperationParameter = this._inputs.find(input => input.name == $event.name);
+ if (inputOperationParameter) {
+ inputOperationParameter.value = $event.value;
+ this.inputValueChangeEvent.emit(new InputOperationParameter(inputOperationParameter));
+ }
+ }
+
+ onDelete(inputName: string) {
+ this.inputDeleteEvent.emit(inputName);
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html
deleted file mode 100644
index 156b657645..0000000000
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!--
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2021 Nordix Foundation. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- -->
-
-<div class="cell field-input-name">
- <sdc-input
- [(value)]="input.name"
- testId="interface-operation-input-name"
- (valueChange)="onChange()">
- </sdc-input>
-</div>
-
-<div class="cell field-input-value">
- <sdc-input
- [(value)]="input.toscaDefaultValue"
- testId="interface-operation-input-value"
- (valueChange)="onChange()">
- </sdc-input>
-</div>
-
-<div class="cell remove" *ngIf="!readonly">
- <svg-icon
- name="trash-o"
- mode="info"
- size="small"
- (click)="onRemoveInput(input)"
- [clickable]="true">
- </svg-icon>
-</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.less
deleted file mode 100644
index 12eacc6473..0000000000
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.less
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2021 Nordix Foundation. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-@import '../../../../../../../assets/styles/variables.less';
-
-.remove {
- display: flex;
- align-items: center;
- justify-content: center;
-
- svg-icon {
- position: relative;
- right: -3px;
-
- &:hover {
- cursor: pointer;
- }
- }
-}
-
-.cell {
- min-height: 50px;
- padding: 10px;
- display: flex;
- align-items: center;
-
- > * {
- flex-basis: 100%;
- }
-
- /deep/ select {
- height: 30px;
- }
-
- input {
- height: 30px;
- border: none;
- padding-left: 10px;
- }
-
- select {
- width: 100%;
- }
-
- &.field-property {
- &:last-child {
- flex: 1;
- }
-
- .no-properties-error {
- color: @func_color_q;
- font-style: italic;
- }
- }
-}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.ts
deleted file mode 100644
index 48bb804173..0000000000
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* ============LICENSE_START=======================================================
-* SDC
-* ================================================================================
-* Copyright (C) 2021 Nordix Foundation. All rights reserved.
-* ================================================================================
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-* SPDX-License-Identifier: Apache-2.0
-* ============LICENSE_END=========================================================
-*/
-
-import {Component, Input} from '@angular/core';
-import {InputOperationParameter} from "../../../../../../models/interfaceOperation";
-
-@Component({
- selector: 'input-param-row',
- templateUrl: './input-param-row.component.html',
- styleUrls: ['./input-param-row.component.less']
-})
-
-export class InputParamRowComponent {
- @Input() input: InputOperationParameter;
- @Input() onRemoveInput: Function;
- @Input() readonly: boolean;
- @Input() validityChanged: Function;
-
- constructor() {
- }
-
- ngOnInit() {
- this.validityChanged();
- }
-
- onChange() {
- this.validityChanged();
- }
-
-}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html
index 6dec4160f6..46db3b94a9 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html
@@ -124,32 +124,23 @@
</div>
</div>
</div>
-
- <div class="separator-buttons">
- <tab tabTitle="Inputs"></tab>
- <a class="add-param-link add-btn"
- [ngClass]="{'disabled': readonly || isViewOnly}"
- (click)="onAddInput()">{{'OPERATION_ADD_INPUT' | translate}}
- </a>
+ <div class="group-with-border content-row" *ngIf="dataTypeMap">
+ <input-list
+ [inputs]="inputs" [dataTypeMap]="dataTypeMap"
+ [isViewOnly]="isViewOnly"
+ (onValueChange)="onInputValueChange($event)"
+ (onDelete)="onInputDelete($event)"
+ >
+ </input-list>
</div>
-
- <div class="generic-table">
- <div class="header-row table-row">
- <span class="cell header-cell field-input-name">{{ 'OPERATION_PARAM_NAME' | translate }}</span>
- <span class="cell header-cell field-input-value">{{ 'OPERATION_INPUT_VALUE' | translate }}</span>
- <span class="cell header-cell remove">â—Źâ—Źâ—Ź</span>
- </div>
- <div class="empty-msg data-row" *ngIf="!inputs.length">
- <div>{{ 'OPERATION_INPUT_EMPTY' | translate }}</div>
- </div>
- <input-param-row
- *ngFor="let inputParameter of inputs"
- class="data-row"
- [input]="inputParameter"
- [onRemoveInput]="onRemoveInput"
- [validityChanged]="validityChanged">
- </input-param-row>
+ <div class="group-with-border content-row">
+ <app-add-input
+ [dataTypeMap]="dataTypeMap$"
+ [isView]="isViewOnly"
+ [existingInputNames]="collectInputNames()"
+ (onAddInput)="onAddInput($event)"
+ >
+ </app-add-input>
</div>
-
</form>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less
index 955720c49d..cb47c8d167 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less
@@ -28,10 +28,9 @@
padding-bottom: 20px;
.group-with-border {
- margin: 25px 0;
- padding: 15px 0;
+ margin: 10px 0;
+ padding: 10px 0;
border-top: 1px solid @tlv_color_u;
- border-bottom: 1px solid @tlv_color_u;
.content-row:not(:last-of-type) {
padding-bottom: 13px;
}
@@ -148,6 +147,14 @@
}
}
+ .input-param-component {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ padding: 14px;
+ }
+
.generic-table {
max-height: 244px;
min-height: 91px;
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts
index 1099391548..ed295e867c 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts
@@ -19,13 +19,9 @@
* ============LICENSE_END=========================================================
*/
-import {Component, EventEmitter, Output} from '@angular/core';
+import {Component, EventEmitter, Input, Output} from '@angular/core';
import {UIInterfaceModel} from "../interface-operations.component";
-import {
- InputOperationParameter,
- InterfaceOperationModel,
- IOperationParamsList
-} from "../../../../../models/interfaceOperation";
+import {InputOperationParameter, InterfaceOperationModel, IOperationParamsList} from "../../../../../models/interfaceOperation";
import {TranslateService} from "../../../../shared/translator/translate.service";
import {IDropDownOption} from "onap-ui-angular/dist/form-elements/dropdown/dropdown-models";
import {DropdownValue} from "../../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
@@ -33,6 +29,9 @@ import {ArtifactModel} from "../../../../../models/artifacts";
import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model";
import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
import {PropertyFEModel} from "../../../../../models/properties-inputs/property-fe-model";
+import {DataTypeService} from "../../../../services/data-type.service";
+import {Observable} from "rxjs/Observable";
+import {DataTypeModel} from "../../../../../models/data-types";
@Component({
selector: 'operation-handler',
@@ -40,10 +39,10 @@ import {PropertyFEModel} from "../../../../../models/properties-inputs/property-
styleUrls: ['./interface-operation-handler.component.less'],
providers: [TranslateService]
})
-
export class InterfaceOperationHandlerComponent {
- @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
+ @Input() private modelName: string;
+ @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
input: {
toscaArtifactTypes: Array<DropdownValue>;
selectedInterface: UIInterfaceModel;
@@ -52,6 +51,8 @@ export class InterfaceOperationHandlerComponent {
isViewOnly: boolean;
};
+ dataTypeMap$: Observable<Map<string, DataTypeModel>>;
+ dataTypeMap: Map<string, DataTypeModel>;
interfaceType: string;
artifactVersion: string;
artifactName: string;
@@ -70,23 +71,40 @@ export class InterfaceOperationHandlerComponent {
enableAddArtifactImplementation: boolean;
propertyValueValid: boolean = true;
+ inputTypeOptions: any[];
+
+ constructor(private dataTypeService: DataTypeService) {
+ this.dataTypeMap$ = new Observable<Map<string, DataTypeModel>>(subscriber => {
+ this.dataTypeService.findAllDataTypesByModel(this.modelName)
+ .then((dataTypesMap: Map<string, DataTypeModel>) => {
+ subscriber.next(dataTypesMap);
+ });
+ });
+ this.dataTypeMap$.subscribe(value => {
+ this.dataTypeMap = value;
+ });
+
+ }
ngOnInit() {
this.isViewOnly = this.input.isViewOnly;
this.interfaceType = this.input.selectedInterface.displayType();
- this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation);
+ this.operationToUpdate = this.input.selectedInterfaceOperation;
this.operationToUpdate.interfaceId = this.input.selectedInterface.uniqueId;
this.operationToUpdate.interfaceType = this.input.selectedInterface.type;
+ this.initInputs();
+ this.removeImplementationQuote();
+ this.validityChanged();
+ this.loadInterfaceOperationImplementation();
+ }
+
+ private initInputs() {
if (!this.operationToUpdate.inputs) {
this.operationToUpdate.inputs = new class implements IOperationParamsList {
listToscaDataDefinition: Array<InputOperationParameter> = [];
}
}
-
- this.inputs = this.operationToUpdate.inputs.listToscaDataDefinition;
- this.removeImplementationQuote();
- this.validityChanged();
- this.loadInterfaceOperationImplementation();
+ this.inputs = Array.from(this.operationToUpdate.inputs.listToscaDataDefinition);
}
private loadInterfaceOperationImplementation() {
@@ -160,11 +178,8 @@ export class InterfaceOperationHandlerComponent {
}
}
- onAddInput(inputOperationParameter?: InputOperationParameter): void {
- let newInput = new InputOperationParameter(inputOperationParameter)
- newInput.type = "string";
- newInput.inputId = this.generateUniqueId();
- this.inputs.push(newInput);
+ onAddInput(inputOperationParameter: InputOperationParameter) {
+ this.addInput(inputOperationParameter);
this.validityChanged();
}
@@ -196,16 +211,6 @@ export class InterfaceOperationHandlerComponent {
}
}
- private generateUniqueId = (): string => {
- let result = '';
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- const charactersLength = characters.length;
- for (let i = 0; i < 36; i++ ) {
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
- }
- return result;
- }
-
validityChanged = () => {
let validState = this.checkFormValidForSubmit();
this.input.validityChangedCallback(validState);
@@ -243,7 +248,7 @@ export class InterfaceOperationHandlerComponent {
}
private isParamsValid = (): boolean => {
- const isInputValid = (input) => input.name && input.inputId;
+ const isInputValid = (input) => input.name && input.inputId && input.type;
const isValid = this.inputs.every(isInputValid);
if (!isValid) {
this.readonly = true;
@@ -255,4 +260,48 @@ export class InterfaceOperationHandlerComponent {
return { value : val, label: val };
}
+ /**
+ * Handles the input value change event.
+ * @param changedInput the changed input
+ */
+ onInputValueChange(changedInput: InputOperationParameter) {
+ if (changedInput.value instanceof Object) {
+ changedInput.value = JSON.stringify(changedInput.value);
+ }
+ const inputOperationParameter = this.inputs.find(value => value.name == changedInput.name);
+ inputOperationParameter.value = changedInput.value;
+ }
+
+ /**
+ * Handles the add input event.
+ * @param input the input to add
+ * @private
+ */
+ private addInput(input: InputOperationParameter) {
+ this.operationToUpdate.inputs.listToscaDataDefinition.push(input);
+ this.inputs = Array.from(this.operationToUpdate.inputs.listToscaDataDefinition);
+ }
+
+ /**
+ * Return a list with current input names.
+ */
+ collectInputNames() {
+ return this.inputs.map((input) => input.name);
+ }
+
+ /**
+ * Handles the delete input event.
+ * @param inputName the name of the input to be deleted
+ */
+ onInputDelete(inputName: string) {
+ const currentInputs = this.operationToUpdate.inputs.listToscaDataDefinition;
+ const input1 = currentInputs.find(value => value.name === inputName);
+ const indexOfInput = currentInputs.indexOf(input1);
+ if (indexOfInput === -1) {
+ console.error(`Could delete input '${inputName}'. Input not found.`);
+ return;
+ }
+ currentInputs.splice(currentInputs.indexOf(input1), 1);
+ this.inputs = Array.from(currentInputs);
+ }
}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts
index 259530105c..b212eec034 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts
@@ -22,22 +22,27 @@
import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common";
-import {FormsModule} from "@angular/forms";
+import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module";
import {TranslateModule} from "app/ng2/shared/translator/translate.module";
-import {SdcUiComponentsModule} from 'onap-ui-angular';
-import {UiElementsModule} from '../../../../components/ui/ui-elements.module';
-import {InputParamRowComponent} from './input-param-row/input-param-row.component';
-import {InterfaceOperationHandlerComponent} from "./interface-operation-handler.component";
-import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
-import {PropertyTableModule} from "../../../../components/logic/properties-table/property-table.module";
+
+import {SdcUiComponentsModule} from "onap-ui-angular/dist";
+import { InterfaceOperationHandlerComponent } from "app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component";
+import { PropertyParamRowComponent } from "app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component";
+import { UiElementsModule } from "app/ng2/components/ui/ui-elements.module";
+import { PropertyTableModule } from "app/ng2/components/logic/properties-table/property-table.module";
+import { AddInputComponent } from './add-input/add-input.component';
+import { InputListComponent } from './input-list/input-list.component';
+import { InputListItemComponent } from './input-list/input-list-item/input-list-item.component';
@NgModule({
declarations: [
InterfaceOperationHandlerComponent,
- InputParamRowComponent,
- PropertyParamRowComponent
+ PropertyParamRowComponent,
+ AddInputComponent,
+ InputListComponent,
+ InputListItemComponent
],
imports: [
CommonModule,
@@ -46,7 +51,8 @@ import {PropertyTableModule} from "../../../../components/logic/properties-table
FormElementsModule,
TranslateModule,
UiElementsModule,
- PropertyTableModule
+ PropertyTableModule,
+ ReactiveFormsModule
],
exports: [
PropertyParamRowComponent
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/panel-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/panel-tab.component.ts
index c148a4e579..df8f46d784 100644
--- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/panel-tab.component.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/panel-tab.component.ts
@@ -1,13 +1,21 @@
-import { NgModule, Component, Compiler, ViewContainerRef, ViewChild, Input, ComponentRef, ComponentFactoryResolver, ChangeDetectorRef } from '@angular/core';
-import {Component as TopologyTemplate} from "app/models";
-import { SdcUiServices } from "onap-ui-angular";
+import {
+ Component,
+ ViewContainerRef,
+ ViewChild,
+ Input,
+ ComponentRef,
+ ComponentFactoryResolver,
+ ChangeDetectorRef,
+ OnChanges, OnDestroy, AfterViewInit
+} from '@angular/core';
+import {Component as TopologyTemplate} from 'app/models';
// Helper component to add dynamic tabs
@Component({
selector: 'panel-tab',
template: `<div #content></div>`
})
-export class PanelTabComponent {
+export class PanelTabComponent implements OnChanges, OnDestroy, AfterViewInit {
@ViewChild('content', { read: ViewContainerRef }) content;
@Input() isActive:boolean;
@Input() panelTabType;
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts
index 1cbb4e17ec..6690410653 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts
@@ -1,27 +1,30 @@
-import { CommonModule } from '@angular/common';
-import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
-import { FormElementsModule } from 'app/ng2/components/ui/form-components/form-elements.module';
-import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module';
-import { TranslateModule } from '../../../shared/translator/translate.module';
-import { PropertyCreatorComponent } from './property-creator.component';
+import {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {FormsModule} from '@angular/forms';
+import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module';
+import {UiElementsModule} from 'app/ng2/components/ui/ui-elements.module';
+import {TranslateModule} from '../../../shared/translator/translate.module';
+import {PropertyCreatorComponent} from './property-creator.component';
+import {SdcUiComponentsModule} from "onap-ui-angular/dist";
@NgModule({
- declarations: [
- PropertyCreatorComponent,
- ],
- imports: [
- CommonModule,
- FormsModule,
- FormElementsModule,
- UiElementsModule,
- TranslateModule
- ],
- exports: [],
- entryComponents: [
- PropertyCreatorComponent
- ],
- providers: []
+ declarations: [
+ PropertyCreatorComponent,
+ ],
+ imports: [
+ CommonModule,
+ FormsModule,
+ SdcUiComponentsModule,
+ FormElementsModule,
+ UiElementsModule,
+ TranslateModule
+ ],
+ exports: [],
+ entryComponents: [
+ PropertyCreatorComponent
+ ],
+ providers: []
})
-export class PropertyCreatorModule {}
+export class PropertyCreatorModule {
+}
diff --git a/catalog-ui/src/app/ng2/services/data-type.service.ts b/catalog-ui/src/app/ng2/services/data-type.service.ts
index 5b08e9323f..70555a5efd 100644
--- a/catalog-ui/src/app/ng2/services/data-type.service.ts
+++ b/catalog-ui/src/app/ng2/services/data-type.service.ts
@@ -60,6 +60,10 @@ export class DataTypeService {
return this.dataTypeService.getAllDataTypesFromModel(modelName);
}
+ public findAllDataTypesByModel(modelName: string): Promise<Map<string, DataTypeModel>> {
+ return this.dataTypeService.findAllDataTypesByModel(modelName);
+ }
+
public getConstraintsByParentTypeAndUniqueID(rootPropertyType, propertyName){
// const property = this.dataTypes[rootPropertyType].properties.filter(property =>
// property.name == propertyName);
diff --git a/catalog-ui/src/app/services/data-types-service.ts b/catalog-ui/src/app/services/data-types-service.ts
index 08b49ae422..1a0fc47aae 100644
--- a/catalog-ui/src/app/services/data-types-service.ts
+++ b/catalog-ui/src/app/services/data-types-service.ts
@@ -27,7 +27,7 @@ import {
PropertyModel,
InputPropertyBase,
IAppConfigurtaion,
- SchemaProperty
+ SchemaProperty, DataTypeModel
} from "../models";
import {PROPERTY_DATA} from "../utils/constants";
@@ -40,7 +40,8 @@ export interface IDataTypesService {
selectedInstance:ComponentInstance;
selectedComponentInputs:Array<InputModel>;
//declare methods
- fetchDataTypesByModel(modelName:string):void;
+ loadDataTypesCache(modelName:string):void;
+ findAllDataTypesByModel(modelName: string): void;
getAllDataTypes():DataTypesMap;
getFirsLevelOfDataTypeProperties(dataTypeName:string):Array<DataTypePropertyModel>;
isDataTypeForSchemaType(property:SchemaProperty):boolean;
@@ -70,7 +71,7 @@ export class DataTypesService implements IDataTypesService {
selectedInstance:ComponentInstance;
selectedComponentInputs:Array<InputModel>;
- public fetchDataTypesByModel = (modelName: string):void => {
+ public loadDataTypesCache = (modelName: string): void => {
let model;
if (modelName) {
model = {'model': modelName}
@@ -82,11 +83,35 @@ export class DataTypesService implements IDataTypesService {
});
};
+ public fetchDataTypesByModel = (modelName: string): angular.IHttpPromise<any> => {
+ let model;
+ if (modelName) {
+ model = {'model': modelName}
+ }
+ return this.$http.get(this.baseUrl + "dataTypes", {params: model});
+ };
+
public getAllDataTypesFromModel = (modelName: string): DataTypesMap => {
- this.fetchDataTypesByModel(modelName);
+ this.loadDataTypesCache(modelName);
return this.dataTypes;
}
+ public findAllDataTypesByModel = (modelName: string): Promise<Map<string, DataTypeModel>> => {
+ return new Promise<Map<string, DataTypeModel>>((resolve, reject) => {
+ this.fetchDataTypesByModel(modelName).then(response => {
+ const dataTypes = response.data;
+ delete dataTypes[PROPERTY_DATA.ROOT_DATA_TYPE];
+ const dataTypeMap = new Map<string, DataTypeModel>();
+ for(const dataTypeKey of Object.keys(dataTypes)) {
+ dataTypeMap.set(dataTypeKey, new DataTypeModel(dataTypes[dataTypeKey]))
+ }
+ resolve(dataTypeMap);
+ }).catch(reason => {
+ reject(reason);
+ });
+ });
+ }
+
public getAllDataTypes = ():DataTypesMap => {
return this.dataTypes;
};
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json
index 1779a0a92d..85e2ec2141 100644
--- a/catalog-ui/src/assets/languages/en_US.json
+++ b/catalog-ui/src/assets/languages/en_US.json
@@ -1,620 +1,539 @@
{
- "PROJECT_TITLE": "SDC",
-
- "=========== VALIDATION ===========": "",
- "VALIDATION_ERROR_MAX_LENGTH": "Max length {{max}} characters.",
- "VALIDATION_ERROR_MIN_LENGTH": "Min length {{min}} characters.",
- "VALIDATION_ERROR_REQUIRED": "{{field}} is required.",
- "VALIDATION_ERROR_SPECIAL_CHARS_NOT_ALLOWED": "Special characters not allowed.",
- "LABEL_MAX_SIZE_XX": "Max size is up to {{size}}",
- "LABEL_ALL_FIELDS_ARE_MANDATORY": "All fields are mandatory.",
- "VALIDATION_ERROR_BOOLEAN": "Value should be 'TRUE' or 'FALSE'.",
- "VALIDATION_ERROR_TYPE": "Value should be of type {{type}}.",
- "VALIDATION_ERROR_MAX_LENGTH_NOT_INCLUDING_NAME": "Max length {{max}} characters (including name length).",
- "VALIDATION_ERROR_MAX_FILE_SIZE": "Max file size is 10 MB.",
- "VALIDATION_ERROR_EMPTY_FILE": "The file you uploaded was empty, please upload a valid file.",
- "VALIDATION_ERROR_VALUE_MUST_BE_CHANGED": "Value must be changed",
- "VALIDATION_ERROR_INVALID_NAME": "Invalid name.",
-
- "=========== GENERAL ===========": "",
- "GENERAL_LABEL_TYPE": "Type:",
- "GENERAL_LABEL_NAME": "Name:",
- "GENERAL_LABEL_VERSION": "Version:",
- "GENERAL_LABEL_CATEGORY": "Category:",
- "GENERAL_LABEL_SUB_CATEGORY": "Sub Category:",
- "GENERAL_LABEL_CREATION_DATE": "Creation Date:",
- "GENERAL_LABEL_AUTHOR": "Author:",
- "GENERAL_LABEL_CONTACT_ID": "Contact ID:",
- "GENERAL_LABEL_RESOURCE_MODEL_NUMBER":"Vendor Model Number:",
- "GENERAL_LABEL_SERVICE_TYPE": "Service Type:",
- "GENERAL_LABEL_SERVICE_ROLE": "Service Role:",
- "GENERAL_LABEL_STATUS": "Status:",
- "GENERAL_LABEL_SERVICE_FUNCTION": "Service Function:",
- "GENERAL_LABEL_DESCRIPTION": "Description:",
- "GENERAL_LABEL_TAGS": "Tags:",
- "GENERAL_LABEL_RESOURCE_TYPE": "Resource Type:",
- "GENERAL_LABEL_VENDOR_NAME": "Vendor Name:",
- "GENERAL_LABEL_VENDOR_RELEASE": "Vendor Release:",
- "GENERAL_LABEL_LICENSE_TYPE": "License Type:",
- "GENERAL_LABEL_SERVICE": "Service:",
- "GENERAL_LABEL_RESOURCE": "Resource:",
- "GENERAL_LABEL_LIFE_CYCLE_STATUS": "Life Cycle Status:",
- "GENERAL_LABEL_DISTRIBUTION_STATUS": "Distribution Status:",
- "GENERAL_LABEL_SYSTEM_NAME": "System Name:",
- "GENERAL_LABEL_SOURCE_SERVICE_NAME": "Source Service Name:",
- "GENERAL_LABEL_RESOURCE_CUSTOMIZATION_UUID": "Resource Customization UUID:",
-
-
- "=========== GENERAL_TAB ===========": "",
- "GENERAL_TAB_LABEL_RESOURCE_MODEL_NUMBER":"Vendor Model Number",
- "GENERAL_TAB_LABEL_SERVICE_TYPE": "Service Type",
- "GENERAL_TAB_LABEL_SERVICE_ROLE": "Service Role",
- "GENERAL_TAB_LABEL_SERVICE_FUNCTION": "Service Function",
-
- "=========== GENERAL ERROR PAGES ===========": "",
- "GENERAL_ERROR_403_TITLE": "SDC Access Denied",
- "GENERAL_ERROR_403_DESCRIPTION": "Sorry, you are not authorized to view this page. Please visit the Portal Application to provision a user account for SDC.",
-
- "=========== ERROR VIEW MODEL ===========": "",
- "ADMIN_EMAIL": "",
- "EMAIL_SUBJECT_PREFIX": "SDC Access Request for",
-
- "=========== TOP MENU ===========": "",
- "TOP_MENU_HOME_BUTTON": "HOME",
- "TOP_MENU_CATALOG_BUTTON": "CATALOG",
- "TOP_MENU_ON_BOARD_BUTTON": "ONBOARD",
- "TOP_MENU_DCAE_BUTTON": "DCAE",
-
- "=========== SIGN IN PAGE ===========": "",
- "SIGN_IN_CAPTION": "Signing in",
- "SIGN_IN_DESCRIPTION": "Please wait. If you are using Internet Explorer, please reattempt access using Chrome or Firefox.",
-
- "=========== TUTORIAL PAGE ===========": "",
- "TUTRIAL_GENERAL_PREVIOUS_BUTTON": "prev",
- "TUTRIAL_GENERAL_NEXT_BUTTON": "next",
- "TUTRIAL_GENERAL_SKIP_BUTTON": "skip",
- "TUTRIAL_GENERAL_CLOSE_BUTTON": "close",
- "TUTRIAL_GENERAL_NEXT_BUTTON_END": "done",
-
- "TUTRIAL_GENERAL_TAB_1": "Workspace",
- "TUTRIAL_GENERAL_TAB_2": "Catalog",
- "TUTRIAL_GENERAL_TAB_3": "Design Studio",
-
- "TUTORIAL_PAGE1_TITLE": "Your Personal Workspace",
- "TUTORIAL_PAGE1_TEXT": "SDC keeps track of the Resources and Services you are assigned to work on. You access these assets directly from your Workspace.",
-
- "TUTORIAL_PAGE2_TITLE": "Folders",
- "TUTORIAL_PAGE2_TEXT": "Your personal Workspace shows the Resources and Services on which you have recently worked. To view a subset, filter by selecting a folder from the left pane.",
-
- "TUTORIAL_PAGE3_TITLE": "Assets Status and Type",
- "TUTORIAL_PAGE3_TEXT": "Each of your assets is represented as an item on your Workspace.",
-
- "TUTORIAL_PAGE4_TITLE": "Asset Type",
- "TUTORIAL_PAGE4_TEXT": "At the top left corner, R indicates a Resource and S indicates a Service.",
-
- "TUTORIAL_PAGE5_TITLE": "Asset Name",
- "TUTORIAL_PAGE5_TEXT": "At the bottom, Resource or Service name and version number are displayed.",
-
- "TUTORIAL_PAGE6_TITLE": "Asset Icon",
- "TUTORIAL_PAGE6_TEXT": "A Resource or Service is represented by an icon chosen by the Designer.",
-
- "TUTORIAL_PAGE7_TITLE": "Asset Status",
- "TUTORIAL_PAGE7_TEXT": "In the top right corner, an indication of the asset's current status is displayed.",
-
- "TUTORIAL_PAGE8_TITLE": "Asset Menu",
- "TUTORIAL_PAGE8_TEXT": "Hover over the three vertical dots to view a menu of actions you can request for the Resource or Service.",
-
- "TUTORIAL_PAGE9_TITLE": "SDC Catalog",
- "TUTORIAL_PAGE9_TEXT": "In the SDC Catalog you can view all available Resources and Services. Access the Catalog by clicking Catalog in the left pane.",
-
- "TUTORIAL_PAGE10_TITLE": "Catalog Filtering",
- "TUTORIAL_PAGE10_TEXT": "You can filter the Resources and Services displayed in the Catalog. Click on combinations of the Type, Category, and State criteria displayed in the left pane to filter by those criteria.",
-
- "TUTORIAL_PAGE11_TITLE": "Catalog Search",
- "TUTORIAL_PAGE11_TEXT": "You can also filter by using the search bar. Type a term, or multiple terms separated by commas. All Resources and Services with a Name, Tag, or Description containing the search term(s) will be displayed.",
-
- "TUTORIAL_PAGE12_TITLE": "Design Studio",
- "TUTORIAL_PAGE12_TEXT": "As a Designer, you have access to the Design Studio. You can add, change, and delete information related to a Resource or Service.",
-
- "TUTORIAL_PAGE13_TITLE": "Create & Modify Asset",
- "TUTORIAL_PAGE13_TEXT": "From your personal Workspace you can:<ul><li>Create a New Resource or Service (Click Create New)</li><li>Modify an existing Service or Resource (using the menu actions)</li></uL>",
-
- "TUTORIAL_PAGE14_TITLE": "Create New Asset",
- "TUTORIAL_PAGE14_TEXT": "When you create a new Resource or Service, you need to fill in profile data to create a new Catalog entry.",
-
- "TUTORIAL_PAGE15_TITLE": "Left Pane",
- "TUTORIAL_PAGE15_TEXT": "In creating or editing a Service, you can choose elements from the left pane to add to your Service. You can enter search criteria to change the visible elements in the left pane.",
-
- "TUTORIAL_PAGE16_TITLE": "Drag & Drop",
- "TUTORIAL_PAGE16_TEXT": "To include an element in your Service, drag it onto the Design Studio. If a green guide indication appears, drop the element near the guide and the Design Studio will automatically connect the two elements for you.",
-
- "TUTORIAL_PAGE17_TITLE": "Relationship Selection",
- "TUTORIAL_PAGE17_TEXT": "When you connect two elements, you can define the relationship between the two. Design Studio will display the allowed relationships from which you can choose.",
-
- "TUTORIAL_PAGE18_TITLE": "View & Delete Relationship",
- "TUTORIAL_PAGE18_TEXT": "You can view or delete the relationship between the two elements by selecting the relationship icon on the connecting line.",
-
- "TUTORIAL_PAGE19_TITLE": "Information tab",
- "TUTORIAL_PAGE19_TEXT": "Here you can review general information about the Resource, such as version, category, author, and description.",
-
- "TUTORIAL_PAGE20_TITLE": "Structure tab",
- "TUTORIAL_PAGE20_TEXT": "Here you can review the structural components of the Resource in a hierarchical tree diagram, including any connected Resources.",
-
- "TUTORIAL_PAGE21_TITLE": "Deployment Artifacts tab",
- "TUTORIAL_PAGE21_TEXT": "Here you can view and manage the Artifact files associated with the Resource. You can download existing files, upload additional files, and manage HEAT template parameters.",
-
- "TUTORIAL_PAGE22_TITLE": "Properties tab",
- "TUTORIAL_PAGE22_TEXT": "Here you can manage the properties of the Resource. You can view, edit, add and delete properties.",
-
- "TUTORIAL_PAGE23_TITLE": "Information Artifacts tab",
- "TUTORIAL_PAGE23_TEXT": "Here you can manage documents associated with the Resource (such as test scripts, features, and capacity).",
-
- "TUTORIAL_PAGE24_TITLE": "Requirements and Capabilities tab",
- "TUTORIAL_PAGE24_TEXT": "Here you can view the Resource capabilities and requirements, and from where the requirements are derived. If a Resource is connected to other Resources, the relationship associated with this connection is reflected (in the Requirements section) of this tab.",
-
- "TUTORIAL_PAGE25_TITLE": "Information tab",
- "TUTORIAL_PAGE25_TEXT": "Here you can view general information about the Service, such as version, category, author, and description.",
-
- "TUTORIAL_PAGE26_TITLE": "Structure tab",
- "TUTORIAL_PAGE26_TEXT": "Here you can view the Service structure in a hierarchical tree diagram, including the component Resources.",
-
- "TUTORIAL_PAGE27_TITLE": "Deployment Artifacts tab",
- "TUTORIAL_PAGE27_TEXT": "Here you can view and manage the Artifact files associated with the Service. You can download existing files, upload additional files, and manage HEAT template parameters.",
-
- "TUTORIAL_PAGE28_TITLE": "Inputs tab",
- "TUTORIAL_PAGE28_TEXT": "Here you can view and edit the properties of the Service, and see from which Resource the parameters originated. Properties are grouped by Resource instance.",
-
- "TUTORIAL_PAGE29_TITLE": "Information Artifacts tab",
- "TUTORIAL_PAGE29_TEXT": "Here you can manage documents associated with the Service (such as service topology, message flows, and management flows). Some of these documents are created by embedded tools, such as ASE tools.",
-
- "TUTORIAL_PAGE30_TITLE": "API tab",
- "TUTORIAL_PAGE30_TEXT": "Here you can manage the Service API (such as monitoring and instantiation), and you can upload an archive containing the HTML pages and the API URL.",
-
- "TUTORIAL_LAST_PAGE_TITLE": "Great!",
- "TUTORIAL_LAST_PAGE_TEXT": "Now that you are familiar with the system, you can begin building!",
- "TUTORIAL_LAST_PAGE_BTN_ACTION_MY_DASHBOARD": "My Dashboard",
-
- "=========== CATALOG PAGE ===========": "",
- "HEADER_CAPTION_CATALOG": "Catalog",
- "SORT_CAPTION": "Order By:",
- "SORT_BY_UPDATE_DATE": "Last updated",
- "SORT_ALPHABETICAL": "Alphabetical order",
-
-
- "=========== HEADER PAGE ===========": "",
- "HEADER_HELP_TEXT_CATALOG_TUTORIAL": "Catalog Tutorial",
- "HEADER_HELP_TEXT_DESIGNER_TUTORIAL": "Design Studio Tutorial",
- "HEADER_HELP_TEXT_WORKSPACE_TUTORIAL": "Workspace Tutorial",
-
- "=========== WELCOME PAGE ===========": "",
- "WELCOME_HELLO": "Hello {{username}},",
- "WELCOME_MESSAGE_1": "Welcome to Service Design and Creation (SDC) Portal. SDC supports Domain 2.0 Resource Onboarding and Service Creation.",
- "WELCOME_MESSAGE_2": "This tutorial walks first-time users through the SDC portal components. Future logins directly access the SDC work platform without displaying the tutorial. To see the tutorial, click the Tutorial link on each SDC page.",
- "WELCOME_MESSAGE_CURRENT_VERSION": "Current Version {{version}}",
- "WELCOME_MESSAGE_SEE_WHATS_NEW": "See what's new",
- "WELCOME_BTN_START_TUTORIAL": "Let's start",
- "WELCOME_BTN_SKIP": "skip for now",
- "WELCOME_BTN_ACTION_DESIGN_STUDIO": "Design Studio",
- "WELCOME_BTN_ACTION_DISTRIBUTION_STUDIO": "Distribution Studio",
- "WELCOME_BTN_ACTION_CATALOG": "Catalog",
-
- "=========== ONBOARD VENDOR PAGE ===========": "",
- "HEADER_CAPTION_ONBOARD":"On Board",
-
- "=========== NEW RESOURCE SERVICE ===========": "",
- "NEW_SERVICE_RESOURCE_WRAPPER_TAB_GENERAL_INFORMATION": "General Information",
- "NEW_SERVICE_RESOURCE_WRAPPER_TAB_ADDITIONAL_INFO": "Additional Information",
- "NEW_SERVICE_RESOURCE_WRAPPER_TAB_BILLING_AND_ORDERING": "Order Attributes & Rules",
- "NEW_SERVICE_RESOURCE_SAVE_BUTTON": "Save",
- "NEW_SERVICE_RESOURCE_DONE_BUTTON": "Done",
-
- "=========== NEW RESOURCE SERVICE ERRORS ===========": "",
- "NEW_SERVICE_RESOURCE_ERROR_SERVICE_NAME_REQUIRED": "Service name is required.",
- "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_25": "Max length 25 characters.",
- "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_50": "Max length 50 characters.",
- "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_128": "Max length 128 characters.",
- "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_1024": "Max length 1024 characters.",
- "NEW_SERVICE_RESOURCE_ERROR_NAME_EXISTS": "Name already exists.",
- "NEW_SERVICE_RESOURCE_ERROR_SPECIAL_CHARS": "Special characters not allowed.",
- "NEW_SERVICE_RESOURCE_ERROR_CATEGORY_REQUIRED": "category is required.",
- "NEW_SERVICE_RESOURCE_ERROR_CATEGORY_NOT_VALID": "Category not valid for base type.",
- "NEW_SERVICE_RESOURCE_ERROR_CONTACT_REQUIRED": "Contact is required.",
- "NEW_SERVICE_RESOURCE_ERROR_CONTACT_NOT_VALID": "Contact is not valid.",
- "NEW_SERVICE_RESOURCE_ERROR_SERVICE_DESCRIPTION_REQUIRED": "Service description is required.",
- "NEW_SERVICE_RESOURCE_ERROR_MIN_ONE_TAG": "Enter at least one tag.",
- "NEW_SERVICE_RESOURCE_ERROR_TAG_NAME_EXIST": "Tag name already exists.",
- "NEW_SERVICE_RESOURCE_ERROR_SERVICE_ICON": "Icon required.",
- "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_ICON": "Icon required.",
- "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_NAME_REQUIRED": "Name is required.",
- "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_DESCRIPTION_REQUIRED": "Description is required.",
- "NEW_SERVICE_RESOURCE_ERROR_VENDOR_NAME_REQUIRED": "Vendor name is required.",
- "NEW_SERVICE_RESOURCE_ERROR_VENDOR_RELEASE_REQUIRED": "Vendor Release is required.",
- "NEW_SERVICE_RESOURCE_ERROR_REQUIRED": "Value is required.",
- "NEW_SERVICE_RESOURCE_ERROR_TEMPLATE_REQUIRED": "Template is required.",
- "NEW_SERVICE_RESOURCE_ERROR_TAG_PATTERN": "{{text}}",
- "NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS_TITLE": "Invalid Tosca file",
- "NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS": "File extension should be {{extensions}}.",
- "NEW_SERVICE_RESOURCE_ERROR_TOSCA_FILE_REQUIRED": "Tosca file is required.",
- "NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS_TITLE": "Invalid csar file",
- "NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS": "File extension should be {{extensions}}.",
-
- "=========== SUGGESTED ICONS TOOLTIP ===========": "",
- "call_controll": "Call Control",
- "mobility": "Mobility",
- "network_l_1-3": "Network L 1-3",
- "network_l_4": "Network L 4+",
- "router": "Router",
- "database": "Database",
- "network": "Network",
- "objectStorage": "Object Storage",
- "connector": "Connector",
- "brocade": "Brocade",
- "cisco": "Cisco",
- "ericsson": "Ericsson",
- "tropo": "Tropo",
- "fortinet": "Fortinet",
- "att": "AT&T",
- "broadsoft": "BroadSoft",
- "alcatelLucent": "Alcatel-Lucent",
- "metaswitch": "Metaswitch",
- "aricent": "Aricent",
- "mySql": "MySQL",
- "juniper": "Juniper Networks",
- "oracle": "Oracle Corporation",
- "nokia_siemens": "Nokia Networks",
- "borderElement": "Border Element",
- "applicationServer": "Application Server",
- "server": "Server",
- "port": "Port",
- "loadBalancer": "Load Balancer",
- "compute": "Compute",
- "gateway": "Gateway",
- "defaulticon": "Default Icon",
- "monitoring_template": "Monitoring Template",
-
- "=========== ADD ARTIFACT FROM ===========": "",
- "ADD_ARTIFACT_ERROR_VALID_EXTENSIONS": "File extension should be {{extensions}}.",
- "ADD_ARTIFACT_ERROR_FILE_REQUIRED": "Artifact file is required.",
- "ADD_ARTIFACT_ERROR_LABEL_REQUIRED": "Artifact label is required.",
- "ADD_ARTIFACT_ERROR_LABEL_MAXLENGTH": "Max length 25 characters.",
- "ADD_ARTIFACT_ERROR_LABEL_PATTERN": "not allowed special characters.",
- "ADD_ARTIFACT_ERROR_TYPE_REQUIRED": "type is required.",
- "ADD_ARTIFACT_ERROR_TIMEOUT_MIN": "Timeout can't be set to zero.",
- "ADD_ARTIFACT_ERROR_TIMEOUT_MAXLENGTH": "Max length 25 characters.",
- "ADD_ARTIFACT_ERROR_TIMEOUT_PATTERN": "Invalid value.",
- "ADD_ARTIFACT_ERROR_APIURL_REQUIRED": "Artifact URL is required.",
- "ADD_ARTIFACT_ERROR_APIURL_MAXLENGTH": "Max length 100 characters.",
- "ADD_ARTIFACT_ERROR_APIURL_URL": "Url not valid",
- "ADD_ARTIFACT_ERROR_DESCRIPTION_REQUIRED": "Description is required.",
- "ADD_ARTIFACT_ERROR_DESCRIPTION_MAXLENGTH": "Max length 256 characters.",
- "ADD_ARTIFACT_ERROR_DESCRIPTION_PATTERN": "not allowed special characters.",
-
- "=========== ARTIFACT VIEW ===========": "",
- "ARTIFACT_VIEW_DELETE_MODAL_TITLE": "Delete Artifact Confirmation",
- "ARTIFACT_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete '{{name}}'?",
-
- "=========== PROPERTY VIEW ===========": "",
- "PROPERTY_VIEW_DELETE_MODAL_TITLE": "Delete Property Confirmation",
- "PROPERTY_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete '{{name}}'?",
- "PROPERTY_EDIT_PATTERN": "Invalid value.",
- "PROPERTY_EDIT_LIST_STRING": "Invalid value. The correct value is \"X\",\"Y\"",
- "PROPERTY_EDIT_MAP_STRING": "Invalid value. The correct value is \"Key\":\"value\"",
- "PROPERTY_EDIT_LIST_GENERIC": "Invalid value. The correct value is X, Y",
- "PROPERTY_EDIT_MAP_GENERIC": "Invalid value. The correct value is \"Key\":value",
- "PROPERTY_EDIT_MAP_UNIQUE_KEYS": "Key must be unique.",
-
- "=========== ATTRIBUTE VIEW ===========": "",
- "ATTRIBUTE_VIEW_DELETE_MODAL_TITLE": "Delete Attribute Confirmation",
- "ATTRIBUTE_DETAILS_MODAL_TITLE": "Attribute Details",
- "ATTRIBUTE_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete '{{name}}'?",
- "ATTRIBUTE_EDIT_PATTERN": "Invalid value.",
- "NEW_ATTRIBUTE_ERROR_NAME_EXISTS":"Name already exists.",
- "ATTRIBUTE_EDIT_LIST_STRING": "Invalid value. The correct value is \"X\",\"Y\".",
- "ATTRIBUTE_EDIT_MAP_STRING": "Invalid value. The correct value is \"Key\":\"value\".",
- "ATTRIBUTE_EDIT_LIST_BOOLEAN": "Invalid value. The correct value is true,false.",
- "ATTRIBUTE_EDIT_MAP_BOOLEAN": "Invalid value. The correct value is \"Key\":true.",
- "ATTRIBUTE_EDIT_LIST_GENERIC": "Invalid value. The correct value is X, Y.",
- "ATTRIBUTE_EDIT_MAP_GENERIC": "Invalid value. The correct value is \"Key\":value.",
- "ATTRIBUTE_EDIT_MAP_UNIQUE_KEYS": "Key must be unique.",
-
- "=========== UPDATE PARAMETERS FROM ===========": "",
- "UPDATE_PARAMETERS_TEXT": "Review the parameters and their default values. If necessary, you can modify the values by editing the text fields.",
- "ENV_FILE_GENERATION": "Please notice: empty fields will not be included in the ENV file",
-
- "=========== ENTITY VIEWER ===========": "",
- "ENTITY_VIEWER_PROPERTIES_TAB": "Properties",
- "ENTITY_VIEWER_ACTIVITY_LOG_TAB": "Activity Log",
-
- "=========== WHATS NEW ===========": "",
- "WHATS_NEW_ON": "What's new on {{version}}",
- "WHATS_NEW_LIST": "",
- "WHATS_NEW_1_TITLE": "VNF On-Boarding",
- "WHATS_NEW_1_BODY": "Vendors can upload VNF HEAT files & License artifacts<ul><li>Upload VNF HEAT files</li><li>Licensing</li><li>Questionnaire</li>",
- "WHATS_NEW_2_TITLE": "Call & Network Flow-Tool",
- "WHATS_NEW_2_BODY": "Introduced the ability to host a 3rd party<br/>Enhance VF and Service design with Call and Network flows; Call & Network Flows created and stored as Information Artifacts.",
- "WHATS_NEW_3_TITLE": "Import VF from On-Boarded VNF",
- "WHATS_NEW_3_BODY": "Import VF Metadata from vendor supplied CSAR file<br/>Create the VF based on data included in the CSAR file. Includes; VF topology and deployment artifacts<br/>Once checked in the VF is Displayed in the Catalog",
- "WHATS_NEW_4_TITLE": "App Navigation",
- "WHATS_NEW_4_BODY": "This release introduces View and Edit modes<ol><li>Use the view mode when:<ul><li>User does not have authorization to edit an Asset</li><li>Asset is in Check-In Mode</li></ul></li><li>Use the Edit Mode when:<ul><li>User has authorization to edit an Asset</li><li>Asset is in Check-out Mode</li></ul></li></ol>",
- "WHATS_NEW_5_TITLE": "Certification Studio",
- "WHATS_NEW_6_TITLE": "Composition: Virtual Link",
- "WHATS_NEW_6_BODY": "The ability to link VFs via a Virtual link has been expanded. Now a Virtual link can be defined as having either Point-to-Point connectivity or Multi-point connectivity. Additionally from within a Virtual Link, Point-to-Point connectivity can be dynamically changed to Multi-Point connectivity.",
- "WHATS_NEW_7_TITLE": "Distribution",
- "WHATS_NEW_7_BODY": "<ul><li>Distribution of artifact to App-C</li><li>Distribution of artifact to ALTS</li><li>Distribution of artifact to A&AI</li></ul>",
- "WHATS_NEW_8_TITLE": "New Brand",
- "WHATS_NEW_8_BODY": "Effort was invested in improving the overall application Usability, and the User Interface was modified to better reflect branding standards.",
-
- "=========== USER_MANAGEMENT SCREEN ===========": "",
- "USER_MANAGEMENT": "User Management",
- "USER_MANAGEMENT_TABLE_HEADER_USER_ID": "User ID",
- "USER_MANAGEMENT_SEARCH_LABEL": "Search user by name, user id, email or role",
- "USER_MANAGEMENT_SEARCH_TEXT": "Enter user id",
- "CATEGORY_MANAGEMENT": "Category Management",
- "ECOMP": "ECOMP",
- "MONITOR": "Monitor",
- "USER_MANAGEMENT_VIEW_DELETE_MODAL_TITLE": "Delete User Confirmation",
- "USER_MANAGEMENT_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete the user?",
- "NEW_USER_ERROR_USER_ID_REQUIRED": "User id is required.",
- "NEW_USER_ERROR_USER_ID_NOT_VALID": "User id not valid.",
- "NEW_USER_ERROR_ROLE_REQUIRED": "User role is required.",
-
- "=========== CONFIRMATION_MODAL ===========": "",
- "CONFIRMATION_MODAL_PLACEHOLDER": "Comment...",
-
- "=========== CATEGORY_MANAGEMENT SCREEN ===========": "",
- "RESOURCE_CATEGORY_HEADER": "Resource Category",
- "SERVICE_CATEGORY_HEADER": "Service Category",
- "SUBCATEGORY_HEADER": "Sub Category",
- "ADD_CATEGORY": "New",
- "ADD_SUBCATEGORY": "New",
- "DELETE_CATEGORY_MODAL_HEADER": "Delete {{modelType}}",
- "DELETE_CATEGORY_MODAL_CATEGORY_NAME": "Are you sure you want to delete the {{modelType}}?",
- "CREATE_CATEGORY_MODAL_HEADER": "Create new {{modelType}}",
- "CREATE_CATEGORY_MODAL_CATEGORY_NAME": "Enter {{modelType}} name",
- "CREATE_CATEGORY_MODAL_REQUIRED": "{{modelType}} name is mandatory",
- "CREATE_CATEGORY_MODAL_MINLENGTH": "{{modelType}} name should be at least {{minlength}} characters",
- "CREATE_CATEGORY_MODAL_PATTERN": "{{modelType}} name is not valid"
-
-,"=========== PDF FILE ===========": "",
- "PDF_FILE_DECLARATION_BOLD": "",
- "PDF_FILE_DECLARATION": ""
-
-,"=========== DEPLOYMENT ARTIFACTS ===========": "",
- "DEPLOYMENT_ARTIFACT_NO_ARTIFACTS_TO_DISPLAY": "There are no deployment artifacts to display",
- "DEPLOYMENT_ARTIFACT_BUTTON_ADD_HEAT": "Add {{name}}",
- "DEPLOYMENT_ARTIFACT_BUTTON_ADD_BASE_HEAT": "Add Base HEAT Artifact",
- "DEPLOYMENT_ARTIFACT_BUTTON_ADD_NETWORK_HEAT": "Add Network HEAT Artifact",
- "DEPLOYMENT_ARTIFACT_BUTTON_ADD_VOLUME_HEAT": "Add Volume HEAT Artifact",
- "DEPLOYMENT_ARTIFACT_BUTTON_ADD_OTHER": "Add Other Artifact",
- "DEPLOYMENT_ARTIFACT_GAB_NO_CONFIG": "Generic Artifact Browser has no columns configured"
-
- ,"=========== IMPORT VF ===========": "",
- "IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_TITLE": "Create VF",
- "IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_DESCRIPTION": "Your VF is being created.<br/>It can take up to 10 minutes.<br/>When done, you can view it in SDC Catalog.",
- "IMPORT_VF_MESSAGE_CREATE_FINISHED_TITLE": "Create/Update",
- "IMPORT_VF_MESSAGE_CREATE_FINISHED_DESCRIPTION": "saved successfully",
- "IMPORT_VF_ALREADY_EXISTS_TITLE": "Create VF",
- "IMPORT_VF_ALREADY_EXISTS_DESCRIPTION": "The VF {{vfName}} is already certified.<br/>When updating a VF that was already certified, the values for several parameters will not be changed.<br/>These parameters are: Name, Category and Icon.",
-
- "=========== TABS TITLE ===========": "",
- "HIERARCHY_TAB_TITLE": "HIERARCHY",
- "DEPLOYMENT_TAB_TITLE": "DEPLOYMENT",
-
- "=========== DISTRIBUTION VIEW ===========": "",
- "DISTRIBUTION_VIEW_TITLE_USER_ID": "User id:",
-
- "=========== SUCCESS MESSAGES ===========": "",
- "CHECKIN_SUCCESS_MESSAGE_TEXT": "Checked in successfully",
- "CHECKIN_SUCCESS_MESSAGE_TITLE": "Check in",
- "CHECKOUT_SUCCESS_MESSAGE_TEXT": "Checked out successfully",
- "CHECKOUT_SUCCESS_MESSAGE_TITLE": "Check out",
- "DELETE_SUCCESS_MESSAGE_TEXT": "Deleted successfully",
- "DELETE_SUCCESS_MESSAGE_TITLE": "Delete",
- "APPROVE_SUCCESS_MESSAGE_TEXT": "Approved successfully",
- "APPROVE_SUCCESS_MESSAGE_TITLE": "Approve",
- "DISTRIBUTE_SUCCESS_MESSAGE_TEXT": "Distributed successfully",
- "DISTRIBUTE_SUCCESS_MESSAGE_TITLE": "Distribute",
- "RESTORE_SUCCESS_MESSAGE_TITLE":"Restore",
- "RESTORE_SUCCESS_MESSAGE_TEXT":"successfully restored",
- "ARCHIVE_SUCCESS_MESSAGE_TITLE":"Archive",
- "ARCHIVE_SUCCESS_MESSAGE_TEXT":"successfully archived",
-
- "=========== ON BOARDING MODAL ===========": "",
- "ON_BOARDING_MODAL_SUB_TITLE": "Select one of the software product component below:",
- "ON_BOARDING_GENERAL_INFO": "Displays a table of VSPs created using Onboarding.\nEach row displays details for a single VSP.\nWhen expanded you can either import CSAR files that are yet to be imported or update CSAR files that were previously imported.",
- "ON_BOARDING_IMPORT_INFO": "Displays the Onboarding repository and supports importing on-boarded CSAR files.\nSelect an imported CSAR file to create a VF from the on-boarded and imported information.",
- "ON_BOARDING_UPDATE_INFO": "Displays the Onboarding repository and supports updating on-boarded and previously imported CSAR files.\nClicking Update, updates the existing VF with information available from a new version of the CSAR file.",
-
- "=========== HEAT PARAMETERS MODAL INFO MESSAGES ===========": "",
- "DEFAULT_VALUE_INFO": "This column indicates all the default values that were declared in the Main Heat ",
- "CURRENT_VALUE_INFO": "This column indicates:<br/>• Default values that were declared in the main HEAT & does not have a value in the ENV<br/>• Values that were declared in the ENV<br/>• All the values that appear in the current value fields will be generated into the ENV",
-
- "=========== MODULE PROPERTY FORM ===========": "",
- "MIN_VALIDATION_ERROR": "Value cannot be lower than the 'min_vf_module_instances' and 'initial_count'",
- "MAX_VALIDATION_ERROR": "Value cannot be higher than the 'max_vf_module_instances' and 'initial_count'",
- "MIN_MAX_VALIDATION": "Value must be between 'min_vf_module_instances' and 'max vf module instances'",
- "MIN_VALIDATION_VF_LEVE_ERROR": " Value of 'min_vf_module_instances' must not be lower than defined in VF level",
- "MAX_VALIDATION_VF_LEVE_ERROR": " Value of 'max_vf_module_instances' must not be higher than defined in VF level",
-
- "=========== SERVICE PATH SELECTOR ===========": "",
- "SERVICE_PATH_SELECTOR_HIDE_ALL_VALUE" : "⚊ Hide all ⚊",
- "SERVICE_PATH_SELECTOR_SHOW_ALL_VALUE" : "⚊ Show all ⚊",
- "SERVICE_OPERATION_PROPERTY_TOOLTIP_TEXT": "Service properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.",
-
- "=========== INTERFACE DEFINITION ==========": "",
+ "PROJECT_TITLE": "SDC",
+ "=========== VALIDATION ===========": "",
+ "VALIDATION_ERROR_MAX_LENGTH": "Max length {{max}} characters.",
+ "VALIDATION_ERROR_MIN_LENGTH": "Min length {{min}} characters.",
+ "VALIDATION_ERROR_REQUIRED": "{{field}} is required.",
+ "VALIDATION_ERROR_SPECIAL_CHARS_NOT_ALLOWED": "Special characters not allowed.",
+ "LABEL_MAX_SIZE_XX": "Max size is up to {{size}}",
+ "LABEL_ALL_FIELDS_ARE_MANDATORY": "All fields are mandatory.",
+ "VALIDATION_ERROR_BOOLEAN": "Value should be 'TRUE' or 'FALSE'.",
+ "VALIDATION_ERROR_TYPE": "Value should be of type {{type}}.",
+ "VALIDATION_ERROR_MAX_LENGTH_NOT_INCLUDING_NAME": "Max length {{max}} characters (including name length).",
+ "VALIDATION_ERROR_MAX_FILE_SIZE": "Max file size is 10 MB.",
+ "VALIDATION_ERROR_EMPTY_FILE": "The file you uploaded was empty, please upload a valid file.",
+ "VALIDATION_ERROR_VALUE_MUST_BE_CHANGED": "Value must be changed",
+ "VALIDATION_ERROR_INVALID_NAME": "Invalid name.",
+ "=========== GENERAL ===========": "",
+ "GENERAL_LABEL_TYPE": "Type:",
+ "GENERAL_LABEL_NAME": "Name:",
+ "GENERAL_LABEL_VERSION": "Version:",
+ "GENERAL_LABEL_CATEGORY": "Category:",
+ "GENERAL_LABEL_SUB_CATEGORY": "Sub Category:",
+ "GENERAL_LABEL_CREATION_DATE": "Creation Date:",
+ "GENERAL_LABEL_AUTHOR": "Author:",
+ "GENERAL_LABEL_CONTACT_ID": "Contact ID:",
+ "GENERAL_LABEL_RESOURCE_MODEL_NUMBER": "Vendor Model Number:",
+ "GENERAL_LABEL_SERVICE_TYPE": "Service Type:",
+ "GENERAL_LABEL_SERVICE_ROLE": "Service Role:",
+ "GENERAL_LABEL_STATUS": "Status:",
+ "GENERAL_LABEL_SERVICE_FUNCTION": "Service Function:",
+ "GENERAL_LABEL_DESCRIPTION": "Description:",
+ "GENERAL_LABEL_TAGS": "Tags:",
+ "GENERAL_LABEL_RESOURCE_TYPE": "Resource Type:",
+ "GENERAL_LABEL_VENDOR_NAME": "Vendor Name:",
+ "GENERAL_LABEL_VENDOR_RELEASE": "Vendor Release:",
+ "GENERAL_LABEL_LICENSE_TYPE": "License Type:",
+ "GENERAL_LABEL_SERVICE": "Service:",
+ "GENERAL_LABEL_RESOURCE": "Resource:",
+ "GENERAL_LABEL_LIFE_CYCLE_STATUS": "Life Cycle Status:",
+ "GENERAL_LABEL_DISTRIBUTION_STATUS": "Distribution Status:",
+ "GENERAL_LABEL_SYSTEM_NAME": "System Name:",
+ "GENERAL_LABEL_SOURCE_SERVICE_NAME": "Source Service Name:",
+ "GENERAL_LABEL_RESOURCE_CUSTOMIZATION_UUID": "Resource Customization UUID:",
+ "=========== GENERAL_TAB ===========": "",
+ "GENERAL_TAB_LABEL_RESOURCE_MODEL_NUMBER": "Vendor Model Number",
+ "GENERAL_TAB_LABEL_SERVICE_TYPE": "Service Type",
+ "GENERAL_TAB_LABEL_SERVICE_ROLE": "Service Role",
+ "GENERAL_TAB_LABEL_SERVICE_FUNCTION": "Service Function",
+ "=========== GENERAL ERROR PAGES ===========": "",
+ "GENERAL_ERROR_403_TITLE": "SDC Access Denied",
+ "GENERAL_ERROR_403_DESCRIPTION": "Sorry, you are not authorized to view this page. Please visit the Portal Application to provision a user account for SDC.",
+ "=========== ERROR VIEW MODEL ===========": "",
+ "ADMIN_EMAIL": "",
+ "EMAIL_SUBJECT_PREFIX": "SDC Access Request for",
+ "=========== TOP MENU ===========": "",
+ "TOP_MENU_HOME_BUTTON": "HOME",
+ "TOP_MENU_CATALOG_BUTTON": "CATALOG",
+ "TOP_MENU_ON_BOARD_BUTTON": "ONBOARD",
+ "TOP_MENU_DCAE_BUTTON": "DCAE",
+ "=========== SIGN IN PAGE ===========": "",
+ "SIGN_IN_CAPTION": "Signing in",
+ "SIGN_IN_DESCRIPTION": "Please wait. If you are using Internet Explorer, please reattempt access using Chrome or Firefox.",
+ "=========== TUTORIAL PAGE ===========": "",
+ "TUTRIAL_GENERAL_PREVIOUS_BUTTON": "prev",
+ "TUTRIAL_GENERAL_NEXT_BUTTON": "next",
+ "TUTRIAL_GENERAL_SKIP_BUTTON": "skip",
+ "TUTRIAL_GENERAL_CLOSE_BUTTON": "close",
+ "TUTRIAL_GENERAL_NEXT_BUTTON_END": "done",
+ "TUTRIAL_GENERAL_TAB_1": "Workspace",
+ "TUTRIAL_GENERAL_TAB_2": "Catalog",
+ "TUTRIAL_GENERAL_TAB_3": "Design Studio",
+ "TUTORIAL_PAGE1_TITLE": "Your Personal Workspace",
+ "TUTORIAL_PAGE1_TEXT": "SDC keeps track of the Resources and Services you are assigned to work on. You access these assets directly from your Workspace.",
+ "TUTORIAL_PAGE2_TITLE": "Folders",
+ "TUTORIAL_PAGE2_TEXT": "Your personal Workspace shows the Resources and Services on which you have recently worked. To view a subset, filter by selecting a folder from the left pane.",
+ "TUTORIAL_PAGE3_TITLE": "Assets Status and Type",
+ "TUTORIAL_PAGE3_TEXT": "Each of your assets is represented as an item on your Workspace.",
+ "TUTORIAL_PAGE4_TITLE": "Asset Type",
+ "TUTORIAL_PAGE4_TEXT": "At the top left corner, R indicates a Resource and S indicates a Service.",
+ "TUTORIAL_PAGE5_TITLE": "Asset Name",
+ "TUTORIAL_PAGE5_TEXT": "At the bottom, Resource or Service name and version number are displayed.",
+ "TUTORIAL_PAGE6_TITLE": "Asset Icon",
+ "TUTORIAL_PAGE6_TEXT": "A Resource or Service is represented by an icon chosen by the Designer.",
+ "TUTORIAL_PAGE7_TITLE": "Asset Status",
+ "TUTORIAL_PAGE7_TEXT": "In the top right corner, an indication of the asset's current status is displayed.",
+ "TUTORIAL_PAGE8_TITLE": "Asset Menu",
+ "TUTORIAL_PAGE8_TEXT": "Hover over the three vertical dots to view a menu of actions you can request for the Resource or Service.",
+ "TUTORIAL_PAGE9_TITLE": "SDC Catalog",
+ "TUTORIAL_PAGE9_TEXT": "In the SDC Catalog you can view all available Resources and Services. Access the Catalog by clicking Catalog in the left pane.",
+ "TUTORIAL_PAGE10_TITLE": "Catalog Filtering",
+ "TUTORIAL_PAGE10_TEXT": "You can filter the Resources and Services displayed in the Catalog. Click on combinations of the Type, Category, and State criteria displayed in the left pane to filter by those criteria.",
+ "TUTORIAL_PAGE11_TITLE": "Catalog Search",
+ "TUTORIAL_PAGE11_TEXT": "You can also filter by using the search bar. Type a term, or multiple terms separated by commas. All Resources and Services with a Name, Tag, or Description containing the search term(s) will be displayed.",
+ "TUTORIAL_PAGE12_TITLE": "Design Studio",
+ "TUTORIAL_PAGE12_TEXT": "As a Designer, you have access to the Design Studio. You can add, change, and delete information related to a Resource or Service.",
+ "TUTORIAL_PAGE13_TITLE": "Create & Modify Asset",
+ "TUTORIAL_PAGE13_TEXT": "From your personal Workspace you can:<ul><li>Create a New Resource or Service (Click Create New)</li><li>Modify an existing Service or Resource (using the menu actions)</li></uL>",
+ "TUTORIAL_PAGE14_TITLE": "Create New Asset",
+ "TUTORIAL_PAGE14_TEXT": "When you create a new Resource or Service, you need to fill in profile data to create a new Catalog entry.",
+ "TUTORIAL_PAGE15_TITLE": "Left Pane",
+ "TUTORIAL_PAGE15_TEXT": "In creating or editing a Service, you can choose elements from the left pane to add to your Service. You can enter search criteria to change the visible elements in the left pane.",
+ "TUTORIAL_PAGE16_TITLE": "Drag & Drop",
+ "TUTORIAL_PAGE16_TEXT": "To include an element in your Service, drag it onto the Design Studio. If a green guide indication appears, drop the element near the guide and the Design Studio will automatically connect the two elements for you.",
+ "TUTORIAL_PAGE17_TITLE": "Relationship Selection",
+ "TUTORIAL_PAGE17_TEXT": "When you connect two elements, you can define the relationship between the two. Design Studio will display the allowed relationships from which you can choose.",
+ "TUTORIAL_PAGE18_TITLE": "View & Delete Relationship",
+ "TUTORIAL_PAGE18_TEXT": "You can view or delete the relationship between the two elements by selecting the relationship icon on the connecting line.",
+ "TUTORIAL_PAGE19_TITLE": "Information tab",
+ "TUTORIAL_PAGE19_TEXT": "Here you can review general information about the Resource, such as version, category, author, and description.",
+ "TUTORIAL_PAGE20_TITLE": "Structure tab",
+ "TUTORIAL_PAGE20_TEXT": "Here you can review the structural components of the Resource in a hierarchical tree diagram, including any connected Resources.",
+ "TUTORIAL_PAGE21_TITLE": "Deployment Artifacts tab",
+ "TUTORIAL_PAGE21_TEXT": "Here you can view and manage the Artifact files associated with the Resource. You can download existing files, upload additional files, and manage HEAT template parameters.",
+ "TUTORIAL_PAGE22_TITLE": "Properties tab",
+ "TUTORIAL_PAGE22_TEXT": "Here you can manage the properties of the Resource. You can view, edit, add and delete properties.",
+ "TUTORIAL_PAGE23_TITLE": "Information Artifacts tab",
+ "TUTORIAL_PAGE23_TEXT": "Here you can manage documents associated with the Resource (such as test scripts, features, and capacity).",
+ "TUTORIAL_PAGE24_TITLE": "Requirements and Capabilities tab",
+ "TUTORIAL_PAGE24_TEXT": "Here you can view the Resource capabilities and requirements, and from where the requirements are derived. If a Resource is connected to other Resources, the relationship associated with this connection is reflected (in the Requirements section) of this tab.",
+ "TUTORIAL_PAGE25_TITLE": "Information tab",
+ "TUTORIAL_PAGE25_TEXT": "Here you can view general information about the Service, such as version, category, author, and description.",
+ "TUTORIAL_PAGE26_TITLE": "Structure tab",
+ "TUTORIAL_PAGE26_TEXT": "Here you can view the Service structure in a hierarchical tree diagram, including the component Resources.",
+ "TUTORIAL_PAGE27_TITLE": "Deployment Artifacts tab",
+ "TUTORIAL_PAGE27_TEXT": "Here you can view and manage the Artifact files associated with the Service. You can download existing files, upload additional files, and manage HEAT template parameters.",
+ "TUTORIAL_PAGE28_TITLE": "Inputs tab",
+ "TUTORIAL_PAGE28_TEXT": "Here you can view and edit the properties of the Service, and see from which Resource the parameters originated. Properties are grouped by Resource instance.",
+ "TUTORIAL_PAGE29_TITLE": "Information Artifacts tab",
+ "TUTORIAL_PAGE29_TEXT": "Here you can manage documents associated with the Service (such as service topology, message flows, and management flows). Some of these documents are created by embedded tools, such as ASE tools.",
+ "TUTORIAL_PAGE30_TITLE": "API tab",
+ "TUTORIAL_PAGE30_TEXT": "Here you can manage the Service API (such as monitoring and instantiation), and you can upload an archive containing the HTML pages and the API URL.",
+ "TUTORIAL_LAST_PAGE_TITLE": "Great!",
+ "TUTORIAL_LAST_PAGE_TEXT": "Now that you are familiar with the system, you can begin building!",
+ "TUTORIAL_LAST_PAGE_BTN_ACTION_MY_DASHBOARD": "My Dashboard",
+ "=========== CATALOG PAGE ===========": "",
+ "HEADER_CAPTION_CATALOG": "Catalog",
+ "SORT_CAPTION": "Order By:",
+ "SORT_BY_UPDATE_DATE": "Last updated",
+ "SORT_ALPHABETICAL": "Alphabetical order",
+ "=========== HEADER PAGE ===========": "",
+ "HEADER_HELP_TEXT_CATALOG_TUTORIAL": "Catalog Tutorial",
+ "HEADER_HELP_TEXT_DESIGNER_TUTORIAL": "Design Studio Tutorial",
+ "HEADER_HELP_TEXT_WORKSPACE_TUTORIAL": "Workspace Tutorial",
+ "=========== WELCOME PAGE ===========": "",
+ "WELCOME_HELLO": "Hello {{username}},",
+ "WELCOME_MESSAGE_1": "Welcome to Service Design and Creation (SDC) Portal. SDC supports Domain 2.0 Resource Onboarding and Service Creation.",
+ "WELCOME_MESSAGE_2": "This tutorial walks first-time users through the SDC portal components. Future logins directly access the SDC work platform without displaying the tutorial. To see the tutorial, click the Tutorial link on each SDC page.",
+ "WELCOME_MESSAGE_CURRENT_VERSION": "Current Version {{version}}",
+ "WELCOME_MESSAGE_SEE_WHATS_NEW": "See what's new",
+ "WELCOME_BTN_START_TUTORIAL": "Let's start",
+ "WELCOME_BTN_SKIP": "skip for now",
+ "WELCOME_BTN_ACTION_DESIGN_STUDIO": "Design Studio",
+ "WELCOME_BTN_ACTION_DISTRIBUTION_STUDIO": "Distribution Studio",
+ "WELCOME_BTN_ACTION_CATALOG": "Catalog",
+ "=========== ONBOARD VENDOR PAGE ===========": "",
+ "HEADER_CAPTION_ONBOARD": "On Board",
+ "=========== NEW RESOURCE SERVICE ===========": "",
+ "NEW_SERVICE_RESOURCE_WRAPPER_TAB_GENERAL_INFORMATION": "General Information",
+ "NEW_SERVICE_RESOURCE_WRAPPER_TAB_ADDITIONAL_INFO": "Additional Information",
+ "NEW_SERVICE_RESOURCE_WRAPPER_TAB_BILLING_AND_ORDERING": "Order Attributes & Rules",
+ "NEW_SERVICE_RESOURCE_SAVE_BUTTON": "Save",
+ "NEW_SERVICE_RESOURCE_DONE_BUTTON": "Done",
+ "=========== NEW RESOURCE SERVICE ERRORS ===========": "",
+ "NEW_SERVICE_RESOURCE_ERROR_SERVICE_NAME_REQUIRED": "Service name is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_25": "Max length 25 characters.",
+ "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_50": "Max length 50 characters.",
+ "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_128": "Max length 128 characters.",
+ "NEW_SERVICE_RESOURCE_ERROR_MAX_LENGTH_1024": "Max length 1024 characters.",
+ "NEW_SERVICE_RESOURCE_ERROR_NAME_EXISTS": "Name already exists.",
+ "NEW_SERVICE_RESOURCE_ERROR_SPECIAL_CHARS": "Special characters not allowed.",
+ "NEW_SERVICE_RESOURCE_ERROR_CATEGORY_REQUIRED": "category is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_CATEGORY_NOT_VALID": "Category not valid for base type.",
+ "NEW_SERVICE_RESOURCE_ERROR_CONTACT_REQUIRED": "Contact is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_CONTACT_NOT_VALID": "Contact is not valid.",
+ "NEW_SERVICE_RESOURCE_ERROR_SERVICE_DESCRIPTION_REQUIRED": "Service description is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_MIN_ONE_TAG": "Enter at least one tag.",
+ "NEW_SERVICE_RESOURCE_ERROR_TAG_NAME_EXIST": "Tag name already exists.",
+ "NEW_SERVICE_RESOURCE_ERROR_SERVICE_ICON": "Icon required.",
+ "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_ICON": "Icon required.",
+ "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_NAME_REQUIRED": "Name is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_DESCRIPTION_REQUIRED": "Description is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_VENDOR_NAME_REQUIRED": "Vendor name is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_VENDOR_RELEASE_REQUIRED": "Vendor Release is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_REQUIRED": "Value is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_TEMPLATE_REQUIRED": "Template is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_TAG_PATTERN": "{{text}}",
+ "NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS_TITLE": "Invalid Tosca file",
+ "NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS": "File extension should be {{extensions}}.",
+ "NEW_SERVICE_RESOURCE_ERROR_TOSCA_FILE_REQUIRED": "Tosca file is required.",
+ "NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS_TITLE": "Invalid csar file",
+ "NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS": "File extension should be {{extensions}}.",
+ "=========== SUGGESTED ICONS TOOLTIP ===========": "",
+ "call_controll": "Call Control",
+ "mobility": "Mobility",
+ "network_l_1-3": "Network L 1-3",
+ "network_l_4": "Network L 4+",
+ "router": "Router",
+ "database": "Database",
+ "network": "Network",
+ "objectStorage": "Object Storage",
+ "connector": "Connector",
+ "brocade": "Brocade",
+ "cisco": "Cisco",
+ "ericsson": "Ericsson",
+ "tropo": "Tropo",
+ "fortinet": "Fortinet",
+ "att": "AT&T",
+ "broadsoft": "BroadSoft",
+ "alcatelLucent": "Alcatel-Lucent",
+ "metaswitch": "Metaswitch",
+ "aricent": "Aricent",
+ "mySql": "MySQL",
+ "juniper": "Juniper Networks",
+ "oracle": "Oracle Corporation",
+ "nokia_siemens": "Nokia Networks",
+ "borderElement": "Border Element",
+ "applicationServer": "Application Server",
+ "server": "Server",
+ "port": "Port",
+ "loadBalancer": "Load Balancer",
+ "compute": "Compute",
+ "gateway": "Gateway",
+ "defaulticon": "Default Icon",
+ "monitoring_template": "Monitoring Template",
+ "=========== ADD ARTIFACT FROM ===========": "",
+ "ADD_ARTIFACT_ERROR_VALID_EXTENSIONS": "File extension should be {{extensions}}.",
+ "ADD_ARTIFACT_ERROR_FILE_REQUIRED": "Artifact file is required.",
+ "ADD_ARTIFACT_ERROR_LABEL_REQUIRED": "Artifact label is required.",
+ "ADD_ARTIFACT_ERROR_LABEL_MAXLENGTH": "Max length 25 characters.",
+ "ADD_ARTIFACT_ERROR_LABEL_PATTERN": "not allowed special characters.",
+ "ADD_ARTIFACT_ERROR_TYPE_REQUIRED": "type is required.",
+ "ADD_ARTIFACT_ERROR_TIMEOUT_MIN": "Timeout can't be set to zero.",
+ "ADD_ARTIFACT_ERROR_TIMEOUT_MAXLENGTH": "Max length 25 characters.",
+ "ADD_ARTIFACT_ERROR_TIMEOUT_PATTERN": "Invalid value.",
+ "ADD_ARTIFACT_ERROR_APIURL_REQUIRED": "Artifact URL is required.",
+ "ADD_ARTIFACT_ERROR_APIURL_MAXLENGTH": "Max length 100 characters.",
+ "ADD_ARTIFACT_ERROR_APIURL_URL": "Url not valid",
+ "ADD_ARTIFACT_ERROR_DESCRIPTION_REQUIRED": "Description is required.",
+ "ADD_ARTIFACT_ERROR_DESCRIPTION_MAXLENGTH": "Max length 256 characters.",
+ "ADD_ARTIFACT_ERROR_DESCRIPTION_PATTERN": "not allowed special characters.",
+ "=========== ARTIFACT VIEW ===========": "",
+ "ARTIFACT_VIEW_DELETE_MODAL_TITLE": "Delete Artifact Confirmation",
+ "ARTIFACT_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete '{{name}}'?",
+ "=========== PROPERTY VIEW ===========": "",
+ "PROPERTY_VIEW_DELETE_MODAL_TITLE": "Delete Property Confirmation",
+ "PROPERTY_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete '{{name}}'?",
+ "PROPERTY_EDIT_PATTERN": "Invalid value.",
+ "PROPERTY_EDIT_LIST_STRING": "Invalid value. The correct value is \"X\",\"Y\"",
+ "PROPERTY_EDIT_MAP_STRING": "Invalid value. The correct value is \"Key\":\"value\"",
+ "PROPERTY_EDIT_LIST_GENERIC": "Invalid value. The correct value is X, Y",
+ "PROPERTY_EDIT_MAP_GENERIC": "Invalid value. The correct value is \"Key\":value",
+ "PROPERTY_EDIT_MAP_UNIQUE_KEYS": "Key must be unique.",
+ "=========== ATTRIBUTE VIEW ===========": "",
+ "ATTRIBUTE_VIEW_DELETE_MODAL_TITLE": "Delete Attribute Confirmation",
+ "ATTRIBUTE_DETAILS_MODAL_TITLE": "Attribute Details",
+ "ATTRIBUTE_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete '{{name}}'?",
+ "ATTRIBUTE_EDIT_PATTERN": "Invalid value.",
+ "NEW_ATTRIBUTE_ERROR_NAME_EXISTS": "Name already exists.",
+ "ATTRIBUTE_EDIT_LIST_STRING": "Invalid value. The correct value is \"X\",\"Y\".",
+ "ATTRIBUTE_EDIT_MAP_STRING": "Invalid value. The correct value is \"Key\":\"value\".",
+ "ATTRIBUTE_EDIT_LIST_BOOLEAN": "Invalid value. The correct value is true,false.",
+ "ATTRIBUTE_EDIT_MAP_BOOLEAN": "Invalid value. The correct value is \"Key\":true.",
+ "ATTRIBUTE_EDIT_LIST_GENERIC": "Invalid value. The correct value is X, Y.",
+ "ATTRIBUTE_EDIT_MAP_GENERIC": "Invalid value. The correct value is \"Key\":value.",
+ "ATTRIBUTE_EDIT_MAP_UNIQUE_KEYS": "Key must be unique.",
+ "=========== UPDATE PARAMETERS FROM ===========": "",
+ "UPDATE_PARAMETERS_TEXT": "Review the parameters and their default values. If necessary, you can modify the values by editing the text fields.",
+ "ENV_FILE_GENERATION": "Please notice: empty fields will not be included in the ENV file",
+ "=========== ENTITY VIEWER ===========": "",
+ "ENTITY_VIEWER_PROPERTIES_TAB": "Properties",
+ "ENTITY_VIEWER_ACTIVITY_LOG_TAB": "Activity Log",
+ "=========== WHATS NEW ===========": "",
+ "WHATS_NEW_ON": "What's new on {{version}}",
+ "WHATS_NEW_LIST": "",
+ "WHATS_NEW_1_TITLE": "VNF On-Boarding",
+ "WHATS_NEW_1_BODY": "Vendors can upload VNF HEAT files & License artifacts<ul><li>Upload VNF HEAT files</li><li>Licensing</li><li>Questionnaire</li>",
+ "WHATS_NEW_2_TITLE": "Call & Network Flow-Tool",
+ "WHATS_NEW_2_BODY": "Introduced the ability to host a 3rd party<br/>Enhance VF and Service design with Call and Network flows; Call & Network Flows created and stored as Information Artifacts.",
+ "WHATS_NEW_3_TITLE": "Import VF from On-Boarded VNF",
+ "WHATS_NEW_3_BODY": "Import VF Metadata from vendor supplied CSAR file<br/>Create the VF based on data included in the CSAR file. Includes; VF topology and deployment artifacts<br/>Once checked in the VF is Displayed in the Catalog",
+ "WHATS_NEW_4_TITLE": "App Navigation",
+ "WHATS_NEW_4_BODY": "This release introduces View and Edit modes<ol><li>Use the view mode when:<ul><li>User does not have authorization to edit an Asset</li><li>Asset is in Check-In Mode</li></ul></li><li>Use the Edit Mode when:<ul><li>User has authorization to edit an Asset</li><li>Asset is in Check-out Mode</li></ul></li></ol>",
+ "WHATS_NEW_5_TITLE": "Certification Studio",
+ "WHATS_NEW_6_TITLE": "Composition: Virtual Link",
+ "WHATS_NEW_6_BODY": "The ability to link VFs via a Virtual link has been expanded. Now a Virtual link can be defined as having either Point-to-Point connectivity or Multi-point connectivity. Additionally from within a Virtual Link, Point-to-Point connectivity can be dynamically changed to Multi-Point connectivity.",
+ "WHATS_NEW_7_TITLE": "Distribution",
+ "WHATS_NEW_7_BODY": "<ul><li>Distribution of artifact to App-C</li><li>Distribution of artifact to ALTS</li><li>Distribution of artifact to A&AI</li></ul>",
+ "WHATS_NEW_8_TITLE": "New Brand",
+ "WHATS_NEW_8_BODY": "Effort was invested in improving the overall application Usability, and the User Interface was modified to better reflect branding standards.",
+ "=========== USER_MANAGEMENT SCREEN ===========": "",
+ "USER_MANAGEMENT": "User Management",
+ "USER_MANAGEMENT_TABLE_HEADER_USER_ID": "User ID",
+ "USER_MANAGEMENT_SEARCH_LABEL": "Search user by name, user id, email or role",
+ "USER_MANAGEMENT_SEARCH_TEXT": "Enter user id",
+ "CATEGORY_MANAGEMENT": "Category Management",
+ "ECOMP": "ECOMP",
+ "MONITOR": "Monitor",
+ "USER_MANAGEMENT_VIEW_DELETE_MODAL_TITLE": "Delete User Confirmation",
+ "USER_MANAGEMENT_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete the user?",
+ "NEW_USER_ERROR_USER_ID_REQUIRED": "User id is required.",
+ "NEW_USER_ERROR_USER_ID_NOT_VALID": "User id not valid.",
+ "NEW_USER_ERROR_ROLE_REQUIRED": "User role is required.",
+ "=========== CONFIRMATION_MODAL ===========": "",
+ "CONFIRMATION_MODAL_PLACEHOLDER": "Comment...",
+ "=========== CATEGORY_MANAGEMENT SCREEN ===========": "",
+ "RESOURCE_CATEGORY_HEADER": "Resource Category",
+ "SERVICE_CATEGORY_HEADER": "Service Category",
+ "SUBCATEGORY_HEADER": "Sub Category",
+ "ADD_CATEGORY": "New",
+ "ADD_SUBCATEGORY": "New",
+ "DELETE_CATEGORY_MODAL_HEADER": "Delete {{modelType}}",
+ "DELETE_CATEGORY_MODAL_CATEGORY_NAME": "Are you sure you want to delete the {{modelType}}?",
+ "CREATE_CATEGORY_MODAL_HEADER": "Create new {{modelType}}",
+ "CREATE_CATEGORY_MODAL_CATEGORY_NAME": "Enter {{modelType}} name",
+ "CREATE_CATEGORY_MODAL_REQUIRED": "{{modelType}} name is mandatory",
+ "CREATE_CATEGORY_MODAL_MINLENGTH": "{{modelType}} name should be at least {{minlength}} characters",
+ "CREATE_CATEGORY_MODAL_PATTERN": "{{modelType}} name is not valid",
+ "=========== PDF FILE ===========": "",
+ "PDF_FILE_DECLARATION_BOLD": "",
+ "PDF_FILE_DECLARATION": "",
+ "=========== DEPLOYMENT ARTIFACTS ===========": "",
+ "DEPLOYMENT_ARTIFACT_NO_ARTIFACTS_TO_DISPLAY": "There are no deployment artifacts to display",
+ "DEPLOYMENT_ARTIFACT_BUTTON_ADD_HEAT": "Add {{name}}",
+ "DEPLOYMENT_ARTIFACT_BUTTON_ADD_BASE_HEAT": "Add Base HEAT Artifact",
+ "DEPLOYMENT_ARTIFACT_BUTTON_ADD_NETWORK_HEAT": "Add Network HEAT Artifact",
+ "DEPLOYMENT_ARTIFACT_BUTTON_ADD_VOLUME_HEAT": "Add Volume HEAT Artifact",
+ "DEPLOYMENT_ARTIFACT_BUTTON_ADD_OTHER": "Add Other Artifact",
+ "DEPLOYMENT_ARTIFACT_GAB_NO_CONFIG": "Generic Artifact Browser has no columns configured",
+ "=========== IMPORT VF ===========": "",
+ "IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_TITLE": "Create VF",
+ "IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_DESCRIPTION": "Your VF is being created.<br/>It can take up to 10 minutes.<br/>When done, you can view it in SDC Catalog.",
+ "IMPORT_VF_MESSAGE_CREATE_FINISHED_TITLE": "Create/Update",
+ "IMPORT_VF_MESSAGE_CREATE_FINISHED_DESCRIPTION": "saved successfully",
+ "IMPORT_VF_ALREADY_EXISTS_TITLE": "Create VF",
+ "IMPORT_VF_ALREADY_EXISTS_DESCRIPTION": "The VF {{vfName}} is already certified.<br/>When updating a VF that was already certified, the values for several parameters will not be changed.<br/>These parameters are: Name, Category and Icon.",
+ "=========== TABS TITLE ===========": "",
+ "HIERARCHY_TAB_TITLE": "HIERARCHY",
+ "DEPLOYMENT_TAB_TITLE": "DEPLOYMENT",
+ "=========== DISTRIBUTION VIEW ===========": "",
+ "DISTRIBUTION_VIEW_TITLE_USER_ID": "User id:",
+ "=========== SUCCESS MESSAGES ===========": "",
+ "CHECKIN_SUCCESS_MESSAGE_TEXT": "Checked in successfully",
+ "CHECKIN_SUCCESS_MESSAGE_TITLE": "Check in",
+ "CHECKOUT_SUCCESS_MESSAGE_TEXT": "Checked out successfully",
+ "CHECKOUT_SUCCESS_MESSAGE_TITLE": "Check out",
+ "DELETE_SUCCESS_MESSAGE_TEXT": "Deleted successfully",
+ "DELETE_SUCCESS_MESSAGE_TITLE": "Delete",
+ "APPROVE_SUCCESS_MESSAGE_TEXT": "Approved successfully",
+ "APPROVE_SUCCESS_MESSAGE_TITLE": "Approve",
+ "DISTRIBUTE_SUCCESS_MESSAGE_TEXT": "Distributed successfully",
+ "DISTRIBUTE_SUCCESS_MESSAGE_TITLE": "Distribute",
+ "RESTORE_SUCCESS_MESSAGE_TITLE": "Restore",
+ "RESTORE_SUCCESS_MESSAGE_TEXT": "successfully restored",
+ "ARCHIVE_SUCCESS_MESSAGE_TITLE": "Archive",
+ "ARCHIVE_SUCCESS_MESSAGE_TEXT": "successfully archived",
+ "=========== ON BOARDING MODAL ===========": "",
+ "ON_BOARDING_MODAL_SUB_TITLE": "Select one of the software product component below:",
+ "ON_BOARDING_GENERAL_INFO": "Displays a table of VSPs created using Onboarding.\nEach row displays details for a single VSP.\nWhen expanded you can either import CSAR files that are yet to be imported or update CSAR files that were previously imported.",
+ "ON_BOARDING_IMPORT_INFO": "Displays the Onboarding repository and supports importing on-boarded CSAR files.\nSelect an imported CSAR file to create a VF from the on-boarded and imported information.",
+ "ON_BOARDING_UPDATE_INFO": "Displays the Onboarding repository and supports updating on-boarded and previously imported CSAR files.\nClicking Update, updates the existing VF with information available from a new version of the CSAR file.",
+ "=========== HEAT PARAMETERS MODAL INFO MESSAGES ===========": "",
+ "DEFAULT_VALUE_INFO": "This column indicates all the default values that were declared in the Main Heat ",
+ "CURRENT_VALUE_INFO": "This column indicates:<br/>• Default values that were declared in the main HEAT & does not have a value in the ENV<br/>• Values that were declared in the ENV<br/>• All the values that appear in the current value fields will be generated into the ENV",
+ "=========== MODULE PROPERTY FORM ===========": "",
+ "MIN_VALIDATION_ERROR": "Value cannot be lower than the 'min_vf_module_instances' and 'initial_count'",
+ "MAX_VALIDATION_ERROR": "Value cannot be higher than the 'max_vf_module_instances' and 'initial_count'",
+ "MIN_MAX_VALIDATION": "Value must be between 'min_vf_module_instances' and 'max vf module instances'",
+ "MIN_VALIDATION_VF_LEVE_ERROR": " Value of 'min_vf_module_instances' must not be lower than defined in VF level",
+ "MAX_VALIDATION_VF_LEVE_ERROR": " Value of 'max_vf_module_instances' must not be higher than defined in VF level",
+ "=========== SERVICE PATH SELECTOR ===========": "",
+ "SERVICE_PATH_SELECTOR_HIDE_ALL_VALUE": "⚊ Hide all ⚊",
+ "SERVICE_PATH_SELECTOR_SHOW_ALL_VALUE": "⚊ Show all ⚊",
+ "SERVICE_OPERATION_PROPERTY_TOOLTIP_TEXT": "Service properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.",
+ "=========== INTERFACE DEFINITION ==========": "",
"INTERFACE_DATA_EMPTY": "No Interface data to display",
"=========== INTERFACE OPERATION ==========": "",
- "INTERFACE_ADD_OPERATION": "Add Operation",
- "INTERFACE_EXPAND_ALL": "Expand All",
- "INTERFACE_COLLAPSE_ALL": "Collapse All",
- "INTERFACE_HEADER_NAME": "Name",
- "INTERFACE_HEADER_DESCRIPTION": "Description",
-
- "=========== INTERFACE OPERATION MODAL ATTRIBUTES =========": "",
- "INTERFACE_CREATE_TITLE": "Create New Operation",
- "INTERFACE_EDIT_TITLE": "Edit Operation",
- "INTERFACE_DELETE_TITLE": "Delete Operation",
- "INTERFACE_CANCEL_BUTTON": "Cancel",
- "INTERFACE_SAVE_BUTTON": "Save",
- "INTERFACE_CREATE_BUTTON": "Create",
- "INTERFACE_DELETE_BUTTON": "Delete",
- "INTERFACE_DELETE_TEXT": "Are you sure you want to delete {{operationName}}?",
-
- "=========== OPERATION CREATOR ============": "",
- "OPERATION_PROPERTY_TOOLTIP_TEXT": "VNF properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.",
- "SERVICE_OPERATION_PROPERTY_TOOLTIP_TEXT": "Service properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.",
- "NO_WORKFLOW_ASSOCIATION": "No Workflow",
- "NEW_WORKFLOW_ASSOCIATION": "New Workflow",
- "EXISTING_WORKFLOW_ASSOCIATION": "Internal Workflow",
- "EXTERNAL_WORKFLOW_ASSOCIATION": "External Workflow",
-
- "OPERATION_INTERFACE_TYPE": "Interface Name",
- "OPERATION_NAME": "Operation Name",
- "OPERATION_IMPLEMENTATION": "Implementation",
- "IMPLEMENTATION_NAME": "Implementation Name",
- "OPERATION_DESCRIPTION": "Description",
- "OPERATION_ARTIFACT": "Workflow Artifact",
- "OPERATION_WORKFLOW_ASSIGNMENT": "Workflow Assignment",
- "OPERATION_WORKFLOW": "Workflow",
- "OPERATION_NO_WORKFLOW_ERROR": "No Certified Versions Available",
- "OPERATION_NO_WORKFLOW_CONNECTION": "Failed to Load Workflows",
- "OPERATION_WORKFLOW_ARCHIVED": "Archived",
- "OPERATION_WORKFLOW_VERSION": "Workflow Version",
- "OPERATION_ADD_INPUT": "Add Input",
- "OPERATION_PARAM_NAME": "Name",
- "OPERATION_PARAM_TYPE": "Type",
- "OPERATION_PARAM_VALUE": "Value",
- "OPERATION_PARAM_PROPERTY": "Property",
- "OPERATION_PARAM_MANDATORY": "Mandatory",
- "OPERATION_INPUT_EMPTY": "No Input Data",
- "OPERATION_INPUT_VALUE": "Value",
- "OPERATION_ADD_INPUT": "Add Input",
- "OPERATION_ADD": "Add",
- "OPERATION_ADD1": "Add Operation",
- "OPERATION_CANCEL": "Cancel",
- "OPERATION_INTERFACE_REQUIRED_ERROR": "Interface is required",
- "OPERATION_OPERATION_REQUIRED_ERROR": "Operation is required",
- "OPERATION_IMPLEMENTATION_REQUIRED_ERROR": "Implementation is required",
- "OPERATION_INPUT_NAME_UNIQUE_ERROR": "The input names must be unique",
- "OPERATION_INPUT_NAME_ERROR": "The input name must not be empty or blank",
- "OPERATION_INPUT_NAME_REQUIRED": "Input name is required",
-
- "EMPTY_PARAM_TABLE_HEADER": "NO PARAMETERS TO SHOW",
- "EMPTY_PARAM_TABLE_NO_SELECTED_WORKFLOW_1": "Select Workflow and Workflow Version above",
- "EMPTY_PARAM_TABLE_NO_SELECTED_WORKFLOW_2": "in order to see the parameters",
- "EMPTY_PARAM_TABLE_NO_WORKFLOWS": "Only <b>certified</b> workflow versions can be assigned to an operation",
-
- "PARAM_NONE_OF_TYPE": "No available properties of this type.",
-
- "=========== OPERATION UPDATE ===============": "",
- "DEPLOYMENT_ARTIFACT_TYPE": "Deployment Artifact Type",
- "TOSCA_ARTIFACT_TYPE": "Tosca Artifact Type",
- "ARTIFACT_VERSION": "Artifact Version",
- "IMPLEMENTATION_ARTIFACT_PROPERTY_NAME": "Name",
- "IMPLEMENTATION_ARTIFACT_PROPERTY_TYPE": "Type",
- "IMPLEMENTATION_ARTIFACT_PROPERTY_VALUE": "Value",
- "INTERFACE_OPERATION_IMPLEMENTATION": "Implementation",
- "INTERFACE_OPERATION_IMPLEMENTATION_NAME": "Name",
- "INTERFACE_OPERATION_IMPLEMENTATION_FILE": "File",
- "ADD_INTERFACE_OPERATION_IMPLEMENTATION_ARTIFACT": "Enable add Artifact To Implementation",
-
- "=========== PLUGIN NOT CONNECTED ===========": "",
- "PLUGIN_NOT_CONNECTED_ERROR_MAIN": "The \"{{pluginName}}\" plugin is currently unavailable.",
- "PLUGIN_NOT_CONNECTED_ERROR_SUB": "Please try again later.",
-
- "============SERVICE CONSUMPTION=============" : "",
- "CONSUMPTION_TYPE": "Type",
- "CONSUMPTION_SOURCE": "Source",
- "CONSUMPTION_STATIC_VALUES": "Static Values",
- "CONSUMPTION_EXPAND_ALL": "Expand All",
- "CONSUMPTION_COLLAPSE_ALL": "Collapse All",
- "CONSUMPTION_NO_INPUTS_TO_SHOW": "NO INPUTS TO SHOW",
- "CONSUMPTION_NO_OPERATIONS_TO_SHOW": "NO OPERATIONS TO SHOW",
-
- "============= DIRECTIVES AND NODE FILTER DEPENDENCY ============" : "",
- "DIRECTIVES_AND_NODE_FILTER_ADD_NODE_FILTER": "Add Node Filter",
- "DIRECTIVES_AND_NODE_FILTER_UPDATE_NODE_FILTER": "Update Node Filter",
- "DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER": "Delete Node Filter",
- "DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER_MSG": "Are you sure you want to delete this node filter?",
- "DIRECTIVES_AND_NODE_FILTER_REMOVE_TITLE": "Remove Directives",
- "DIRECTIVES_AND_NODE_FILTER_REMOVE_TEXT": "Removing \"Directive Option\" will remove directives value and erase all the node filter. Are you sure you want to remove directives?",
- "DIRECTIVES_AND_NODE_FILTER_UPDATE_TITLE": "Update Directives",
- "DIRECTIVES_AND_NODE_FILTER_UPDATE_TEXT": "Changing \"Directive Option\" will remove directives value and erase all the node filter. Are you sure you want to update directives?",
- "VALIDATE_CAPABILITIES_TXT": "Node Filter for Capabilities Properties",
- "VALIDATE_CAPABILITIES_MSG": "The selected Component Instance does not have any capability property",
- "VALIDATE_NODE_PROPERTIES_TXT": "Node Filter for Properties",
- "VALIDATE_NODE_PROPERTIES_MSG": "The selected Component Instance does not have any property",
-
- "============= SUBSTITUTION FILTER MANAGE TAB ======" : "",
- "ADD_SUBSTITUTION_FILTER": "Add Substitution Filter",
- "UPDATE_SUBSTITUTION_FILTER": "Update Substitution Filter",
- "DELETE_SUBSTITUTION_FILTER": "Delete Substitution Filter",
- "DELETE_SUBSTITUTION_FILTER_MSG": "Are you sure you want to delete this Substitution Filter?",
-
- "============= COMPOSITION DETAILS TAB ======" : "",
- "DETAILS_TAB_CHANGE_VERSION_MODAL_TITLE": "Change Version",
- "DETAILS_TAB_CHANGE_VERSION_MODAL_MSG": "Are you sure you want to change the version?\nIt will affect Service-Consumption and Service-Dependencies data",
-
- "============= Generic Modal Btn ============" : "",
- "MODAL_APPROVE" : "Yes",
- "MODAL_SAVE" : "Save",
- "MODAL_CREATE" : "Create",
- "MODAL_CANCEL" : "Cancel",
- "MODAL_DELETE" : "Delete",
-
- "=========== POLICY AND GROUPS ===========": "",
- "ADD_TARGETS" : "Add Targets",
- "ADD_MEMBERS" : "Add Members",
-
- "=========== PROPERTIES ASSIGNMENT DECLARE AS POLICY ===========": "",
- "DELETE_POLICY_TITLE": "Delete Policy",
- "DELETE_POLICY_MSG": "Are you sure you want to delete policy '{{policyName}}'?",
-
- "=========== PROPERTIES ASSIGNMENT SELECT INPUT BUTTON ===========": "",
- "SELECT_INPUT_LABEL": "Select Input" ,
- "DESELECT_INPUT_LABEL": "Deselect Input",
-
- "=========== AUTOMATED UPGRADE ===========": "",
- "RESOURCE_UPGRADE_TITLE" : "Upgrade Services",
- "SERVICE_UPGRADE_TITLE" : "Update Service References",
- "RESOURCE_UPGRADE_STATUS_TITLE" : "Upgrade Services - Status",
- "SERVICE_UPGRADE_STATUS_TITLE" : "Update Service References - Status",
- "RESOURCE_NOTHING_TO_UPGRADE" : "There are no services which include instance of <b>\"{{vspName}}\"</b> VF.<br/>Please close this popup window to continue your work.",
- "SERVICE_NOTHING_TO_UPGRADE" : "There aren’t any services which include a reference to {{vspName}}.",
- "RESOURCE_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE": "The following services include instance of <b>\"{{vspName}}\"</b> VF.<br/>Services eligible for upgrade are auto selected with the latest version of <b>\"{{vspName}}\" {{vspVersion}}</b>.<br/>Please de-select them if you do not want them to be upgraded",
- "RESOURCE_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED": "The following services include instance of <b>\"{{vspName}}\"</b> VF, however they are locked and can not be automatically upgraded with <b>\"{{vspName}}\" {{vspVersion}}</b>.<br/>Please close this popup window to continue your work.",
- "RESOURCE_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED": "The listed services each include the <b>\"{{vspName}}\"</b> VF and have already been upgraded with the most recently certified version of the <b>{{vspName}} {{vspVersion}}</b>.<br/>Please close this popup window to continue your work.",
- "RESOURCE_CERTIFICATION_STATUS_TEXT": "The \"{{resourceName}}\" VF was successfully updated and certified.",
- "RESOURCE_UPGRADE_STATUS_SUCCESS": "Automated service upgrade was completed and successful.<br/>The services which are successfully upgraded are in checked-in state with version displayed below. Please close this popup window and proceed with design completion on the services",
- "RESOURCE_UPGRADE_STATUS_FAIL": "Automated service upgrade failed.",
- "SERVICE_UPGRADE_STATUS_SUCCESS": "Automated service upgrade was completed and successful.<br/>The services which are successfully upgraded are in checked-in state with version displayed below. Please close this popup window and proceed with design completion on the services",
- "SERVICE_UPGRADE_STATUS_FAIL": "Automated service upgrade failed.",
- "SERVICE_CERTIFICATION_STATUS_TEXT": "Service successfully certified",
- "SERVICE_CERTIFICATION_STATUS_TITLE": "Service Certification",
- "SERVICE_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE": "The following services reference <b>{{vspName}}</b>.<br/> One or more of the services were not yet upgraded with the most recently certified version of <b>{{vspName}}</b>.</br>Select services from the list to upgrade them with <b>{{vspName}} {{vspVersion}}</b>.",
- "SERVICE_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED": "The listed services reference <b>{{vspName}}</b>.<br/> These services were not upgraded with the most recently certified version of <b>{{vspName}}</b>. Currently they are locked from being upgraded with <b>{{vspName}} {{vspVersion}}</b>",
- "SERVICE_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED": "The listed services each reference <b>{{vspName}}</b> and have already been updated with the most recently certified version of the <b>{{vspName}} {{vspVersion}}</b>",
-
- "=========== ERROR_MODAL ===========": "",
- "ERROR_MODAL_TEXT": "Error code: {{messageId}} <br/> Status code: {{status}} <br/> {{message}}",
- "DEFAULT_ERROR_MESSAGE": "Error getting response from server",
-
- "=========== CONFORMANCE_LEVEL_MODAL ===========": "",
- "CONFORMANCE_LEVEL_MODAL_TITLE": "Warning",
- "CONFORMANCE_LEVEL_MODAL_TEXT": "<p>You are about to distribute a service with models and artifacts created with an <b>older version of the platform</b>.For such service, new properties, metadata and requirements needed by ECOMP components will not be available.</p><p>It is highly recommended that you upgrade the service models and artifacts.</p><p>Click \"Continue\" if you need to distribute the current service version.<br />Click \"Reject\" if you need to stop the distribution and manually upgrade the service.</p>",
-
- "=========== REQUIREMENTS AND CAPABILITIES ===========": "",
- "REQ_NAME": "Requirement Name",
- "REQ_RELATED_CAPABILITY": "Related Capability",
- "REQ_NODE": "Node",
- "REQ_RELATIONSHIP": "Relationship",
- "REQ_CAP_OCCURRENCES": "Occurrences",
- "REQ_CAP_OCCURRENCES_UNBOUNDED": "UNBOUNDED",
- "REQ_CAP_OCCURRENCES_MIN": "Min",
- "REQ_CAP_OCCURRENCES_MAX": "Max",
- "CAP_NAME": "Capability Name",
- "CAP_TYPE": "Capability Type",
- "CAP_DESCRIPTION": "Description",
- "CAP_VALID_SOURCE": "Valid Sources"
+ "INTERFACE_ADD_OPERATION": "Add Operation",
+ "INTERFACE_EXPAND_ALL": "Expand All",
+ "INTERFACE_COLLAPSE_ALL": "Collapse All",
+ "INTERFACE_HEADER_NAME": "Name",
+ "INTERFACE_HEADER_DESCRIPTION": "Description",
+ "=========== INTERFACE OPERATION MODAL ATTRIBUTES =========": "",
+ "INTERFACE_CREATE_TITLE": "Create New Operation",
+ "INTERFACE_EDIT_TITLE": "Edit Operation",
+ "INTERFACE_DELETE_TITLE": "Delete Operation",
+ "INTERFACE_CANCEL_BUTTON": "Cancel",
+ "INTERFACE_CLOSE_BUTTON": "Close",
+ "INTERFACE_SAVE_BUTTON": "Save",
+ "INTERFACE_CREATE_BUTTON": "Create",
+ "INTERFACE_DELETE_BUTTON": "Delete",
+ "INTERFACE_DELETE_TEXT": "Are you sure you want to delete {{operationName}}?",
+ "=========== OPERATION CREATOR ============": "",
+ "OPERATION_PROPERTY_TOOLTIP_TEXT": "VNF properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.",
+ "NO_WORKFLOW_ASSOCIATION": "No Workflow",
+ "NEW_WORKFLOW_ASSOCIATION": "New Workflow",
+ "EXISTING_WORKFLOW_ASSOCIATION": "Internal Workflow",
+ "EXTERNAL_WORKFLOW_ASSOCIATION": "External Workflow",
+ "OPERATION_INTERFACE_TYPE": "Interface Name",
+ "OPERATION_NAME": "Operation Name",
+ "OPERATION_IMPLEMENTATION": "Implementation",
+ "IMPLEMENTATION_NAME": "Implementation Name",
+ "OPERATION_DESCRIPTION": "Description",
+ "OPERATION_ARTIFACT": "Workflow Artifact",
+ "OPERATION_WORKFLOW_ASSIGNMENT": "Workflow Assignment",
+ "OPERATION_WORKFLOW": "Workflow",
+ "OPERATION_NO_WORKFLOW_ERROR": "No Certified Versions Available",
+ "OPERATION_NO_WORKFLOW_CONNECTION": "Failed to Load Workflows",
+ "OPERATION_WORKFLOW_ARCHIVED": "Archived",
+ "OPERATION_WORKFLOW_VERSION": "Workflow Version",
+ "OPERATION_PARAM_NAME": "Name",
+ "OPERATION_PARAM_TYPE": "Type",
+ "OPERATION_PARAM_VALUE": "Value",
+ "OPERATION_PARAM_PROPERTY": "Property",
+ "OPERATION_PARAM_MANDATORY": "Mandatory",
+ "OPERATION_INPUT_EMPTY": "No Input Data",
+ "OPERATION_INPUT_VALUE": "Value",
+ "OPERATION_INPUT_NAME": "Name",
+ "OPERATION_INPUT_TYPE": "Type",
+ "OPERATION_INPUT_SCHEMA": "Schema",
+ "OPERATION_ADD_INPUT": "Add Input",
+ "OPERATION_ADD": "Add",
+ "OPERATION_ADD1": "Add Operation",
+ "OPERATION_CANCEL": "Cancel",
+ "OPERATION_INTERFACE_REQUIRED_ERROR": "Interface is required",
+ "OPERATION_OPERATION_REQUIRED_ERROR": "Operation is required",
+ "OPERATION_IMPLEMENTATION_REQUIRED_ERROR": "Implementation is required",
+ "OPERATION_INPUT_NAME_UNIQUE_ERROR": "The input names must be unique",
+ "OPERATION_INPUT_NAME_ERROR": "The input name must not be empty or blank",
+ "OPERATION_INPUT_NAME_REQUIRED": "Input name is required",
+ "EMPTY_PARAM_TABLE_HEADER": "NO PARAMETERS TO SHOW",
+ "EMPTY_PARAM_TABLE_NO_SELECTED_WORKFLOW_1": "Select Workflow and Workflow Version above",
+ "EMPTY_PARAM_TABLE_NO_SELECTED_WORKFLOW_2": "in order to see the parameters",
+ "EMPTY_PARAM_TABLE_NO_WORKFLOWS": "Only <b>certified</b> workflow versions can be assigned to an operation",
+ "PARAM_NONE_OF_TYPE": "No available properties of this type.",
+ "=========== OPERATION UPDATE ===============": "",
+ "DEPLOYMENT_ARTIFACT_TYPE": "Deployment Artifact Type",
+ "TOSCA_ARTIFACT_TYPE": "Tosca Artifact Type",
+ "ARTIFACT_VERSION": "Artifact Version",
+ "IMPLEMENTATION_ARTIFACT_PROPERTY_NAME": "Name",
+ "IMPLEMENTATION_ARTIFACT_PROPERTY_TYPE": "Type",
+ "IMPLEMENTATION_ARTIFACT_PROPERTY_VALUE": "Value",
+ "IMPLEMENTATION_ARTIFACT_PROPERTY_SCHEMA": "Schema",
+ "INPUT_LIST_MAP_KEY_PLACEHOLDER": "new map key",
+ "INPUT_LIST_ADD_MAP_ENTRY": "Add Map Entry",
+ "INPUT_LIST_ADD_LIST_ENTRY": "Add List Entry",
+ "INPUT_LIST_TITLE": "Inputs",
+ "ADD_INPUT_TITLE": "New Input",
+ "INTERFACE_OPERATION_IMPLEMENTATION": "Implementation",
+ "INTERFACE_OPERATION_IMPLEMENTATION_NAME": "Name",
+ "INTERFACE_OPERATION_IMPLEMENTATION_FILE": "File",
+ "ADD_INTERFACE_OPERATION_IMPLEMENTATION_ARTIFACT": "Enable add Artifact To Implementation",
+ "=========== PLUGIN NOT CONNECTED ===========": "",
+ "PLUGIN_NOT_CONNECTED_ERROR_MAIN": "The \"{{pluginName}}\" plugin is currently unavailable.",
+ "PLUGIN_NOT_CONNECTED_ERROR_SUB": "Please try again later.",
+ "============SERVICE CONSUMPTION=============": "",
+ "CONSUMPTION_TYPE": "Type",
+ "CONSUMPTION_SOURCE": "Source",
+ "CONSUMPTION_STATIC_VALUES": "Static Values",
+ "CONSUMPTION_EXPAND_ALL": "Expand All",
+ "CONSUMPTION_COLLAPSE_ALL": "Collapse All",
+ "CONSUMPTION_NO_INPUTS_TO_SHOW": "NO INPUTS TO SHOW",
+ "CONSUMPTION_NO_OPERATIONS_TO_SHOW": "NO OPERATIONS TO SHOW",
+ "============= DIRECTIVES AND NODE FILTER DEPENDENCY ============": "",
+ "DIRECTIVES_AND_NODE_FILTER_ADD_NODE_FILTER": "Add Node Filter",
+ "DIRECTIVES_AND_NODE_FILTER_UPDATE_NODE_FILTER": "Update Node Filter",
+ "DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER": "Delete Node Filter",
+ "DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER_MSG": "Are you sure you want to delete this node filter?",
+ "DIRECTIVES_AND_NODE_FILTER_REMOVE_TITLE": "Remove Directives",
+ "DIRECTIVES_AND_NODE_FILTER_REMOVE_TEXT": "Removing \"Directive Option\" will remove directives value and erase all the node filter. Are you sure you want to remove directives?",
+ "DIRECTIVES_AND_NODE_FILTER_UPDATE_TITLE": "Update Directives",
+ "DIRECTIVES_AND_NODE_FILTER_UPDATE_TEXT": "Changing \"Directive Option\" will remove directives value and erase all the node filter. Are you sure you want to update directives?",
+ "VALIDATE_CAPABILITIES_TXT": "Node Filter for Capabilities Properties",
+ "VALIDATE_CAPABILITIES_MSG": "The selected Component Instance does not have any capability property",
+ "VALIDATE_NODE_PROPERTIES_TXT": "Node Filter for Properties",
+ "VALIDATE_NODE_PROPERTIES_MSG": "The selected Component Instance does not have any property",
+ "============= SUBSTITUTION FILTER MANAGE TAB ======": "",
+ "ADD_SUBSTITUTION_FILTER": "Add Substitution Filter",
+ "UPDATE_SUBSTITUTION_FILTER": "Update Substitution Filter",
+ "DELETE_SUBSTITUTION_FILTER": "Delete Substitution Filter",
+ "DELETE_SUBSTITUTION_FILTER_MSG": "Are you sure you want to delete this Substitution Filter?",
+ "============= COMPOSITION DETAILS TAB ======": "",
+ "DETAILS_TAB_CHANGE_VERSION_MODAL_TITLE": "Change Version",
+ "DETAILS_TAB_CHANGE_VERSION_MODAL_MSG": "Are you sure you want to change the version?\nIt will affect Service-Consumption and Service-Dependencies data",
+ "============= Generic Modal Btn ============": "",
+ "MODAL_APPROVE": "Yes",
+ "MODAL_SAVE": "Save",
+ "MODAL_CREATE": "Create",
+ "MODAL_CANCEL": "Cancel",
+ "MODAL_DELETE": "Delete",
+ "=========== POLICY AND GROUPS ===========": "",
+ "ADD_TARGETS": "Add Targets",
+ "ADD_MEMBERS": "Add Members",
+ "=========== PROPERTIES ASSIGNMENT DECLARE AS POLICY ===========": "",
+ "DELETE_POLICY_TITLE": "Delete Policy",
+ "DELETE_POLICY_MSG": "Are you sure you want to delete policy '{{policyName}}'?",
+ "=========== PROPERTIES ASSIGNMENT SELECT INPUT BUTTON ===========": "",
+ "SELECT_INPUT_LABEL": "Select Input",
+ "DESELECT_INPUT_LABEL": "Deselect Input",
+ "=========== AUTOMATED UPGRADE ===========": "",
+ "RESOURCE_UPGRADE_TITLE": "Upgrade Services",
+ "SERVICE_UPGRADE_TITLE": "Update Service References",
+ "RESOURCE_UPGRADE_STATUS_TITLE": "Upgrade Services - Status",
+ "SERVICE_UPGRADE_STATUS_TITLE": "Update Service References - Status",
+ "RESOURCE_NOTHING_TO_UPGRADE": "There are no services which include instance of <b>\"{{vspName}}\"</b> VF.<br/>Please close this popup window to continue your work.",
+ "SERVICE_NOTHING_TO_UPGRADE": "There aren’t any services which include a reference to {{vspName}}.",
+ "RESOURCE_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE": "The following services include instance of <b>\"{{vspName}}\"</b> VF.<br/>Services eligible for upgrade are auto selected with the latest version of <b>\"{{vspName}}\" {{vspVersion}}</b>.<br/>Please de-select them if you do not want them to be upgraded",
+ "RESOURCE_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED": "The following services include instance of <b>\"{{vspName}}\"</b> VF, however they are locked and can not be automatically upgraded with <b>\"{{vspName}}\" {{vspVersion}}</b>.<br/>Please close this popup window to continue your work.",
+ "RESOURCE_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED": "The listed services each include the <b>\"{{vspName}}\"</b> VF and have already been upgraded with the most recently certified version of the <b>{{vspName}} {{vspVersion}}</b>.<br/>Please close this popup window to continue your work.",
+ "RESOURCE_CERTIFICATION_STATUS_TEXT": "The \"{{resourceName}}\" VF was successfully updated and certified.",
+ "RESOURCE_UPGRADE_STATUS_SUCCESS": "Automated service upgrade was completed and successful.<br/>The services which are successfully upgraded are in checked-in state with version displayed below. Please close this popup window and proceed with design completion on the services",
+ "RESOURCE_UPGRADE_STATUS_FAIL": "Automated service upgrade failed.",
+ "SERVICE_UPGRADE_STATUS_SUCCESS": "Automated service upgrade was completed and successful.<br/>The services which are successfully upgraded are in checked-in state with version displayed below. Please close this popup window and proceed with design completion on the services",
+ "SERVICE_UPGRADE_STATUS_FAIL": "Automated service upgrade failed.",
+ "SERVICE_CERTIFICATION_STATUS_TEXT": "Service successfully certified",
+ "SERVICE_CERTIFICATION_STATUS_TITLE": "Service Certification",
+ "SERVICE_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE": "The following services reference <b>{{vspName}}</b>.<br/> One or more of the services were not yet upgraded with the most recently certified version of <b>{{vspName}}</b>.</br>Select services from the list to upgrade them with <b>{{vspName}} {{vspVersion}}</b>.",
+ "SERVICE_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED": "The listed services reference <b>{{vspName}}</b>.<br/> These services were not upgraded with the most recently certified version of <b>{{vspName}}</b>. Currently they are locked from being upgraded with <b>{{vspName}} {{vspVersion}}</b>",
+ "SERVICE_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED": "The listed services each reference <b>{{vspName}}</b> and have already been updated with the most recently certified version of the <b>{{vspName}} {{vspVersion}}</b>",
+ "=========== ERROR_MODAL ===========": "",
+ "ERROR_MODAL_TEXT": "Error code: {{messageId}} <br/> Status code: {{status}} <br/> {{message}}",
+ "DEFAULT_ERROR_MESSAGE": "Error getting response from server",
+ "=========== CONFORMANCE_LEVEL_MODAL ===========": "",
+ "CONFORMANCE_LEVEL_MODAL_TITLE": "Warning",
+ "CONFORMANCE_LEVEL_MODAL_TEXT": "<p>You are about to distribute a service with models and artifacts created with an <b>older version of the platform</b>.For such service, new properties, metadata and requirements needed by ECOMP components will not be available.</p><p>It is highly recommended that you upgrade the service models and artifacts.</p><p>Click \"Continue\" if you need to distribute the current service version.<br />Click \"Reject\" if you need to stop the distribution and manually upgrade the service.</p>",
+ "=========== REQUIREMENTS AND CAPABILITIES ===========": "",
+ "REQ_NAME": "Requirement Name",
+ "REQ_RELATED_CAPABILITY": "Related Capability",
+ "REQ_NODE": "Node",
+ "REQ_RELATIONSHIP": "Relationship",
+ "REQ_CAP_OCCURRENCES": "Occurrences",
+ "REQ_CAP_OCCURRENCES_UNBOUNDED": "UNBOUNDED",
+ "REQ_CAP_OCCURRENCES_MIN": "Min",
+ "REQ_CAP_OCCURRENCES_MAX": "Max",
+ "CAP_NAME": "Capability Name",
+ "CAP_TYPE": "Capability Type",
+ "CAP_DESCRIPTION": "Description",
+ "CAP_VALID_SOURCE": "Valid Sources"
}
diff --git a/catalog-ui/src/main.ts b/catalog-ui/src/main.ts
index f19f9c4b4e..fd6c834b08 100644
--- a/catalog-ui/src/main.ts
+++ b/catalog-ui/src/main.ts
@@ -18,7 +18,6 @@
* ============LICENSE_END=========================================================
*/
-//import './app/app.ts';
import {ng1appModule} from './app/app';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {enableProdMode} from '@angular/core';
@@ -29,21 +28,21 @@ import {IAppConfigurtaion} from "./app/models/app-config";
declare const __ENV__: string;
export declare let sdc2Config: IAppConfigurtaion;
-if (__ENV__==='prod') {
- sdc2Config = require('./../configurations/prod.js');
- enableProdMode();
+if (__ENV__ === 'prod') {
+ sdc2Config = require('./../configurations/prod.js');
+ enableProdMode();
} else {
- sdc2Config = require('./../configurations/dev.js');
+ sdc2Config = require('./../configurations/dev.js');
}
-// Ugliy fix because the cookie recieved from webseal change his value after some seconds.
-let timeout:number = 0;
-if (__ENV__==='dev'){
- timeout=0;
+// Uglify fix because the cookie received from webseal change his value after some seconds.
+let timeout: number = 0;
+if (__ENV__ === 'dev') {
+ timeout = 0;
}
-window.setTimeout(()=>{
- platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
- const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
- upgrade.bootstrap(document.body, [ng1appModule.name], {strictDi: true});
- });
-},timeout);
+window.setTimeout(() => {
+ platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
+ const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
+ upgrade.bootstrap(document.body, [ng1appModule.name], {strictDi: true});
+ });
+}, timeout);
diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java b/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java
index 6ee4984b9f..be534d2909 100644
--- a/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java
+++ b/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java
@@ -47,8 +47,15 @@ public class JsonUtils {
return json.entrySet().isEmpty();
}
- public static boolean isEmptyJson(JsonElement json) {
- return json.isJsonPrimitive() ? false : JsonUtils.isEmptyJson(json.getAsJsonObject());
+ public static boolean isEmptyJson(final JsonElement json) {
+ if (json.isJsonArray()) {
+ return json.getAsJsonArray().isEmpty();
+ }
+ if (json.isJsonObject()) {
+ return JsonUtils.isEmptyJson(json.getAsJsonObject());
+ }
+
+ return false;
}
public static boolean isJsonNullOrEmpty(JsonObject json) {
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
index bac613861b..e1705a2255 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
@@ -30,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
import com.aventstack.extentreports.Status;
import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.collections.MapUtils;
@@ -59,6 +60,7 @@ import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInfor
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsTab;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
@@ -150,7 +152,7 @@ public class ImportVfcUiTest extends SetupCDTest {
assertTrue(interfaceDefinitionPage.isInterfaceDefinitionOperationPresent(OPERATION_NAME));
final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal = interfaceDefinitionPage.clickOnInterfaceDefinitionOperation(
OPERATION_NAME);
- interfaceDefinitionOperationsModal.isLoaded();
+ interfaceDefinitionOperationsModal.isLoaded(true);
ExtentTestActions
.takeScreenshot(Status.INFO, "clickOnOInterfaceOperation", "Interface Definition Operation Modal opened");
checkInterfaceDefinitionData(interfaceDefinitionOperationsModal);
@@ -171,9 +173,9 @@ public class ImportVfcUiTest extends SetupCDTest {
private void checkInterfaceDefinitionData(final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal) {
assertTrue(interfaceDefinitionOperationsModal.getDescription().isEmpty());
- assertEquals(interfaceDefinitionOperationsModal.getImplementationName(), "path/to/my/implementation.sh");
- assertEquals(interfaceDefinitionOperationsModal.getInputName(), "first");
- assertEquals(interfaceDefinitionOperationsModal.getInputValue(), "1234");
+ assertEquals("path/to/my/implementation.sh", interfaceDefinitionOperationsModal.getImplementationName());
+ final List<InputData> inputList = interfaceDefinitionOperationsModal.getInputs();
+ assertTrue(inputList.stream().anyMatch(inputData -> "first".equals(inputData.getName())), "Input of name 'first' expected");
}
private ComponentPage manageAttributes(final ComponentPage componentPage) {
@@ -223,13 +225,18 @@ public class ImportVfcUiTest extends SetupCDTest {
compositionInterfaceOperationsModal.isLoaded();
ExtentTestActions
.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
- compositionInterfaceOperationsModal.clickOnDelete();
+ compositionInterfaceOperationsModal.deleteInput("first");
ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.clickOnDelete", "Input deleted");
- compositionInterfaceOperationsModal.addInput();
- ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.addInput", "Adding Input");
- final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData = new InterfaceDefinitionOperationsModal.InterfaceOperationsData
- ("This is CREATE operation", "fullPath/to/my/newImplementation.sh", "second", "9876");
+ List<InputData> inputDataList = List.of(
+ new InputData("stringInput", "string", "1"),
+ new InputData("booleanInput", "boolean", true),
+ new InputData("integerInput", "integer", 1)
+ );
+ final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData =
+ new InterfaceDefinitionOperationsModal.InterfaceOperationsData(
+ "This is CREATE operation", "fullPath/to/my/newImplementation.sh", inputDataList
+ );
compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData);
compositionInterfaceOperationsTab.isLoaded();
@@ -404,7 +411,10 @@ public class ImportVfcUiTest extends SetupCDTest {
final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
assertEquals(interfaceOperationsData.getDescription(), compositionInterfaceOperationsModal.getDescription());
assertEquals(interfaceOperationsData.getImplementationName(), compositionInterfaceOperationsModal.getImplementationName());
- assertEquals(interfaceOperationsData.getInputName(), compositionInterfaceOperationsModal.getInputName());
- assertEquals(interfaceOperationsData.getInputValue(), compositionInterfaceOperationsModal.getInputValue());
+ interfaceOperationsData.getInputList().forEach(inputData -> {
+ final boolean hasInput = compositionInterfaceOperationsModal.getInputs().stream()
+ .anyMatch(inputData1 -> inputData1.getName().equals(inputData.getName()));
+ assertTrue(hasInput, String.format("Expecting input '%s'", inputData.getName()));
+ });
}
}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
index 46c0aefe18..96193f69a2 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
@@ -81,6 +81,7 @@ import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInfor
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsTab;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.RelationshipWizardInterfaceOperation.InterfaceOperationsData;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
@@ -247,9 +248,12 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
compositionPage.isLoaded();
ExtentTestActions.addScreenshot(Status.INFO, "select-VFC-node", "Selecting Node on composition");
compositionPage.selectNode(vfcs.get(1).getName());
+ final List<InputData> inputList = List.of(
+ new InputData("My_IT_InputName", "string", "My_IT_InputValue")
+ );
final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData =
new InterfaceDefinitionOperationsModal.InterfaceOperationsData("IT for updating an Interface Operation",
- "MyIntegrationTestImplementationName", "My_IT_InputName", "My_IT_InputValue");
+ "MyIntegrationTestImplementationName", inputList);
updateInterfaceOperation(compositionPage, interfaceOperationsData);
componentPage = compositionPage.goToGeneral();
componentPage.isLoaded();
@@ -387,7 +391,6 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
.clickOnOperation(interfaceOperationName);
compositionInterfaceOperationsModal.isLoaded();
ExtentTestActions.takeScreenshot(Status.INFO, "update-interface-operation-modal", "Loading Interface Operations Modal");
- compositionInterfaceOperationsModal.addInput();
compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData);
compositionInterfaceOperationsTab.isLoaded();
ExtentTestActions.addScreenshot(Status.INFO, "updated-interface-operation",
@@ -420,10 +423,10 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
equalToIgnoringCase(compositionInterfaceOperationsModal.getDescription()));
assertThat("The Interface Operation Implementation Name should match", interfaceOperationsData.getImplementationName(),
equalToIgnoringCase(compositionInterfaceOperationsModal.getImplementationName()));
- assertThat("The Interface Operation Input key should match", interfaceOperationsData.getInputName(),
- equalToIgnoringCase(compositionInterfaceOperationsModal.getInputName()));
- assertThat("The Interface Operation Input Value should match", interfaceOperationsData.getInputValue(),
- equalToIgnoringCase(compositionInterfaceOperationsModal.getInputValue()));
+// assertThat("The Interface Operation Input key should match", interfaceOperationsData.getInputName(),
+// equalToIgnoringCase(compositionInterfaceOperationsModal.getInputName()));
+// assertThat("The Interface Operation Input Value should match", interfaceOperationsData.getInputValue(),
+// equalToIgnoringCase(compositionInterfaceOperationsModal.getInputValue()));
compositionInterfaceOperationsModal.clickOnCancel();
}
@@ -453,10 +456,12 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
assertThat("The Interface Operation Implementation Name should match",
updatedInterfaceOperation.get("implementation").equals(interfaceOperationsData.getImplementationName()));
final Map<String, Object> updatedInterfaceOperationInput = (Map<String, Object>) updatedInterfaceOperation.get("inputs");
- assertThat("The Interface Operation Input Key should match",
- updatedInterfaceOperationInput.containsKey(interfaceOperationsData.getInputName()));
- assertThat("The Interface Operation Input Value should match",
- updatedInterfaceOperationInput.containsValue(interfaceOperationsData.getInputValue()));
+ interfaceOperationsData.getInputList().forEach(inputData -> {
+ assertThat("The Interface Operation Input Key should match",
+ updatedInterfaceOperationInput.containsKey(inputData.getName()));
+ assertThat("The Interface Operation Input Value should match",
+ updatedInterfaceOperationInput.containsValue(inputData.getValue()));
+ });
}
private Map<String, Object> downloadToscaArtifact(final ComponentPage resourceCreatePage) throws UnzipException {
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java
index 47b655924c..d834c4c3bc 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java
@@ -117,6 +117,17 @@ public abstract class AbstractPageObject implements PageObject {
}
/**
+ * Find elements inside the provided element using the provided xpath.
+ *
+ * @param element the parent element
+ * @param xpath the xpath expression to search for the internal element
+ * @return the list of WebElement if any found, otherwise throws an exception
+ */
+ protected List<WebElement> findSubElements(final WebElement element, final String xpath) {
+ return element.findElements(By.xpath(xpath));
+ }
+
+ /**
* Find elements inside the provided element using the provided By locator.
*
* @param element the parent element
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java
index c8af405411..5a2cb2f5d5 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java
@@ -21,10 +21,12 @@ package org.onap.sdc.frontend.ci.tests.pages.component.workspace;
import com.aventstack.extentreports.Status;
import java.time.Duration;
+import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
@@ -35,23 +37,33 @@ import org.openqa.selenium.interactions.Actions;
*/
public class InterfaceDefinitionOperationsModal extends AbstractPageObject {
+ private InterfaceOperationInputListComponent inputListComponent;
+ private InterfaceOperationAddInputComponent addInputComponent;
+
public InterfaceDefinitionOperationsModal(final WebDriver webDriver) {
super(webDriver);
}
@Override
public void isLoaded() {
+ isLoaded(false);
+ }
+
+ public void isLoaded(boolean isInViewMode) {
waitForElementVisibility(By.xpath(XpathSelector.TITLE_SPAN.getXPath()));
waitForElementVisibility(By.xpath(XpathSelector.INTERFACE_NAME_LABEL.getXPath()));
waitForElementVisibility(By.xpath(XpathSelector.OPERATION_NAME_LABEL.getXPath()));
- waitForElementVisibility(By.xpath(XpathSelector.INPUT_NAME_SPAN.getXPath()));
- waitForElementVisibility(By.xpath(XpathSelector.INPUT_VALUE_SPAN.getXPath()));
- waitForElementVisibility(By.xpath(XpathSelector.ADD_INPUT_BTN.getXPath()));
waitForElementVisibility(By.xpath(XpathSelector.SAVE_BTN.getXPath()));
waitToBeClickable(By.xpath(XpathSelector.CANCEL_BTN.getXPath()));
+ this.inputListComponent = new InterfaceOperationInputListComponent(webDriver);
+ this.inputListComponent.isLoaded();
+ if (!isInViewMode) {
+ this.addInputComponent = new InterfaceOperationAddInputComponent(webDriver);
+ this.addInputComponent.isLoaded();
+ }
}
- public void clickOnSave() {
+ private void clickOnSave() {
waitToBeClickable(By.xpath(XpathSelector.SAVE_BTN.getXPath())).click();
}
@@ -63,11 +75,26 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject {
waitToBeClickable(By.xpath(XpathSelector.DELETE_BTN.getXPath())).click();
}
+ public void deleteInput(String inputName) {
+ inputListComponent.loadInputList();
+ inputListComponent.deleteInput(inputName);
+ }
+
public void updateInterfaceOperation(final InterfaceOperationsData interfaceOperationsData) {
fillDescription(interfaceOperationsData.getDescription());
fillImplementationName(interfaceOperationsData.getImplementationName());
- fillInputName(interfaceOperationsData.getInputName());
- fillInputValue(interfaceOperationsData.getInputValue());
+ interfaceOperationsData.getInputList().forEach(inputData -> {
+ final InterfaceOperationAddInputComponent addInputComponent = new InterfaceOperationAddInputComponent(webDriver);
+ addInputComponent.isLoaded();
+ addInputComponent.clickOnAddInputLink();
+ addInputComponent.fillInput(inputData);
+ addInputComponent.clickOnAddButton();
+ ExtentTestActions.takeScreenshot(Status.INFO,
+ "compositionInterfaceOperationsModal.addInput." + inputData.getName(),
+ String.format("Input '%s' added", inputData.getName())
+ );
+ addInputComponent.fillValue(inputData);
+ });
clickOnSave();
//there is no feedback from the UI to check if the update was successful. Forcing a wait time trying to guarantee that,
// although time is never a guarantee in this case.
@@ -82,14 +109,6 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject {
setInputField(By.xpath(XpathSelector.INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT.getXPath()), implementationName);
}
- private void fillInputName(final String inputName) {
- setInputField(By.xpath(XpathSelector.FIELD_INPUT_NAME_INPUT.getXPath()), inputName);
- }
-
- private void fillInputValue(final String inputValue) {
- setInputField(By.xpath(XpathSelector.FIELD_INPUT_VALUE_INPUT.getXPath()), inputValue);
- }
-
private void setInputField(final By locator, final String value) {
if (value == null) {
return;
@@ -97,11 +116,12 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject {
final WebElement webElement = findElement(locator);
webElement.clear();
webElement.sendKeys(value);
+
ExtentTestActions.takeScreenshot(Status.INFO, value, value);
}
- public void addInput() {
- waitToBeClickable(By.xpath(XpathSelector.ADD_INPUT_BTN.getXPath())).click();
+ public void clickOnAddInput() {
+ addInputComponent.clickOnAddInputLink();
}
public String getDescription() {
@@ -112,42 +132,44 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject {
return findElement(By.xpath(XpathSelector.INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT.getXPath())).getAttribute("value");
}
- public String getInputName() {
- return findElement(By.xpath(XpathSelector.FIELD_INPUT_NAME_INPUT.getXPath())).getAttribute("value");
- }
-
- public String getInputValue() {
- return findElement(By.xpath(XpathSelector.FIELD_INPUT_VALUE_INPUT.getXPath())).getAttribute("value");
- }
-
- @Getter
- @AllArgsConstructor
- public static class InterfaceOperationsData {
-
- private final String description;
- private final String implementationName;
- private final String inputName;
- private final String inputValue;
+ public List<InputData> getInputs() {
+ inputListComponent.loadInputList();
+ return inputListComponent.getInputList();
}
@AllArgsConstructor
private enum XpathSelector {
TITLE_SPAN("//span[@class='title' and contains(text(), 'Edit Operation')]"),
- ADD_INPUT_BTN("//a[contains(@class,'add-param-link add-btn') and contains(text(), 'Add Input')]"),
DELETE_BTN("//svg-icon[@name='trash-o']"),
SAVE_BTN("//button[@data-tests-id='Save']"),
CANCEL_BTN("//button[@data-tests-id='Cancel']"),
INTERFACE_NAME_LABEL("//label[contains(@class,'sdc-input') and contains(text(), 'Interface Name')]"),
OPERATION_NAME_LABEL("//label[contains(@class,'sdc-input') and contains(text(), 'Operation Name')]"),
INTERFACE_OPERATION_DESCRIPTION_INPUT("//input[@data-tests-id='interface-operation-description']"),
- INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT("//input[@data-tests-id='interface-operation-implementation-name']"),
- INPUT_NAME_SPAN("//span[contains(@class,'field-input-name') and contains(text(), 'Name')]"),
- INPUT_VALUE_SPAN("//span[contains(@class,'field-input-value') and contains(text(), 'Value')]"),
- FIELD_INPUT_NAME_INPUT("//input[@data-tests-id='interface-operation-input-name']"),
- FIELD_INPUT_VALUE_INPUT("//input[@data-tests-id='interface-operation-input-value']");
+ INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT("//input[@data-tests-id='interface-operation-implementation-name']");
- @Getter
private final String xPath;
+ public String getXPath(final String... xpathParams) {
+ return String.format(xPath, xpathParams);
+ }
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public static class InterfaceOperationsData {
+
+ private final String description;
+ private final String implementationName;
+ private final List<InputData> inputList;
+
+ @Getter
+ @AllArgsConstructor
+ public static class InputData {
+
+ private final String name;
+ private final String type;
+ private final Object value;
+ }
}
}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java
new file mode 100644
index 0000000000..f28d98d3c7
--- /dev/null
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java
@@ -0,0 +1,134 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.sdc.frontend.ci.tests.pages.component.workspace;
+
+import lombok.AllArgsConstructor;
+import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+/**
+ * Handles the add input inside the interface operation modal.
+ *
+ * @see "catalog-ui app-add-input component"
+ */
+public class InterfaceOperationAddInputComponent extends AbstractPageObject {
+
+ public InterfaceOperationAddInputComponent(final WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ @Override
+ public void isLoaded() {
+ waitForElementVisibility(XpathSelector.ADD_INPUT_LINK.getXPath());
+ }
+
+ /**
+ * Clicks on the add input link, that opens the add input form.
+ */
+ public void clickOnAddInputLink() {
+ waitToBeClickable(By.xpath(XpathSelector.ADD_INPUT_LINK.getXPath())).click();
+ waitForElementVisibility(XpathSelector.NAME_INPUT.getXPath());
+ waitForElementVisibility(XpathSelector.TYPE_INPUT.getXPath());
+ waitForElementVisibility(XpathSelector.ADD_BTN.getXPath());
+ waitForElementVisibility(XpathSelector.CANCEL_BTN.getXPath());
+ }
+
+ /**
+ * Clicks on the add button that submits the input form.
+ */
+ public void clickOnAddButton() {
+ waitToBeClickable(By.xpath(XpathSelector.ADD_BTN.getXPath())).click();
+ }
+
+ /**
+ * Fills the input form fields with the given data.
+ *
+ * @param inputData the input information
+ */
+ public void fillInput(final InputData inputData) {
+ fillName(inputData.getName());
+ fillType(inputData.getType());
+ }
+
+ /**
+ * Fills an input value, in the input list, based on the given input data.
+ *
+ * @param inputData the input information
+ */
+ public void fillValue(final InputData inputData) {
+ var interfaceOperationInputListComponent = new InterfaceOperationInputListComponent(webDriver);
+ interfaceOperationInputListComponent.isLoaded();
+ interfaceOperationInputListComponent.fillInputValue(inputData.getName(), inputData.getValue());
+ }
+
+ /**
+ * Fills the input name field.
+ *
+ * @param name the name to fill
+ */
+ public void fillName(final String name) {
+ setInputValue(By.xpath(XpathSelector.NAME_INPUT.getXPath()), name);
+ }
+
+ /**
+ * Fills the input type field.
+ *
+ * @param type the type to fill
+ */
+ public void fillType(final String type) {
+ final WebElement inputElement = findElement(By.xpath(XpathSelector.TYPE_INPUT.getXPath()));
+ inputElement.click();
+ waitForElementVisibility(By.xpath(XpathSelector.DROPDOWN_RESULTS.getXPath()));
+ inputElement.sendKeys(type);
+ waitForElementVisibility(By.xpath(XpathSelector.DROPDOWN_OPTION.getXPath(type))).click();
+ }
+
+ private void setInputValue(final By locator, final String value) {
+ if (value == null) {
+ return;
+ }
+
+ final WebElement webElement = findElement(locator);
+ webElement.clear();
+ webElement.sendKeys(value);
+ }
+
+ @AllArgsConstructor
+ private enum XpathSelector {
+ ADD_INPUT_LINK("//a[@data-tests-id='add-input.add-input-link']"),
+ NAME_INPUT("//input[@data-tests-id='add-input.input-name']"),
+ TYPE_INPUT("//input[starts-with(@data-tests-id, 'add-input.input-type')]"),
+ ADD_BTN("//button[@data-tests-id='add-input.add-input-btn']"),
+ CANCEL_BTN("//button[@data-tests-id='add-input.cancel-btn']"),
+ DROPDOWN_RESULTS("//dropdown-results"),
+ DROPDOWN_OPTION("//li[@data-tests-id='%s']");
+
+ private final String xPath;
+
+ public String getXPath(final String... xpathParams) {
+ return String.format(xPath, xpathParams);
+ }
+ }
+}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java
new file mode 100644
index 0000000000..c023401deb
--- /dev/null
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java
@@ -0,0 +1,160 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.sdc.frontend.ci.tests.pages.component.workspace;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import lombok.AllArgsConstructor;
+import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+/**
+ * Handles the input list inside the interface operation modal.
+ *
+ * @see "catalog-ui app-input-list and app-input-list-item ui components"
+ */
+public class InterfaceOperationInputListComponent extends AbstractPageObject {
+
+ private WebElement wrappingElement;
+ private List<WebElement> inputList = new ArrayList<>();
+
+ public InterfaceOperationInputListComponent(final WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ @Override
+ public void isLoaded() {
+ this.wrappingElement = waitForElementVisibility(XpathSelector.WRAPPING_ELEMENT.getXPath());
+ loadInputList();
+ }
+
+ /**
+ * Loads the input list
+ */
+ public void loadInputList() {
+ this.inputList = findSubElements(wrappingElement, XpathSelector.INPUT_LIST.getXPath());
+ }
+
+ /**
+ * Fill an input value.
+ *
+ * @param inputName the input name
+ * @param value the value
+ */
+ public void fillInputValue(final String inputName, final Object value) {
+ if (value == null) {
+ return;
+ }
+ if (value instanceof String || value instanceof Integer || value instanceof Boolean) {
+ fillSimpleValue(inputName, String.valueOf(value));
+ return;
+ }
+ throw new UnsupportedOperationException("Set input value not yet implemented for value type: " + value.getClass().getName());
+ }
+
+ /**
+ * Expands or retracts an input in the input list.
+ *
+ * @param name the input name
+ */
+ public void toggleInputExpansion(final String name) {
+ final Optional<WebElement> inputOpt = findInput(name);
+ final By expandIconSelector = By.xpath(XpathSelector.EXPAND_ICON.getXPath());
+ inputOpt.ifPresent(webElement ->
+ webElement.findElement(expandIconSelector).click()
+ );
+ }
+
+ /**
+ * Deletes an input from the input list.
+ *
+ * @param name the name of the input to delete
+ */
+ public void deleteInput(final String name) {
+ final Optional<WebElement> inputOpt = findInput(name);
+ final By deleteIconSelector = By.xpath(XpathSelector.DELETE_ICON.getXPath());
+ inputOpt.ifPresent(webElement ->
+ webElement.findElement(deleteIconSelector).click()
+ );
+ loadInputList();
+ assertTrue(findInput(name).isEmpty());
+ }
+
+ public List<InputData> getInputList() {
+ if (inputList.isEmpty()) {
+ return Collections.emptyList();
+ }
+ final List<InputData> inputDataList = new ArrayList<>();
+ final By inputLabelSelector = By.xpath(XpathSelector.INPUT_LABEL.getXPath());
+ final By inputTypeSelector = By.xpath(XpathSelector.INPUT_TYPE.getXPath());
+ inputList.forEach(inputWebElement -> {
+ String inputLabel = inputWebElement.findElement(inputLabelSelector).getText();
+ inputLabel = inputLabel.substring(0, inputLabel.length() -1);
+ final String inputType = inputWebElement.findElement(inputTypeSelector).getText();
+ var inputData = new InputData(inputLabel, inputType, null);
+ inputDataList.add(inputData);
+ });
+
+ return inputDataList;
+ }
+
+ private Optional<WebElement> findInput(final String name) {
+ final String label = name + ":";
+ final By inputLabelSelector = By.xpath(XpathSelector.INPUT_LABEL.getXPath());
+ return inputList.stream().filter(webElement -> {
+ final WebElement inputLabel = webElement.findElement(inputLabelSelector);
+ return label.equals(inputLabel.getText());
+ }).findFirst();
+ }
+
+ private void fillSimpleValue(final String inputName, final String inputValue) {
+ toggleInputExpansion(inputName);
+ final Optional<WebElement> inputOpt = findInput(inputName);
+ assertTrue(inputOpt.isPresent(), String.format("Could not set value for input '%s'. The input was not found.", inputName));
+ final By simpleInputValueSelector = By.xpath(XpathSelector.SIMPLE_VALUE_INPUT_RELATIVE_FROM_INPUT_INFO.getXPath());
+ inputOpt.ifPresent(webElement -> webElement.findElement(simpleInputValueSelector).sendKeys(inputValue));
+ }
+
+ @AllArgsConstructor
+ private enum XpathSelector {
+ WRAPPING_ELEMENT("//div[@class='input-tree']"),
+ INPUT_LIST("//div[@class='input-tree']/*/*/*/span[@class='input-info']"),
+ INPUT_LABEL("label[@class='input-label']"),
+ INPUT_TYPE("em[@data-tests-id='input-type']"),
+ SIMPLE_VALUE_INPUT_RELATIVE_FROM_INPUT_INFO("..//li[@class='input-value']/input"),
+ EXPAND_ICON("em[contains(concat(' ',normalize-space(@class),' '),' round-expand-icon ')]"),
+ DELETE_ICON("span[contains(concat(' ',normalize-space(@class),' '),' delete-btn ')]");
+
+ private final String xPath;
+
+ public String getXPath(final String... xpathParams) {
+ return String.format(xPath, xpathParams);
+ }
+ }
+}