Add UI support for adding tosca artifact types

UI support for adding artifacts to an interface operation implementation

Issue-ID: SDC-3768
Signed-off-by: aribeiro <anderson.ribeiro@est.tech>
Change-Id: I71b3e49a160521e35a45515ad7adef836f901e78
diff --git a/catalog-ui/src/app/models/artifacts.ts b/catalog-ui/src/app/models/artifacts.ts
index e290dc6..e6e76e0 100644
--- a/catalog-ui/src/app/models/artifacts.ts
+++ b/catalog-ui/src/app/models/artifacts.ts
@@ -24,6 +24,7 @@
 import * as _ from "lodash";
 import {ArtifactType} from './../utils';
 import {HeatParameterModel} from "./heat-parameters";
+import {PropertyBEModel} from "./properties-inputs/property-be-model";
 
 //this object contains keys, each key contain ArtifactModel
 export class ArtifactGroupModel {
@@ -76,6 +77,7 @@
     originalDescription:string;
     envArtifact:ArtifactModel;
     allowDeleteAndUpdate: boolean;
+    properties:Array<PropertyBEModel>;
 
     constructor(artifact?:ArtifactModel) {
         if (artifact) {
@@ -104,6 +106,7 @@
             this.selected = artifact.selected ? artifact.selected : false;
             this.originalDescription = artifact.description;
             this.isFromCsar = artifact.isFromCsar;
+            this.properties = _.sortBy(_.cloneDeep(artifact.properties), 'name');
         }
     }
 
diff --git a/catalog-ui/src/app/models/interfaceOperation.ts b/catalog-ui/src/app/models/interfaceOperation.ts
index 5c69688..109babb 100644
--- a/catalog-ui/src/app/models/interfaceOperation.ts
+++ b/catalog-ui/src/app/models/interfaceOperation.ts
@@ -19,6 +19,8 @@
 
 'use strict';
 
+import {ArtifactModel} from "./artifacts";
+
 export class InputOperationParameter {
     name: string;
     type: string;
@@ -36,6 +38,22 @@
     }
 }
 
+export class PropertyOperationParameter {
+    name: string;
+    type: string;
+    value?: string;
+    propertyId: string;
+
+    constructor(param?: any) {
+        if (param) {
+            this.name = param.name;
+            this.type = param.type;
+            this.value = param.value;
+            this.propertyId = param.propertyId;
+        }
+    }
+}
+
 export interface IOperationParamsList {
     listToscaDataDefinition: Array<InputOperationParameter>;
 }
@@ -45,7 +63,7 @@
     description: string;
     uniqueId: string;
     inputs: IOperationParamsList;
-    implementation?: InterfaceOperationImplementation;
+    implementation: ArtifactModel;
 
     constructor(operation?: any) {
         if (operation) {
@@ -64,8 +82,8 @@
     operationType: string;
     description: string;
     uniqueId: string;
-    implementation?: InterfaceOperationImplementation;
     inputParams: IOperationParamsList;
+    implementation: ArtifactModel;
 
     constructor(operation?: any) {
         super(operation);
@@ -76,6 +94,7 @@
             this.operationType = operation.operationType;
             this.uniqueId = operation.uniqueId;
             this.inputParams = operation.inputParams;
+            this.implementation = operation.implementation;
         }
     }
 
@@ -84,10 +103,6 @@
     }
 }
 
-export class InterfaceOperationImplementation {
-    artifactName: string;
-}
-
 export class ComponentInstanceInterfaceModel {
     type: string;
     uniqueId: string;
diff --git a/catalog-ui/src/app/models/toscaArtifact.ts b/catalog-ui/src/app/models/toscaArtifact.ts
new file mode 100644
index 0000000..eb87728
--- /dev/null
+++ b/catalog-ui/src/app/models/toscaArtifact.ts
@@ -0,0 +1,45 @@
+/*
+* ============LICENSE_START=======================================================
+*  Copyright (C) 2021 Nordix Foundation. All rights reserved.
+*  ================================================================================
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at
+*
+*        http://www.apache.org/licenses/LICENSE-2.0
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*
+*  SPDX-License-Identifier: Apache-2.0
+*  ============LICENSE_END=========================================================
+*/
+
+import {PropertyBEModel} from "./properties-inputs/property-be-model";
+
+export class ToscaArtifactModel {
+  type: string;
+  file: string;
+  repository: string
+  description: string
+  deploy_path: string;
+  artifact_version: string;
+  checksum: string;
+  checksum_algorithm: string;
+  propertiesData: Array<PropertyBEModel>;
+
+  constructor(param?: any) {
+    this.type = param.type;
+    this.file = param.file;
+    this.repository = param.repository;
+    this.description = param.description;
+    this.deploy_path = param.deploy_path;
+    this.artifact_version = param.artifact_version;
+    this.checksum = param.checksum;
+    this.checksum_algorithm = param.checksum_algorithm;
+    this.propertiesData = param.propertiesData;
+  }
+
+}
diff --git a/catalog-ui/src/app/modules/service-module.ts b/catalog-ui/src/app/modules/service-module.ts
index de62091..b9191cc 100644
--- a/catalog-ui/src/app/modules/service-module.ts
+++ b/catalog-ui/src/app/modules/service-module.ts
@@ -70,6 +70,7 @@
 import { FileUtils } from '../utils/file-utils';
 import { ValidationUtils } from '../utils/validation-utils';
 import {ReqAndCapabilitiesService} from "../ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service";
+import {ToscaArtifactService} from "../ng2/services/tosca-artifact.service";
 
 const moduleName: string = 'Sdc.Services';
 const serviceModule: ng.IModule = angular.module(moduleName, []);
@@ -131,3 +132,4 @@
 serviceModule.service('ElementService', downgradeInjectable(ElementService));
 serviceModule.service('ModelService', downgradeInjectable(ModelService));
 serviceModule.service('ImportVSPService', downgradeInjectable(ImportVSPService));
+serviceModule.service('ToscaArtifactService', downgradeInjectable(ToscaArtifactService));
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index bb11199..5b12ae9 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -101,6 +101,7 @@
 import {AttributesOutputsModule} from "./pages/attributes-outputs/attributes-outputs.module";
 import { ElementService } from "./services/element.service";
 import { ModelService } from "./services/model.service";
+import {ToscaArtifactService} from "./services/tosca-artifact.service";
 
 
 declare const __ENV__: string;
@@ -201,6 +202,7 @@
     OnboardingService,
     ElementService,
     ModelService,
+    ToscaArtifactService,
     ServiceServiceNg2,
     AutomatedUpgradeService,
     WorkflowServiceNg2,
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 304fbce..2cc91a9 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
@@ -19,7 +19,7 @@
 *  ============LICENSE_END=========================================================
 */
 
-import {Component, ComponentRef, Input} from '@angular/core';
+import {Component, ComponentRef, Inject, Input} from '@angular/core';
 import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
 import {TranslateService} from "../../../shared/translator/translate.service";
 import {ModalService } from 'app/ng2/services/modal.service';
@@ -45,15 +45,17 @@
   InterfaceModel,
   InputBEModel,
   ModalModel,
-  ComponentInstance
+  ComponentInstance, ArtifactModel
 } from 'app/models';
+import {ArtifactGroupType} from "../../../../utils/constants";
+import {DropdownValue} from "../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
+import {ToscaArtifactService} from "../../../services/tosca-artifact.service";
+import {ToscaArtifactModel} from "../../../../models/toscaArtifact";
 
 export class UIInterfaceOperationModel extends InterfaceOperationModel {
   isCollapsed: boolean = true;
   isEllipsis: boolean;
   MAX_LENGTH = 75;
-  _description: string;
-
   constructor(operation: InterfaceOperationModel) {
     super(operation);
 
@@ -119,7 +121,6 @@
 })
 export class InterfaceOperationsComponent {
   interfaces: UIInterfaceModel[];
-  selectedOperation: InterfaceOperationModel;
   inputs: Array<InputBEModel>;
   isLoading: boolean;
   interfaceTypes: { [interfaceType: string]: string[] };
@@ -130,6 +131,9 @@
   modalTranslation: ModalTranslation;
   componentInstancesInterfaces: Map<string, InterfaceModel[]>;
 
+  deploymentArtifactsFilePath: Array<DropdownValue> = [];
+  toscaArtifactTypes: Array<DropdownValue> = [];
+
   @Input() component: ComponentInstance;
   @Input() readonly: boolean;
   @Input() enableMenuItems: Function;
@@ -141,8 +145,10 @@
       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);
   }
@@ -150,6 +156,8 @@
   ngOnInit(): void {
     this.componentMetaData = this.workspaceService.metadata;
     this.loadComponentInstances();
+    this.loadDeployedArtifacts();
+    this.loadToscaArtifacts()
   }
 
   private loadComponentInstances() {
@@ -167,7 +175,7 @@
     this.sortInterfaces();
   }
 
-  private initInterfaces(interfaces: InterfaceModel[]): void {
+  private initInterfaces(interfaces: ComponentInstanceInterfaceModel[]): void {
     this.interfaces = _.map(interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
   }
 
@@ -201,7 +209,7 @@
   }
 
   private enableOrDisableSaveButton = (): boolean => {
-    return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
+    return this.modalInstance.instance.dynamicContent.instance.readonly;
   }
 
   onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
@@ -215,6 +223,8 @@
         this.modalInstance,
         InterfaceOperationHandlerComponent,
         {
+          deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
+          toscaArtifactTypes: this.toscaArtifactTypes,
           selectedInterface: interfaceModel,
           selectedInterfaceOperation: operation,
           validityChangedCallback: this.enableOrDisableSaveButton
@@ -235,13 +245,43 @@
         this.componentMetaData.uniqueId,
         this.componentMetaData.componentType,
         this.componentInstanceSelected.uniqueId,
-        operationUpdated)
-    .subscribe((updatedComponentInstance: ComponentInstance) => {
-      this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance);
-      this.initComponentInstanceInterfaceOperations();
+        operationUpdated).subscribe((updatedComponentInstance: ComponentInstance) => {
+          this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance);
+          this.initComponentInstanceInterfaceOperations();
     });
     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)));
+        });
+      }}, 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'
+      });
+    });
+  }
+
 }
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 f711020..428c4cd 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
@@ -41,7 +41,7 @@
             </div>
         </div>
 
-        <div class="i-sdc-form-item">
+        <div class="form-item">
             <sdc-input
                 label="{{'OPERATION_DESCRIPTION' | translate}}"
                 [(value)]="operationToUpdate.description"
@@ -50,12 +50,73 @@
             </sdc-input>
         </div>
 
-        <div class="i-sdc-form-item">
-            <sdc-input
-                label="{{'IMPLEMENTATION_NAME' | translate}}"
-                testId="interface-operation-implementation-name"
-                [(value)]="operationToUpdate.implementation.artifactName">
-            </sdc-input>
+        <div class="group-with-border content-row">
+            <label class="occurrences-label"> {{ 'INTERFACE_OPERATION_IMPLEMENTATION' | translate}}</label>
+            <div class="form-item">
+                <checkbox [label]="'Add Artifact To Implementation'"
+                          [(checked)]="enableAddArtifactImplementation"
+                          (checkedChange)="onMarkToAddArtifactToImplementation($event)">
+                </checkbox>
+            </div>
+            <div class="form-item" *ngIf="!enableAddArtifactImplementation">
+                <sdc-input
+                    label="{{'INTERFACE_OPERATION_IMPLEMENTATION_NAME' | translate}}"
+                    testId="interface-operation-implementation-name"
+                    [(value)]="artifactName"
+                    (valueChange)="onImplementationNameChange($event)">
+                </sdc-input>
+            </div>
+
+            <div class="side-by-side" *ngIf="enableAddArtifactImplementation">
+                <div class="form-item" *ngIf="toscaArtifactTypes">
+                    <sdc-dropdown
+                        label="{{ 'TOSCA_ARTIFACT_TYPE' | translate }}"
+                        testId="selectToscaArtifactType"
+                        [required]="true"
+                        [selectedOption]="toscaArtifactTypeSelected"
+                        placeHolder="{{toscaArtifactTypeSelected != undefined ? toscaArtifactTypeSelected : 'Select...'}}"
+                        (changed)="onSelectToscaArtifactType($event)"
+                        [options]="toscaArtifactTypes">
+                    </sdc-dropdown>
+                </div>
+                <div class="form-item" *ngIf="toscaArtifactTypeSelected && enableAddArtifactImplementation">
+                    <sdc-input
+                        label="{{ 'INTERFACE_OPERATION_IMPLEMENTATION_FILE' | translate }}"
+                        data-tests-id="artifactFile"
+                        [(value)]="artifactName"
+                        [required]="true"
+                        (valueChange)="onArtifactFileChange($event)">
+                    </sdc-input>
+                </div>
+                <div class="form-item">
+                    <sdc-input
+                        label="{{ 'ARTIFACT_VERSION' | translate }}"
+                        data-tests-id="artifactVersion"
+                        [(value)]="artifactVersion"
+                        (valueChange)="onArtifactVersionChange($event)">
+                    </sdc-input>
+                </div>
+            </div>
+            <div class="form-item" *ngIf="toscaArtifactTypeSelected && enableAddArtifactImplementation">
+                <label class="sdc-input__label">{{ 'ENTITY_VIEWER_PROPERTIES_TAB' | translate }}</label>
+                <div class="generic-table">
+                    <div class="header-row table-row">
+                        <span class="cell header-cell field-input-name">{{ 'IMPLEMENTATION_ARTIFACT_PROPERTY_NAME' | translate }}</span>
+                        <span class="cell header-cell field-input-type">{{ 'IMPLEMENTATION_ARTIFACT_PROPERTY_TYPE' | translate }}</span>
+                        <span class="cell header-cell field-input-value">{{ 'IMPLEMENTATION_ARTIFACT_PROPERTY_VALUE' | translate }}</span>
+                    </div>
+
+                    <div class="empty-msg data-row" *ngIf="!toscaArtifactTypeProperties.length">
+                        <div>{{ 'EMPTY_PARAM_TABLE_HEADER' | translate }}</div>
+                    </div>
+                    <property-param-row
+                        *ngFor="let property of toscaArtifactTypeProperties"
+                        class="data-row"
+                        [artifactProperty]="property"
+                        [isPropertyValueValid]="propertyValueValidation">
+                    </property-param-row>
+                </div>
+            </div>
         </div>
 
         <div class="separator-buttons">
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less
index 8bbed9d..955720c 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less
@@ -27,6 +27,22 @@
     padding-top: 12px;
     padding-bottom: 20px;
 
+    .group-with-border {
+        margin: 25px 0;
+        padding: 15px 0;
+        border-top: 1px solid @tlv_color_u;
+        border-bottom: 1px solid @tlv_color_u;
+        .content-row:not(:last-of-type) {
+            padding-bottom: 13px;
+        }
+    }
+
+    .occurrences-label {
+        font-family: @font-opensans-regular;
+        margin-bottom: 19px;
+        font-size: 14px;
+    }
+
     .i-sdc-form-label {
         font-size: 12px;
     }
@@ -175,7 +191,7 @@
         }
 
         /deep/ .cell {
-            &.field-input-name, &.field-input-value{
+            &.field-input-name, &.field-input-type, &.field-input-value{
                 flex: 1;
             }
 
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 1618af4..0b0efde 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts
@@ -19,7 +19,7 @@
 *  ============LICENSE_END=========================================================
 */
 
-import {Component} from '@angular/core';
+import {Component, EventEmitter, Output} from '@angular/core';
 import {UIInterfaceModel} from "../interface-operations.component";
 import {
     InputOperationParameter,
@@ -27,6 +27,12 @@
     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";
 
 @Component({
     selector: 'operation-handler',
@@ -36,20 +42,32 @@
 })
 
 export class InterfaceOperationHandlerComponent {
+    @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
 
     input: {
+        toscaArtifactTypes: Array<DropdownValue>;
         selectedInterface: UIInterfaceModel;
         selectedInterfaceOperation: InterfaceOperationModel;
         validityChangedCallback: Function;
     };
 
     interfaceType: string;
+    artifactVersion: string;
+    artifactName: string;
     interfaceOperationName: string;
     operationToUpdate: InterfaceOperationModel;
     inputs: Array<InputOperationParameter> = [];
+    properties: Array<PropertyParamRowComponent> = [];
     isLoading: boolean = false;
     readonly: boolean;
 
+    toscaArtifactTypeSelected: string;
+    toscaArtifactTypeProperties: Array<PropertyBEModel> = [];
+
+    toscaArtifactTypes: Array<DropdownValue> = [];
+
+    enableAddArtifactImplementation: boolean;
+
     ngOnInit() {
         this.interfaceType = this.input.selectedInterface.displayType();
         this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation);
@@ -60,9 +78,82 @@
                 listToscaDataDefinition: Array<InputOperationParameter> = [];
             }
         }
+
         this.inputs = this.operationToUpdate.inputs.listToscaDataDefinition;
         this.removeImplementationQuote();
         this.validityChanged();
+        this.loadInterfaceOperationImplementation();
+    }
+
+    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;
+        this.getArtifactTypesSelected();
+    }
+
+    onDescriptionChange= (value: any): void => {
+        this.operationToUpdate.description = value;
+    }
+
+    onImplementationNameChange(value: any) {
+        this.readonly = true
+        if (value) {
+            let artifact = new ArtifactModel();
+            artifact.artifactName = value;
+            this.operationToUpdate.implementation = artifact;
+            this.enableAddArtifactImplementation = false;
+            this.readonly = false;
+        }
+    }
+
+    onPropertyValueChange = (propertyValue) => {
+        this.emitter.emit(propertyValue);
+    }
+
+    onMarkToAddArtifactToImplementation(event: any) {
+        if (!event) {
+            this.toscaArtifactTypeSelected = undefined;
+            this.artifactVersion = undefined;
+            if (this.operationToUpdate.implementation.artifactType) {
+                this.artifactName = undefined;
+            }
+            this.toscaArtifactTypeProperties = undefined;
+        } else {
+            this.getArtifactTypesSelected();
+        }
+        this.enableAddArtifactImplementation = event;
+        this.validateRequiredField();
+    }
+
+    onSelectToscaArtifactType(type: IDropDownOption) {
+        if (type) {
+            let toscaArtifactType = type.value;
+            let artifact = new ArtifactModel();
+            this.artifactName = undefined;
+            this.artifactVersion = undefined;
+            artifact.artifactType = toscaArtifactType.type;
+            artifact.properties = toscaArtifactType.properties;
+            this.toscaArtifactTypeProperties = artifact.properties;
+            this.toscaArtifactTypeSelected = artifact.artifactType;
+            this.operationToUpdate.implementation = artifact;
+            this.getArtifactTypesSelected();
+        }
+        this.validateRequiredField();
+    }
+
+    onArtifactFileChange(value: any) {
+        if (value) {
+            this.operationToUpdate.implementation.artifactName = value;
+        }
+        this.validateRequiredField();
+    }
+
+    onArtifactVersionChange(value: any) {
+        if (value) {
+            this.operationToUpdate.implementation.artifactVersion = value;
+        }
     }
 
     onAddInput(inputOperationParameter?: InputOperationParameter): void {
@@ -73,12 +164,32 @@
         this.validityChanged();
     }
 
+    propertyValueValidation = (propertyValue): void => {
+        this.onPropertyValueChange(propertyValue);
+        this.readonly = !propertyValue.isValid;
+    }
+
     onRemoveInput = (inputParam: InputOperationParameter): void => {
         let index = this.inputs.indexOf(inputParam);
         this.inputs.splice(index, 1);
         this.validityChanged();
     }
 
+    private removeImplementationQuote(): void {
+        if (this.operationToUpdate.implementation) {
+            if (!this.operationToUpdate.implementation
+                || !this.operationToUpdate.implementation.artifactName) {
+                return;
+            }
+
+            let implementation = this.operationToUpdate.implementation.artifactName.trim();
+
+            if (implementation.startsWith("'") && implementation.endsWith("'")) {
+                this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1);
+            }
+        }
+    }
+
     private generateUniqueId = (): string => {
         let result = '';
         const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
@@ -97,8 +208,24 @@
         }
     }
 
-    onDescriptionChange= (value: any): void => {
-        this.operationToUpdate.description = value;
+    private getArtifactTypesSelected() {
+        if (this.operationToUpdate.implementation && this.operationToUpdate.implementation.artifactType) {
+            this.artifactName = this.operationToUpdate.implementation.artifactName;
+            this.toscaArtifactTypeSelected = this.operationToUpdate.implementation.artifactType;
+            this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
+            this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
+            this.enableAddArtifactImplementation = true;
+        }
+        this.validateRequiredField();
+    }
+
+    validateRequiredField = () => {
+        this.readonly = true;
+        let requiredFieldSelected = this.toscaArtifactTypeSelected && this.artifactName ? true : false;
+        this.input.validityChangedCallback(requiredFieldSelected);
+        if (requiredFieldSelected) {
+            this.readonly = false;
+        }
     }
 
     private checkFormValidForSubmit = (): boolean => {
@@ -114,17 +241,8 @@
         return isValid;
     }
 
-    private removeImplementationQuote(): void {
-        if (!this.operationToUpdate.implementation
-            || !this.operationToUpdate.implementation.artifactName) {
-            return;
-        }
-
-        let implementation = this.operationToUpdate.implementation.artifactName.trim();
-
-        if (implementation.startsWith("'") && implementation.endsWith("'")) {
-            this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1);
-        }
+    toDropDownOption(val: string) {
+        return { value : val, label: val };
     }
 
 }
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 deba50a..2595301 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
@@ -30,11 +30,14 @@
 import {UiElementsModule} from '../../../../components/ui/ui-elements.module';
 import {InputParamRowComponent} from './input-param-row/input-param-row.component';
 import {InterfaceOperationHandlerComponent} from "./interface-operation-handler.component";
+import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
+import {PropertyTableModule} from "../../../../components/logic/properties-table/property-table.module";
 
 @NgModule({
   declarations: [
     InterfaceOperationHandlerComponent,
-    InputParamRowComponent
+    InputParamRowComponent,
+    PropertyParamRowComponent
   ],
   imports: [
     CommonModule,
@@ -42,9 +45,12 @@
     FormsModule,
     FormElementsModule,
     TranslateModule,
-    UiElementsModule
+    UiElementsModule,
+    PropertyTableModule
   ],
-  exports: [],
+  exports: [
+    PropertyParamRowComponent
+  ],
   entryComponents: [
     InterfaceOperationHandlerComponent
   ],
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.html
new file mode 100644
index 0000000..ef7b94c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.html
@@ -0,0 +1,44 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2021 Nordix Foundation. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ -->
+
+<div class="cell field-input-name">
+    <sdc-input
+        [(value)]="artifactProperty.name"
+        [disabled]="true"
+        testId="interface-operation-input-name">
+    </sdc-input>
+</div>
+
+<div class="cell field-input-type">
+    <sdc-input
+        [(value)]="artifactProperty.type"
+        [disabled]="true"
+        testId="operation-implementation-property-type">
+    </sdc-input>
+</div>
+
+<div class="cell field-input-value">
+    <dynamic-element
+        [(value)]="artifactProperty.value"
+        data-tests-id="operation-implementation-property-value"
+        (elementChanged)="isPropertyValueValid($event)"
+        [type]="artifactProperty ? artifactProperty.type : 'string'">
+    </dynamic-element>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.less
new file mode 100644
index 0000000..12eacc6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.less
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2021 Nordix Foundation. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+@import '../../../../../../../assets/styles/variables.less';
+
+.remove {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    svg-icon {
+        position: relative;
+        right: -3px;
+
+        &:hover {
+            cursor: pointer;
+        }
+    }
+}
+
+.cell {
+    min-height: 50px;
+    padding: 10px;
+    display: flex;
+    align-items: center;
+
+    > * {
+        flex-basis: 100%;
+    }
+
+    /deep/ select {
+        height: 30px;
+    }
+
+    input {
+        height: 30px;
+        border: none;
+        padding-left: 10px;
+    }
+
+    select {
+        width: 100%;
+    }
+
+    &.field-property {
+        &:last-child {
+            flex: 1;
+        }
+
+        .no-properties-error {
+            color: @func_color_q;
+            font-style: italic;
+        }
+    }
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.ts
new file mode 100644
index 0000000..6ae75fa
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.ts
@@ -0,0 +1,35 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2021 Nordix Foundation. All rights reserved.
+*  ================================================================================
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at
+*
+*        http://www.apache.org/licenses/LICENSE-2.0
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*
+*  SPDX-License-Identifier: Apache-2.0
+*  ============LICENSE_END=========================================================
+*/
+
+import {Component, Input} from '@angular/core';
+import {PropertyOperationParameter} from "../../../../../../models/interfaceOperation";
+
+@Component({
+  selector: 'property-param-row',
+  templateUrl: './property-param-row.component.html',
+  styleUrls: ['./property-param-row.component.less']
+})
+
+export class PropertyParamRowComponent {
+  @Input() artifactProperty: PropertyOperationParameter;
+  @Input() isPropertyValueValid: Function;
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
index 1e217f1..16c3f33 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
@@ -211,8 +211,6 @@
         if (inputOperation) {
             this.onSelectInterface(new DropDownOption(this.operation.interfaceType));
 
-            this.operation.artifactFileName = this.operation.artifactFileName || this.operation.implementation.artifactName;
-
             if (this.enableWorkflowAssociation && inputOperation.workflowVersionId && this.isUsingExistingWF(inputOperation)) {
                 this.assignInputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
                 this.assignOutputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
diff --git a/catalog-ui/src/app/ng2/services/tosca-artifact.service.ts b/catalog-ui/src/app/ng2/services/tosca-artifact.service.ts
new file mode 100644
index 0000000..11a8cb9
--- /dev/null
+++ b/catalog-ui/src/app/ng2/services/tosca-artifact.service.ts
@@ -0,0 +1,42 @@
+/*
+* ============LICENSE_START=======================================================
+*  Copyright (C) 2021 Nordix Foundation. All rights reserved.
+*  ================================================================================
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at
+*
+*        http://www.apache.org/licenses/LICENSE-2.0
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*
+*  SPDX-License-Identifier: Apache-2.0
+*  ============LICENSE_END=========================================================
+*/
+import { HttpClient } from '@angular/common/http';
+import { Inject, Injectable } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { ISdcConfig, SdcConfigToken } from '../config/sdc-config.config';
+import {ToscaArtifactModel} from "../../models/toscaArtifact";
+
+@Injectable()
+export class ToscaArtifactService {
+
+  protected baseUrl;
+
+  constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) {
+    this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root;
+  }
+
+  getToscaArtifacts(modelName: string):Observable<ToscaArtifactModel[]> {
+    const url = this.baseUrl + "artifactTypes";
+    if (modelName) {
+      return this.http.get<ToscaArtifactModel[]>(url, {params: {model: modelName}});
+    }
+    return this.http.get<ToscaArtifactModel[]>(url);
+  }
+
+}
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json
index cf27783..1a79c0a 100644
--- a/catalog-ui/src/assets/languages/en_US.json
+++ b/catalog-ui/src/assets/languages/en_US.json
@@ -504,6 +504,18 @@
 
     "PARAM_NONE_OF_TYPE": "No available properties of this type.",
 
+    "=========== OPERATION UPDATE ===============": "",
+    "DEPLOYMENT_ARTIFACT_TYPE": "Deployment Artifact Type",
+    "TOSCA_ARTIFACT_TYPE": "Tosca Artifact Type",
+    "ARTIFACT_VERSION": "Artifact Version",
+    "IMPLEMENTATION_ARTIFACT_PROPERTY_NAME": "Name",
+    "IMPLEMENTATION_ARTIFACT_PROPERTY_TYPE": "Type",
+    "IMPLEMENTATION_ARTIFACT_PROPERTY_VALUE": "Value",
+    "INTERFACE_OPERATION_IMPLEMENTATION": "Implementation",
+    "INTERFACE_OPERATION_IMPLEMENTATION_NAME": "Name",
+    "INTERFACE_OPERATION_IMPLEMENTATION_FILE": "File",
+    "ADD_INTERFACE_OPERATION_IMPLEMENTATION_ARTIFACT": "Enable add Artifact To Implementation",
+
     "=========== PLUGIN NOT CONNECTED ===========": "",
     "PLUGIN_NOT_CONNECTED_ERROR_MAIN": "The \"{{pluginName}}\" plugin is currently unavailable.",
     "PLUGIN_NOT_CONNECTED_ERROR_SUB": "Please try again later.",