2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
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, GroupInstance, PolicyInstance, PropertyBEModel, DerivedFEProperty, 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 import { InstanceFeDetails } from "../../../models/instance-fe-details";
42 import { SdcUiComponents } from "sdc-ui/lib/angular";
43 //import { ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service";
44 import { IModalButtonComponent } from "sdc-ui/lib/angular/modals/models/modal-config";
45 import { UnsavedChangesComponent } from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
48 templateUrl: './properties-assignment.page.component.html',
49 styleUrls: ['./properties-assignment.page.component.less']
51 export class PropertiesAssignmentComponent {
52 title = "Properties & Inputs";
54 component: ComponentData;
55 componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
57 propertiesNavigationData = [];
58 instancesNavigationData = [];
60 instanceFePropertiesMap:InstanceFePropertiesMap;
61 inputs: Array<InputFEModel> = [];
62 instances: Array<ComponentInstance|GroupInstance|PolicyInstance> = [];
64 propertyStructureHeader: string;
66 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
67 selectedInstanceData: ComponentInstance|GroupInstance|PolicyInstance = null;
68 checkedPropertiesCount: number = 0;
70 hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
71 hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
72 displayClearSearch = false;
73 searchPropertyName:string;
75 isInputsTabSelected:boolean;
76 isPropertiesTabSelected:boolean;
78 resourceIsReadonly:boolean;
79 loadingInstances:boolean = false;
80 loadingInputs:boolean = false;
81 loadingProperties:boolean = false;
82 changedData:Array<PropertyFEModel|InputFEModel>;
83 hasChangedData:boolean;
84 isValidChangedData:boolean;
85 savingChangedData:boolean;
86 stateChangeStartUnregister:Function;
88 @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
89 @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
90 @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
92 constructor(private propertiesService: PropertiesService,
93 private hierarchyNavService: HierarchyNavService,
94 private propertiesUtils:PropertiesUtils,
95 private inputsUtils:InputsUtils,
96 private componentServiceNg2:ComponentServiceNg2,
97 private componentInstanceServiceNg2:ComponentInstanceServiceNg2,
98 @Inject("$stateParams") _stateParams,
99 @Inject("$scope") private $scope:ng.IScope,
100 @Inject("$state") private $state:ng.ui.IStateService,
101 @Inject("Notification") private Notification:any,
102 private componentModeService:ComponentModeService,
103 private ModalService:ModalService,
104 private EventListenerService:EventListenerService,
105 private ModalServiceSdcUI: SdcUiComponents.ModalService) {
107 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
109 /* 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
110 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
111 this.component = _stateParams.component;
112 this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
113 this.updateViewMode();
115 this.changedData = [];
116 this.updateHasChangedData();
117 this.isValidChangedData = true;
121 console.log("==>" + this.constructor.name + ": ngOnInit");
122 this.loadingInputs = true;
123 this.loadingInstances = true;
124 this.loadingProperties = true;
125 this.componentServiceNg2
126 .getComponentInputs(this.component)
127 .subscribe(response => {
128 _.forEach(response.inputs, (input: InputBEModel) => {
129 const newInput: InputFEModel = new InputFEModel(input);
130 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
131 this.inputs.push(newInput); //only push items that were declared via SDC
133 this.loadingInputs = false;
135 }, error => {}); //ignore error
136 this.componentServiceNg2
137 .getComponentResourcePropertiesData(this.component)
138 .subscribe(response => {
140 this.instances.push(...response.componentInstances);
141 this.instances.push(...response.groupInstances);
142 this.instances.push(...response.policies);
144 _.forEach(this.instances, (instance) => {
145 this.instancesNavigationData.push(instance);
146 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{name: instance.name, iconClass:instance.iconClass, originArchived:instance.originArchived};
148 this.loadingInstances = false;
149 if (this.instancesNavigationData[0] == undefined) {
150 this.loadingProperties = false;
152 this.selectFirstInstanceByDefault();
153 }, error => {}); //ignore error
155 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
156 // stop if has changed properties
157 if (this.hasChangedData) {
158 event.preventDefault();
159 this.showUnsavedChangesAlert().then(() => {
160 this.$state.go(toState, toParams);
167 this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
168 this.stateChangeStartUnregister();
171 selectFirstInstanceByDefault = () => {
172 if (this.instancesNavigationData[0] !== undefined) {
173 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
177 updateViewMode = () => {
178 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
181 onCheckout = (component:ComponentData) => {
182 this.component = component;
183 this.updateViewMode();
187 onInstanceSelectedUpdate = (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
188 // stop if has changed properties
189 if (this.hasChangedData) {
190 this.showUnsavedChangesAlert().then((resolve)=> {
191 this.changeSelectedInstance(instance)
196 this.changeSelectedInstance(instance);
199 changeSelectedInstance = (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
200 this.selectedInstanceData = instance;
201 this.loadingProperties = true;
202 if (instance instanceof ComponentInstance) {
203 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
204 if (this.isInput(instance.originType)) {
205 this.componentInstanceServiceNg2
206 .getComponentInstanceInputs(this.component, instance)
207 .subscribe(response => {
208 instanceBePropertiesMap[instance.uniqueId] = response;
209 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
210 this.loadingProperties = false;
214 this.componentInstanceServiceNg2
215 .getComponentInstanceProperties(this.component, instance.uniqueId)
216 .subscribe(response => {
217 instanceBePropertiesMap[instance.uniqueId] = response;
218 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
219 this.loadingProperties = false;
224 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
225 } else if (instance instanceof GroupInstance) {
226 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
227 this.componentInstanceServiceNg2
228 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
229 .subscribe((response) => {
230 instanceBePropertiesMap[instance.uniqueId] = response;
231 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
232 this.loadingProperties = false;
234 } else if (instance instanceof PolicyInstance) {
235 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
236 this.componentInstanceServiceNg2
237 .getComponentPolicyInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
238 .subscribe((response) => {
239 instanceBePropertiesMap[instance.uniqueId] = response;
240 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
241 this.loadingProperties = false;
244 this.loadingProperties = false;
247 if (this.searchPropertyName) {
250 //clear selected property from the navigation
251 this.selectedFlatProperty = new SimpleFlatProperty();
252 this.propertiesNavigationData = [];
256 * Entry point handling response from server
258 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
259 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
260 this.checkedPropertiesCount = 0;
264 /*** VALUE CHANGE EVENTS ***/
265 dataChanged = (item:PropertyFEModel|InputFEModel) => {
267 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
268 itemHasChanged = item.hasValueObjChanged();
269 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
270 itemHasChanged = item.hasDefaultValueChanged();
273 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
274 if (itemHasChanged) {
275 if (dataChangedIdx === -1) {
276 this.changedData.push(item);
279 if (dataChangedIdx !== -1) {
280 this.changedData.splice(dataChangedIdx, 1);
284 if (this.isPropertiesTabSelected) {
285 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
286 } else if (this.isInputsTabSelected) {
287 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
289 this.updateHasChangedData();
293 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
296 * Handle select node in navigation area, and select the row in table
298 onPropertySelectedUpdate = ($event) => {
299 console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
300 this.selectedFlatProperty = $event;
301 let parentProperty:PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
302 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
306 * When user select row in table, this will prepare the hirarchy object for the tree.
308 selectPropertyRow = (propertyRowSelectedEvent:PropertyRowSelectedEvent) => {
309 console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
310 let property = propertyRowSelectedEvent.propertyModel;
311 let instanceName = propertyRowSelectedEvent.instanceName;
312 this.propertyStructureHeader = null;
314 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
315 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
316 let simpleFlatProperty:Array<SimpleFlatProperty>;
317 if (property instanceof PropertyFEModel) {
318 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
319 } else if (property instanceof DerivedFEProperty) {
320 // Need to find parent PropertyFEModel
321 let parentPropertyFEModel:PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty):boolean => {
322 return property.propertiesName.indexOf(tmpFeProperty.name)===0;
324 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
326 this.propertiesNavigationData = simpleFlatProperty;
329 // Update the header in the navigation tree with property name.
330 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
332 // Set selected property in table
333 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
334 this.hierarchyNavTabs.triggerTabChange('Property Structure');
338 selectInstanceRow = ($event) => {//get instance name
339 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance:ComponentInstance) => {
340 return instance.name == $event;
342 this.hierarchyNavTabs.triggerTabChange('Composition');
345 tabChanged = (event) => {
346 // stop if has changed properties
347 if (this.hasChangedData) {
348 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
349 this.showUnsavedChangesAlert().then((proceed) => {
350 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
356 console.log("==>" + this.constructor.name + ": tabChanged " + event);
357 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
358 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
359 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
360 this.propertyStructureHeader = null;
361 this.searchQuery = '';
366 /*** DECLARE PROPERTIES/INPUTS ***/
367 declareProperties = (): void => {
368 console.log("==>" + this.constructor.name + ": declareProperties");
370 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
371 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
372 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
373 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
374 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
376 angular.forEach(instancesIds, (instanceId: string): void => {
377 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
378 if (selectedInstanceData instanceof ComponentInstance) {
379 if (!this.isInput(selectedInstanceData.originType)) {
380 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
382 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
384 } else if (selectedInstanceData instanceof GroupInstance) {
385 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
386 } else if (selectedInstanceData instanceof PolicyInstance) {
387 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
391 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
393 this.componentServiceNg2
394 .createInput(this.component, inputsToCreate)
395 .subscribe(response => {
396 this.setInputTabIndication(response.length);
397 this.checkedPropertiesCount = 0;
398 _.forEach(response, (input: InputBEModel) => {
399 let newInput: InputFEModel = new InputFEModel(input);
400 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
401 this.inputs.push(newInput);
402 this.updatePropertyValueAfterDeclare(newInput);
404 }, error => {}); //ignore error
407 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
408 return new Promise((resolve, reject) => {
409 if (!this.isValidChangedData) {
410 reject('Changed data is invalid - cannot save!');
413 if (!this.changedData.length) {
418 // make request and its handlers
420 let handleSuccess, handleError;
421 if (this.isPropertiesTabSelected) {
422 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
423 changedProp = <PropertyFEModel>changedProp;
424 const propBE = new PropertyBEModel(changedProp);
425 propBE.value = changedProp.getJSONValue();
429 if (this.selectedInstanceData instanceof ComponentInstance) {
430 if (this.isInput(this.selectedInstanceData.originType)) {
431 request = this.componentInstanceServiceNg2
432 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedProperties);
433 handleSuccess = (response) => {
434 // reset each changed property with new value and remove it from changed properties list
435 response.forEach((resInput) => {
436 const changedProp = <PropertyFEModel>this.changedData.shift();
437 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
439 console.log('updated instance inputs:', response);
442 request = this.componentInstanceServiceNg2
443 .updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties)
444 handleSuccess = (response) => {
445 // reset each changed property with new value and remove it from changed properties list
446 response.forEach((resProp) => {
447 const changedProp = <PropertyFEModel>this.changedData.shift();
448 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
451 console.log("updated instance properties: ", response);
454 } else if (this.selectedInstanceData instanceof GroupInstance) {
455 request = this.componentInstanceServiceNg2
456 .updateComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties);
457 handleSuccess = (response) => {
458 // reset each changed property with new value and remove it from changed properties list
459 response.forEach((resProp) => {
460 const changedProp = <PropertyFEModel>this.changedData.shift();
461 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
464 console.log("updated group instance properties: ", response);
466 } else if (this.selectedInstanceData instanceof PolicyInstance) {
467 request = this.componentInstanceServiceNg2
468 .updateComponentPolicyInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties);
469 handleSuccess = (response) => {
470 // reset each changed property with new value and remove it from changed properties list
471 response.forEach((resProp) => {
472 const changedProp = <PropertyFEModel>this.changedData.shift();
473 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
476 console.log("updated policy instance properties: ", response);
479 } else if (this.isInputsTabSelected) {
480 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
481 changedInput = <InputFEModel>changedInput;
482 const inputBE = new InputBEModel(changedInput);
483 inputBE.defaultValue = changedInput.getJSONDefaultValue();
486 request = this.componentServiceNg2
487 .updateComponentInputs(this.component, changedInputs);
488 handleSuccess = (response) => {
489 // reset each changed property with new value and remove it from changed properties list
490 response.forEach((resInput) => {
491 const changedInput = <InputFEModel>this.changedData.shift();
492 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
494 console.log("updated the component inputs and got this response: ", response);
498 this.savingChangedData = true;
501 this.savingChangedData = false;
502 handleSuccess && handleSuccess(response);
503 this.updateHasChangedData();
507 this.savingChangedData = false;
508 handleError && handleError(error);
509 this.updateHasChangedData();
516 reverseChangedData = ():void => {
517 // make reverse item handler
518 let handleReverseItem;
519 if (this.isPropertiesTabSelected) {
520 handleReverseItem = (changedItem) => {
521 changedItem = <PropertyFEModel>changedItem;
522 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
524 } else if (this.isInputsTabSelected) {
525 handleReverseItem = (changedItem) => {
526 changedItem = <InputFEModel>changedItem;
527 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
531 this.changedData.forEach(handleReverseItem);
532 this.changedData = [];
533 this.updateHasChangedData();
536 updateHasChangedData = ():boolean => {
537 const curHasChangedData:boolean = (this.changedData.length > 0);
538 if (curHasChangedData !== this.hasChangedData) {
539 this.hasChangedData = curHasChangedData;
540 if(this.hasChangedData) {
541 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
543 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
546 return this.hasChangedData;
549 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
550 this.saveChangedData().then(
552 this.Notification.success({
553 message: 'Successfully saved changes',
556 if(onSuccessFunction) onSuccessFunction();
559 this.Notification.error({
560 message: 'Failed to save changes!',
563 if(onError) onError();
568 showUnsavedChangesAlert = ():Promise<any> => {
569 let modalTitle:string;
570 if (this.isPropertiesTabSelected) {
571 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
572 } else if (this.isInputsTabSelected) {
573 modalTitle = `Unsaved inputs for ${this.component.name}`;
576 return new Promise<any>((resolve, reject) => {
577 const modal = this.ModalServiceSdcUI.openCustomModal(
585 {id: 'cancelButton', text: 'Cancel', type: 'secondary', size: 'xsm', closeModal: true, callback: () => reject()},
586 {id: 'discardButton', text: 'Discard', type: 'secondary', size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
587 {id: 'saveButton', text: 'Save', type: 'primary', size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
588 ] as IModalButtonComponent[]
589 }, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
594 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
595 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
596 let propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
597 return feProperty.name == input.relatedPropertyName;
599 let inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
600 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
601 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
602 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
606 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
607 updateCheckedPropertyCount = (increment: boolean): void => {
608 this.checkedPropertiesCount += (increment) ? 1 : -1;
609 console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
612 setInputTabIndication = (numInputs: number): void => {
613 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
616 resetUnsavedChangesForInput = (input:InputFEModel) => {
617 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
618 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
619 this.updateHasChangedData();
622 deleteInput = (input: InputFEModel) => {
623 //reset any unsaved changes to the input before deleting it
624 this.resetUnsavedChangesForInput(input);
626 console.log("==>" + this.constructor.name + ": deleteInput");
627 let inputToDelete = new InputBEModel(input);
629 this.componentServiceNg2
630 .deleteInput(this.component, inputToDelete)
631 .subscribe(response => {
632 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
634 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
635 this.changeSelectedInstance(this.selectedInstanceData);
636 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
638 // if (instanceFeProperties) {
639 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
640 // return prop.name == input.propertyName;
643 // if (propToEnable) {
644 // if (propToEnable.name == response.inputPath) response.inputPath = null;
645 // propToEnable.setNonDeclared(response.inputPath);
646 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
647 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
650 }, error => {}); //ignore error
655 /*** SEARCH RELATED FUNCTIONS ***/
656 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
657 let instanceBePropertiesMap:InstanceBePropertiesMap;
658 this.componentServiceNg2
659 .filterComponentInstanceProperties(this.component, filterData)
660 .subscribe(response => {
662 this.processInstancePropertiesResponse(response, false);
663 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
664 this.searchPropertyName = filterData.propertyName;//mark in table
665 this.hierarchyNavTabs.triggerTabChange('Composition');
666 this.propertiesNavigationData = [];
667 this.displayClearSearch = true;
668 }, error => {}); //ignore error
672 clearSearch = () => {
673 this.instancesNavigationData = this.instances;
674 this.searchPropertyName = "";
675 this.hierarchyPropertiesDisplayOptions.searchText = "";
676 this.displayClearSearch = false;
677 this.advanceSearch.clearAll();
678 this.searchQuery = '';
681 clickOnClearSearch = () => {
683 this.selectFirstInstanceByDefault();
684 this.hierarchyNavTabs.triggerTabChange('Composition');
687 private isInput = (instanceType:string):boolean =>{
688 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;