Sync Integ to Master
[sdc.git] / catalog-ui / src / app / ng2 / pages / properties-assignment / properties-assignment.page.component.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 import * as _ from "lodash";
22 import {Component, ViewChild, Inject, TemplateRef} from "@angular/core";
23 import { PropertiesService } from "../../services/properties.service";
24 import { PropertyFEModel, InstanceFePropertiesMap, InstanceBePropertiesMap, InstancePropertiesAPIMap, Component as ComponentData, FilterPropertiesAssignmentData, ModalModel, ButtonModel } from "app/models";
25 import { ResourceType } from "app/utils";
26 import {ComponentServiceNg2} from "../../services/component-services/component.service";
27 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
28 import { InputBEModel, InputFEModel, ComponentInstance, PropertyBEModel, DerivedFEProperty, ResourceInstance, SimpleFlatProperty } from "app/models";
29 import { KeysPipe } from 'app/ng2/pipes/keys.pipe';
30 import {WorkspaceMode, EVENTS} from "../../../utils/constants";
31 import {EventListenerService} from "app/services/event-listener-service"
32 import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
33 import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
34 import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component";
35 import {HierarchyNavService} from "./services/hierarchy-nav.service";
36 import {PropertiesUtils} from "./services/properties.utils";
37 import {ComponentModeService} from "../../services/component-services/component-mode.service";
38 import {ModalService} from "../../services/modal.service";
39 import {Tabs, Tab} from "../../components/ui/tabs/tabs.component";
40 import {InputsUtils} from "./services/inputs.utils";
41
42 @Component({
43     templateUrl: './properties-assignment.page.component.html',
44     styleUrls: ['./properties-assignment.page.component.less']
45 })
46 export class PropertiesAssignmentComponent {
47     title = "Properties & Inputs";
48
49     component: ComponentData;
50     componentInstanceNamesMap: Map<string, string> = new Map<string, string>();//instanceUniqueId, name
51
52     propertiesNavigationData = [];
53     instancesNavigationData = [];
54
55     instanceFePropertiesMap:InstanceFePropertiesMap;
56     inputs: Array<InputFEModel> = [];
57     instances: Array<ComponentInstance> = [];
58     searchQuery: string;
59     propertyStructureHeader: string;
60
61     selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
62     selectedInstanceType: string;
63     selectedInstanceData: ComponentInstance = new ComponentInstance();
64     checkedPropertiesCount: number = 0;
65
66     hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
67     hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name');
68     displayClearSearch = false;
69     searchPropertyName:string;
70     currentMainTab:Tab;
71     isInputsTabSelected:boolean;
72     isPropertiesTabSelected:boolean;
73     isReadonly:boolean;
74     loadingInstances:boolean = false;
75     loadingInputs:boolean = false;
76     loadingProperties:boolean = false;
77     changedData:Array<PropertyFEModel|InputFEModel>;
78     hasChangedData:boolean;
79     isValidChangedData:boolean;
80     savingChangedData:boolean;
81     stateChangeStartUnregister:Function;
82
83     @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
84     @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
85     @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
86     @ViewChild('saveChangedDataModalContentTemplate') saveChangedDataModalContentTemplateRef: TemplateRef<void>;
87
88     constructor(private propertiesService: PropertiesService,
89                 private hierarchyNavService: HierarchyNavService,
90                 private propertiesUtils:PropertiesUtils,
91                 private inputsUtils:InputsUtils,
92                 private componentServiceNg2:ComponentServiceNg2,
93                 private componentInstanceServiceNg2:ComponentInstanceServiceNg2,
94                 @Inject("$stateParams") _stateParams,
95                 @Inject("$scope") private $scope:ng.IScope,
96                 @Inject("$state") private $state:ng.ui.IStateService,
97                 @Inject("Notification") private Notification:any,
98                 private componentModeService:ComponentModeService,
99                 private ModalService:ModalService,
100                 private EventListenerService:EventListenerService) {
101
102         this.instanceFePropertiesMap = new InstanceFePropertiesMap();
103
104         /* 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
105         than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
106         this.component = _stateParams.component;
107         this.EventListenerService.registerObserverCallback(EVENTS.ON_CHECKOUT, this.onCheckout);
108         this.updateViewMode();
109
110         this.changedData = [];
111         this.updateHasChangedData();
112         this.isValidChangedData = true;
113     }
114
115     ngOnInit() {
116         console.log("==>" + this.constructor.name + ": ngOnInit");
117         this.loadingInputs = true;
118         this.loadingInstances = true;
119         this.loadingProperties = true;
120         this.componentServiceNg2
121             .getComponentInputs(this.component)
122             .subscribe(response => {
123                 _.forEach(response.inputs, (input: InputBEModel) => {
124                     const newInput: InputFEModel = new InputFEModel(input);
125                     this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
126                     this.inputs.push(newInput); //only push items that were declared via SDC
127                 });
128                 this.loadingInputs = false;
129
130             }, error => {}); //ignore error
131         this.componentServiceNg2
132             .getComponentResourceInstances(this.component)
133             .subscribe(response => {
134                 this.instances = response.componentInstances;
135
136                 _.forEach(this.instances, (instance) => {
137                     this.instancesNavigationData.push(instance);
138                     this.componentInstanceNamesMap[instance.uniqueId] = instance.name;
139                 });
140                 this.loadingInstances = false;
141                 if (this.instancesNavigationData[0] == undefined) {
142                     this.loadingProperties = false;
143                 }
144                 this.selectFirstInstanceByDefault();
145             }, error => {}); //ignore error
146
147         this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
148             // stop if has changed properties
149             if (this.hasChangedData) {
150                 event.preventDefault();
151                 this.openChangedDataModal().then((proceed) => {
152                     if (proceed) {
153                         this.$state.go(toState, toParams);
154                     }
155                 });
156             }
157         });
158     };
159
160     ngOnDestroy() {
161         this.EventListenerService.unRegisterObserver(EVENTS.ON_CHECKOUT);
162         this.stateChangeStartUnregister();
163     }
164
165     selectFirstInstanceByDefault = () => {
166         if (this.instancesNavigationData[0] !== undefined) {
167             this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
168         }
169     };
170
171     updateViewMode = () => {
172         this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
173     }
174
175     onCheckout = (component:ComponentData) => {
176         this.component = component;
177         this.updateViewMode();
178     }
179
180
181     onInstanceSelectedUpdate = (resourceInstance: ResourceInstance) => {
182         console.log("==>" + this.constructor.name + ": onInstanceSelectedUpdate");
183
184         // stop if has changed properties
185         if (this.hasChangedData) {
186             this.openChangedDataModal().then((proceed) => {
187                 if (proceed) {
188                     this.onInstanceSelectedUpdate(resourceInstance);
189                 }
190             });
191             return;
192         }
193
194         let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
195         this.selectedInstanceData = resourceInstance;
196         this.selectedInstanceType = resourceInstance.originType;
197
198         this.loadingProperties = true;
199         if (this.isInput(resourceInstance.originType)) {
200             this.componentInstanceServiceNg2
201                 .getComponentInstanceInputs(this.component, resourceInstance)
202                 .subscribe(response => {
203                     instanceBePropertiesMap[resourceInstance.uniqueId] = response;
204                     this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
205                     this.loadingProperties = false;
206
207                 }, error => {
208                 }); //ignore error
209         } else {
210             this.componentInstanceServiceNg2
211                 .getComponentInstanceProperties(this.component, resourceInstance.uniqueId)
212                 .subscribe(response => {
213                     instanceBePropertiesMap[resourceInstance.uniqueId] = response;
214                     this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
215                     this.loadingProperties = false;
216                 }, error => {
217                 }); //ignore error
218         }
219
220         if (resourceInstance.componentName === "vnfConfiguration") {
221             this.isReadonly = true;
222         }
223
224         if (this.searchPropertyName) {
225             this.clearSearch();
226         }
227         //clear selected property from the navigation
228         this.selectedFlatProperty = new SimpleFlatProperty();
229         this.propertiesNavigationData = [];
230     };
231
232     /**
233      * Entry point handling response from server
234      */
235     processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
236         this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
237         this.checkedPropertiesCount = 0;
238     };
239
240
241     /*** VALUE CHANGE EVENTS ***/
242     dataChanged = (item:PropertyFEModel|InputFEModel) => {
243         let itemHasChanged;
244         if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
245             itemHasChanged = item.hasValueObjChanged();
246         } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
247             itemHasChanged = item.hasDefaultValueChanged();
248         }
249
250         const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
251         if (itemHasChanged) {
252             if (dataChangedIdx === -1) {
253                 this.changedData.push(item);
254             }
255         } else {
256             if (dataChangedIdx !== -1) {
257                 this.changedData.splice(dataChangedIdx, 1);
258             }
259         }
260
261         if (this.isPropertiesTabSelected) {
262             this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
263         } else if (this.isInputsTabSelected) {
264             this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
265         }
266         this.updateHasChangedData();
267     };
268
269
270     /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
271
272     /**
273      * Handle select node in navigation area, and select the row in table
274      */
275     onPropertySelectedUpdate = ($event) => {
276         console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
277         this.selectedFlatProperty = $event;
278         let parentProperty:PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
279         parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
280     };
281
282     /**
283      * When user select row in table, this will prepare the hirarchy object for the tree.
284      */
285     selectPropertyRow = (propertyRowSelectedEvent:PropertyRowSelectedEvent) => {
286         console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
287         let property = propertyRowSelectedEvent.propertyModel;
288         let instanceName = propertyRowSelectedEvent.instanceName;
289         this.propertyStructureHeader = null;
290
291         // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
292         if(this.selectedInstanceData.originType !== ResourceType.VF) {
293             let simpleFlatProperty:Array<SimpleFlatProperty>;
294             if (property instanceof PropertyFEModel) {
295                 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
296             } else if (property instanceof DerivedFEProperty) {
297                 // Need to find parent PropertyFEModel
298                 let parentPropertyFEModel:PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty):boolean => {
299                     return property.propertiesName.indexOf(tmpFeProperty.name)===0;
300                 });
301                 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
302             }
303             this.propertiesNavigationData = simpleFlatProperty;
304         }
305
306         // Update the header in the navigation tree with property name.
307         this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
308
309         // Set selected property in table
310         this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
311         this.hierarchyNavTabs.triggerTabChange('Property Structure');
312     };
313
314
315     selectInstanceRow = ($event) => {//get instance name
316         this.selectedInstanceData =  _.find(this.instancesNavigationData, (instance:ComponentInstance) => {
317             return instance.name == $event;
318         });
319         this.hierarchyNavTabs.triggerTabChange('Composition');
320     };
321
322     tabChanged = (event) => {
323         // stop if has changed properties
324         if (this.hasChangedData) {
325             this.openChangedDataModal().then((proceed) => {
326                 if (proceed) {
327                     this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
328                 }
329             });
330
331             // return to show the current tab
332             this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
333             return;
334         }
335
336         console.log("==>" + this.constructor.name + ": tabChanged " + event);
337         this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
338         this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
339         this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
340         this.propertyStructureHeader = null;
341         this.searchQuery = '';
342     };
343
344
345
346     /*** DECLARE PROPERTIES/INPUTS ***/
347     declareProperties = (): void => {
348         console.log("==>" + this.constructor.name + ": declareProperties");
349
350         let selectedProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
351         let selectedInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
352         let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
353
354         angular.forEach(instancesIds, (instanceId: string): void => {
355             let selectedInstanceData: ResourceInstance = this.instances.find(instance => instance.uniqueId == instanceId);
356             let originType: string = (selectedInstanceData) ? selectedInstanceData.originType : this.selectedInstanceType;
357             if (!this.isInput(originType)) {
358                 selectedProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
359             } else {
360                 selectedInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
361             }
362         });
363
364         let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedInputs, selectedProperties);
365
366         this.componentServiceNg2
367             .createInput(this.component, inputsToCreate)
368             .subscribe(response => {
369                 this.setInputTabIndication(response.length);
370                 this.checkedPropertiesCount = 0;
371                 _.forEach(response, (input: InputBEModel) => {
372                     let newInput: InputFEModel = new InputFEModel(input);
373                     this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
374                     this.inputs.push(newInput);
375                     this.updatePropertyValueAfterDeclare(newInput);
376                 });
377             }, error => {}); //ignore error
378     };
379
380     saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
381         return new Promise((resolve, reject) => {
382             if (!this.isValidChangedData) {
383                 reject('Changed data is invalid - cannot save!');
384                 return;
385             }
386             if (!this.changedData.length) {
387                 resolve([]);
388                 return;
389             }
390
391             // make request and its handlers
392             let request;
393             let handleSuccess, handleError;
394             if (this.isPropertiesTabSelected) {
395                 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
396                     changedProp = <PropertyFEModel>changedProp;
397                     const propBE = new PropertyBEModel(changedProp);
398                     propBE.value = changedProp.getJSONValue();
399                     return propBE;
400                 });
401
402                 if (this.isInput(this.selectedInstanceData.originType)) {
403                     request = this.componentInstanceServiceNg2
404                         .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedProperties);
405                     handleSuccess = (response) => {
406                         // reset each changed property with new value and remove it from changed properties list
407                         response.forEach((resInput) => {
408                             const changedProp = <PropertyFEModel>this.changedData.shift();
409                             this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
410                         });
411                         console.log('updated instance inputs:', response);
412                     };
413                 } else {
414                     request = this.componentInstanceServiceNg2
415                         .updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties)
416                     handleSuccess = (response) => {
417                         // reset each changed property with new value and remove it from changed properties list
418                         response.forEach((resProp) => {
419                             const changedProp = <PropertyFEModel>this.changedData.shift();
420                             this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
421                         });
422                         resolve(response);
423                         console.log("updated instance properties: ", response);
424                     };
425                 }
426             } else if (this.isInputsTabSelected) {
427                 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
428                     changedInput = <InputFEModel>changedInput;
429                     const inputBE = new InputBEModel(changedInput);
430                     inputBE.defaultValue = changedInput.getJSONDefaultValue();
431                     return inputBE;
432                 });
433                 request = this.componentServiceNg2
434                     .updateComponentInputs(this.component, changedInputs);
435                 handleSuccess = (response) => {
436                     // reset each changed property with new value and remove it from changed properties list
437                     response.forEach((resInput) => {
438                         const changedInput = <InputFEModel>this.changedData.shift();
439                         this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
440                     });
441                     console.log("updated the component inputs and got this response: ", response);
442                 }
443             }
444
445             this.savingChangedData = true;
446             request.subscribe(
447                 (response) => {
448                     this.savingChangedData = false;
449                     handleSuccess && handleSuccess(response);
450                     this.updateHasChangedData();
451                     resolve(response);
452                 },
453                 (error) => {
454                     this.savingChangedData = false;
455                     handleError && handleError(error);
456                     this.updateHasChangedData();
457                     reject(error);
458                 }
459             );
460         });
461     };
462
463     reverseChangedData = ():void => {
464         // make reverse item handler
465         let handleReverseItem;
466         if (this.isPropertiesTabSelected) {
467             handleReverseItem = (changedItem) => {
468                 changedItem = <PropertyFEModel>changedItem;
469                 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
470             };
471         } else if (this.isInputsTabSelected) {
472             handleReverseItem = (changedItem) => {
473                 changedItem = <InputFEModel>changedItem;
474                 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
475             };
476         }
477
478         this.changedData.forEach(handleReverseItem);
479         this.changedData = [];
480         this.updateHasChangedData();
481     };
482
483     updateHasChangedData = ():boolean => {
484         const curHasChangedData:boolean = (this.changedData.length > 0);
485         if (curHasChangedData !== this.hasChangedData) {
486             this.hasChangedData = curHasChangedData;
487             this.$scope.$emit('setWorkspaceTopBarActive', !this.hasChangedData);
488         }
489         return this.hasChangedData;
490     };
491
492     doSaveChangedData = ():void => {
493         this.saveChangedData().then(
494             () => {
495                 this.Notification.success({
496                     message: 'Successfully saved changes',
497                     title: 'Saved'
498                 });
499             },
500             () => {
501                 this.Notification.error({
502                     message: 'Failed to save changes!',
503                     title: 'Failure'
504                 });
505             }
506         );
507     };
508
509     openChangedDataModal = ():Promise<boolean> => {
510         let modalTitle;
511         if (this.isPropertiesTabSelected) {
512             modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
513         } else if (this.isInputsTabSelected) {
514             modalTitle = `Unsaved inputs for ${this.component.name}`;
515         }
516
517         return new Promise<boolean>((resolve) => {
518             const modal = this.ModalService.createCustomModal(new ModalModel(
519                 'sm',
520                 modalTitle,
521                 null,
522                 [
523                     new ButtonModel('Cancel', 'outline grey', () => {
524                         modal.instance.close();
525                         resolve(false);
526                     }),
527                     new ButtonModel('Discard', 'outline blue', () => {
528                         this.reverseChangedData();
529                         modal.instance.close();
530                         resolve(true);
531                     }),
532                     new ButtonModel('Save', 'blue', () => {
533                         this.saveChangedData().then(() => {
534                             modal.instance.close();
535                             resolve(true);
536                         }, () => {
537                             modal.instance.close();
538                             resolve(false);
539                         });
540                     }, () => !this.isValidChangedData)
541                 ]
542             ));
543             this.ModalService.addDynamicTemplateToModal(modal, this.saveChangedDataModalContentTemplateRef);
544             modal.instance.open();
545         });
546     };
547
548     updatePropertyValueAfterDeclare = (input: InputFEModel) => {
549         if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
550             let propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
551                 return feProperty.name == input.relatedPropertyName;
552             });
553             let inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
554             propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
555             this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
556             this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
557         }
558     }
559
560     //used for declare button, to keep count of newly checked properties (and ignore declared properties)
561     updateCheckedPropertyCount = (increment: boolean): void => {
562         this.checkedPropertiesCount += (increment) ? 1 : -1;
563         console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
564     };
565
566     setInputTabIndication = (numInputs: number): void => {
567         this.propertyInputTabs.setTabIndication('Inputs', numInputs);
568     };
569
570     deleteInput = (input: InputFEModel) => {
571         console.log("==>" + this.constructor.name + ": deleteInput");
572         let inputToDelete = new InputBEModel(input);
573
574         this.componentServiceNg2
575             .deleteInput(this.component, inputToDelete)
576             .subscribe(response => {
577                 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
578
579                 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
580                 this.onInstanceSelectedUpdate(this.selectedInstanceData);
581                 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
582
583                 // if (instanceFeProperties) {
584                 //     let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
585                 //         return prop.name == input.propertyName;
586                 //     });
587
588                 //     if (propToEnable) {
589                 //         if (propToEnable.name == response.inputPath) response.inputPath = null;
590                 //         propToEnable.setNonDeclared(response.inputPath);
591                 //         //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
592                 //         this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
593                 //     }
594                 // }
595             }, error => {}); //ignore error
596     };
597
598
599
600     /*** SEARCH RELATED FUNCTIONS ***/
601     searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
602         let instanceBePropertiesMap:InstanceBePropertiesMap;
603         this.componentServiceNg2
604             .filterComponentInstanceProperties(this.component, filterData)
605             .subscribe(response => {
606
607                 this.processInstancePropertiesResponse(response, false);
608                 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
609                 this.searchPropertyName = filterData.propertyName;//mark in table
610                 this.hierarchyNavTabs.triggerTabChange('Composition');
611                 this.propertiesNavigationData = [];
612                 this.displayClearSearch = true;
613             }, error => {}); //ignore error
614
615     };
616
617     clearSearch = () => {
618         this.instancesNavigationData = this.instances;
619         this.searchPropertyName = "";
620         this.hierarchyPropertiesDisplayOptions.searchText = "";
621         this.displayClearSearch = false;
622         this.advanceSearch.clearAll();
623         this.searchQuery = '';
624     };
625
626     clickOnClearSearch = () => {
627         this.clearSearch();
628         this.selectFirstInstanceByDefault();
629         this.hierarchyNavTabs.triggerTabChange('Composition');
630     };
631
632     private isInput = (instanceType:string):boolean =>{
633         return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
634     }
635
636 }