Allow multiple entry for map/list when tosca function is selected
[sdc.git] / catalog-ui / src / app / ng2 / pages / properties-assignment / properties-assignment.page.component.ts
index e4a8749..c828fab 100644 (file)
  */
 
 import * as _ from "lodash";
-import { Component, ViewChild, Inject, TemplateRef } from "@angular/core";
-import { PropertiesService } from "../../services/properties.service";
-import { PropertyFEModel, InstanceFePropertiesMap, InstanceBePropertiesMap, InstancePropertiesAPIMap, Component as ComponentData, FilterPropertiesAssignmentData, ModalModel, ButtonModel } from "app/models";
-import { ResourceType } from "app/utils";
-import { ComponentServiceNg2 } from "../../services/component-services/component.service";
-import { TopologyTemplateService } from "../../services/component-services/topology-template.service";
-import { ComponentInstanceServiceNg2 } from "../../services/component-instance-services/component-instance.service"
-import { InputBEModel, InputFEModel, ComponentInstance, GroupInstance, PolicyInstance, PropertyBEModel, DerivedFEProperty, SimpleFlatProperty } from "app/models";
-import { KeysPipe } from 'app/ng2/pipes/keys.pipe';
-import { WorkspaceMode, EVENTS, PROPERTY_TYPES } from "../../../utils/constants";
-import { EventListenerService } from "app/services/event-listener-service"
-import { HierarchyDisplayOptions } from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
-import { FilterPropertiesAssignmentComponent } from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
-import { PropertyRowSelectedEvent } from "../../components/logic/properties-table/properties-table.component";
-import { HierarchyNavService } from "./services/hierarchy-nav.service";
-import { PropertiesUtils } from "./services/properties.utils";
-import { ComponentModeService } from "../../services/component-services/component-mode.service";
-import { Tabs, Tab } from "../../components/ui/tabs/tabs.component";
-import { InputsUtils } from "./services/inputs.utils";
-import { InstanceFeDetails } from "../../../models/instance-fe-details";
-import { SdcUiServices, SdcUiCommon } from "onap-ui-angular";
-import { UnsavedChangesComponent } from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
+import {Component, Inject, ViewChild} from "@angular/core";
+import {PropertiesService} from "../../services/properties.service";
+import {
+    ButtonModel,
+    Component as ComponentData,
+    ComponentInstance,
+    DerivedFEProperty,
+    FilterPropertiesAssignmentData,
+    GroupInstance,
+    InputBEModel,
+    InputFEModel,
+    InstanceBePropertiesMap,
+    InstanceFePropertiesMap,
+    InstancePropertiesAPIMap,
+    ModalModel,
+    PolicyInstance,
+    PropertyBEModel,
+    PropertyFEModel,
+    Service,
+    SimpleFlatProperty,
+    PropertyDeclareAPIModel,
+    PropertiesGroup
+} from "app/models";
+import {ResourceType} from "app/utils";
+import {ComponentServiceNg2} from "../../services/component-services/component.service";
+import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
+import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
+import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
+import {EVENTS, PROPERTY_TYPES, WorkspaceMode, PROPERTY_DATA} from "../../../utils/constants";
+import {EventListenerService} from "app/services/event-listener-service"
+import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
+import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
+import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component";
+import {HierarchyNavService} from "./services/hierarchy-nav.service";
+import {PropertiesUtils} from "./services/properties.utils";
+import {ComponentModeService} from "../../services/component-services/component-mode.service";
+import {Tab, Tabs} from "../../components/ui/tabs/tabs.component";
+import {InputsUtils} from "./services/inputs.utils";
+import {InstanceFeDetails} from "../../../models/instance-fe-details";
+import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
+import {UnsavedChangesComponent} from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
 import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
 import {ModalService} from "../../services/modal.service";
-import { DeclareListComponent } from "./declare-list/declare-list.component";
-import { CapabilitiesGroup, Capability } from "../../../models/capability";
-import { ToscaPresentationData } from "../../../models/tosca-presentation";
-import { Observable } from "rxjs";
+import {DeclareListComponent} from "./declare-list/declare-list.component";
+import {ToscaFunctionComponent, ToscaFunctionValidationEvent} from "./tosca-function/tosca-function.component";
+import {CapabilitiesGroup, Capability} from "../../../models/capability";
+import {ToscaPresentationData} from "../../../models/tosca-presentation";
+import {Observable} from "rxjs";
+import {TranslateService} from "../../shared/translator/translate.service";
+import {ToscaFunction} from "../../../models/tosca-function";
+import {SubPropertyToscaFunction} from "../../../models/sub-property-tosca-function";
+import {DeclareInputComponent} from "./declare-input/declare-input.component";
+import {ElementService} from "../../services/element.service";
+import {CustomToscaFunction} from "../../../models/default-custom-functions";
+import {ToscaFunctionType} from "../../../models/tosca-function-type.enum";
 
 const SERVICE_SELF_TITLE = "SELF";
 @Component({
@@ -57,141 +84,190 @@ export class PropertiesAssignmentComponent {
     title = "Properties & Inputs";
 
     component: ComponentData;
-    componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
+    componentInstanceNamesMap: { [key: string]: InstanceFeDetails } = {}; //key is the instance uniqueId
+    componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); //key is the instance uniqueId
+    customToscaFunctions: Array<CustomToscaFunction> = [];
 
     propertiesNavigationData = [];
     instancesNavigationData = [];
 
-    instanceFePropertiesMap:InstanceFePropertiesMap;
+    instanceFePropertiesMap: InstanceFePropertiesMap;
     inputs: Array<InputFEModel> = [];
     policies: Array<PolicyInstance> = [];
-    instances: Array<ComponentInstance|GroupInstance|PolicyInstance> = [];
+    instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
     searchQuery: string;
     propertyStructureHeader: string;
 
     selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
-    selectedInstanceData: ComponentInstance|GroupInstance|PolicyInstance = null;
+    selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
     checkedPropertiesCount: number = 0;
     checkedChildPropertiesCount: number = 0;
+    enableToscaFunction: boolean = false;
+    checkedToscaCount: number = 0;
 
-    hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
-    hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
+    hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
+    hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
     displayClearSearch = false;
-    searchPropertyName:string;
-    currentMainTab:Tab;
-    isInputsTabSelected:boolean;
-    isPropertiesTabSelected:boolean;
-    isPoliciesTabSelected:boolean;
-    isReadonly:boolean;
-    resourceIsReadonly:boolean;
-    loadingInstances:boolean = false;
-    loadingInputs:boolean = false;
-    loadingPolicies:boolean = false;
-    loadingProperties:boolean = false;
-    changedData:Array<PropertyFEModel|InputFEModel>;
-    hasChangedData:boolean;
-    isValidChangedData:boolean;
-    savingChangedData:boolean;
-    stateChangeStartUnregister:Function;
+    searchPropertyName: string;
+    currentMainTab: Tab;
+    isInputsTabSelected: boolean;
+    isPropertiesTabSelected: boolean;
+    isPoliciesTabSelected: boolean;
+    isReadonly: boolean;
+    resourceIsReadonly: boolean;
+    loadingInstances: boolean = false;
+    loadingInputs: boolean = false;
+    loadingPolicies: boolean = false;
+    loadingProperties: boolean = false;
+    changedData: Array<PropertyFEModel | InputFEModel>;
+    hasChangedData: boolean;
+    isValidChangedData: boolean;
+    savingChangedData: boolean;
+    stateChangeStartUnregister: Function;
     serviceBePropertiesMap: InstanceBePropertiesMap;
     serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
     selectedInstance_FlattenCapabilitiesList: Capability[];
+    componentInstancePropertyMap : PropertiesGroup;
+    defaultInputName: string;
+    doNotExtendBaseType: boolean;
 
     @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
     @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
     @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
-   
+
     constructor(private propertiesService: PropertiesService,
                 private hierarchyNavService: HierarchyNavService,
-                private propertiesUtils:PropertiesUtils,
-                private inputsUtils:InputsUtils,
-                private componentServiceNg2:ComponentServiceNg2,
-                private componentInstanceServiceNg2:ComponentInstanceServiceNg2,
+                private propertiesUtils: PropertiesUtils,
+                private inputsUtils: InputsUtils,
+                private componentServiceNg2: ComponentServiceNg2,
+                private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
+                private propertyCreatorComponent: PropertyCreatorComponent,
                 @Inject("$stateParams") _stateParams,
-                @Inject("$scope") private $scope:ng.IScope,
-                @Inject("$state") private $state:ng.ui.IStateService,
-                @Inject("Notification") private Notification:any,
-                private componentModeService:ComponentModeService,
-                private EventListenerService:EventListenerService,
+                @Inject("$scope") private $scope: ng.IScope,
+                @Inject("$state") private $state: ng.ui.IStateService,
+                @Inject("Notification") private notification: any,
+                private componentModeService: ComponentModeService,
+                private eventListenerService: EventListenerService,
                 private ModalServiceSdcUI: SdcUiServices.ModalService,
-                private ModalService: ModalService,
-                private keysPipe:KeysPipe,
-                private topologyTemplateService: TopologyTemplateService) {
+                private modalService: ModalService,
+                private keysPipe: KeysPipe,
+                private topologyTemplateService: TopologyTemplateService,
+                private translateService: TranslateService,
+                private service: ElementService) {
 
         this.instanceFePropertiesMap = new InstanceFePropertiesMap();
         /* This is the way you can access the component data, please do not use any data except metadata, all other data should be received from the new api calls on the first time
         than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
         this.component = _stateParams.component;
-        this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
+        this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
         this.updateViewMode();
-
         this.changedData = [];
         this.updateHasChangedData();
         this.isValidChangedData = true;
     }
 
     ngOnInit() {
-        console.log("==>" + this.constructor.name + ": ngOnInit");
+        console.debug("==>" + this.constructor.name + ": ngOnInit");
         this.loadingInputs = true;
         this.loadingPolicies = true;
         this.loadingInstances = true;
         this.loadingProperties = true;
         this.topologyTemplateService
-            .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
-            .subscribe(response => {
-                _.forEach(response.inputs, (input: InputBEModel) => {
-                    const newInput: InputFEModel = new InputFEModel(input);
-                    this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
-                    this.inputs.push(newInput); //only push items that were declared via SDC
-                });
-                this.loadingInputs = false;
+        .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
+        .subscribe(response => {
+            _.forEach(response.inputs, (input: InputBEModel) => {
+                const newInput: InputFEModel = new InputFEModel(input);
+                this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
+                this.inputs.push(newInput); //only push items that were declared via SDC
+            });
+            this.componentInstancePropertyMap = response.componentInstancesProperties;
+            this.loadingInputs = false;
+
+        }, error => {
+        }); //ignore error
+
+        this.topologyTemplateService.getDefaultCustomFunction().toPromise().then((data) => {
+            for (let customFunction of data) {
+                this.customToscaFunctions.push(new CustomToscaFunction(customFunction));
+            }
+        });
 
-            }, error => {}); //ignore error
         this.componentServiceNg2
-            .getComponentResourcePropertiesData(this.component)
-            .subscribe(response => {
-                this.loadingPolicies = false;
-                this.instances = [];
-                this.instances.push(...response.componentInstances);
-                this.instances.push(...response.groupInstances);
-                this.instances.push(...response.policies);
-
-                _.forEach(response.policies, (policy: any) => {
-                    const newPolicy: InputFEModel = new InputFEModel(policy);
-                    this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
-                    this.policies.push(policy);
+        .getComponentResourcePropertiesData(this.component)
+        .subscribe(response => {
+            this.loadingPolicies = false;
+            this.instances = [];
+            this.instances.push(...response.componentInstances);
+            this.instances.push(...response.groupInstances);
+            this.instances.push(...response.policies);
+
+            if (response.componentInstances) {
+                response.componentInstances.forEach(instance => {
+                    this.componentInstanceMap.set(instance.uniqueId, <InstanceFeDetails>{
+                        name: instance.name,
+                        iconClass: instance.iconClass,
+                        originArchived: instance.originArchived
+                    });
                 });
+            }
 
-                // add the service self instance to the top of the list.
-                const serviceInstance = new ComponentInstance();
-                serviceInstance.name = SERVICE_SELF_TITLE;
-                serviceInstance.uniqueId = this.component.uniqueId;
-                this.instances.unshift(serviceInstance);
+            _.forEach(response.policies, (policy: any) => {
+                const newPolicy: InputFEModel = new InputFEModel(policy);
+                this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
+                this.policies.push(policy);
+            });
 
-                _.forEach(this.instances, (instance) => {
-                    this.instancesNavigationData.push(instance);
-                    this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{name: instance.name, iconClass:instance.iconClass, originArchived:instance.originArchived};
-                });
-                this.loadingInstances = false;
-                if (this.instancesNavigationData[0] == undefined) {
-                    this.loadingProperties = false;
-                }
-                this.selectFirstInstanceByDefault();
-            }, error => { this.loadingInstances = false; }); //ignore error
+            // add the service self instance to the top of the list.
+            const serviceInstance = new ComponentInstance();
+            serviceInstance.name = SERVICE_SELF_TITLE;
+            serviceInstance.uniqueId = this.component.uniqueId;
+            this.instances.unshift(serviceInstance);
+
+            _.forEach(this.instances, (instance) => {
+                this.instancesNavigationData.push(instance);
+                this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
+                    name: instance.name,
+                    iconClass: instance.iconClass,
+                    originArchived: instance.originArchived
+                };
+            });
+            this.loadingInstances = false;
+            if (this.instancesNavigationData[0] == undefined) {
+                this.loadingProperties = false;
+            }
+            this.selectFirstInstanceByDefault();
+        }, error => {
+            this.loadingInstances = false;
+        }); //ignore error
+        let modelName = this.component.model ? this.component.model : null;
+        const categoryName= this.component.categories[0].name;
+        if (this.component.categories[0].name != null && this.component.model != null) {
+            this.service.getCategoryBaseTypes(categoryName, modelName).subscribe((response: ListBaseTypesResponse) => {
+                this.doNotExtendBaseType = response.doNotExtendBaseType;
+                this.loadingProperties = false;
 
+            }, error => {
+                //ignore error
+            }, () => {
+                this.loadingProperties = false;
+            });
+        }
         this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
             // stop if has changed properties
             if (this.hasChangedData) {
                 event.preventDefault();
                 this.showUnsavedChangesAlert().then(() => {
                     this.$state.go(toState, toParams);
-                }, () => {});
+                }, () => {
+                });
             }
         });
-    };
 
-    ngOnDestroy() {
-        this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
+      this.loadDataTypesByComponentModel(this.component.model);
+    }
+
+    ngOnDestroy(){
+        this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
         this.stateChangeStartUnregister();
     }
 
@@ -205,33 +281,58 @@ export class PropertiesAssignmentComponent {
         this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
     }
 
-    onCheckout = (component:ComponentData) => {
+    onCheckout = (component: ComponentData) => {
         this.component = component;
         this.updateViewMode();
     }
 
-    isSelf = ():boolean => {
+    isSelf = (): boolean => {
         return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
     }
 
-    getServiceProperties(){
-        this.loadingProperties = false;
+    showAddProperties = (): boolean => {
+        if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
+            return false;
+        } else if (this.hideAddProperties()) {
+            return false;
+        }
+        return this.isSelf();
+
+    }
+
+    hideAddProperties = (): boolean => {
+        if (this.component.isService() && this.doNotExtendBaseType && this.isSelf) {
+            return true;
+        }
+            return false;
+
+    }
+
+    disablePropertyValue = () : boolean => {
+        if (this.component.isService() && this.doNotExtendBaseType && this.isSelf()){
+            return true;
+        }
+        return false;
+    }
+
+    getServiceProperties() {
+        this.loadingProperties = true;
         this.topologyTemplateService
-            .getServiceProperties(this.component.uniqueId)
-            .subscribe((response) => {
-                this.serviceBePropertiesMap = new InstanceBePropertiesMap();
-                this.serviceBePropertiesMap[this.component.uniqueId] = response;
-                this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
-                this.loadingProperties = false;
-            }, (error) => {
-                this.loadingProperties = false;
-            });
+        .getServiceProperties(this.component.uniqueId)
+        .subscribe((response) => {
+            this.serviceBePropertiesMap = new InstanceBePropertiesMap();
+            this.serviceBePropertiesMap[this.component.uniqueId] = response;
+            this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
+            this.loadingProperties = false;
+        }, (error) => {
+            this.loadingProperties = false;
+        });
     }
 
-    onInstanceSelectedUpdate = (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
+    onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
         // stop if has changed properties
         if (this.hasChangedData) {
-            this.showUnsavedChangesAlert().then((resolve)=> {
+            this.showUnsavedChangesAlert().then((resolve) => {
                 this.changeSelectedInstance(instance)
             }, (reject) => {
             });
@@ -240,52 +341,62 @@ export class PropertiesAssignmentComponent {
         this.changeSelectedInstance(instance);
     };
 
-    changeSelectedInstance =  (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
+    changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
         this.selectedInstanceData = instance;
         this.loadingProperties = true;
         if (instance instanceof ComponentInstance) {
             let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
             if (this.isInput(instance.originType)) {
                 this.componentInstanceServiceNg2
-                    .getComponentInstanceInputs(this.component, instance)
-                    .subscribe(response => {
-                        instanceBePropertiesMap[instance.uniqueId] = response;
-                        this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
-                        this.loadingProperties = false;
-                    }, error => {
-                    }); //ignore error
+                .getComponentInstanceInputs(this.component, instance)
+                .subscribe(response => {
+                    instanceBePropertiesMap[instance.uniqueId] = response;
+                    this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
+                }, () => {
+                    //ignore error
+                }, () => {
+                    this.loadingProperties = false;
+                });
             } else if (this.isSelf()) {
                 this.getServiceProperties();
             } else {
                 this.componentInstanceServiceNg2
-                    .getComponentInstanceProperties(this.component, instance.uniqueId)
-                    .subscribe(response => {
-                        instanceBePropertiesMap[instance.uniqueId] = response;
-                        this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
-                        this.loadingProperties = false;
-                    }, error => {
-                    }); //ignore error
+                .getComponentInstanceProperties(this.component, instance.uniqueId)
+                .subscribe(response => {
+                    instanceBePropertiesMap[instance.uniqueId] = response;
+                    this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+                }, () => {
+                    //ignore error
+                }, () => {
+                    this.loadingProperties = false;
+                });
             }
-
+            this.loadingProperties = false;
             this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
         } else if (instance instanceof GroupInstance) {
             let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
             this.componentInstanceServiceNg2
-                .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
-                .subscribe((response) => {
-                    instanceBePropertiesMap[instance.uniqueId] = response;
-                    this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
-                    this.loadingProperties = false;
-                });
+            .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
+            .subscribe((response) => {
+                instanceBePropertiesMap[instance.uniqueId] = response;
+                this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+            }, () => {
+                //ignore error
+            }, () => {
+                this.loadingProperties = false;
+            });
         } else if (instance instanceof PolicyInstance) {
             let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
             this.componentInstanceServiceNg2
-                .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
-                .subscribe((response) => {
-                    instanceBePropertiesMap[instance.uniqueId] = response;
-                    this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
-                    this.loadingProperties = false;
-                });
+            .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
+            .subscribe((response) => {
+                instanceBePropertiesMap[instance.uniqueId] = response;
+                this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+            }, () => {
+                //ignore error
+            }, () => {
+                this.loadingProperties = false;
+            });
         } else {
             this.loadingProperties = false;
         }
@@ -296,13 +407,15 @@ export class PropertiesAssignmentComponent {
         //clear selected property from the navigation
         this.selectedFlatProperty = new SimpleFlatProperty();
         this.propertiesNavigationData = [];
+        this.checkedToscaCount = 0;
+        this.enableToscaFunction = false;
     };
 
     /**
      * Entry point handling response from server
      */
     processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
-        this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
+        this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
         this.checkedPropertiesCount = 0;
         this.checkedChildPropertiesCount = 0;
     };
@@ -316,7 +429,7 @@ export class PropertiesAssignmentComponent {
             this.selectedInstance_FlattenCapabilitiesList,
             (result, cap: Capability) => {
                 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
-                    selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() && 
+                    selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
                     cap.ownerId === selectedComponentInstanceData.sourceModelUid;
                 if (cap.properties && isCapabilityOwnedByInstance) {
                     _.forEach(cap.properties, prop => {
@@ -344,7 +457,7 @@ export class PropertiesAssignmentComponent {
     };
 
     /*** VALUE CHANGE EVENTS ***/
-    dataChanged = (item:PropertyFEModel|InputFEModel) => {
+    dataChanged = (item: PropertyFEModel | InputFEModel) => {
         let itemHasChanged;
         if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
             itemHasChanged = item.hasValueObjChanged();
@@ -382,30 +495,30 @@ export class PropertiesAssignmentComponent {
      * Handle select node in navigation area, and select the row in table
      */
     onPropertySelectedUpdate = ($event) => {
-        console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
+        console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
         this.selectedFlatProperty = $event;
-        let parentProperty:PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
+        let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
         parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
     };
 
     /**
      * When user select row in table, this will prepare the hirarchy object for the tree.
      */
-    selectPropertyRow = (propertyRowSelectedEvent:PropertyRowSelectedEvent) => {
-        console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
+    selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
+        console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
         let property = propertyRowSelectedEvent.propertyModel;
         let instanceName = propertyRowSelectedEvent.instanceName;
         this.propertyStructureHeader = null;
 
         // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
         if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
-            let simpleFlatProperty:Array<SimpleFlatProperty>;
+            let simpleFlatProperty: Array<SimpleFlatProperty>;
             if (property instanceof PropertyFEModel) {
                 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
             } else if (property instanceof DerivedFEProperty) {
                 // Need to find parent PropertyFEModel
-                let parentPropertyFEModel:PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty):boolean => {
-                    return property.propertiesName.indexOf(tmpFeProperty.name)===0;
+                let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
+                    return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
                 });
                 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
             }
@@ -422,7 +535,7 @@ export class PropertiesAssignmentComponent {
 
 
     selectInstanceRow = ($event) => {//get instance name
-        this.selectedInstanceData =  _.find(this.instancesNavigationData, (instance:ComponentInstance) => {
+        this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
             return instance.name == $event;
         });
         this.hierarchyNavTabs.triggerTabChange('Composition');
@@ -434,12 +547,12 @@ export class PropertiesAssignmentComponent {
             this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
             this.showUnsavedChangesAlert().then((proceed) => {
                 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
-            }, ()=> {
+            }, () => {
             });
             return;
         }
 
-        console.log("==>" + this.constructor.name + ": tabChanged " + event);
+        console.debug("==>" + this.constructor.name + ": tabChanged " + event);
         this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
         this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
         this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
@@ -448,11 +561,238 @@ export class PropertiesAssignmentComponent {
         this.searchQuery = '';
     };
 
+    /**
+     * Select Tosca function value from defined values
+     */
+    selectToscaFunctionAndValues = (): void => {
+        const selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = this.getSelectedInstance();
+        if (!selectedInstanceData) {
+            return;
+        }
+        this.openToscaGetFunctionModal();
+    }
+
+    private getSelectedInstance(): ComponentInstance | GroupInstance | PolicyInstance {
+        const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+        const instanceId: string = instancesIds[0];
+        return <ComponentInstance | GroupInstance | PolicyInstance> this.instances.find(instance => 
+            instance.uniqueId == instanceId && (instance instanceof ComponentInstance || instance instanceof GroupInstance || instance instanceof PolicyInstance));
+    }
+
+    private buildCheckedInstanceProperty(): PropertyBEModel {
+        return this.buildCheckedInstanceProperties()[0];
+    }
+
+    private buildCheckedInstanceProperties(): PropertyBEModel[] {
+        const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+        const instanceId: string = instancesIds[0];
+        return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+    }
 
+    private openToscaGetFunctionModal() {
+        const modalTitle = this.translateService.translate('TOSCA_FUNCTION_MODAL_TITLE');
+        const modalButtons = [];
+        let disableSaveButtonFlag = true;
+        const modal = this.modalService.createCustomModal(new ModalModel(
+            'sm',
+            modalTitle,
+            null,
+            modalButtons,
+            null /* type */
+        ));
+        modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
+            () => {
+                const toscaGetFunction: ToscaFunction = modal.instance.dynamicContent.instance.toscaFunctionForm.value;
+                if (toscaGetFunction) {
+                    this.updateCheckedInstancePropertyFunctionValue(toscaGetFunction);
+                } else {
+                    this.clearCheckedInstancePropertyValue();
+                }
+                this.modalService.closeCurrentModal();
+            },
+            (): boolean => { return disableSaveButtonFlag }
+        ));
+        const checkedInstanceProperty = this.buildCheckedInstanceProperty();
+        modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
+            this.modalService.closeCurrentModal();
+        }));
+
+
+        this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
+            'property': checkedInstanceProperty,
+            'componentInstanceMap': this.componentInstanceMap,
+            'customToscaFunctions': this.customToscaFunctions
+        });
+        modal.instance.dynamicContent.instance.onValidityChange.subscribe((validationEvent: ToscaFunctionValidationEvent) => {
+            disableSaveButtonFlag = !validationEvent.isValid;
+        });
+        modal.instance.open();
+    }
+
+    private clearCheckedInstancePropertyValue() {
+        const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+        const currentValue : any = checkedInstanceProperty.value;
+        checkedInstanceProperty.getInputValues = null;
+        checkedInstanceProperty.value = null;
+        checkedInstanceProperty.toscaFunction = null;
+        if (checkedInstanceProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName){
+            const propertiesNameArray = (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName;
+            const parts = propertiesNameArray.split("#");
+            let currentKey = (<DerivedFEProperty>checkedInstanceProperty.input).toscaPath;
+            if (propertiesNameArray.length > 1){
+                const index = checkedInstanceProperty.subPropertyToscaFunctions.findIndex(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
+                checkedInstanceProperty.subPropertyToscaFunctions.splice(index, 1);
+            }
+            if (this.enableToscaFunction) {
+                this.processSubtoscaFunction(checkedInstanceProperty,null);
+                return;
+            }
+        }
+        if (this.selectedInstanceData instanceof ComponentInstance) {
+            var toRemove = this.changedData.filter(obj => {
+                return obj.name == checkedInstanceProperty.name && obj.type == checkedInstanceProperty.type && obj.value == null;
+            });
+            const index: number = this.changedData.indexOf(toRemove[0]);
+            if (index !== -1) {
+                this.changedData.splice(index, 1);
+            }
+            this.updateInstanceProperty(checkedInstanceProperty);
+        } else if (this.selectedInstanceData instanceof GroupInstance) {
+            this.updateGroupInstanceProperty(checkedInstanceProperty);
+        } else if (this.selectedInstanceData instanceof PolicyInstance) {
+            this.updatePolicyInstanceProperty(checkedInstanceProperty);
+        }
+    }
+
+    private processSubtoscaFunction(checkedProperty : PropertyDeclareAPIModel, toscaFunction: ToscaFunction) {
+        const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+        const instanceId: string = instancesIds[0];
+        this.instanceFePropertiesMap[instanceId].forEach(prop => {
+            if (prop.flattenedChildren) {
+                prop.flattenedChildren.forEach((child) => {
+                    if (child.isSelected && !child.isDeclared && !child.isDisabled) {
+                        prop.subPropertyToscaFunctions = checkedProperty.subPropertyToscaFunctions;
+                        if (toscaFunction) {
+                            child.value = toscaFunction.buildValueString();
+                            child.valueObj = toscaFunction.buildValueObject();
+                            child.toscaFunction = toscaFunction;
+                            this.hasChangedData = true;
+                            if (this.changedData.length == 0) {
+                                this.changedData.push(prop);
+                            }
+                        } else {
+                            child.valueObj = null;
+                            child.toscaFunction = null;
+                        }
+                        child.isSelected = false;
+                        this.togggleToscaBtn(false);                                
+                    }
+                });
+            }
+        });
+    }
+
+    private updateCheckedInstancePropertyFunctionValue(toscaFunction: ToscaFunction) {
+        const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+        if (checkedProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedProperty).propertiesName){
+            const propertiesName = (<PropertyDeclareAPIModel>checkedProperty).propertiesName;
+            const parts = propertiesName.split("#");
+            let currentKey = (<DerivedFEProperty>checkedProperty.input).toscaPath;
+            if (checkedProperty.subPropertyToscaFunctions == null){
+                checkedProperty.subPropertyToscaFunctions = [];
+            }
+            let subPropertyToscaFunction = checkedProperty.subPropertyToscaFunctions.find(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
+            if (!subPropertyToscaFunction){
+                 subPropertyToscaFunction = new SubPropertyToscaFunction();
+                 checkedProperty.subPropertyToscaFunctions.push(subPropertyToscaFunction);
+            }
+            subPropertyToscaFunction.toscaFunction = toscaFunction;
+            subPropertyToscaFunction.subPropertyPath = currentKey.length > 0 ? currentKey : parts.slice(1);
+            if (this.enableToscaFunction) {
+                this.processSubtoscaFunction(checkedProperty,toscaFunction);
+                return;
+            }
+        } else {
+            checkedProperty.subPropertyToscaFunctions = null;
+            checkedProperty.toscaFunction = toscaFunction;
+        }
+        if (this.selectedInstanceData instanceof ComponentInstance) {
+            this.updateInstanceProperty(checkedProperty);
+        } else if (this.selectedInstanceData instanceof GroupInstance) {
+            this.updateGroupInstanceProperty(checkedProperty);
+        } else if (this.selectedInstanceData instanceof PolicyInstance) {
+            this.updatePolicyInstanceProperty(checkedProperty);
+        }
+    }
+
+    private isComplexSchemaType(propertyType: string): boolean {
+        return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1;
+    }
+
+    private isListOrMap(propertyType: string): boolean {
+        return PROPERTY_TYPES.MAP === propertyType || PROPERTY_TYPES.LIST === propertyType;
+    }
+
+    private areEqual(array1: string[], array2: string[]): boolean {
+        return array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
+    }
+
+    updateInstanceProperty(instanceProperty: PropertyBEModel) {
+        this.loadingProperties = true;
+        this.enableToscaFunction = false;
+        this.checkedToscaCount = 0;
+
+        this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
+            this.selectedInstanceData.uniqueId, [instanceProperty])
+        .subscribe(() => {
+            this.changeSelectedInstance(this.getSelectedInstance());
+        }, (error) => {
+            this.loadingProperties = false;
+            console.error(error);
+        }, () => {
+            this.loadingProperties = false;
+        });
+    }
+
+    updateGroupInstanceProperty(instanceProperty: PropertyBEModel) {
+        this.loadingProperties = true;
+        this.componentInstanceServiceNg2.updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId,
+            this.selectedInstanceData.uniqueId, [instanceProperty])
+        .subscribe(() => {
+            this.changeSelectedInstance(this.getSelectedInstance());
+        }, (error) => {
+            this.loadingProperties = false;
+            console.error(error);
+        }, () => {
+            this.loadingProperties = false;
+        });
+    }
+
+    updatePolicyInstanceProperty(instanceProperty: PropertyBEModel) {
+        this.loadingProperties = true;
+        this.componentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId,
+            this.selectedInstanceData.uniqueId, [instanceProperty])
+        .subscribe(() => {
+            this.changeSelectedInstance(this.getSelectedInstance());
+        }, (error) => {
+            this.loadingProperties = false;
+            console.error(error);
+        }, () => {
+            this.loadingProperties = false;
+        });
+    }
+
+    declareInput = (): void => {
+        if (this.checkedPropertiesCount == 1) {
+            this.openAddInputNameAndDeclareInputModal();
+        } else if (this.checkedPropertiesCount > 1) {
+            this.declareInputFromProperties();
+        }
+    }
 
     /*** DECLARE PROPERTIES/INPUTS ***/
-    declareProperties = (): void => {
-        console.log("==>" + this.constructor.name + ": declareProperties");
+    declareInputFromProperties = (inputName?: string): void => {
+        console.debug("==>" + this.constructor.name + ": declareProperties");
 
         let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
         let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
@@ -466,6 +806,9 @@ export class PropertiesAssignmentComponent {
                 if (!this.isInput(selectedInstanceData.originType)) {
                     // convert Property FE model -> Property BE model, extract only checked
                     selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+                    if (inputName) {
+                        selectedComponentInstancesProperties[instanceId][0].inputName = inputName;
+                    }
                 } else {
                     selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
                 }
@@ -507,6 +850,8 @@ export class PropertiesAssignmentComponent {
         this.topologyTemplateService
             .createInput(this.component, inputsToCreate, this.isSelf())
             .subscribe((response) => {
+                this.selectInstanceRow(SERVICE_SELF_TITLE);
+                this.onInstanceSelectedUpdate(this.instances[0]);
                 this.setInputTabIndication(response.length);
                 this.checkedPropertiesCount = 0;
                 this.checkedChildPropertiesCount = 0;
@@ -522,9 +867,64 @@ export class PropertiesAssignmentComponent {
             }, error => {}); //ignore error
     };
 
-    declareListProperties = (): void => {
-        console.log('declareListProperties() - enter');
+    generateDefaultInputName = (): string => {
+        let defaultInputName: string;
+        let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+        angular.forEach(instancesIds, (instanceId: string) => {
+            let selectedProperty: PropertyBEModel = new PropertyBEModel(this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId])[0]);
+            let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
+            defaultInputName = this.generateInputName(selectedInstanceData.invariantName, selectedProperty.name);
+        });
+        return defaultInputName;
+    }
 
+    private generateInputName = (componentName: string, propertyName: string): string => {
+        let inputName: string;
+        if (propertyName) {
+            if (propertyName.includes("::")) {
+                propertyName = propertyName.replace(/::/g, "_");
+            }
+            if (componentName) {
+                inputName = componentName + "_" + propertyName;
+            } else {
+                inputName = propertyName;
+            }
+        }
+        return inputName;
+    }
+
+    private openAddInputNameAndDeclareInputModal = (): void => {
+        const modalTitle = this.translateService.translate('ADD_INPUT_NAME_TO_DECLARE');
+        const modalButtons = [];
+        const modal = this.modalService.createCustomModal(new ModalModel(
+            'sm',
+            modalTitle,
+            null,
+            modalButtons,
+            null /* type */
+        ));
+        modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
+            () => {
+                const inputName: string = modal.instance.dynamicContent.instance.inputNameForm.value;
+                if (inputName) {
+                    this.declareInputFromProperties(inputName);
+                } else {
+                    this.notification.warning({
+                        message: 'Failed to set input name',
+                        title: 'Warning'
+                    });
+                }
+                this.modalService.closeCurrentModal();
+            }
+        ));
+        modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
+            this.modalService.closeCurrentModal();
+        }));
+        this.modalService.addDynamicContentToModal(modal, DeclareInputComponent, {defaultInputName: this.generateDefaultInputName()});
+        modal.instance.open();
+    }
+
+    declareListProperties = (): void => {
         // get selected properties
         let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
         let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
@@ -535,7 +935,6 @@ export class PropertiesAssignmentComponent {
         let insId :string;
 
         angular.forEach(instancesIds, (instanceId: string): void => {
-            console.log("instanceId="+instanceId);
             insId = instanceId;
             let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
             let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
@@ -561,7 +960,7 @@ export class PropertiesAssignmentComponent {
         let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
 
         let modalTitle = 'Declare Properties as List Input';
-        const modal = this.ModalService.createCustomModal(new ModalModel(
+        const modal = this.modalService.createCustomModal(new ModalModel(
             'sm', /* size */
             modalTitle, /* title */
             null, /* content */
@@ -604,7 +1003,6 @@ export class PropertiesAssignmentComponent {
                             componentInstInputsMap: content.inputsToCreate,
                             listInput: reglistInput
                         };
-                        console.log("save button clicked. input=", input);
 
                         this.topologyTemplateService
                         .createListInput(this.component, input, this.isSelf())
@@ -635,9 +1033,8 @@ export class PropertiesAssignmentComponent {
             null /* type */
         ));
         // 3rd arg is passed to DeclareListComponent instance
-        this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
+        this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
         modal.instance.open();
-        console.log('declareListProperties() - leave');
     };
 
      /*** DECLARE PROPERTIES/POLICIES ***/
@@ -731,7 +1128,6 @@ export class PropertiesAssignmentComponent {
                                 const changedProp = <PropertyFEModel>this.changedData.shift();
                                 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
                             });
-                            console.log('updated instance inputs:', response);
                         };
                     } else {
                         if (this.isSelf()) {
@@ -750,7 +1146,6 @@ export class PropertiesAssignmentComponent {
                                 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
                             });
                             resolve(response);
-                            console.log("updated instance properties: ", response);
                         };
                     }
                 } else if (this.selectedInstanceData instanceof GroupInstance) {
@@ -763,7 +1158,6 @@ export class PropertiesAssignmentComponent {
                             this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
                         });
                         resolve(response);
-                        console.log("updated group instance properties: ", response);
                     };
                 } else if (this.selectedInstanceData instanceof PolicyInstance) {
                     request = this.componentInstanceServiceNg2
@@ -775,7 +1169,6 @@ export class PropertiesAssignmentComponent {
                             this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
                         });
                         resolve(response);
-                        console.log("updated policy instance properties: ", response);
                     };
                 }
             } else if (this.isInputsTabSelected) {
@@ -796,7 +1189,6 @@ export class PropertiesAssignmentComponent {
                         changedInput.required = resInput.required;
                         changedInput.requiredOrig = resInput.required;
                     });
-                    console.log("updated the component inputs and got this response: ", response);
                 }
             }
 
@@ -841,8 +1233,6 @@ export class PropertiesAssignmentComponent {
             handleReverseItem = (changedItem) => {
                 changedItem = <PropertyFEModel>changedItem;
                 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
-                this.checkedPropertiesCount = 0;
-                this.checkedChildPropertiesCount = 0;
             };
         } else if (this.isInputsTabSelected) {
             handleReverseItem = (changedItem) => {
@@ -863,9 +1253,9 @@ export class PropertiesAssignmentComponent {
         if (curHasChangedData !== this.hasChangedData) {
             this.hasChangedData = curHasChangedData;
             if(this.hasChangedData) {
-                this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
+                this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
             } else {
-                this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
+                this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
             }
         } 
         return this.hasChangedData;
@@ -874,18 +1264,14 @@ export class PropertiesAssignmentComponent {
     doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
         this.saveChangedData().then(
             () => {
-                this.Notification.success({
+                this.notification.success({
                     message: 'Successfully saved changes',
                     title: 'Saved'
                 });
                 if(onSuccessFunction) onSuccessFunction();
-                if(this.isPropertiesTabSelected){
-                    this.checkedPropertiesCount = 0;
-                    this.checkedChildPropertiesCount = 0;
-                }
             },
             () => {
-                this.Notification.error({
+                this.notification.error({
                     message: 'Failed to save changes!',
                     title: 'Failure'
                 });
@@ -937,13 +1323,24 @@ export class PropertiesAssignmentComponent {
     //used for declare button, to keep count of newly checked properties (and ignore declared properties)
     updateCheckedPropertyCount = (increment: boolean): void => {
         this.checkedPropertiesCount += (increment) ? 1 : -1;
-        console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
+        this.checkedToscaCount = 0;
+        this.enableToscaFunction = false;
+        console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
     };
 
     updateCheckedChildPropertyCount = (increment: boolean): void => {
         this.checkedChildPropertiesCount += (increment) ? 1 : -1;
     };
 
+    togggleToscaBtn = (toscaFlag: boolean) : void => {
+        this.checkedToscaCount += toscaFlag ? 1 : -1;
+        if(this.checkedToscaCount == 1){
+            this.enableToscaFunction = true;
+        }else{
+            this.enableToscaFunction = false;
+        }
+    };
+
     setInputTabIndication = (numInputs: number): void => {
         this.propertyInputTabs.setTabIndication('Inputs', numInputs);
     };
@@ -962,7 +1359,7 @@ export class PropertiesAssignmentComponent {
         //reset any unsaved changes to the input before deleting it
         this.resetUnsavedChangesForInput(input);
 
-        console.log("==>" + this.constructor.name + ": deleteInput");
+        console.debug("==>" + this.constructor.name + ": deleteInput");
         let inputToDelete = new InputBEModel(input);
 
         this.componentServiceNg2
@@ -995,7 +1392,6 @@ export class PropertiesAssignmentComponent {
             .deletePolicy(this.component, policy)
             .subscribe((response) => {
                 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
-                //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
                 this.changeSelectedInstance(this.selectedInstanceData);
                 this.loadingPolicies = false;
             });
@@ -1018,9 +1414,10 @@ export class PropertiesAssignmentComponent {
     }
 
     /*** addProperty ***/
-    addProperty = () => {
+    addProperty = (model: string) => {
+        this.loadDataTypesByComponentModel(model)
         let modalTitle = 'Add Property';
-        let modal = this.ModalService.createCustomModal(new ModalModel(
+        let modal = this.modalService.createCustomModal(new ModalModel(
             'sm',
             modalTitle,
             null,
@@ -1036,7 +1433,7 @@ export class PropertiesAssignmentComponent {
                             modal.instance.close();
                         }, (error) => {
                             modal.instance.dynamicContent.instance.isLoading = false;
-                            this.Notification.error({
+                            this.notification.error({
                                 message: 'Failed to add property:' + error,
                                 title: 'Failure'
                             });
@@ -1048,7 +1445,42 @@ export class PropertiesAssignmentComponent {
             ],
             null
         ));
-        this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
+        modal.instance.open();
+        this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
+    }
+
+    /*** addInput ***/
+    addInput = () => {
+        let modalTitle = 'Add Input';
+        let modal = this.modalService.createCustomModal(new ModalModel(
+            'sm',
+            modalTitle,
+            null,
+            [
+                new ButtonModel('Save', 'blue', () => {
+                    modal.instance.dynamicContent.instance.isLoading = true;
+                    const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
+                    this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
+                        .subscribe((response) => {
+                            modal.instance.dynamicContent.instance.isLoading = false;
+                            const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
+                            this.inputs.push(newInputProp);
+                            modal.instance.close();
+                        }, (error) => {
+                            modal.instance.dynamicContent.instance.isLoading = false;
+                            this.notification.error({
+                                message: 'Failed to add input:' + error,
+                                title: 'Failure'
+                            });
+                        });
+                }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
+                new ButtonModel('Cancel', 'outline grey', () => {
+                    modal.instance.close();
+                }),
+            ],
+            null
+        ));
+        this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
         modal.instance.open();
     }
 
@@ -1086,6 +1518,9 @@ export class PropertiesAssignmentComponent {
     private isInput = (instanceType:string):boolean =>{
         return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
     }
-    
+
+    loadDataTypesByComponentModel(model:string) {
+        this.propertyCreatorComponent.filterDataTypesByModel(model);
+    }
 
 }