Implement adding Interface to VFC

Change-Id: I7cd8b82c306294d897d37d486aa3eeff7ca4206d
Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech>
Issue-ID: SDC-3893
Signed-off-by: andre.schmid <andre.schmid@est.tech>
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index e9ae120..37167b4 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -45,6 +45,7 @@
 import {ConnectionWizardModule} from './pages/composition/graph/connection-wizard/connection-wizard.module';
 import {InterfaceOperationModule} from './pages/interface-operation/interface-operation.module';
 import {OperationCreatorModule} from './pages/interface-operation/operation-creator/operation-creator.module';
+import {OperationCreatorInterfaceDefinitionModule} from './pages/interface-definition/operation-creator/operation-creator-interface-definition.module';
 import {LayoutModule} from './components/layout/layout.module';
 import {UserService} from './services/user.service';
 import {DynamicComponentService} from './services/dynamic-component.service';
@@ -158,6 +159,7 @@
     InterfaceOperationModule,
     InterfaceDefinitionModule,
     OperationCreatorModule,
+    OperationCreatorInterfaceDefinitionModule,
     InterfaceOperationHandlerModule,
     ServicePathCreatorModule,
     ServicePathsListModule,
diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/connection-wizard/create-interface-operation/create-interface-operation.component.less b/catalog-ui/src/app/ng2/pages/composition/graph/connection-wizard/create-interface-operation/create-interface-operation.component.less
index 4c7f8ab..ac91713 100644
--- a/catalog-ui/src/app/ng2/pages/composition/graph/connection-wizard/create-interface-operation/create-interface-operation.component.less
+++ b/catalog-ui/src/app/ng2/pages/composition/graph/connection-wizard/create-interface-operation/create-interface-operation.component.less
@@ -20,7 +20,7 @@
 @import '../../../../../../../assets/styles/variables.less';
 @import '../../../../../../../assets/styles/override.less';
 
-.operation-creator {
+.operation-creator-interface-definition {
   font-family: @font-opensans-regular;
   user-select: none;
   padding-top: 12px;
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 07d8fd6..c17c130 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
@@ -20,7 +20,9 @@
 */
 
 import {Component, ComponentRef, Inject, Input} from '@angular/core';
-import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
+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';
@@ -29,265 +31,282 @@
 import {SelectedComponentType} from "../common/store/graph.actions";
 
 import {WorkspaceService} from "../../workspace/workspace.service";
-import {ComponentInterfaceDefinitionModel, InterfaceOperationModel} from "../../../../models/interfaceOperation";
-import {InterfaceOperationHandlerComponent} from "./operation-creator/interface-operation-handler.component";
+import {
+    ComponentInterfaceDefinitionModel,
+    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 {
+    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 {
+    DropdownValue
+} from "../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
 import {ToscaArtifactService} from "../../../services/tosca-artifact.service";
 import {ToscaArtifactModel} from "../../../../models/toscaArtifact";
 
 export class UIInterfaceOperationModel extends InterfaceOperationModel {
-  isCollapsed: boolean = true;
-  isEllipsis: boolean;
-  MAX_LENGTH = 75;
-  constructor(operation: InterfaceOperationModel) {
-    super(operation);
+    isCollapsed: boolean = true;
+    isEllipsis: boolean;
+    MAX_LENGTH = 75;
 
-    if (!operation.description) {
-      this.description = '';
+    constructor(operation: InterfaceOperationModel) {
+        super(operation);
+
+        if (!operation.description) {
+            this.description = '';
+        }
+
+        if (this.description.length > this.MAX_LENGTH) {
+            this.isEllipsis = true;
+        } else {
+            this.isEllipsis = false;
+        }
     }
 
-    if (this.description.length > this.MAX_LENGTH) {
-      this.isEllipsis = true;
-    } else {
-      this.isEllipsis = false;
+    getDescriptionEllipsis(): string {
+        if (this.isCollapsed && this.description.length > this.MAX_LENGTH) {
+            return this.description.substr(0, this.MAX_LENGTH - 3) + '...';
+        }
+        return this.description;
     }
-  }
 
-  getDescriptionEllipsis(): string {
-    if (this.isCollapsed && this.description.length > this.MAX_LENGTH) {
-      return this.description.substr(0, this.MAX_LENGTH - 3) + '...';
+    toggleCollapsed(e) {
+        e.stopPropagation();
+        this.isCollapsed = !this.isCollapsed;
     }
-    return this.description;
-  }
-
-  toggleCollapsed(e) {
-    e.stopPropagation();
-    this.isCollapsed = !this.isCollapsed;
-  }
 }
 
 class ModalTranslation {
-  EDIT_TITLE: string;
-  CANCEL_BUTTON: string;
-  CLOSE_BUTTON: string;
-  SAVE_BUTTON: string;
+    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");
-    });
-  }
+    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");
+        });
+    }
 }
 
 export class UIInterfaceModel extends ComponentInterfaceDefinitionModel {
-  isCollapsed: boolean = false;
+    isCollapsed: boolean = false;
 
-  constructor(interf?: any) {
-    super(interf);
-    this.operations = _.map(
-        this.operations,
-        (operation) => new UIInterfaceOperationModel(operation)
-    );
-  }
+    constructor(interf?: any) {
+        super(interf);
+        this.operations = _.map(
+            this.operations,
+            (operation) => new UIInterfaceOperationModel(operation)
+        );
+    }
 
-  toggleCollapse() {
-    this.isCollapsed = !this.isCollapsed;
-  }
+    toggleCollapse() {
+        this.isCollapsed = !this.isCollapsed;
+    }
 }
 
 @Component({
-  selector: 'app-interface-operations',
-  templateUrl: './interface-operations.component.html',
-  styleUrls: ['./interface-operations.component.less'],
-  providers: [ModalService, TranslateService]
+    selector: 'app-interface-operations',
+    templateUrl: './interface-operations.component.html',
+    styleUrls: ['./interface-operations.component.less'],
+    providers: [ModalService, TranslateService]
 })
 export class InterfaceOperationsComponent {
-  interfaces: UIInterfaceModel[];
-  inputs: Array<InputBEModel>;
-  isLoading: boolean;
-  interfaceTypes: { [interfaceType: string]: string[] };
-  topologyTemplate: TopologyTemplate;
-  componentMetaData: ComponentMetadata;
-  componentInstanceSelected: ComponentInstance;
-  modalInstance: ComponentRef<ModalComponent>;
-  modalTranslation: ModalTranslation;
-  componentInstancesInterfaces: Map<string, InterfaceModel[]>;
+    interfaces: UIInterfaceModel[];
+    inputs: Array<InputBEModel>;
+    isLoading: boolean;
+    interfaceTypes: { [interfaceType: string]: string[] };
+    topologyTemplate: TopologyTemplate;
+    componentMetaData: ComponentMetadata;
+    componentInstanceSelected: ComponentInstance;
+    modalInstance: ComponentRef<ModalComponent>;
+    modalTranslation: ModalTranslation;
+    componentInstancesInterfaces: Map<string, InterfaceModel[]>;
 
-  deploymentArtifactsFilePath: Array<DropdownValue> = [];
-  toscaArtifactTypes: Array<DropdownValue> = [];
+    deploymentArtifactsFilePath: Array<DropdownValue> = [];
+    toscaArtifactTypes: Array<DropdownValue> = [];
 
-  @Input() component: ComponentInstance;
-  @Input() isViewOnly: boolean;
-  @Input() enableMenuItems: Function;
-  @Input() disableMenuItems: Function;
-  @Input() componentType: SelectedComponentType;
+    @Input() component: ComponentInstance;
+    @Input() isViewOnly: boolean;
+    @Input() enableMenuItems: Function;
+    @Input() disableMenuItems: Function;
+    @Input() componentType: SelectedComponentType;
 
 
-  constructor(
-      private TranslateService: TranslateService,
-      private PluginsService: PluginsService,
-      private topologyTemplateService: TopologyTemplateService,
-      private toscaArtifactService: ToscaArtifactService,
-      private modalServiceNg2: ModalService,
-      private workspaceService: WorkspaceService,
-      @Inject("Notification") private Notification: any,
-  ) {
-    this.modalTranslation = new ModalTranslation(TranslateService);
-  }
-
-  ngOnInit(): void {
-    this.componentMetaData = this.workspaceService.metadata;
-    this.loadComponentInstances();
-    this.loadDeployedArtifacts();
-    this.loadToscaArtifacts()
-  }
-
-  private loadComponentInstances() {
-    this.isLoading = true;
-    this.topologyTemplateService.getComponentInstances(this.componentMetaData.componentType, this.componentMetaData.uniqueId)
-    .subscribe((response) => {
-      this.componentInstanceSelected = response.componentInstances.find(ci => ci.uniqueId === this.component.uniqueId);
-      this.initComponentInstanceInterfaceOperations();
-      this.isLoading = false;
-    });
-  }
-
-  private initComponentInstanceInterfaceOperations() {
-    this.initInterfaces(this.componentInstanceSelected.interfaces);
-    this.sortInterfaces();
-  }
-
-  private initInterfaces(interfaces: ComponentInterfaceDefinitionModel[]): void {
-    this.interfaces = _.map(interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
-  }
-
-  private sortInterfaces(): void {
-    this.interfaces = _.filter(this.interfaces, (interf) => interf.operations && interf.operations.length > 0); // remove empty interfaces
-    this.interfaces.sort((a, b) => a.type.localeCompare(b.type)); // sort interfaces alphabetically
-    _.forEach(this.interfaces, (interf) => {
-      interf.operations.sort((a, b) => a.name.localeCompare(b.name)); // sort operations alphabetically
-    });
-  }
-
-  collapseAll(value: boolean = true): void {
-    _.forEach(this.interfaces, (interf) => {
-      interf.isCollapsed = value;
-    });
-  }
-
-  isAllCollapsed(): boolean {
-    return _.every(this.interfaces, (interf) => interf.isCollapsed);
-  }
-
-  isAllExpanded(): boolean {
-    return _.every(this.interfaces, (interf) => !interf.isCollapsed);
-  }
-
-  isListEmpty(): boolean {
-    return _.filter(
-        this.interfaces,
-        (interf) => interf.operations && interf.operations.length > 0
-    ).length === 0;
-  }
-
-  private enableOrDisableSaveButton = (): boolean => {
-    return this.isViewOnly;
-  }
-
-  onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
-
-    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);
+    constructor(
+        private TranslateService: TranslateService,
+        private PluginsService: PluginsService,
+        private topologyTemplateService: TopologyTemplateService,
+        private toscaArtifactService: ToscaArtifactService,
+        private modalServiceNg2: ModalService,
+        private workspaceService: WorkspaceService,
+        @Inject("Notification") private Notification: any,
+    ) {
+        this.modalTranslation = new ModalTranslation(TranslateService);
     }
-    const modalModel: ModalModel = new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', buttonList, 'custom');
-    this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
 
-    this.modalServiceNg2.addDynamicContentToModal(
-        this.modalInstance,
-        InterfaceOperationHandlerComponent,
-        {
-          deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
-          toscaArtifactTypes: this.toscaArtifactTypes,
-          selectedInterface: interfaceModel,
-          selectedInterfaceOperation: operation,
-          validityChangedCallback: this.enableOrDisableSaveButton,
-          isViewOnly: this.isViewOnly
+    ngOnInit(): void {
+        this.componentMetaData = this.workspaceService.metadata;
+        this.loadComponentInstances();
+        this.loadDeployedArtifacts();
+        this.loadToscaArtifacts()
+    }
+
+    private loadComponentInstances() {
+        this.isLoading = true;
+        this.topologyTemplateService.getComponentInstances(this.componentMetaData.componentType, this.componentMetaData.uniqueId)
+        .subscribe((response) => {
+            this.componentInstanceSelected = response.componentInstances.find(ci => ci.uniqueId === this.component.uniqueId);
+            this.initComponentInstanceInterfaceOperations();
+            this.isLoading = false;
+        });
+    }
+
+    private initComponentInstanceInterfaceOperations() {
+        this.initInterfaces(this.componentInstanceSelected.interfaces);
+        this.sortInterfaces();
+    }
+
+    private initInterfaces(interfaces: ComponentInterfaceDefinitionModel[]): void {
+        this.interfaces = _.map(interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
+    }
+
+    private sortInterfaces(): void {
+        this.interfaces = _.filter(this.interfaces, (interf) => interf.operations && interf.operations.length > 0); // remove empty interfaces
+        this.interfaces.sort((a, b) => a.type.localeCompare(b.type)); // sort interfaces alphabetically
+        _.forEach(this.interfaces, (interf) => {
+            interf.operations.sort((a, b) => a.name.localeCompare(b.name)); // sort operations alphabetically
+        });
+    }
+
+    collapseAll(value: boolean = true): void {
+        _.forEach(this.interfaces, (interf) => {
+            interf.isCollapsed = value;
+        });
+    }
+
+    isAllCollapsed(): boolean {
+        return _.every(this.interfaces, (interf) => interf.isCollapsed);
+    }
+
+    isAllExpanded(): boolean {
+        return _.every(this.interfaces, (interf) => !interf.isCollapsed);
+    }
+
+    isListEmpty(): boolean {
+        return _.filter(
+            this.interfaces,
+            (interf) => interf.operations && interf.operations.length > 0
+        ).length === 0;
+    }
+
+    private enableOrDisableSaveButton = (): boolean => {
+        return this.isViewOnly;
+    }
+
+    onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
+
+        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);
         }
-    );
-    this.modalInstance.instance.open();
-  }
+        const modalModel: ModalModel = new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', buttonList, 'custom');
+        this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
 
-  private cancelAndCloseModal = () => {
-    this.loadComponentInstances();
-    return this.modalServiceNg2.closeCurrentModal();
-  }
-
-  private updateInterfaceOperation() {
-    this.isLoading = true;
-    const interfaceOperationHandlerComponentInstance: InterfaceOperationHandlerComponent = this.modalInstance.instance.dynamicContent.instance;
-    const operationUpdated: InterfaceOperationModel = interfaceOperationHandlerComponentInstance.operationToUpdate;
-    const isArtifactChecked = interfaceOperationHandlerComponentInstance.enableAddArtifactImplementation;
-    if (!isArtifactChecked) {
-      let artifactName = interfaceOperationHandlerComponentInstance.artifactName;
-      artifactName = artifactName === undefined ? '' : artifactName;
-      operationUpdated.implementation = new ArtifactModel({'artifactName': artifactName} as ArtifactModel);
+        this.modalServiceNg2.addDynamicContentToModal(
+            this.modalInstance,
+            InterfaceOperationHandlerComponent,
+            {
+                deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
+                toscaArtifactTypes: this.toscaArtifactTypes,
+                selectedInterface: interfaceModel ? interfaceModel : new UIInterfaceModel(),
+                selectedInterfaceOperation: operation ? operation : new InterfaceOperationModel(),
+                validityChangedCallback: this.enableOrDisableSaveButton,
+                isViewOnly: this.isViewOnly
+            }
+        );
+        this.modalInstance.instance.open();
     }
-    this.topologyTemplateService.updateComponentInstanceInterfaceOperation(
-        this.componentMetaData.uniqueId,
-        this.componentMetaData.componentType,
-        this.componentInstanceSelected.uniqueId,
-        operationUpdated)
+
+    private cancelAndCloseModal = () => {
+        this.loadComponentInstances();
+        return this.modalServiceNg2.closeCurrentModal();
+    }
+
+    private updateInterfaceOperation() {
+        this.isLoading = true;
+        const interfaceOperationHandlerComponentInstance: InterfaceOperationHandlerComponent = this.modalInstance.instance.dynamicContent.instance;
+        const operationUpdated: InterfaceOperationModel = interfaceOperationHandlerComponentInstance.operationToUpdate;
+        const isArtifactChecked = interfaceOperationHandlerComponentInstance.enableAddArtifactImplementation;
+        if (!isArtifactChecked) {
+            let artifactName = interfaceOperationHandlerComponentInstance.artifactName;
+            artifactName = artifactName === undefined ? '' : artifactName;
+            operationUpdated.implementation = new ArtifactModel({'artifactName': artifactName} as ArtifactModel);
+        }
+        this.topologyTemplateService.updateComponentInstanceInterfaceOperation(
+            this.componentMetaData.uniqueId,
+            this.componentMetaData.componentType,
+            this.componentInstanceSelected.uniqueId,
+            operationUpdated)
         .subscribe((updatedComponentInstance: ComponentInstance) => {
             this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance);
             this.initComponentInstanceInterfaceOperations();
         });
-    this.modalServiceNg2.closeCurrentModal();
-    this.isLoading = false;
-  }
+        this.modalServiceNg2.closeCurrentModal();
+        this.isLoading = false;
+    }
 
-  loadDeployedArtifacts() {
-    this.topologyTemplateService.getArtifactsByType(this.componentMetaData.componentType, this.componentMetaData.uniqueId, ArtifactGroupType.DEPLOYMENT)
-    .subscribe(response => {
-      let artifactsDeployment = response.deploymentArtifacts;
-      if (artifactsDeployment) {
-        let deploymentArtifactsFound = <ArtifactModel[]>_.values(artifactsDeployment)
-        deploymentArtifactsFound.forEach(value => {
-          this.deploymentArtifactsFilePath.push(new DropdownValue(value, value.artifactType.concat('->').concat(value.artifactName)));
+    loadDeployedArtifacts() {
+        this.topologyTemplateService.getArtifactsByType(this.componentMetaData.componentType, this.componentMetaData.uniqueId, ArtifactGroupType.DEPLOYMENT)
+        .subscribe(response => {
+            let artifactsDeployment = response.deploymentArtifacts;
+            if (artifactsDeployment) {
+                let deploymentArtifactsFound = <ArtifactModel[]>_.values(artifactsDeployment)
+                deploymentArtifactsFound.forEach(value => {
+                    this.deploymentArtifactsFilePath.push(new DropdownValue(value, value.artifactType.concat('->').concat(value.artifactName)));
+                });
+            }
+        }, error => {
+            this.Notification.error({
+                message: 'Failed to Load the Deployed Artifacts:' + error,
+                title: 'Failure'
+            });
         });
-      }}, error => {
-      this.Notification.error({
-        message: 'Failed to Load the Deployed Artifacts:' + error,
-        title: 'Failure'
-      });
-    });
-  }
+    }
 
-  loadToscaArtifacts() {
-    this.toscaArtifactService.getToscaArtifacts(this.componentMetaData.model).subscribe(response => {
-      if (response) {
-        let toscaArtifactsFound = <ToscaArtifactModel[]>_.values(response);
-        toscaArtifactsFound.forEach(value => this.toscaArtifactTypes.push(new DropdownValue(value, value.type)));
-      }
-    }, error => {
-      this.Notification.error({
-        message: 'Failed to Load Tosca Artifacts:' + error,
-        title: 'Failure'
-      });
-    });
-  }
+    loadToscaArtifacts() {
+        this.toscaArtifactService.getToscaArtifacts(this.componentMetaData.model).subscribe(response => {
+            if (response) {
+                let toscaArtifactsFound = <ToscaArtifactModel[]>_.values(response);
+                toscaArtifactsFound.forEach(value => this.toscaArtifactTypes.push(new DropdownValue(value, value.type)));
+            }
+        }, error => {
+            this.Notification.error({
+                message: 'Failed to Load Tosca Artifacts:' + error,
+                title: 'Failure'
+            });
+        });
+    }
 
 }
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 7a73a5b..5f02bc2 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
@@ -25,19 +25,30 @@
 
         <div class="side-by-side">
             <div class="form-item">
-                <sdc-input
+                <sdc-dropdown
                     label="{{ 'OPERATION_INTERFACE_TYPE' | translate }}"
-                    [(value)]="interfaceType"
-                    [disabled]=!isViewOnly>
-                </sdc-input>
+                    [required]="true"
+                    [testId]="'interface-name'"
+                    [selectedOption]="selectedInterfaceType"
+                    [placeHolder]="'Select...'"
+                    [disabled]="isViewOnly || isEdit"
+                    (changed)="onSelectInterface($event)"
+                    [options]="interfaceTypeOptions">
+                </sdc-dropdown>
             </div>
 
             <div class="form-item">
-                <sdc-input
+                <sdc-dropdown
+                    #interfaceOperationDropDown
                     label="{{ 'OPERATION_NAME' | translate }}"
-                    [(value)]="operationToUpdate.name"
-                    [disabled]=!isViewOnly>
-                </sdc-input>
+                    [required]="true"
+                    [testId]="'operation-name'"
+                    [selectedOption]="selectedInterfaceOperation"
+                    [placeHolder]="'Select...'"
+                    [disabled]="isViewOnly || isEdit"
+                    (changed)="onSelectOperation($event)"
+                    [options]="interfaceOperationOptions">
+                </sdc-dropdown>
             </div>
         </div>
 
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 0597085..5cc7f69 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
@@ -18,17 +18,18 @@
 *  SPDX-License-Identifier: Apache-2.0
 *  ============LICENSE_END=========================================================
 */
-
-import {Component, EventEmitter, Input, Output} from '@angular/core';
+import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core';
 import {UIInterfaceModel} from "../interface-operations.component";
 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";
 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 {IDropDownOption} from 'onap-ui-angular';
+import {ComponentServiceNg2} from "../../../../services/component-services/component.service";
+import {DropDownComponent} from "onap-ui-angular/dist/form-elements/dropdown/dropdown.component";
 import {DataTypeService} from "../../../../services/data-type.service";
 import {Observable} from "rxjs/Observable";
 import {DataTypeModel} from "../../../../../models/data-types";
@@ -43,13 +44,15 @@
 
     @Input() private modelName: string;
     @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
+    @ViewChild('interfaceOperationDropDown') interfaceOperationDropDown: DropDownComponent;
+
     input: {
         toscaArtifactTypes: Array<DropdownValue>;
         selectedInterface: UIInterfaceModel;
         selectedInterfaceOperation: InterfaceOperationModel;
         validityChangedCallback: Function;
         isViewOnly: boolean;
-        interfaceTypesMap: Map<string, string[]>;
+        isEdit: boolean;
     };
 
     dataTypeMap$: Observable<Map<string, DataTypeModel>>;
@@ -64,10 +67,13 @@
     isLoading: boolean = false;
     readonly: boolean;
     isViewOnly: boolean;
+    isEdit: boolean;
     interfaceTypes: Array<DropdownValue> = [];
-    interfaceOperations: Array<DropdownValue> = [];
-
-    interfaceTypesMap: Map<string, string[]>;
+    interfaceTypeOptions: Array<DropDownOption> = [];
+    selectedInterfaceType: DropDownOption = undefined;
+    interfaceOperationMap: Map<string, Array<string>> = new Map<string, Array<string>>();
+    interfaceOperationOptions: Array<DropDownOption> = [];
+    selectedInterfaceOperation: DropDownOption = undefined;
 
     toscaArtifactTypeSelected: string;
     toscaArtifactTypeProperties: Array<PropertyBEModel> = [];
@@ -80,7 +86,7 @@
     propertyValueValid: boolean = true;
     inputTypeOptions: any[];
 
-    constructor(private dataTypeService: DataTypeService) {
+    constructor(private dataTypeService: DataTypeService, private componentServiceNg2: ComponentServiceNg2) {
         this.dataTypeMap$ = new Observable<Map<string, DataTypeModel>>(subscriber => {
             this.dataTypeService.findAllDataTypesByModel(this.modelName)
             .then((dataTypesMap: Map<string, DataTypeModel>) => {
@@ -95,6 +101,7 @@
 
     ngOnInit() {
         this.isViewOnly = this.input.isViewOnly;
+        this.isEdit = this.input.isEdit;
         this.interfaceType = this.input.selectedInterface.type;
         this.operationToUpdate = this.input.selectedInterfaceOperation;
         this.operationToUpdate.interfaceId = this.input.selectedInterface.uniqueId;
@@ -113,18 +120,56 @@
         }
 
         this.inputs = Array.from(this.operationToUpdate.inputs.listToscaDataDefinition);
-        this.interfaceTypesMap = this.input.interfaceTypesMap;
-        this.loadInterfaceTypesAndOperations();
         this.removeImplementationQuote();
         this.validityChanged();
         this.loadInterfaceOperationImplementation();
+        this.loadInterfaceType();
+    }
+
+    private loadInterfaceType() {
+        this.componentServiceNg2.getInterfaceTypesByModel(undefined)
+        .subscribe(response => {
+            if (response) {
+                this.interfaceOperationMap = new Map<string, Array<string>>();
+                for (const interfaceType of Object.keys(response).sort()) {
+                    const operationList = response[interfaceType];
+                    operationList.sort();
+                    this.interfaceOperationMap.set(interfaceType, operationList);
+                    const operationDropDownOption: DropDownOption = new DropDownOption(interfaceType);
+                    this.interfaceTypeOptions.push(operationDropDownOption);
+                    if (this.interfaceType == interfaceType) {
+                        this.selectedInterfaceType = operationDropDownOption;
+                    }
+                }
+                this.loadInterfaceTypeOperations();
+            }
+        });
+    }
+
+    loadInterfaceTypeOperations() {
+        this.interfaceOperationOptions = new Array<DropDownOption>();
+        const interfaceOperationList = this.interfaceOperationMap.get(this.interfaceType);
+
+        if (interfaceOperationList) {
+            interfaceOperationList.forEach(operationName => {
+                const operationOption = new DropDownOption(operationName, operationName);
+                this.interfaceOperationOptions.push(operationOption);
+                if (this.operationToUpdate.name == operationName) {
+                    this.selectedInterfaceOperation = operationOption
+                }
+            });
+        }
+
+        this.interfaceOperationDropDown.allOptions = this.interfaceOperationOptions;
     }
 
     private loadInterfaceOperationImplementation() {
         this.toscaArtifactTypes = this.input.toscaArtifactTypes;
-        this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
-        this.artifactName = this.operationToUpdate.implementation.artifactName;
-        this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
+        if (this.operationToUpdate.implementation) {
+            this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
+            this.artifactName = this.operationToUpdate.implementation.artifactName;
+            this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
+        }
         this.artifactTypeProperties = this.convertArtifactsPropertiesToInput();
         this.getArtifactTypesSelected();
     }
@@ -348,11 +393,43 @@
         return inputList;
     }
 
-    private loadInterfaceTypesAndOperations() {
-        console.log("loadInterfaceTypesAndOperations ", this.interfaceTypesMap.keys());
-
-        Array.from(this.interfaceTypesMap.keys()).forEach(value => this.interfaceTypes.push(new DropdownValue(value, value)));
-        console.log("loadInterfaceTypesAndOperations interfaceType ", this.interfaceTypes);
+    onSelectInterface(dropDownOption: DropDownOption) {
+        if (dropDownOption) {
+            this.setInterfaceType(dropDownOption);
+        } else {
+            this.setInterfaceType(undefined);
+        }
+        this.setInterfaceOperation(undefined);
+        this.interfaceOperationDropDown.selectOption({} as IDropDownOption);
+        this.loadInterfaceTypeOperations();
     }
 
+    onSelectOperation(dropDownOption: DropDownOption) {
+        if (this.selectedInterfaceType && dropDownOption) {
+            this.setInterfaceOperation(dropDownOption);
+        }
+    }
+
+    private setInterfaceType(dropDownOption: DropDownOption) {
+        this.selectedInterfaceType = dropDownOption ? dropDownOption : undefined;
+        this.interfaceType = dropDownOption ? dropDownOption.value : undefined;
+        this.operationToUpdate.interfaceType = dropDownOption ? dropDownOption.value : undefined;
+        this.operationToUpdate.interfaceId = dropDownOption ? dropDownOption.value : undefined;
+    }
+
+    private setInterfaceOperation(dropDownOption: DropDownOption) {
+        this.operationToUpdate.name = dropDownOption ? dropDownOption.value : undefined;
+        this.operationToUpdate.operationType = dropDownOption ? dropDownOption.value : undefined;
+        this.selectedInterfaceOperation = dropDownOption ? dropDownOption : undefined;
+    }
 }
+
+class DropDownOption implements IDropDownOption {
+    value: string;
+    label: string;
+
+    constructor(value: string, label?: string) {
+        this.value = value;
+        this.label = label || value;
+    }
+}
\ No newline at end of file
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 b212eec..bcc797c 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
@@ -25,16 +25,14 @@
 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 {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';
+import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
+import {InterfaceOperationHandlerComponent} from "./interface-operation-handler.component";
 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';
+import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module";
+import {PropertyTableModule} from "app/ng2/components/logic/properties-table/property-table.module";
 
 @NgModule({
   declarations: [
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html
index 25ccf11..f3043ff 100644
--- a/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html
@@ -24,6 +24,13 @@
       <div>{{ 'INTERFACE_DATA_EMPTY' | translate }}</div>
     </div>
   </div>
+  <div
+      class="top-add-btn add-btn"
+      [ngClass]="{'disabled': readonly}"
+      data-tests-id="add-operation"
+      (click)="onSelectInterfaceOperation(undefined, undefined)">
+    {{ 'INTERFACE_ADD_OPERATION' | translate }}
+  </div>
   <div class="operation-list">
     <div *ngIf="!isInterfaceListEmpty()">
       <div class="expand-collapse" *ngIf="isOperationListEmpty()">
@@ -38,11 +45,11 @@
         </a>
       </div>
 
-      <div class="interface-row" *ngFor="let interface of interfaces">
-        <div class="interface-accordion" (click)="interface.toggleCollapse()">
+      <div class="interface-row" *ngFor="let interface1 of interfaces">
+        <div class="interface-accordion" (click)="interface1.toggleCollapse()">
           <span
               class="chevron-container"
-              [ngClass]="{'isCollapsed': interface.isCollapsed}"
+              [ngClass]="{'isCollapsed': interface1.isCollapsed}"
               *ngIf="isOperationListEmpty()">
               <svg-icon
                   name="caret1-down-o"
@@ -50,10 +57,10 @@
                   size="small">
               </svg-icon>
           </span>
-          <span class="interface-name">{{interface.type}}</span>
+          <span class="interface-name">{{interface1.type}}</span>
         </div>
 
-        <div class="generic-table" *ngIf="!interface.isCollapsed && isOperationListEmpty()">
+        <div class="generic-table" *ngIf="!interface1.isCollapsed && isOperationListEmpty()">
           <div class="header-row table-row">
             <span
                 class="cell header-cell field-name header-name">
@@ -63,20 +70,14 @@
               {{ 'INTERFACE_HEADER_DESCRIPTION' | translate }}
             </span>
           </div>
-
-          <div class="data-row" *ngFor="let operation of interface.operations"
-               (click)="onSelectInterfaceOperation(interface, operation)">
-            <span
-                class="cell field-name">
-                {{operation.name}}
-            </span>
-            <span class="cell field-description"
-                  [ngClass]="{'collapsed': operation.isCollapsed}">
-              {{operation.getDescriptionEllipsis()}}
+          <div class="data-row" *ngFor="let operation of interface1.operations" (click)="onSelectInterfaceOperation(interface1, operation)">
+            <span class="cell field-name">{{operation.name}}</span>
+            <span class="cell field-description" [ngClass]="{'collapsed': operation.isCollapsed}">
+                {{operation.getDescriptionEllipsis()}}
               <span class="more-or-less link" (click)="operation.toggleCollapsed($event)">
-                {{!operation.isEllipsis ? '' : operation.isCollapsed ? 'More' : 'Less'}}
+                  {{!operation.isEllipsis ? '' : operation.isCollapsed ? 'More' : 'Less'}}
+                </span>
               </span>
-            </span>
           </div>
         </div>
       </div>
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts
index 8dd17f6..c9a6d07 100644
--- a/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts
@@ -20,26 +20,27 @@
 */
 import {Component, ComponentRef, Inject, Input} from '@angular/core';
 import {Component as IComponent} from 'app/models/components/component';
+import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
 
 import {ISdcConfig, SdcConfigToken} from "app/ng2/config/sdc-config.config";
 import {TranslateService} from "app/ng2/shared/translator/translate.service";
-
+import {IModalButtonComponent, SdcUiServices} from 'onap-ui-angular';
 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
+
 import {ModalService} from 'app/ng2/services/modal.service';
-import {ButtonModel, CapabilitiesGroup, ModalModel, OperationModel} from 'app/models';
+import {
+    ButtonModel,
+    CapabilitiesGroup,
+    InputBEModel,
+    InterfaceModel,
+    ModalModel,
+    OperationModel,
+    WORKFLOW_ASSOCIATION_OPTIONS
+} from 'app/models';
 
 import {ComponentServiceNg2} from 'app/ng2/services/component-services/component.service';
-
-import {SdcUiServices} from 'onap-ui-angular';
 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
-import {
-    ComponentInterfaceDefinitionModel,
-    InputOperationParameter,
-    InterfaceOperationModel
-} from "../../../models/interfaceOperation";
-import {
-    PropertyParamRowComponent
-} from "../composition/interface-operatons/operation-creator/property-param-row/property-param-row.component";
+import {InterfaceOperationModel} from "../../../models/interfaceOperation";
 import {
     InterfaceOperationHandlerComponent
 } from "../composition/interface-operatons/operation-creator/interface-operation-handler.component";
@@ -49,15 +50,17 @@
 import {ToscaArtifactModel} from "../../../models/toscaArtifact";
 import {ToscaArtifactService} from "../../services/tosca-artifact.service";
 import {
-    UIInterfaceOperationModel
-} from "../composition/interface-operatons/interface-operations.component";
+    InterfaceOperationComponent
+} from "../interface-operation/interface-operation.page.component";
+import {Observable} from "rxjs/Observable";
+import {PluginsService} from 'app/ng2/services/plugins.service';
 
 export class UIOperationModel extends OperationModel {
     isCollapsed: boolean = true;
     isEllipsis: boolean;
     MAX_LENGTH = 75;
 
-    constructor(operation: UIOperationModel) {
+    constructor(operation: OperationModel) {
         super(operation);
 
         if (!operation.description) {
@@ -109,15 +112,14 @@
     }
 }
 
-export class UIInterfaceModel extends ComponentInterfaceDefinitionModel {
+export class UIInterfaceModel extends InterfaceModel {
     isCollapsed: boolean = false;
 
     constructor(interf?: any) {
         super(interf);
-        this.operations = _.map(
-            this.operations,
-            (operation) => new UIInterfaceOperationModel(operation)
-        );
+        if (this.operations) {
+            this.operations = this.operations.map((operation) => new UIOperationModel(operation));
+        }
     }
 
     toggleCollapse() {
@@ -130,16 +132,14 @@
     selector: 'interface-definition',
     templateUrl: './interface-definition.page.component.html',
     styleUrls: ['interface-definition.page.component.less'],
-    providers: [ModalService, TranslateService]
+    providers: [ModalService, TranslateService, InterfaceOperationComponent]
 })
-
 export class InterfaceDefinitionComponent {
 
     modalInstance: ComponentRef<ModalComponent>;
     interfaces: UIInterfaceModel[];
-    inputs: Array<InputOperationParameter> = [];
+    inputs: InputBEModel[];
 
-    properties: Array<PropertyParamRowComponent> = [];
     deploymentArtifactsFilePath: Array<DropdownValue> = [];
 
     toscaArtifactTypes: Array<DropdownValue> = [];
@@ -153,6 +153,10 @@
     capabilities: CapabilitiesGroup;
     isViewOnly: boolean;
 
+    openOperation: OperationModel;
+    enableWorkflowAssociation: boolean;
+    workflowIsOnline: boolean;
+
     @Input() component: IComponent;
     @Input() readonly: boolean;
     @Input() enableMenuItems: Function;
@@ -167,19 +171,52 @@
         private modalServiceNg2: ModalService,
         private modalServiceSdcUI: SdcUiServices.ModalService,
         private topologyTemplateService: TopologyTemplateService,
-        private toscaArtifactService: ToscaArtifactService
+        private toscaArtifactService: ToscaArtifactService,
+        private ComponentServiceNg2: ComponentServiceNg2,
+        private WorkflowServiceNg2: WorkflowServiceNg2,
+        private ModalServiceSdcUI: SdcUiServices.ModalService,
+        private PluginsService: PluginsService
     ) {
         this.modalTranslation = new ModalTranslation(translateService);
         this.interfaceTypesMap = new Map<string, string[]>();
     }
 
     ngOnInit(): void {
-        console.info("this.component.lifecycleState ", this.component.lifecycleState);
-        if (this.component) {
-            this.isViewOnly = this.component.componentMetadata.isComponentDataEditable();
-            this.initInterfaceDefinition();
-            this.loadInterfaceTypes();
-            this.loadToscaArtifacts();
+        this.isLoading = true;
+        this.interfaces = [];
+        this.workflowIsOnline = !_.isUndefined(this.PluginsService.getPluginByStateUrl('workflowDesigner'));
+        Observable.forkJoin(
+            this.ComponentServiceNg2.getInterfaceOperations(this.component),
+            this.ComponentServiceNg2.getComponentInputs(this.component),
+            this.ComponentServiceNg2.getInterfaceTypes(this.component),
+            this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.component.componentType, this.component.uniqueId)
+        ).subscribe((response: any[]) => {
+            const callback = (workflows) => {
+                this.isLoading = false;
+                this.initInterfaces(response[0].interfaces);
+                this.sortInterfaces();
+                this.inputs = response[1].inputs;
+                this.interfaceTypes = response[2];
+                this.workflows = (workflows.items) ? workflows.items : workflows;
+                this.capabilities = response[3].capabilities;
+            };
+            if (this.enableWorkflowAssociation && this.workflowIsOnline) {
+                this.WorkflowServiceNg2.getWorkflows().subscribe(
+                    callback,
+                    (err) => {
+                        this.workflowIsOnline = false;
+                        callback([]);
+                    }
+                );
+            } else {
+                callback([]);
+            }
+        });
+    }
+
+    initInterfaces(interfaces: InterfaceModel[]): void {
+        if (interfaces) {
+            this.interfaces = interfaces.map((interf) => new UIInterfaceModel(interf));
         }
     }
 
@@ -190,15 +227,18 @@
     private disableSaveButton = (): boolean => {
         return this.isViewOnly ||
             (this.isEnableAddArtifactImplementation()
-                && (!this.modalInstance.instance.dynamicContent.instance.toscaArtifactTypeSelected ||
-                    !this.modalInstance.instance.dynamicContent.instance.artifactName)
+                && (!this.modalInstance.instance.dynamicContent.toscaArtifactTypeSelected ||
+                    !this.modalInstance.instance.dynamicContent.artifactName)
             );
     }
 
     onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
+        const isEdit = operation !== undefined;
         const cancelButton: ButtonModel = new ButtonModel(this.modalTranslation.CANCEL_BUTTON, 'outline white', this.cancelAndCloseModal);
-        const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue', () =>
-            this.updateOperation(), this.disableSaveButton);
+        const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue',
+            () => isEdit ? this.updateOperation() : this.createOperationCallback(),
+            this.disableSaveButton
+        );
         const interfaceDataModal: ModalModel =
             new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', [saveButton, cancelButton], 'custom');
         this.modalInstance = this.modalServiceNg2.createCustomModal(interfaceDataModal);
@@ -209,12 +249,14 @@
             {
                 deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
                 toscaArtifactTypes: this.toscaArtifactTypes,
-                selectedInterface: interfaceModel,
-                selectedInterfaceOperation: operation,
+                selectedInterface: interfaceModel ? interfaceModel : new UIInterfaceModel(),
+                selectedInterfaceOperation: operation ? operation : new InterfaceOperationModel(),
                 validityChangedCallback: this.disableSaveButton,
                 isViewOnly: this.isViewOnly,
+                isEdit: isEdit,
                 interfaceTypesMap: this.interfaceTypesMap,
-            });
+            }
+        );
         this.modalInstance.instance.open();
     }
 
@@ -239,6 +281,27 @@
         this.modalServiceNg2.closeCurrentModal();
     }
 
+    private createOperationCallback(): void {
+        const operationToUpdate = this.modalInstance.instance.dynamicContent.instance.operationToUpdate;
+        console.log('createOperationCallback', operationToUpdate);
+        console.log('this.component', this.component);
+        this.componentServiceNg2.createComponentInterfaceOperation(this.component.uniqueId, this.component.getTypeUrl(), operationToUpdate)
+        .subscribe((newOperation: InterfaceOperationModel) => {
+            const foundInterface = this.interfaces.find(value => value.type === newOperation.interfaceType);
+            if (foundInterface) {
+                foundInterface.operations.push(new UIOperationModel(new OperationModel(newOperation)));
+            } else {
+                const uiInterfaceModel = new UIInterfaceModel();
+                uiInterfaceModel.type = newOperation.interfaceType;
+                uiInterfaceModel.uniqueId = newOperation.interfaceType;
+                uiInterfaceModel.operations = [];
+                uiInterfaceModel.operations.push(new UIOperationModel(new OperationModel(newOperation)));
+                this.interfaces.push(uiInterfaceModel);
+            }
+        });
+        this.modalServiceNg2.closeCurrentModal();
+    }
+
     private handleEnableAddArtifactImplementation = (newOperation: InterfaceOperationModel): InterfaceOperationModel => {
         if (!this.isEnableAddArtifactImplementation()) {
             newOperation.implementation.artifactType = null;
@@ -248,7 +311,7 @@
     }
 
     private isEnableAddArtifactImplementation = (): boolean => {
-        return this.modalInstance.instance.dynamicContent.instance.enableAddArtifactImplementation;
+        return this.modalInstance.instance.dynamicContent.enableAddArtifactImplementation;
     }
 
     private initInterfaceDefinition() {
@@ -257,7 +320,7 @@
         this.topologyTemplateService.getComponentInterfaceOperations(this.component.componentType, this.component.uniqueId)
         .subscribe((response) => {
             if (response.interfaces) {
-                this.interfaces = _.map(response.interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
+                this.interfaces = response.interfaces.map((interfaceModel) => new UIInterfaceModel(interfaceModel));
             }
             this.isLoading = false;
         });
@@ -301,11 +364,11 @@
     }
 
     isAllCollapsed(): boolean {
-        return _.every(this.interfaces, (interfaceData) => interfaceData.isCollapsed);
+        return this.interfaces.every((interfaceData) => interfaceData.isCollapsed);
     }
 
     isAllExpanded(): boolean {
-        return _.every(this.interfaces, (interfaceData) => !interfaceData.isCollapsed);
+        return this.interfaces.every((interfaceData) => !interfaceData.isCollapsed);
     }
 
     isInterfaceListEmpty(): boolean {
@@ -313,8 +376,92 @@
     }
 
     isOperationListEmpty(): boolean {
-        return _.filter(this.interfaces, (interfaceData) =>
-            interfaceData.operations && interfaceData.operations.length > 0).length > 0;
+        return this.interfaces.filter((interfaceData) => interfaceData.operations && interfaceData.operations.length > 0).length > 0;
+    }
+
+    onRemoveOperation = (event: Event, operation: OperationModel): void => {
+        event.stopPropagation();
+
+        const deleteButton: IModalButtonComponent = {
+            id: 'deleteButton',
+            text: this.modalTranslation.DELETE_BUTTON,
+            type: 'primary',
+            size: 'small',
+            closeModal: true,
+            callback: () => {
+                this.ComponentServiceNg2
+                .deleteInterfaceOperation(this.component, operation)
+                .subscribe(() => {
+                    const curInterf = this.interfaces.find((interf) => interf.type === operation.interfaceType);
+                    const index = curInterf.operations.findIndex((el) => el.uniqueId === operation.uniqueId);
+                    curInterf.operations.splice(index, 1);
+                    if (!curInterf.operations.length) {
+                        const interfIndex = this.interfaces.findIndex((interf) => interf.type === operation.interfaceType);
+                        this.interfaces.splice(interfIndex, 1);
+                    }
+                });
+            }
+        };
+
+        const cancelButton: IModalButtonComponent = {
+            id: 'cancelButton',
+            text: this.modalTranslation.CANCEL_BUTTON,
+            type: 'secondary',
+            size: 'small',
+            closeModal: true,
+            callback: () => {
+                this.openOperation = null;
+            },
+        };
+
+        this.ModalServiceSdcUI.openWarningModal(
+            this.modalTranslation.DELETE_TITLE,
+            this.modalTranslation.deleteText(operation.name),
+            'deleteOperationModal',
+            [deleteButton, cancelButton],
+        );
+    }
+
+    private createOperation = (operation: OperationModel): void => {
+        this.ComponentServiceNg2.createInterfaceOperation(this.component, operation).subscribe((response: OperationModel) => {
+            this.openOperation = null;
+
+            let curInterf = this.interfaces.find((interf) => interf.type === operation.interfaceType);
+
+            if (!curInterf) {
+                curInterf = new UIInterfaceModel({
+                    type: response.interfaceType,
+                    uniqueId: response.uniqueId,
+                    operations: []
+                });
+                this.interfaces.push(curInterf);
+            }
+
+            const newOpModel = new UIOperationModel(response);
+            curInterf.operations.push(newOpModel);
+            this.sortInterfaces();
+
+            if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL && operation.artifactData) {
+                this.ComponentServiceNg2.uploadInterfaceOperationArtifact(this.component, newOpModel, operation).subscribe();
+            } else if (response.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) {
+                this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, response).subscribe();
+            } else if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW) {
+                this.$state.go('workspace.plugins', {path: 'workflowDesigner'});
+            }
+        });
+    }
+
+    private enableOrDisableSaveButton = (shouldEnable: boolean): void => {
+        const saveButton = this.modalInstance.instance.dynamicContent.getButtonById('saveButton');
+        saveButton.disabled = !shouldEnable;
+    }
+
+    private sortInterfaces(): void {
+        this.interfaces = this.interfaces.filter((interf) => interf.operations && interf.operations.length > 0); // remove empty interfaces
+        this.interfaces.sort((a, b) => a.type.localeCompare(b.type)); // sort interfaces alphabetically
+        this.interfaces.forEach((interf) => {
+            interf.operations.sort((a, b) => a.name.localeCompare(b.name)); // sort operations alphabetically
+        });
     }
 
 }
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.html b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.html
new file mode 100644
index 0000000..687c79f
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.html
@@ -0,0 +1,211 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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="operation-creator-interface-definition">
+    <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
+
+    <form class="w-sdc-form">
+
+        <div class="side-by-side">
+            <div class="form-item">
+                <sdc-dropdown
+                    label="{{ 'OPERATION_INTERFACE_TYPE' | translate }}"
+                    [required]="true"
+                    testId="interface-name"
+                    [selectedOption]="getSelectedDropdown(interfaceNames, operation.interfaceType)"
+                    placeHolder="Select..."
+                    [disabled]="readonly"
+                    (changed)="onSelectInterface($event)"
+                    [options]="interfaceNames">
+                </sdc-dropdown>
+            </div>
+
+            <div class="form-item" *ngIf="!isInterfaceOther()">
+                <sdc-dropdown
+                    #operationNamesDropdown
+                    label="{{ 'OPERATION_NAME' | translate }}"
+                    [required]="true"
+                    testId="operation-name"
+                    [selectedOption]="getSelectedDropdown(operationNames, operation.name)"
+                    placeHolder="Select..."
+                    [disabled]="readonly"
+                    (changed)="onSelectOperationName($event)"
+                    [options]="operationNames">
+                </sdc-dropdown>
+            </div>
+            <div class="form-item" *ngIf="isInterfaceOther()">
+                <sdc-input
+                    label="{{ 'OPERATION_NAME' | translate }}"
+                    [(value)]="operation.name"
+                    testId="operationName"
+                    (valueChange)="onChangeName()"
+                    [disabled]="readonly">
+                </sdc-input>
+            </div>
+
+        </div>
+
+        <div class="i-sdc-form-item sdc-input">
+            <span class="sdc-input__label">{{ 'OPERATION_DESCRIPTION' | translate }}</span>
+            <textarea
+                data-tests-id="operationDescription"
+                rows="2"
+                name="description"
+                [(ngModel)]="descriptionValue"
+                [ngClass]="{'disabled': readonly}">
+            </textarea>
+        </div>
+
+        <div class="side-by-side" *ngIf="enableWorkflowAssociation">
+            <div class="form-item">
+                <sdc-dropdown
+                    #workflowAssignmentDropdown
+                    label="{{ 'OPERATION_WORKFLOW_ASSIGNMENT' | translate }}"
+                    placeHolder="Select..."
+                    testId="association-type"
+                    [selectedOption]="toDropDownOption(workflowAssociationType)"
+                    [options]="associationOptions"
+                    (changed)="toggleAssociateWorkflow($event)"
+                    [disabled]="readonly">
+                </sdc-dropdown>
+            </div>
+
+            <div class="form-item" *ngIf="!isUsingExistingWF() && !isUsingExternalWF()"></div>
+
+            <div
+                *ngIf="isUsingExternalWF()"
+                class="form-item sdc-input">
+                <label class="sdc-input__label">{{ 'OPERATION_ARTIFACT' | translate }}</label>
+                <div class="i-sdc-form-item i-sdc-form-file-upload">
+                    <span
+                        class="i-sdc-form-file-name"
+                        data-tests-id="artifactFilename">
+                        {{ operation.artifactFileName }}
+                    </span>
+                    <div
+                        *ngIf="operation.artifactFileName"
+                        class="i-sdc-form-file-upload-x-btn"
+                        data-tests-id="clearArtifact"
+                        (click)="onChangeArtifactFile({ target: {} })"></div>
+                    <label
+                        class="i-sdc-form-file-upload-label"
+                        [ngClass]="{'disabled': readonly}">
+                        <input
+                            type="file"
+                            base-sixty-four-input
+                            maxsize="10240"
+                            data-tests-id="artifactUpload"
+                            (change)="onChangeArtifactFile($event)"
+                            (click)="$event.target.value = ''"
+                        />
+                        <div class="file-upload-browse-btn">Browse</div>
+                    </label>
+                </div>
+            </div>
+
+            <div class="form-item sdc-input" *ngIf="isUsingExistingWF()">
+                <label class="sdc-input__label required">{{ 'OPERATION_WORKFLOW' | translate }}
+                    <span class="archive-warning" *ngIf="workflowIsOnline && archivedWorkflowId === operation.workflowId">({{ 'OPERATION_WORKFLOW_ARCHIVED' | translate }})</span>
+                    <span class="no-workflow-warning" *ngIf="!workflowIsOnline">{{ 'OPERATION_NO_WORKFLOW_CONNECTION' | translate }}</span>
+                    <span class="no-workflow-warning" *ngIf="workflowIsOnline && !workflows.length">{{ 'OPERATION_NO_WORKFLOW_ERROR' | translate }}</span>
+                </label>
+                <sdc-dropdown
+                    placeHolder="Select..."
+                    testId="associated-workflow"
+                    [selectedOption]="getSelectedDropdown(workflows, operation.workflowId)"
+                    [options]="workflows"
+                    (changed)="onSelectWorkflow($event)"
+                    [disabled]="readonly || !workflows.length || !workflowIsOnline">
+                </sdc-dropdown>
+            </div>
+
+            <div class="form-item sdc-input" *ngIf="isUsingExistingWF()">
+                <sdc-dropdown
+                    *ngIf="workflowIsOnline && workflows.length"
+                    label="{{ 'OPERATION_WORKFLOW_VERSION' | translate }}"
+                    testId="associated-workflow-version"
+                    [selectedOption]="getSelectedDropdown(workflowVersions, operation.workflowVersionId)"
+                    [options]="workflowVersions"
+                    (changed)="changeWorkflowVersion($event)"
+                    [disabled]="!operation.workflowId || archivedWorkflowId === operation.workflowId || readonly">
+                </sdc-dropdown>
+            </div>
+        </div>
+
+        <div class="separator-buttons">
+            <tabs #propertyInputTabs tabStyle="round-tabs" (tabChanged)="tabChanged($event)" [hideIndicationOnTabChange]="true">
+                <tab tabTitle="Inputs"></tab>
+                <tab tabTitle="Outputs"></tab>
+            </tabs>
+            <a
+                class="add-param-link add-btn"
+                *ngIf="!isUsingExistingWF() && !readonly"
+                data-tests-id="addInputParameter"
+                [ngClass]="{'disabled':!canAdd()}"
+                (click)="addParam()">{{ currentTab === TYPE_INPUT ? 'Add Input' : 'Add Output' }}</a>
+        </div>
+
+        <div class="generic-table">
+            <div class="header-row table-row">
+                <span class="cell header-cell field-name">{{ 'OPERATION_PARAM_NAME' | translate }}</span>
+                <span class="cell header-cell field-type">{{ 'OPERATION_PARAM_TYPE' | translate }}</span>
+                <span class="cell header-cell field-property" *ngIf="currentTab == TYPE_INPUT">
+                    {{ 'OPERATION_PARAM_PROPERTY' | translate }}
+                    <span
+                        *ngIf="!isUsingExistingWF()"
+                        class="sprite-new info-icon"
+                        tooltip="{{propertyTooltipText}}"
+                        tooltipDelay="0">
+                    </span>
+                </span>
+                <span class="cell header-cell field-mandatory" *ngIf="!isUsingExistingWF()">{{ 'OPERATION_PARAM_MANDATORY' | translate }}</span>
+                <span class="cell header-cell remove" *ngIf="!isUsingExistingWF() && !readonly">●●●</span>
+            </div>
+
+            <div class="empty-msg data-row" *ngIf="tableParameters.length === 0">
+                <div>{{ 'EMPTY_PARAM_TABLE_HEADER' | translate }}</div>
+                <div *ngIf="isUsingExistingWF() && !operation.workflowVersionId">
+                    <div *ngIf="workflows.length">
+                        <span class="bold-message">{{ 'EMPTY_PARAM_TABLE_NO_SELECTED_WORKFLOW_1' | translate }}</span>
+                        <span>{{ 'EMPTY_PARAM_TABLE_NO_SELECTED_WORKFLOW_2' | translate }}</span>
+                    </div>
+                    <div *ngIf="!workflows.length">
+                        Only <span class="bold-message">certified</span> workflow versions can be assigned to an operation
+                    </div>
+                </div>
+            </div>
+
+            <param-row
+                    *ngFor="let param of tableParameters"
+                    class="data-row"
+                    [isInputParam]="currentTab === TYPE_INPUT"
+                    [isAssociateWorkflow]="isUsingExistingWF()"
+                    [param]="param"
+                    [inputProps]="inputProperties"
+                    [capabilitiesProps]="componentCapabilities"
+                    [operationOutputs]="operationOutputs"
+                    [onRemoveParam]="onRemoveParam"
+                    [readonly]="readonly"
+                    [validityChanged]="validityChanged">
+            </param-row>
+        </div>
+
+    </form>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.less b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.less
new file mode 100644
index 0000000..0afaa47
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.less
@@ -0,0 +1,200 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2022 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 '../../../../../assets/styles/variables.less';
+@import '../../../../../assets/styles/override.less';
+
+.operation-creator-interface-definition {
+    font-family: @font-opensans-regular;
+    user-select: none;
+    padding-top: 12px;
+    padding-bottom: 20px;
+
+    .i-sdc-form-label {
+        font-size: 12px;
+    }
+
+    .w-sdc-form .i-sdc-form-item {
+        margin-bottom: 15px;
+    }
+
+    textarea {
+        min-height: 74px;
+        margin-bottom: 18px;
+    }
+
+    /deep/ .sdc-dropdown__component-container {
+        .sdc-dropdown__header {
+            height: 38px;
+            line-height: 35px;
+
+            svg-icon {
+                margin: 13px 6px;
+            }
+        }
+    }
+
+    /deep/ .sdc-input {
+        margin-bottom: 0;
+
+        .sdc-input__input {
+            height: 38px;
+        }
+    }
+
+    .side-by-side {
+        display: flex;
+
+        .form-item {
+            flex: 1;
+
+            &:first-child {
+                margin-right: 14px;
+                flex-basis: 37%;
+                flex-grow: 0;
+                flex-shrink: 0;
+            }
+
+            &:nth-child(3) {
+                margin-left: 14px;
+                flex: 0.4;
+            }
+
+            .i-sdc-form-file-upload {
+                height: 37px;
+                margin-bottom: 0;
+
+                .i-sdc-form-file-name {
+                    padding: 8px 10px;
+                }
+
+                .i-sdc-form-file-upload-x-btn {
+                    top: 13px;
+                }
+
+                .file-upload-browse-btn {
+                    height: 100%;
+                    padding: 7px 6px;
+                    z-index: 1;
+                }
+            }
+
+        }
+    }
+
+    .archive-warning {
+        font-family: @font-opensans-bold;
+        color: @main_color_i;
+    }
+
+    .no-workflow-warning {
+        font-family: @font-opensans-bold;
+        color: @sdcui_color_red;
+        float: right;
+    }
+
+    .input-param-title {
+        font-size: 16px;
+        text-transform: uppercase;
+    }
+
+    .separator-buttons {
+        display: flex;
+        justify-content: space-between;
+        margin-top: 10px;
+
+        .add-param-link {
+            &:not(.disabled):hover {
+                cursor: pointer;
+            }
+        }
+
+        .tab {
+            width: 84px;
+            text-align: center;
+        }
+    }
+
+    .generic-table {
+        max-height: 244px;
+        min-height: 91px;
+        background: @main_color_p;
+
+        .header-row .header-cell {
+            .info-icon {
+                float: right;
+                position: relative;
+                top: 2px;
+            }
+            /deep/ .tooltip-inner {
+                padding: 2px;
+                max-width: 270px;
+                font-size: 11px;
+            }
+            &.remove {
+                padding: 10px;
+                font-size: 10px;
+            }
+        }
+
+        .data-row {
+            &.empty-msg {
+                .bold-message {
+                    font-family: @font-opensans-bold;
+                }
+
+                :first-child {
+                    &:not(:only-child) {
+                        margin: 6px 0;
+                    }
+                }
+
+                display: flex;
+                flex-direction: column;
+                justify-content: center;
+                align-items: center;
+                padding: 14px;
+            }
+        }
+
+        /deep/ .cell {
+            &.field-name, &.field-type {
+                flex: 1;
+            }
+
+            &.field-property {
+                &, &:last-child {
+                    flex: 1;
+                }
+            }
+
+            &.field-mandatory {
+                flex: 0.5;
+                text-align: center;
+            }
+
+            &.remove {
+                min-width: 40px;
+                max-width: 40px;
+            }
+        }
+
+    }
+}
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.ts b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.ts
new file mode 100644
index 0000000..1897e31
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.component.ts
@@ -0,0 +1,582 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2022 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 * as _ from "lodash";
+import {Component, ViewChild} from '@angular/core';
+
+import {TranslateService} from "app/ng2/shared/translator/translate.service";
+import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
+import {
+    Capability,
+    InputBEModel,
+    InterfaceModel,
+    OperationModel,
+    OperationParameter,
+    WORKFLOW_ASSOCIATION_OPTIONS
+} from 'app/models';
+
+import {Tabs} from "app/ng2/components/ui/tabs/tabs.component";
+import {
+    DropdownValue
+} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
+import {IDropDownOption} from 'onap-ui-angular';
+import {DropDownComponent} from "onap-ui-angular/dist/components";
+import {DROPDOWN_OPTION_TYPE} from "app/utils";
+import {Subscription} from "rxjs";
+
+export class DropDownOption implements IDropDownOption {
+    value: string;
+    label: string;
+
+    constructor(value: string, label?: string) {
+        this.value = value;
+        this.label = label || value;
+    }
+}
+
+class TypedDropDownOption extends DropDownOption {
+    type: string;
+
+    constructor(value: string, label?: string, type?: string) {
+        super(value, label);
+        this.type = type;
+    }
+}
+
+export interface OperationCreatorInput {
+    allWorkflows: Array<any>,
+    inputOperation: OperationModel,
+    interfaces: Array<InterfaceModel>,
+    inputProperties: Array<InputBEModel>,
+    enableWorkflowAssociation: boolean,
+    readonly: boolean,
+    interfaceTypes: { [interfaceType: string]: Array<string> },
+    validityChangedCallback: Function,
+    workflowIsOnline: boolean,
+    capabilities: Array<Capability>
+}
+
+@Component({
+    selector: 'operation-creator-interface-definition',
+    templateUrl: './operation-creator-interface-definition.component.html',
+    styleUrls: ['./operation-creator-interface-definition.component.less'],
+    providers: [TranslateService]
+})
+
+export class OperationCreatorInterfaceDefinitionComponent implements OperationCreatorInput {
+
+    input: OperationCreatorInput;
+    inputOperation: OperationModel;
+    interfaces: Array<InterfaceModel>;
+    operation: OperationModel;
+    interfaceNames: Array<TypedDropDownOption> = [];
+    interfaceTypes: { [interfaceType: string]: Array<string> };
+    operationNames: Array<TypedDropDownOption> = [];
+    validityChangedCallback: Function;
+    capabilities: Array<Capability>;
+
+    allWorkflows: Array<any>;
+    workflows: Array<DropdownValue> = [];
+    workflowVersions: Array<DropdownValue> = [];
+    inputProperties: Array<InputBEModel> = [];
+    archivedWorkflowId: string = '&';
+
+    inputParameters: Array<OperationParameter> = [];
+    noAssignInputParameters: Array<OperationParameter> = [];
+    assignInputParameters: { [key: string]: { [key: string]: Array<OperationParameter>; }; } = {};
+
+    outputParameters: Array<OperationParameter> = [];
+    noAssignOutputParameters: Array<OperationParameter> = [];
+    assignOutputParameters: { [key: string]: { [key: string]: Array<OperationParameter>; }; } = {};
+    componentCapabilities: Array<Capability> = [];
+
+    tableParameters: Array<OperationParameter> = [];
+    operationOutputs: Array<OperationModel> = [];
+
+    associationOptions: Array<DropdownValue> = [];
+    workflowAssociationType: string;
+
+    enableWorkflowAssociation: boolean;
+    workflowIsOnline: boolean;
+    isEditMode: boolean = false;
+    isLoading: boolean = false;
+    readonly: boolean;
+
+    propertyTooltipText: String;
+
+    TYPE_INPUT = 'Inputs';
+    TYPE_OUTPUT = 'Outputs';
+
+    INTERFACE_OTHER_HEADER = 'Local Interfaces';
+    INTERFACE_OTHER = 'Local';
+
+    @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
+    @ViewChild('operationNamesDropdown') operationNamesDropdown: DropDownComponent;
+    @ViewChild('workflowAssignmentDropdown') workflowAssignmentDropdown: DropDownComponent;
+    currentTab: String;
+
+    constructor(private workflowServiceNg2: WorkflowServiceNg2, private translateService: TranslateService) {
+        this.translateService.languageChangedObservable.subscribe(lang => {
+            this.propertyTooltipText = this.translateService.translate("OPERATION_PROPERTY_TOOLTIP_TEXT");
+
+            this.associationOptions = [
+                new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL, this.translateService.translate("EXTERNAL_WORKFLOW_ASSOCIATION")),
+                new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXISTING, this.translateService.translate("EXISTING_WORKFLOW_ASSOCIATION")),
+            ];
+
+            this.workflowAssociationType = this.operation.workflowAssociationType;
+        });
+
+        this.currentTab = this.TYPE_INPUT;
+    }
+
+    createInterfaceDropdown(type: string) {
+        let label = type;
+        const lastDot = label.lastIndexOf('.');
+        if (lastDot > -1) {
+            label = label.substr(lastDot + 1);
+        }
+        return new TypedDropDownOption(type, label);
+    }
+
+    ngOnInit() {
+        this.interfaceNames = _.map(
+            _.keys(this.interfaceTypes),
+            type => this.createInterfaceDropdown(type)
+        );
+        this.interfaceNames.unshift(new TypedDropDownOption('Existing Interfaces', 'Existing Interfaces', DROPDOWN_OPTION_TYPE.HEADER));
+        this.interfaceNames = this.interfaceNames.concat([
+            new TypedDropDownOption(' ', ' ', DROPDOWN_OPTION_TYPE.HORIZONTAL_LINE),
+            new TypedDropDownOption(this.INTERFACE_OTHER_HEADER, this.INTERFACE_OTHER_HEADER, DROPDOWN_OPTION_TYPE.HEADER),
+            new TypedDropDownOption(this.INTERFACE_OTHER)
+        ]);
+        const inputOperation = this.inputOperation;
+        this.operation = new OperationModel(inputOperation || {});
+
+        this.operationOutputs = _.reduce(
+            this.interfaces,
+            (acc: Array<OperationModel>, interf) => [
+                ...acc,
+                ..._.filter(
+                    interf.operations,
+                    op => op.uniqueId !== this.operation.uniqueId
+                ),
+            ],
+            []);
+
+        if (this.enableWorkflowAssociation) {
+            if (this.workflowIsOnline) {
+                this.workflows = _.map(
+                    _.filter(
+                        this.allWorkflows,
+                        (workflow: any) => {
+                            if (workflow.archiving === this.workflowServiceNg2.WF_STATE_ACTIVE) {
+                                return true;
+                            }
+                            if (workflow.archiving === this.workflowServiceNg2.WF_STATE_ARCHIVED &&
+                                workflow.id === this.operation.workflowId) {
+                                this.archivedWorkflowId = workflow.id;
+                                return true;
+                            }
+                            return false;
+                        }
+                    ),
+                    (workflow: any) => new DropdownValue(workflow.id, workflow.name)
+                );
+            } else {
+                this.workflows = [];
+            }
+        }
+        this.reconstructOperation();
+        this.filterCapabilities();
+        this.validityChanged();
+        this.updateTable();
+    }
+
+    ngAfterViewInit() {
+        if (this.workflowAssignmentDropdown) {
+            this.workflowAssignmentDropdown.allOptions = this.associationOptions && this.associationOptions.length ?
+                this.associationOptions :
+                [
+                    new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL, this.translateService.translate("EXTERNAL_WORKFLOW_ASSOCIATION")),
+                    new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXISTING, this.translateService.translate("EXISTING_WORKFLOW_ASSOCIATION")),
+                ];
+        }
+    }
+
+    reconstructOperation = () => {
+
+        const buildAndUpdate = () => {
+            this.buildParams();
+            this.updateTable();
+        };
+
+        const inputOperation = this.inputOperation;
+        if (inputOperation) {
+            this.onSelectInterface(new DropDownOption(this.operation.interfaceType));
+
+            if (this.enableWorkflowAssociation && inputOperation.workflowVersionId && this.isUsingExistingWF(inputOperation)) {
+                this.assignInputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
+                this.assignOutputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
+                this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
+                this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
+
+                const sub = this.onSelectWorkflow(new DropDownOption(inputOperation.workflowId), inputOperation.workflowVersionId);
+                if (sub) {
+                    sub.add(() => {
+                        buildAndUpdate();
+                        this.operation.workflowVersionId = '-1';
+                        setTimeout(() => this.operation.workflowVersionId = this.inputOperation.workflowVersionId);
+                    });
+                } else {
+                    buildAndUpdate();
+                }
+            } else {
+                this.inputParameters = this.noAssignInputParameters;
+                this.outputParameters = this.noAssignOutputParameters;
+                buildAndUpdate();
+            }
+
+            if (inputOperation.uniqueId) {
+                this.isEditMode = true;
+            }
+        }
+
+    }
+
+    filterCapabilities() {
+        this.componentCapabilities = _.filter(this.capabilities, (cap: Capability) => cap.properties);
+    }
+
+    buildParams = () => {
+
+        if (this.inputOperation.outputs) {
+            this.currentTab = this.TYPE_OUTPUT;
+            this.updateTable();
+            _.forEach(
+                [...this.inputOperation.outputs.listToscaDataDefinition].sort((a, b) => a.name.localeCompare(b.name)),
+                (output: OperationParameter) => {
+                    this.addParam({...output, required: Boolean(output.required)});
+                }
+            );
+        }
+
+        this.currentTab = this.TYPE_INPUT;
+        this.updateTable();
+        if (this.inputOperation.inputs) {
+            _.forEach(
+                [...this.inputOperation.inputs.listToscaDataDefinition].sort((a, b) => a.name.localeCompare(b.name)),
+                (input: OperationParameter) => {
+                    this.addParam({...input, required: Boolean(input.required)});
+                }
+            );
+        }
+
+    }
+
+    isInterfaceOther(): boolean {
+        return this.operation.interfaceType === this.INTERFACE_OTHER;
+    }
+
+    onSelectInterface(interf: IDropDownOption) {
+        if (interf && this.operation.interfaceType !== interf.value) {
+            this.operation.name = null;
+        }
+        this.operation.interfaceType = interf && interf.value;
+        this.operationNames = !this.operation.interfaceType ? [] : (
+            _.map(
+                this.interfaceTypes[this.operation.interfaceType],
+                name => {
+                    const curInterf = _.find(
+                        this.interfaces,
+                        interf => interf.type === this.operation.interfaceType
+                    );
+                    const existingOp = _.find(
+                        curInterf && curInterf.operations || [],
+                        op => op.name === name
+                    );
+                    const ddType = (existingOp && existingOp.uniqueId !== this.operation.uniqueId) ? DROPDOWN_OPTION_TYPE.HORIZONTAL_LINE : DROPDOWN_OPTION_TYPE.SIMPLE;
+                    return new TypedDropDownOption(name, name, ddType);
+                }
+            )
+        );
+        if (this.operationNamesDropdown) {
+            this.operationNamesDropdown.allOptions = <IDropDownOption[]>this.operationNames;
+        }
+        this.validityChanged();
+    }
+
+    onSelectOperationName(name: IDropDownOption) {
+        if (name) {
+            this.operation.name = name.value;
+        }
+        this.validityChanged();
+    }
+
+    onChangeName() {
+        this.validityChanged();
+    }
+
+    get descriptionValue() {
+        return this.operation.description;
+    }
+
+    set descriptionValue(v) {
+        this.operation.description = v || null;
+        this.validityChanged();
+    }
+
+    onSelectWorkflow(workflowId: DropDownOption, selectedVersionId?: string): Subscription {
+
+        if (_.isUndefined(workflowId) || !this.workflowIsOnline) {
+            return;
+        }
+
+        if (this.operation.workflowId === workflowId.value && !selectedVersionId) {
+            return;
+        }
+
+        this.operation.workflowId = workflowId.value;
+        if (!this.assignInputParameters[this.operation.workflowId]) {
+            this.assignInputParameters[this.operation.workflowId] = {};
+            this.assignOutputParameters[this.operation.workflowId] = {};
+        }
+        this.operation.workflowName = workflowId.label;
+        if (!this.assignInputParameters[this.operation.workflowName]) {
+            this.assignInputParameters[this.operation.workflowName] = {};
+            this.assignOutputParameters[this.operation.workflowName] = {};
+        }
+
+        this.isLoading = true;
+        this.validityChanged();
+        return this.workflowServiceNg2.getWorkflowVersions(this.operation.workflowId).subscribe((versions: Array<any>) => {
+            this.isLoading = false;
+
+            this.workflowVersions = _.map(
+                _.filter(
+                    versions, version => version.state === this.workflowServiceNg2.VERSION_STATE_CERTIFIED
+                ).sort((a, b) => a.name.localeCompare(b.name)),
+                (version: any) => {
+                    if (!this.assignInputParameters[this.operation.workflowId][version.id] && version.id !== selectedVersionId) {
+                        this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: any) => {
+                            return new OperationParameter({
+                                ...input,
+                                type: input.type.toLowerCase(),
+                                required: Boolean(input.mandatory)
+                            });
+                        })
+                        .sort((a, b) => a.name.localeCompare(b.name));
+
+                        this.assignOutputParameters[this.operation.workflowId][version.id] = _.map(version.outputs, (output: any) => {
+                            return new OperationParameter({
+                                ...output,
+                                type: output.type.toLowerCase(),
+                                required: Boolean(output.mandatory)
+                            });
+                        })
+                        .sort((a, b) => a.name.localeCompare(b.name));
+                    }
+                    return new DropdownValue(version.id, `V ${version.name}`);
+                }
+            );
+            if (!selectedVersionId && this.workflowVersions.length) {
+                this.operation.workflowVersionId = _.last(this.workflowVersions).value;
+                this.operation.workflowVersion = _.last(this.workflowVersions).label;
+            }
+
+            this.changeWorkflowVersion(new DropDownOption(this.operation.workflowVersionId));
+            this.validityChanged();
+        });
+
+    }
+
+    changeWorkflowVersion(versionId: DropDownOption) {
+
+        if (_.isUndefined(versionId) || !this.workflowIsOnline) {
+            return;
+        }
+
+        this.operation.workflowVersionId = versionId.value;
+        this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
+        this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
+        this.updateTable();
+        this.validityChanged();
+
+    }
+
+    toggleAssociateWorkflow(type: DropDownOption) {
+
+        if (_.isUndefined(type)) {
+            return;
+        }
+
+        this.operation.workflowAssociationType = type.value;
+        this.workflowAssociationType = this.operation.workflowAssociationType;
+
+        if (!this.isUsingExistingWF()) {
+            this.inputParameters = this.noAssignInputParameters;
+            this.outputParameters = this.noAssignOutputParameters;
+        } else {
+            if (!this.operation.workflowId || !this.operation.workflowVersionId) {
+                this.inputParameters = [];
+                this.outputParameters = [];
+            } else {
+                this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
+                this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
+            }
+        }
+
+        this.updateTable();
+        this.validityChanged();
+
+    }
+
+    onChangeArtifactFile(e: any) {
+        const file = e.target.files && e.target.files[0];
+        this.operation.artifactFileName = file && file.name;
+
+        if (!this.operation.artifactFileName) {
+            this.operation.artifactData = null;
+            this.validityChanged();
+            return;
+        }
+
+        const reader = new FileReader();
+        reader.onloadend = () => {
+            this.isLoading = false;
+            const result = <String>reader.result;
+            this.operation.artifactData = result.substring(result.indexOf(',') + 1);
+            this.validityChanged();
+        }
+
+        this.isLoading = true;
+        reader.readAsDataURL(file);
+    }
+
+    tabChanged = (event) => {
+
+        this.currentTab = event.title;
+        this.updateTable();
+
+    }
+
+    updateTable() {
+
+        switch (this.currentTab) {
+            case this.TYPE_INPUT:
+                this.tableParameters = this.inputParameters;
+                break;
+            case this.TYPE_OUTPUT:
+                this.tableParameters = this.outputParameters;
+                break;
+        }
+
+    }
+
+    addParam(param?: OperationParameter): void {
+        this.tableParameters.push(new OperationParameter(param || {required: false}));
+        this.validityChanged();
+    }
+
+    canAdd = (): boolean => {
+
+        let valid = true;
+        if (this.currentTab === this.TYPE_INPUT) {
+            _.forEach(this.inputParameters, param => {
+                if (!param.name || !param.inputId) {
+                    valid = false;
+                }
+            });
+        } else {
+            _.forEach(this.outputParameters, param => {
+                if (!param.name || !param.type) {
+                    valid = false;
+                }
+            });
+        }
+
+        return valid;
+
+    }
+
+    isParamsValid = (): boolean => {
+
+        let valid = true;
+        _.forEach(this.inputParameters, param => {
+            if (!param.name || !param.inputId) {
+                valid = false;
+            }
+        });
+        _.forEach(this.outputParameters, param => {
+            if (!param.name || !param.type) {
+                valid = false;
+            }
+        });
+
+        return valid;
+
+    }
+
+    onRemoveParam = (param: OperationParameter): void => {
+        let index = _.indexOf(this.tableParameters, param);
+        this.tableParameters.splice(index, 1);
+        this.validityChanged();
+    }
+
+    createParamLists = () => {
+        this.operation.createInputsList(this.inputParameters);
+        this.operation.createOutputsList(this.outputParameters);
+    }
+
+    isUsingExistingWF = (operation?: OperationModel): boolean => {
+        operation = operation || this.operation;
+        return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING;
+    }
+
+    isUsingExternalWF = (operation?: OperationModel): boolean => {
+        operation = operation || this.operation;
+        return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL;
+    }
+
+    shouldCreateWF = (operation?: OperationModel): boolean => {
+        operation = operation || this.operation;
+        return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW;
+    }
+
+    checkFormValidForSubmit = (): boolean => {
+        return this.operation.name &&
+            (!this.isUsingExistingWF() || this.operation.workflowVersionId) &&
+            this.isParamsValid();
+    }
+
+    validityChanged = () => {
+        let validState = this.checkFormValidForSubmit();
+        this.validityChangedCallback(validState);
+    }
+
+    getSelectedDropdown(options: DropdownValue[], selectedValue: string): DropdownValue {
+        const selectedDropdown = _.find(options, (option) => option.value === selectedValue);
+        return selectedDropdown || this.toDropDownOption(null);
+    }
+
+    toDropDownOption(val: string) {
+        return {value: val, label: val};
+    }
+}
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.module.ts b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.module.ts
new file mode 100644
index 0000000..7f75240
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/operation-creator-interface-definition.module.ts
@@ -0,0 +1,52 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2022 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 {NgModule} from "@angular/core";
+import {ParamRowComponent} from "./param-row/param-row.component";
+import {OperationCreatorInterfaceDefinitionComponent} from "./operation-creator-interface-definition.component";
+import {UiElementsModule} from "../../../components/ui/ui-elements.module";
+import {TranslateModule} from "../../../shared/translator/translate.module";
+import {SdcUiComponentsModule} from "onap-ui-angular";
+import {CommonModule} from "@angular/common";
+import {FormsModule} from "@angular/forms";
+import {FormElementsModule} from "../../../components/ui/form-components/form-elements.module";
+
+@NgModule({
+    declarations: [
+        OperationCreatorInterfaceDefinitionComponent,
+        ParamRowComponent
+    ],
+    imports: [
+        CommonModule,
+        SdcUiComponentsModule,
+        FormsModule,
+        FormElementsModule,
+        TranslateModule,
+        UiElementsModule
+    ],
+    exports: [],
+    entryComponents: [
+        OperationCreatorInterfaceDefinitionComponent
+    ],
+    providers: []
+})
+
+export class OperationCreatorInterfaceDefinitionModule {
+}
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.html b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.html
new file mode 100644
index 0000000..1ed0375
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.html
@@ -0,0 +1,100 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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-name">
+    <ui-element-input
+        *ngIf="!isAssociateWorkflow"
+        [testId]="'param-name-' + (param.name || 'unnamed')"
+        [(value)]="param.name"
+        (valueChange)="onChangeName()"
+        [readonly]="readonly">
+    </ui-element-input>
+    <span *ngIf="isAssociateWorkflow">{{param.name}}</span>
+</div>
+
+<div class="cell field-type">
+    <ui-element-dropdown
+        *ngIf="!isAssociateWorkflow"
+        [testId]="'param-type-' + (param.name || 'unnamed')"
+        [values]="propTypeEnum"
+        [(value)]="param.type"
+        (valueChange)="onChangeType()"
+        [readonly]="readonly">
+    </ui-element-dropdown>
+    <span *ngIf="isAssociateWorkflow">{{param.type}}</span>
+</div>
+
+<div class="cell field-property" *ngIf="isInputParam">
+    <select
+        *ngIf="filteredInputProps.length || operationOutputCats.length || !isAssociateWorkflow"
+        [(ngModel)]="param.inputId"
+        (change)="onChangeProperty($event)"
+        [ngClass]="{'disabled': readonly}"
+        [attr.data-tests-id]="'value-param-property-' + (param.name || 'unnamed')">
+        <option
+            *ngFor="let prop of filteredInputProps"
+            [ngValue]="prop.value">
+            {{prop.label}}
+        </option>
+        <optgroup
+            *ngFor="let operation of operationOutputCats"
+            label="{{operation.operationName}}">
+            <option
+                *ngFor="let output of operation.outputs"
+                [ngValue]="output.value">
+                {{output.label}}
+            </option>
+        </optgroup>
+        <optgroup
+                *ngFor="let cap of filteredCapabilitiesProps"
+                label="{{cap.capabilityName}}">
+            <option
+                    *ngFor="let prop of cap.properties"
+                    [ngValue]="prop.value">
+                {{prop.label}}
+            </option>
+        </optgroup>
+    </select>
+    <span
+        *ngIf="!filteredInputProps.length && !operationOutputCats.length && isAssociateWorkflow"
+        class="no-properties-error">
+        {{ 'PARAM_NONE_OF_TYPE' | translate }}
+    </span>
+</div>
+
+<div class="cell field-mandatory" *ngIf="!isAssociateWorkflow">
+    <checkbox
+        *ngIf="!isAssociateWorkflow"
+        [attr.data-tests-id]="'param-mandatory-' + (param.name || 'unnamed')"
+        [(checked)]="param.required"
+        [ngClass]="{'disabled':readonly}">
+    </checkbox>
+</div>
+
+<div class="cell remove" *ngIf="!isAssociateWorkflow && !readonly">
+    <svg-icon
+        name="trash-o"
+        mode="info"
+        size="small"
+        [attr.data-tests-id]="'param-remove-' + (param.name || 'unnamed')"
+        (click)="onRemoveParam(param)"
+        [clickable]="true">
+  </svg-icon>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.less b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.less
new file mode 100644
index 0000000..d616bad
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.less
@@ -0,0 +1,73 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2022 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 '../../../../../../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/interface-definition/operation-creator/param-row/param-row.component.ts b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.ts
new file mode 100644
index 0000000..43760ba
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/operation-creator/param-row/param-row.component.ts
@@ -0,0 +1,257 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2022 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 {DataTypeService} from "app/ng2/services/data-type.service";
+import {
+    Capability,
+    DataTypeModel,
+    InputBEModel,
+    OperationModel,
+    OperationParameter
+} from 'app/models';
+import {
+    DropdownValue
+} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
+import {WorkspaceService} from "../../../workspace/workspace.service";
+
+class DropdownValueType extends DropdownValue {
+    type: string;
+
+    constructor(value: string, label: string, type?: string) {
+        super(value, label);
+        if (type) {
+            this.type = type;
+        }
+    }
+}
+
+@Component({
+    selector: 'param-row',
+    templateUrl: './param-row.component.html',
+    styleUrls: ['./param-row.component.less']
+})
+
+export class ParamRowComponent {
+    @Input() param: OperationParameter;
+    @Input() inputProps: Array<InputBEModel>;
+    @Input() operationOutputs: Array<OperationModel>;
+    @Input() capabilitiesProps: Array<Capability>;
+    @Input() onRemoveParam: Function;
+    @Input() isAssociateWorkflow: boolean;
+    @Input() readonly: boolean;
+    @Input() isInputParam: boolean;
+    @Input() validityChanged: Function;
+
+    propTypeEnum: Array<string> = [];
+    operationOutputCats: Array<{ operationName: string, outputs: Array<DropdownValueType> }> = [];
+    filteredInputProps: Array<DropdownValue> = [];
+    filteredCapabilitiesProps: Array<{ capabilityName: string, properties: Array<DropdownValueType> }> = [];
+
+    constructor(private dataTypeService: DataTypeService, protected workspaceService: WorkspaceService) {
+    }
+
+    ngOnInit() {
+        if (this.isInputParam) {
+            this.propTypeEnum = _.uniq(
+                _.map(
+                    _.concat(
+                        this.getPrimitiveSubtypes(),
+                        _.reduce(
+                            this.operationOutputs,
+                            (acc, op) => [...acc, ...op.outputs.listToscaDataDefinition],
+                            []),
+                        _.reduce(
+                            this.capabilitiesProps,
+                            (acc, capab) => [...acc, ...capab.properties],
+                            [])
+                    ),
+                    prop => prop.type
+                )
+            );
+        } else {
+            const dataTypes: Array<DataTypeModel> = _.toArray(this.dataTypeService.getDataTypeByModel(this.workspaceService.metadata.model));
+            this.propTypeEnum = _.concat(
+                _.map(
+                    _.filter(
+                        dataTypes,
+                        type => this.isTypePrimitive(type.name)
+                    ),
+                    type => type.name
+                ).sort(),
+                _.map(
+                    _.filter(
+                        dataTypes,
+                        type => !this.isTypePrimitive(type.name)
+                    ),
+                    type => type.name
+                ).sort()
+            );
+        }
+
+        this.onChangeType();
+        this.validityChanged();
+    }
+
+    onChangeName() {
+        this.validityChanged();
+    }
+
+    onChangeType() {
+        if (!this.isInputParam) {
+            this.validityChanged();
+            return;
+        }
+
+        this.filteredInputProps = _.map(
+            _.filter(
+                this.getPrimitiveSubtypes(),
+                prop => !this.param.type || prop.type === this.param.type
+            ),
+            prop => new DropdownValue(prop.uniqueId, prop.name)
+        );
+        this.filteredInputProps.unshift(new DropdownValue("", ""));
+
+        this.operationOutputCats = _.filter(
+            _.map(
+                this.operationOutputs,
+                op => {
+                    return {
+                        operationName: `${op.displayType()}.${op.name}`,
+                        outputs: _.map(
+                            _.filter(op.outputs.listToscaDataDefinition, output => !this.param.type || output.type === this.param.type),
+                            output => new DropdownValueType(
+                                `${op.interfaceType}.${op.name}.${output.name}`,
+                                output.name,
+                                output.type
+                            )
+                        )
+                    };
+                }
+            ),
+            category => category.outputs.length > 0
+        );
+
+        this.filteredCapabilitiesProps = _.filter(
+            _.map(
+                this.capabilitiesProps,
+                cap => {
+                    return {
+                        capabilityName: cap.name,
+                        properties: _.map(
+                            _.filter(cap.properties, prop => !this.param.type || prop.type === this.param.type),
+                            prop => new DropdownValueType(
+                                prop.uniqueId,
+                                prop.name,
+                                prop.type
+                            )
+                        )
+                    };
+                }
+            ),
+            capability => capability.properties.length > 0
+        );
+
+        if (this.param.inputId) {
+            const selProp = this.getSelectedProp();
+            if (selProp && selProp.type === this.param.type) {
+                this.param.inputId = '-1';
+                setTimeout(() => this.param.inputId = selProp.uniqueId || selProp.value);
+            } else {
+                this.param.inputId = null;
+            }
+        }
+
+        this.validityChanged();
+    }
+
+    onChangeProperty() {
+        const newProp = this.getSelectedProp();
+
+        if (!this.param.type) {
+            this.param.type = newProp.type;
+            this.onChangeType();
+        }
+
+        if (!this.param.name) {
+            this.param.name = newProp.name || newProp.label;
+        }
+
+        this.validityChanged();
+    }
+
+    getPrimitiveSubtypes(): Array<InputBEModel> {
+        const flattenedProps: Array<any> = [];
+        const dataTypes = this.dataTypeService.getDataTypeByModel(this.workspaceService.metadata.model);
+
+        _.forEach(this.inputProps, prop => {
+            const type: DataTypeModel = _.find(
+                _.toArray(dataTypes),
+                (type: DataTypeModel) => type.name === prop.type
+            );
+            flattenedProps.push(prop);
+            if (!type) {
+                console.error('Could not find prop in dataTypes: ', prop);
+            } else {
+                if (type.properties) {
+                    _.forEach(type.properties, subType => {
+                        if (this.isTypePrimitive(subType.type)) {
+                            flattenedProps.push({
+                                type: subType.type,
+                                name: `${prop.name}.${subType.name}`,
+                                uniqueId: `${prop.uniqueId}.${subType.name}`
+                            });
+                        }
+                    });
+                }
+            }
+        });
+
+        return flattenedProps;
+    }
+
+    getSelectedProp() {
+        return _.find(
+            this.getPrimitiveSubtypes(),
+            prop => this.param.inputId === prop.uniqueId
+        ) || _.find(
+            _.reduce(
+                this.operationOutputCats,
+                (acc, cat) => [...acc, ...cat.outputs],
+                []),
+            (out: DropdownValueType) => this.param.inputId === out.value
+        ) || _.find(
+            _.reduce(
+                this.filteredCapabilitiesProps,
+                (acc, cap) => [...acc, ...cap.properties],
+                []),
+            (prop: DropdownValueType) => this.param.inputId === prop.value
+        );
+    }
+
+    isTypePrimitive(type: string): boolean {
+        return (
+            type === 'string' ||
+            type === 'integer' ||
+            type === 'float' ||
+            type === 'boolean'
+        );
+    }
+}
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
index 4f93e72..75a31b9 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
@@ -1,36 +1,52 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2022 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 * as _ from "lodash";
-import { Component, Input, Inject } from '@angular/core';
-import {Component as IComponent } from 'app/models/components/component';
+import {Component, Inject, Input} from '@angular/core';
+import {Component as IComponent} from 'app/models/components/component';
 
-import { SdcConfigToken, ISdcConfig } from "app/ng2/config/sdc-config.config";
-import {TranslateService } from "app/ng2/shared/translator/translate.service";
+import {ISdcConfig, SdcConfigToken} from "app/ng2/config/sdc-config.config";
+import {TranslateService} from "app/ng2/shared/translator/translate.service";
 
-import {Observable } from "rxjs/Observable";
+import {Observable} from "rxjs/Observable";
 
-import { ModalComponent } from 'onap-ui-angular/dist/modals/modal.component';
-import {ModalService } from 'app/ng2/services/modal.service';
+import {ModalComponent} from 'onap-ui-angular/dist/modals/modal.component';
+import {ModalService} from 'app/ng2/services/modal.service';
 import {
-    InputBEModel,
-    OperationModel,
-    InterfaceModel,
-    WORKFLOW_ASSOCIATION_OPTIONS,
     CapabilitiesGroup,
-    Capability
+    Capability,
+    InputBEModel,
+    InterfaceModel,
+    OperationModel,
+    WORKFLOW_ASSOCIATION_OPTIONS
 } from 'app/models';
 
-// import {SdcUiComponents } from 'sdc-ui/lib/angular';
-// import {ModalButtonComponent } from 'sdc-ui/lib/angular/components';
-// import { IModalButtonComponent, IModalConfig } from 'sdc-ui/lib/angular/modals/models/modal-config';
+import {ComponentServiceNg2} from 'app/ng2/services/component-services/component.service';
+import {PluginsService} from 'app/ng2/services/plugins.service';
+import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
 
-import {ComponentServiceNg2 } from 'app/ng2/services/component-services/component.service';
-import {PluginsService } from 'app/ng2/services/plugins.service';
-import {WorkflowServiceNg2 } from 'app/ng2/services/workflow.service';
-
-import { OperationCreatorComponent, OperationCreatorInput } from 'app/ng2/pages/interface-operation/operation-creator/operation-creator.component';
-import { IModalButtonComponent } from 'onap-ui-angular';
-import { ModalButtonComponent } from 'onap-ui-angular';
-import { IModalConfig } from 'onap-ui-angular';
-import { SdcUiServices } from 'onap-ui-angular';
+import {
+    OperationCreatorComponent,
+    OperationCreatorInput
+} from 'app/ng2/pages/interface-operation/operation-creator/operation-creator.component';
+import {IModalButtonComponent, IModalConfig, SdcUiServices} from 'onap-ui-angular';
 
 export class UIOperationModel extends OperationModel {
     isCollapsed: boolean = true;
@@ -143,7 +159,6 @@
         private WorkflowServiceNg2: WorkflowServiceNg2,
         private ModalServiceNg2: ModalService,
         private ModalServiceSdcUI: SdcUiServices.ModalService
-        
     ) {
         this.enableWorkflowAssociation = sdcConfig.enableWorkflowAssociation;
         this.modalTranslation = new ModalTranslation(TranslateService);
@@ -164,7 +179,7 @@
                 this.sortInterfaces();
                 this.inputs = response[1].inputs;
                 this.interfaceTypes = response[2];
-                this.workflows = (workflows.items) ? workflows.items: workflows;
+                this.workflows = (workflows.items) ? workflows.items : workflows;
                 this.capabilities = response[3].capabilities;
             };
             if (this.enableWorkflowAssociation && this.workflowIsOnline) {
@@ -308,16 +323,16 @@
             closeModal: true,
             callback: () => {
                 this.ComponentServiceNg2
-                    .deleteInterfaceOperation(this.component, operation)
-                    .subscribe(() => {
-                        const curInterf = _.find(this.interfaces, (interf) => interf.type === operation.interfaceType);
-                        const index = _.findIndex(curInterf.operations, (el) => el.uniqueId === operation.uniqueId);
-                        curInterf.operations.splice(index, 1);
-                        if (!curInterf.operations.length) {
-                            const interfIndex = _.findIndex(this.interfaces, (interf) => interf.type === operation.interfaceType);
-                            this.interfaces.splice(interfIndex, 1);
-                        }
-                    });
+                .deleteInterfaceOperation(this.component, operation)
+                .subscribe(() => {
+                    const curInterf = _.find(this.interfaces, (interf) => interf.type === operation.interfaceType);
+                    const index = _.findIndex(curInterf.operations, (el) => el.uniqueId === operation.uniqueId);
+                    curInterf.operations.splice(index, 1);
+                    if (!curInterf.operations.length) {
+                        const interfIndex = _.findIndex(this.interfaces, (interf) => interf.type === operation.interfaceType);
+                        this.interfaces.splice(interfIndex, 1);
+                    }
+                });
             }
         };
 
@@ -372,7 +387,7 @@
             } else if (response.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) {
                 this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, response).subscribe();
             } else if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW) {
-                this.$state.go('workspace.plugins', { path: 'workflowDesigner' });
+                this.$state.go('workspace.plugins', {path: 'workflowDesigner'});
             }
         });
     }
diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
index 8d91eed..3889b73 100644
--- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
@@ -238,12 +238,44 @@
         });
     }
 
+    createComponentInterfaceOperation(componentMetaDataId: string,
+                                      componentMetaDataType: string,
+                                      operation: InterfaceOperationModel): Observable<InterfaceOperationModel> {
+        const operationList = {
+            interfaces: {
+                [operation.interfaceType]: {
+                    type: operation.interfaceType,
+                    operations: {
+                        [operation.name]: new BEInterfaceOperationModel(operation)
+                    }
+                }
+            }
+        };
+        console.log(operationList);
+        console.log(this.baseUrl + componentMetaDataType + componentMetaDataId + '/resource/interfaceOperation')
+        return this.http.post<any>(this.baseUrl + componentMetaDataType + componentMetaDataId + '/resource/interfaceOperation', operationList)
+        .map((res: any) => {
+            const interf: InterfaceModel = _.find(res.interfaces, interf => interf.type === operation.interfaceType);
+            const newOperation: OperationModel = _.find(interf.operations, op => op.name === operation.name);
+
+            return new InterfaceOperationModel({
+                ...newOperation,
+                interfaceType: interf.type,
+                interfaceId: interf.uniqueId,
+            });
+        });
+    }
+
     deleteInterfaceOperation(component: Component, operation: OperationModel): Observable<OperationModel> {
         return this.http.delete<OperationModel>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaces/' + operation.interfaceId + '/operations/' + operation.uniqueId);
     }
 
     getInterfaceTypes(component: Component): Observable<{ [id: string]: Array<string> }> {
-        return this.http.get<any>(this.baseUrl + 'interfaceLifecycleTypes' + ((component && component.model) ? '?model=' + component.model : ''))
+        return this.getInterfaceTypesByModel(component && component.model);
+    }
+
+    getInterfaceTypesByModel(model: string): Observable<{ [id: string]: Array<string> }> {
+        return this.http.get<any>(this.baseUrl + 'interfaceLifecycleTypes' + ((model) ? '?model=' + model : ''))
         .map((res: any) => {
             const interfaceMap = {};
             if (!res) {