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>
diff --git a/catalog-ui/src/app/app.ts b/catalog-ui/src/app/app.ts
index ffa4389..e7e2828 100644
--- a/catalog-ui/src/app/app.ts
+++ b/catalog-ui/src/app/app.ts
@@ -675,7 +675,7 @@
     // $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 3591bc2..e7b1c69 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 7004b43..7fc788b 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 @@
     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 @@
 
         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 109babb..9d8ab36 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;
         }
-        console.info("InputOperationParameter Constructor: ", param)
+    }
+
+    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 {};
+            }
+        }
+
+        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 bd65c3a..267a2ad 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 @@
         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 e1638fb..7c83c55 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 60d6678..b14d0dd 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 {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 {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 @@
 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 @@
   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 @@
   }
 
   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 @@
           selectedInterface: interfaceModel,
           selectedInterfaceOperation: operation,
           validityChangedCallback: this.enableOrDisableSaveButton,
-          isViewOnly: false
+          isViewOnly: this.isViewOnly
         }
     );
     this.modalInstance.instance.open();
@@ -241,7 +238,7 @@
 
   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 0000000..6753b82
--- /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 0000000..5eb4a7f
--- /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 0000000..2c6c1e6
--- /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 0000000..6632d1a
--- /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 0000000..0449da7
--- /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 0000000..cb7346e
--- /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 0000000..b7e34e5
--- /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 0000000..cd75fe8
--- /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 0000000..802bd63
--- /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 0000000..b9784f9
--- /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 0000000..b07a4bb
--- /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 0000000..72812d8
--- /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 156b657..0000000
--- 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 12eacc6..0000000
--- 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 48bb804..0000000
--- 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 6dec416..46db3b9 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 955720c..cb47c8d 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 1099391..ed295e8 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 {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 @@
     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 @@
         isViewOnly: boolean;
     };
 
+    dataTypeMap$: Observable<Map<string, DataTypeModel>>;
+    dataTypeMap: Map<string, DataTypeModel>;
     interfaceType: string;
     artifactVersion: string;
     artifactName: string;
@@ -70,23 +71,40 @@
 
     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 @@
         }
     }
 
-    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 @@
         }
     }
 
-    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 @@
     }
 
     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 @@
         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 2595301..b212eec 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 @@
     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 c148a4e..df8f46d 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 1cbb4e1..6690410 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 5b08e93..70555a5 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 @@
         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 08b49ae..1a0fc47 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 @@
     PropertyModel,
     InputPropertyBase,
     IAppConfigurtaion,
-    SchemaProperty
+    SchemaProperty, DataTypeModel
 } from "../models";
 import {PROPERTY_DATA} from "../utils/constants";
 
@@ -40,7 +40,8 @@
     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 @@
     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 @@
         });
     };
 
+    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;
     };