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, Inject, ViewChild} from "@angular/core";
23 import {PropertiesService} from "../../services/properties.service";
26 Component as ComponentData,
29 FilterPropertiesAssignmentData,
33 InstanceBePropertiesMap,
34 InstanceFePropertiesMap,
35 InstancePropertiesAPIMap,
43 import {ResourceType} from "app/utils";
44 import {ComponentServiceNg2} from "../../services/component-services/component.service";
45 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
46 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
47 import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
48 import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
49 import {EventListenerService} from "app/services/event-listener-service"
50 import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
51 import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
52 import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component";
53 import {HierarchyNavService} from "./services/hierarchy-nav.service";
54 import {PropertiesUtils} from "./services/properties.utils";
55 import {ComponentModeService} from "../../services/component-services/component-mode.service";
56 import {Tab, Tabs} from "../../components/ui/tabs/tabs.component";
57 import {InputsUtils} from "./services/inputs.utils";
58 import {InstanceFeDetails} from "../../../models/instance-fe-details";
59 import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
60 import {UnsavedChangesComponent} from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
61 import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
62 import {ModalService} from "../../services/modal.service";
63 import {DeclareListComponent} from "./declare-list/declare-list.component";
64 import {InputListComponent} from "./input-list/input-list.component";
65 import {CapabilitiesGroup, Capability} from "../../../models/capability";
66 import {ToscaPresentationData} from "../../../models/tosca-presentation";
67 import {Observable} from "rxjs";
68 import {ToscaGetFunctionType} from "../../../models/tosca-get-function-type.enum";
69 import {TranslateService} from "../../shared/translator/translate.service";
71 const SERVICE_SELF_TITLE = "SELF";
73 templateUrl: './properties-assignment.page.component.html',
74 styleUrls: ['./properties-assignment.page.component.less']
76 export class PropertiesAssignmentComponent {
77 title = "Properties & Inputs";
79 component: ComponentData;
80 componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
82 propertiesNavigationData = [];
83 instancesNavigationData = [];
85 instanceFePropertiesMap: InstanceFePropertiesMap;
86 inputs: Array<InputFEModel> = [];
87 policies: Array<PolicyInstance> = [];
88 instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
90 propertyStructureHeader: string;
92 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
93 selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
94 checkedPropertiesCount: number = 0;
95 checkedChildPropertiesCount: number = 0;
97 hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
98 hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
99 displayClearSearch = false;
100 searchPropertyName: string;
102 isInputsTabSelected: boolean;
103 isPropertiesTabSelected: boolean;
104 isInputValueSelected: boolean = false;
105 isPoliciesTabSelected: boolean;
107 resourceIsReadonly: boolean;
108 loadingInstances: boolean = false;
109 loadingInputs: boolean = false;
110 loadingPolicies: boolean = false;
111 loadingProperties: boolean = false;
112 changedData: Array<PropertyFEModel | InputFEModel>;
113 hasChangedData: boolean;
114 isValidChangedData: boolean;
115 savingChangedData: boolean;
116 stateChangeStartUnregister: Function;
117 serviceBePropertiesMap: InstanceBePropertiesMap;
118 serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
119 selectedInstance_FlattenCapabilitiesList: Capability[];
120 propertyType: string;
121 btnSelectInputText: string;
123 @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
124 @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
125 @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
127 constructor(private propertiesService: PropertiesService,
128 private hierarchyNavService: HierarchyNavService,
129 private propertiesUtils: PropertiesUtils,
130 private inputsUtils: InputsUtils,
131 private componentServiceNg2: ComponentServiceNg2,
132 private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
133 @Inject("$stateParams") _stateParams,
134 @Inject("$scope") private $scope: ng.IScope,
135 @Inject("$state") private $state: ng.ui.IStateService,
136 @Inject("Notification") private Notification: any,
137 private componentModeService: ComponentModeService,
138 private EventListenerService: EventListenerService,
139 private ModalServiceSdcUI: SdcUiServices.ModalService,
140 private ModalService: ModalService,
141 private keysPipe: KeysPipe,
142 private topologyTemplateService: TopologyTemplateService,
143 private translateService: TranslateService) {
145 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
146 /* 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
147 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
148 this.component = _stateParams.component;
149 this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
150 this.updateViewMode();
151 this.changedData = [];
152 this.updateHasChangedData();
153 this.isValidChangedData = true;
157 console.log("==>" + this.constructor.name + ": ngOnInit");
158 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
159 this.loadingInputs = true;
160 this.loadingPolicies = true;
161 this.loadingInstances = true;
162 this.loadingProperties = true;
163 this.topologyTemplateService
164 .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
165 .subscribe(response => {
166 _.forEach(response.inputs, (input: InputBEModel) => {
167 const newInput: InputFEModel = new InputFEModel(input);
168 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
169 this.inputs.push(newInput); //only push items that were declared via SDC
171 this.loadingInputs = false;
175 this.componentServiceNg2
176 .getComponentResourcePropertiesData(this.component)
177 .subscribe(response => {
178 this.loadingPolicies = false;
180 this.instances.push(...response.componentInstances);
181 this.instances.push(...response.groupInstances);
182 this.instances.push(...response.policies);
184 _.forEach(response.policies, (policy: any) => {
185 const newPolicy: InputFEModel = new InputFEModel(policy);
186 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
187 this.policies.push(policy);
190 // add the service self instance to the top of the list.
191 const serviceInstance = new ComponentInstance();
192 serviceInstance.name = SERVICE_SELF_TITLE;
193 serviceInstance.uniqueId = this.component.uniqueId;
194 this.instances.unshift(serviceInstance);
196 _.forEach(this.instances, (instance) => {
197 this.instancesNavigationData.push(instance);
198 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
200 iconClass: instance.iconClass,
201 originArchived: instance.originArchived
204 this.loadingInstances = false;
205 if (this.instancesNavigationData[0] == undefined) {
206 this.loadingProperties = false;
208 this.selectFirstInstanceByDefault();
210 this.loadingInstances = false;
213 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
214 // stop if has changed properties
215 if (this.hasChangedData) {
216 event.preventDefault();
217 this.showUnsavedChangesAlert().then(() => {
218 this.$state.go(toState, toParams);
226 this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
227 this.stateChangeStartUnregister();
230 selectFirstInstanceByDefault = () => {
231 if (this.instancesNavigationData[0] !== undefined) {
232 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
236 updateViewMode = () => {
237 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
240 onCheckout = (component: ComponentData) => {
241 this.component = component;
242 this.updateViewMode();
245 isSelf = (): boolean => {
246 return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
249 getServiceProperties() {
250 this.loadingProperties = true;
251 this.topologyTemplateService
252 .getServiceProperties(this.component.uniqueId)
253 .subscribe((response) => {
254 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
255 this.serviceBePropertiesMap[this.component.uniqueId] = response;
256 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
257 this.loadingProperties = false;
259 this.loadingProperties = false;
263 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
264 // stop if has changed properties
265 if (this.hasChangedData) {
266 this.showUnsavedChangesAlert().then((resolve) => {
267 this.changeSelectedInstance(instance)
272 this.changeSelectedInstance(instance);
275 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
276 this.selectedInstanceData = instance;
277 this.loadingProperties = true;
278 if (instance instanceof ComponentInstance) {
279 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
280 if (this.isInput(instance.originType)) {
281 this.componentInstanceServiceNg2
282 .getComponentInstanceInputs(this.component, instance)
283 .subscribe(response => {
284 instanceBePropertiesMap[instance.uniqueId] = response;
285 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
289 this.loadingProperties = false;
291 } else if (this.isSelf()) {
292 this.getServiceProperties();
294 this.componentInstanceServiceNg2
295 .getComponentInstanceProperties(this.component, instance.uniqueId)
296 .subscribe(response => {
297 instanceBePropertiesMap[instance.uniqueId] = response;
298 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
302 this.loadingProperties = false;
305 this.loadingProperties = false;
306 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
307 } else if (instance instanceof GroupInstance) {
308 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
309 this.componentInstanceServiceNg2
310 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
311 .subscribe((response) => {
312 instanceBePropertiesMap[instance.uniqueId] = response;
313 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
317 this.loadingProperties = false;
319 } else if (instance instanceof PolicyInstance) {
320 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
321 this.componentInstanceServiceNg2
322 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
323 .subscribe((response) => {
324 instanceBePropertiesMap[instance.uniqueId] = response;
325 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
329 this.loadingProperties = false;
332 this.loadingProperties = false;
335 if (this.searchPropertyName) {
338 //clear selected property from the navigation
339 this.selectedFlatProperty = new SimpleFlatProperty();
340 this.propertiesNavigationData = [];
344 * Entry point handling response from server
346 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
347 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
348 this.checkedPropertiesCount = 0;
349 this.checkedChildPropertiesCount = 0;
352 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
353 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
354 let currentUniqueId = this.selectedInstanceData.uniqueId;
355 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
356 let isCapabilityOwnedByInstance: boolean;
357 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
358 this.selectedInstance_FlattenCapabilitiesList,
359 (result, cap: Capability) => {
360 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
361 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
362 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
363 if (cap.properties && isCapabilityOwnedByInstance) {
364 _.forEach(cap.properties, prop => {
365 if (!prop.origName) {
366 prop.origName = prop.name;
367 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
370 return result.concat(cap.properties);
374 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
375 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
376 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
377 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
379 //concatenate capabilitiesProps to all props list
380 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
381 this.checkedPropertiesCount = 0;
384 isCapabilityProperty = (prop: PropertyBEModel) => {
385 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
388 /*** VALUE CHANGE EVENTS ***/
389 dataChanged = (item: PropertyFEModel | InputFEModel) => {
391 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
392 itemHasChanged = item.hasValueObjChanged();
393 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
394 itemHasChanged = item.hasChanged();
395 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
396 itemHasChanged = item.hasDefaultValueChanged();
399 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
400 if (itemHasChanged) {
401 if (dataChangedIdx === -1) {
402 this.changedData.push(item);
405 if (dataChangedIdx !== -1) {
406 this.changedData.splice(dataChangedIdx, 1);
410 if (this.isPropertiesTabSelected) {
411 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
412 } else if (this.isInputsTabSelected) {
413 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
414 } else if (this.isPoliciesTabSelected) {
415 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
417 this.updateHasChangedData();
421 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
424 * Handle select node in navigation area, and select the row in table
426 onPropertySelectedUpdate = ($event) => {
427 console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
428 this.selectedFlatProperty = $event;
429 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
430 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
434 * When user select row in table, this will prepare the hirarchy object for the tree.
436 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
437 console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
438 let property = propertyRowSelectedEvent.propertyModel;
439 let instanceName = propertyRowSelectedEvent.instanceName;
440 this.propertyStructureHeader = null;
442 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
443 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
444 let simpleFlatProperty: Array<SimpleFlatProperty>;
445 if (property instanceof PropertyFEModel) {
446 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
447 } else if (property instanceof DerivedFEProperty) {
448 // Need to find parent PropertyFEModel
449 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
450 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
452 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
454 this.propertiesNavigationData = simpleFlatProperty;
457 // Update the header in the navigation tree with property name.
458 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
460 // Set selected property in table
461 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
462 this.hierarchyNavTabs.triggerTabChange('Property Structure');
466 selectInstanceRow = ($event) => {//get instance name
467 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
468 return instance.name == $event;
470 this.hierarchyNavTabs.triggerTabChange('Composition');
473 tabChanged = (event) => {
474 // stop if has changed properties
475 if (this.hasChangedData) {
476 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
477 this.showUnsavedChangesAlert().then((proceed) => {
478 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
484 console.log("==>" + this.constructor.name + ": tabChanged " + event);
485 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
486 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
487 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
488 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
489 this.propertyStructureHeader = null;
490 this.searchQuery = '';
493 /**Select Properties value from defined input values**/
494 selectInput = (): void => {
495 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
496 angular.forEach(instancesIds, (instanceId: string): void => {
497 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId
498 && instance instanceof ComponentInstance);
499 if (selectedInstanceData) {
500 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
501 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
502 this.propertiesService.setCheckedPropertyType(property.type);
503 if (property.toscaGetFunctionType != null) {
504 this.loadingProperties = true;
505 property.getInputValues = null;
506 property.value = null;
507 property.toscaGetFunctionType = null;
508 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
510 let modalTitle = 'Select value from Input';
511 const modal = this.ModalService.createCustomModal(new ModalModel(
516 new ButtonModel('Save', 'blue',
518 this.loadingProperties = true;
519 let selectInputValue: InputFEModel = modal.instance.dynamicContent.instance.selectInputValue;
520 property.getInputValues = [];
521 const propertyInputDetail = new PropertyInputDetail();
522 propertyInputDetail.inputId = selectInputValue.uniqueId;
523 propertyInputDetail.inputName = selectInputValue.name;
524 propertyInputDetail.inputType = selectInputValue.type;
525 property.getInputValues.push(propertyInputDetail);
526 property.value = '{"get_input":"' + selectInputValue.name + '"}';
527 property.toscaGetFunctionType = ToscaGetFunctionType.GET_INPUT;
528 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
529 modal.instance.close();
532 new ButtonModel('Cancel', 'outline grey', () => {
533 modal.instance.close();
538 this.ModalService.addDynamicContentToModal(modal, InputListComponent);
539 modal.instance.open();
546 updateInstancePropertiesWithInput(checkedProperties: PropertyBEModel[], selectedInstanceData: any) {
547 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
548 this.selectedInstanceData.uniqueId, checkedProperties)
550 this.changeSelectedInstance(selectedInstanceData);
552 this.Notification.error({
553 message: 'Failed to select/deselect get_input call: ' + error,
557 this.loadingProperties = false;
558 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
562 selectInputBtnLabel = () => {
563 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
564 angular.forEach(instancesIds, (instanceId: string): void => {
565 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
566 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
567 if(this.checkedPropertiesCount == 1) {
568 if (property.toscaGetFunctionType == null) {
569 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
571 this.btnSelectInputText = this.translateService.translate('DESELECT_INPUT_LABEL');
574 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
581 /*** DECLARE PROPERTIES/INPUTS ***/
582 declareProperties = (): void => {
583 console.log("==>" + this.constructor.name + ": declareProperties");
585 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
586 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
587 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
588 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
589 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
591 angular.forEach(instancesIds, (instanceId: string): void => {
592 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
593 if (selectedInstanceData instanceof ComponentInstance) {
594 if (!this.isInput(selectedInstanceData.originType)) {
595 // convert Property FE model -> Property BE model, extract only checked
596 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
598 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
600 } else if (selectedInstanceData instanceof GroupInstance) {
601 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
602 } else if (selectedInstanceData instanceof PolicyInstance) {
603 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
607 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
609 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
610 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
611 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
613 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
614 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
617 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
618 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
619 prop => !this.isCapabilityProperty(prop)
621 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
622 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
625 let isCapabilityPropertyChanged = false;
627 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
628 (prop: PropertyBEModel) => {
629 prop.name = prop.origName || prop.name;
630 if (this.isCapabilityProperty(prop)) {
631 isCapabilityPropertyChanged = true;
635 this.topologyTemplateService
636 .createInput(this.component, inputsToCreate, this.isSelf())
637 .subscribe((response) => {
638 this.setInputTabIndication(response.length);
639 this.checkedPropertiesCount = 0;
640 this.checkedChildPropertiesCount = 0;
641 _.forEach(response, (input: InputBEModel) => {
642 const newInput: InputFEModel = new InputFEModel(input);
643 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
644 this.inputs.push(newInput);
645 this.updatePropertyValueAfterDeclare(newInput);
647 if (isCapabilityPropertyChanged) {
648 this.reloadInstanceCapabilities();
650 }, error => {}); //ignore error
653 declareListProperties = (): void => {
654 console.log('declareListProperties() - enter');
656 // get selected properties
657 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
658 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
659 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
660 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
661 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
662 let propertyNameList: Array<string> = [];
665 angular.forEach(instancesIds, (instanceId: string): void => {
666 console.log("instanceId="+instanceId);
668 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
669 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
671 if (selectedInstanceData instanceof ComponentInstance) {
672 if (!this.isInput(selectedInstanceData.originType)) {
673 // convert Property FE model -> Property BE model, extract only checked
674 selectedComponentInstancesProperties[instanceId] = checkedProperties;
676 selectedComponentInstancesInputs[instanceId] = checkedProperties;
678 } else if (selectedInstanceData instanceof GroupInstance) {
679 selectedGroupInstancesProperties[instanceId] = checkedProperties;
680 } else if (selectedInstanceData instanceof PolicyInstance) {
681 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
684 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
685 propertyNameList.push(property.name);
689 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
691 let modalTitle = 'Declare Properties as List Input';
692 const modal = this.ModalService.createCustomModal(new ModalModel(
694 modalTitle, /* title */
699 'blue', /* css class */
700 () => { /* callback */
701 let content:any = modal.instance.dynamicContent.instance;
704 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
705 let typelist: any = PROPERTY_TYPES.LIST;
706 let uniID: any = insId;
707 let boolfalse: any = false;
708 let required: any = content.propertyModel.required;
712 "type": content.propertyModel.simpleType,
716 let schemaProp :any = {
717 "type": content.propertyModel.simpleType,
721 reglistInput.description = content.propertyModel.description;
722 reglistInput.name = content.propertyModel.name;
723 reglistInput.type = typelist;
724 reglistInput.schemaType = content.propertyModel.simpleType;
725 reglistInput.instanceUniqueId = uniID;
726 reglistInput.uniqueId = uniID;
727 reglistInput.required = required;
728 reglistInput.schema = schem;
729 reglistInput.schemaProperty = schemaProp;
732 componentInstInputsMap: content.inputsToCreate,
733 listInput: reglistInput
735 console.log("save button clicked. input=", input);
737 this.topologyTemplateService
738 .createListInput(this.component, input, this.isSelf())
739 .subscribe(response => {
740 this.setInputTabIndication(response.length);
741 this.checkedPropertiesCount = 0;
742 this.checkedChildPropertiesCount = 0;
743 _.forEach(response, (input: InputBEModel) => {
744 let newInput: InputFEModel = new InputFEModel(input);
745 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
746 this.inputs.push(newInput);
747 // create list input does not return updated properties info, so need to reload
748 //this.updatePropertyValueAfterDeclare(newInput);
749 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
750 this.changeSelectedInstance(this.selectedInstanceData);
752 modal.instance.close();
754 }, error => {}); //ignore error
757 /*, getDisabled: function */
759 new ButtonModel('Cancel', 'outline grey', () => {
760 modal.instance.close();
765 // 3rd arg is passed to DeclareListComponent instance
766 this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
767 modal.instance.open();
768 console.log('declareListProperties() - leave');
771 /*** DECLARE PROPERTIES/POLICIES ***/
772 declarePropertiesToPolicies = (): void => {
773 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
774 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
776 angular.forEach(instancesIds, (instanceId: string): void => {
777 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
778 if (selectedInstanceData instanceof ComponentInstance) {
779 if (!this.isInput(selectedInstanceData.originType)) {
780 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
785 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
786 this.loadingPolicies = true;
788 this.topologyTemplateService
789 .createPolicy(this.component, policiesToCreate, this.isSelf())
790 .subscribe(response => {
791 this.setPolicyTabIndication(response.length);
792 this.checkedPropertiesCount = 0;
793 this.displayPoliciesAsDeclared(response);
794 this.loadingPolicies = false;
799 displayPoliciesAsDeclared = (policies) => {
800 _.forEach(policies, (policy: any) => {
801 let newPolicy: InputFEModel = new InputFEModel(policy);
802 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
803 newPolicy.relatedPropertyName = policy.name;
804 newPolicy.relatedPropertyValue = policy.value;
805 this.updatePropertyValueAfterDeclare(newPolicy);
806 this.policies.push(policy);
810 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
811 return new Promise((resolve, reject) => {
812 if (!this.isValidChangedData) {
813 reject('Changed data is invalid - cannot save!');
816 if (!this.changedData.length) {
821 // make request and its handlers
823 let handleSuccess, handleError;
824 let changedInputsProperties = [], changedCapabilitiesProperties = [];
825 if (this.isPropertiesTabSelected) {
826 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
827 changedProp = <PropertyFEModel>changedProp;
828 const propBE = new PropertyBEModel(changedProp);
829 propBE.toscaPresentation = new ToscaPresentationData();
830 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
831 propBE.value = changedProp.getJSONValue();
832 propBE.name = changedProp.origName || changedProp.name;
833 delete propBE.origName;
836 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
838 if (this.selectedInstanceData instanceof ComponentInstance) {
839 if (this.isInput(this.selectedInstanceData.originType)) {
840 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
841 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
842 request = Observable.forkJoin(
843 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
844 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
845 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
848 else if (changedInputsProperties.length) {
849 request = this.componentInstanceServiceNg2
850 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
852 else if (changedCapabilitiesProperties.length) {
853 request = this.componentInstanceServiceNg2
854 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
856 handleSuccess = (response) => {
857 // reset each changed property with new value and remove it from changed properties list
858 response.forEach((resInput) => {
859 const changedProp = <PropertyFEModel>this.changedData.shift();
860 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
862 console.log('updated instance inputs:', response);
866 console.log("changedProperties", changedProperties);
867 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
868 delete cp.constraints;
872 request = this.componentInstanceServiceNg2
873 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
875 handleSuccess = (response) => {
876 // reset each changed property with new value and remove it from changed properties list
877 response.forEach((resProp) => {
878 const changedProp = <PropertyFEModel>this.changedData.shift();
879 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
882 console.log("updated instance properties: ", response);
885 } else if (this.selectedInstanceData instanceof GroupInstance) {
886 request = this.componentInstanceServiceNg2
887 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
888 handleSuccess = (response) => {
889 // reset each changed property with new value and remove it from changed properties list
890 response.forEach((resProp) => {
891 const changedProp = <PropertyFEModel>this.changedData.shift();
892 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
895 console.log("updated group instance properties: ", response);
897 } else if (this.selectedInstanceData instanceof PolicyInstance) {
898 request = this.componentInstanceServiceNg2
899 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
900 handleSuccess = (response) => {
901 // reset each changed property with new value and remove it from changed properties list
902 response.forEach((resProp) => {
903 const changedProp = <PropertyFEModel>this.changedData.shift();
904 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
907 console.log("updated policy instance properties: ", response);
910 } else if (this.isInputsTabSelected) {
912 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
913 changedInput = <InputFEModel>changedInput;
914 const inputBE = new InputBEModel(changedInput);
915 inputBE.defaultValue = changedInput.getJSONDefaultValue();
918 request = this.componentServiceNg2
919 .updateComponentInputs(this.component, changedInputs);
920 handleSuccess = (response) => {
921 // reset each changed property with new value and remove it from changed properties list
922 response.forEach((resInput) => {
923 const changedInput = <InputFEModel>this.changedData.shift();
924 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
925 changedInput.required = resInput.required;
926 changedInput.requiredOrig = resInput.required;
928 console.log("updated the component inputs and got this response: ", response);
932 this.savingChangedData = true;
935 this.savingChangedData = false;
936 if (changedCapabilitiesProperties.length) {
937 this.reloadInstanceCapabilities();
939 handleSuccess && handleSuccess(response);
940 this.updateHasChangedData();
944 this.savingChangedData = false;
945 handleError && handleError(error);
946 this.updateHasChangedData();
953 reloadInstanceCapabilities = (): void => {
954 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
955 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
956 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
957 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
958 return instance.capabilities;
961 }, new CapabilitiesGroup());
962 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
966 reverseChangedData = ():void => {
967 // make reverse item handler
968 let handleReverseItem;
969 if (this.isPropertiesTabSelected) {
970 handleReverseItem = (changedItem) => {
971 changedItem = <PropertyFEModel>changedItem;
972 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
974 } else if (this.isInputsTabSelected) {
975 handleReverseItem = (changedItem) => {
976 changedItem = <InputFEModel>changedItem;
977 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
978 changedItem.resetMetadata();
979 changedItem.required = changedItem.requiredOrig;
983 this.changedData.forEach(handleReverseItem);
984 this.changedData = [];
985 this.updateHasChangedData();
988 updateHasChangedData = ():boolean => {
989 const curHasChangedData:boolean = (this.changedData.length > 0);
990 if (curHasChangedData !== this.hasChangedData) {
991 this.hasChangedData = curHasChangedData;
992 if(this.hasChangedData) {
993 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
995 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
998 return this.hasChangedData;
1001 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1002 this.saveChangedData().then(
1004 this.Notification.success({
1005 message: 'Successfully saved changes',
1008 if(onSuccessFunction) onSuccessFunction();
1011 this.Notification.error({
1012 message: 'Failed to save changes!',
1015 if(onError) onError();
1020 showUnsavedChangesAlert = ():Promise<any> => {
1021 let modalTitle:string;
1022 if (this.isPropertiesTabSelected) {
1023 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1024 } else if (this.isInputsTabSelected) {
1025 modalTitle = `Unsaved inputs for ${this.component.name}`;
1028 return new Promise<any>((resolve, reject) => {
1029 const modal = this.ModalServiceSdcUI.openCustomModal(
1033 type: SdcUiCommon.ModalType.custom,
1034 testId: "navigate-modal",
1037 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1038 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1039 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1040 ] as SdcUiCommon.IModalButtonComponent[]
1041 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1046 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1047 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1048 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1049 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1050 return feProperty.name == input.relatedPropertyName &&
1051 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1053 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1054 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1055 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1056 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1060 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1061 updateCheckedPropertyCount = (increment: boolean): void => {
1062 this.checkedPropertiesCount += (increment) ? 1 : -1;
1063 console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1064 this.selectInputBtnLabel();
1067 updateCheckedChildPropertyCount = (increment: boolean): void => {
1068 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1071 setInputTabIndication = (numInputs: number): void => {
1072 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1075 setPolicyTabIndication = (numPolicies: number): void => {
1076 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1079 resetUnsavedChangesForInput = (input:InputFEModel) => {
1080 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1081 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1082 this.updateHasChangedData();
1085 deleteInput = (input: InputFEModel) => {
1086 //reset any unsaved changes to the input before deleting it
1087 this.resetUnsavedChangesForInput(input);
1089 console.log("==>" + this.constructor.name + ": deleteInput");
1090 let inputToDelete = new InputBEModel(input);
1092 this.componentServiceNg2
1093 .deleteInput(this.component, inputToDelete)
1094 .subscribe(response => {
1095 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1097 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1098 this.changeSelectedInstance(this.selectedInstanceData);
1099 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1101 // if (instanceFeProperties) {
1102 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1103 // return prop.name == input.propertyName;
1106 // if (propToEnable) {
1107 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1108 // propToEnable.setNonDeclared(response.inputPath);
1109 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1110 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1113 }, error => {}); //ignore error
1116 deletePolicy = (policy: PolicyInstance) => {
1117 this.loadingPolicies = true;
1118 this.topologyTemplateService
1119 .deletePolicy(this.component, policy)
1120 .subscribe((response) => {
1121 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1122 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1123 this.changeSelectedInstance(this.selectedInstanceData);
1124 this.loadingPolicies = false;
1128 deleteProperty = (property: PropertyFEModel) => {
1129 const propertyToDelete = new PropertyFEModel(property);
1130 this.loadingProperties = true;
1131 const feMap = this.instanceFePropertiesMap;
1132 this.topologyTemplateService
1133 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1134 .subscribe((response) => {
1135 const props = feMap[this.component.uniqueId];
1136 props.splice(props.findIndex(p => p.uniqueId === response),1);
1137 this.loadingProperties = false;
1139 this.loadingProperties = false;
1140 console.error(error);
1144 /*** addProperty ***/
1145 addProperty = () => {
1146 let modalTitle = 'Add Property';
1147 let modal = this.ModalService.createCustomModal(new ModalModel(
1152 new ButtonModel('Save', 'blue', () => {
1153 modal.instance.dynamicContent.instance.isLoading = true;
1154 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1155 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1156 .subscribe((response) => {
1157 modal.instance.dynamicContent.instance.isLoading = false;
1158 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1159 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1160 modal.instance.close();
1162 modal.instance.dynamicContent.instance.isLoading = false;
1163 this.Notification.error({
1164 message: 'Failed to add property:' + error,
1168 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1169 new ButtonModel('Cancel', 'outline grey', () => {
1170 modal.instance.close();
1175 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1176 modal.instance.open();
1181 let modalTitle = 'Add Input';
1182 let modal = this.ModalService.createCustomModal(new ModalModel(
1187 new ButtonModel('Save', 'blue', () => {
1188 modal.instance.dynamicContent.instance.isLoading = true;
1189 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1190 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1191 .subscribe((response) => {
1192 modal.instance.dynamicContent.instance.isLoading = false;
1193 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1194 this.inputs.push(newInputProp);
1195 modal.instance.close();
1197 modal.instance.dynamicContent.instance.isLoading = false;
1198 this.Notification.error({
1199 message: 'Failed to add input:' + error,
1203 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1204 new ButtonModel('Cancel', 'outline grey', () => {
1205 modal.instance.close();
1210 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1211 modal.instance.open();
1214 /*** SEARCH RELATED FUNCTIONS ***/
1215 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1216 let instanceBePropertiesMap:InstanceBePropertiesMap;
1217 this.componentServiceNg2
1218 .filterComponentInstanceProperties(this.component, filterData)
1219 .subscribe((response) => {
1220 this.processInstancePropertiesResponse(response, false);
1221 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1222 this.searchPropertyName = filterData.propertyName;//mark in table
1223 this.hierarchyNavTabs.triggerTabChange('Composition');
1224 this.propertiesNavigationData = [];
1225 this.displayClearSearch = true;
1226 }, (error) => {}); //ignore error
1230 clearSearch = () => {
1231 this.instancesNavigationData = this.instances;
1232 this.searchPropertyName = "";
1233 this.hierarchyPropertiesDisplayOptions.searchText = "";
1234 this.displayClearSearch = false;
1235 this.advanceSearch.clearAll();
1236 this.searchQuery = '';
1239 clickOnClearSearch = () => {
1241 this.selectFirstInstanceByDefault();
1242 this.hierarchyNavTabs.triggerTabChange('Composition');
1245 private isInput = (instanceType:string):boolean =>{
1246 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;