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 {ToscaFunctionComponent, ToscaFunctionValidationEvent} from "./tosca-function/tosca-function.component";
65 import {CapabilitiesGroup, Capability} from "../../../models/capability";
66 import {ToscaPresentationData} from "../../../models/tosca-presentation";
67 import {Observable} from "rxjs";
68 import {TranslateService} from "../../shared/translator/translate.service";
69 import {ToscaFunction} from "../../../models/tosca-function";
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: { [key: string]: InstanceFeDetails } = {}; //key is the instance uniqueId
81 componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); //key is the instance uniqueId
83 propertiesNavigationData = [];
84 instancesNavigationData = [];
86 instanceFePropertiesMap: InstanceFePropertiesMap;
87 inputs: Array<InputFEModel> = [];
88 policies: Array<PolicyInstance> = [];
89 instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
91 propertyStructureHeader: string;
93 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
94 selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
95 checkedPropertiesCount: number = 0;
96 checkedChildPropertiesCount: number = 0;
98 hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
99 hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
100 displayClearSearch = false;
101 searchPropertyName: string;
103 isInputsTabSelected: boolean;
104 isPropertiesTabSelected: boolean;
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[];
121 @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
122 @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
123 @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
125 constructor(private propertiesService: PropertiesService,
126 private hierarchyNavService: HierarchyNavService,
127 private propertiesUtils: PropertiesUtils,
128 private inputsUtils: InputsUtils,
129 private componentServiceNg2: ComponentServiceNg2,
130 private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
131 private propertyCreatorComponent: PropertyCreatorComponent,
132 @Inject("$stateParams") _stateParams,
133 @Inject("$scope") private $scope: ng.IScope,
134 @Inject("$state") private $state: ng.ui.IStateService,
135 @Inject("Notification") private notification: any,
136 private componentModeService: ComponentModeService,
137 private eventListenerService: EventListenerService,
138 private ModalServiceSdcUI: SdcUiServices.ModalService,
139 private modalService: ModalService,
140 private keysPipe: KeysPipe,
141 private topologyTemplateService: TopologyTemplateService,
142 private translateService: TranslateService) {
144 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
145 /* 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
146 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
147 this.component = _stateParams.component;
148 this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
149 this.updateViewMode();
150 this.changedData = [];
151 this.updateHasChangedData();
152 this.isValidChangedData = true;
156 console.debug("==>" + this.constructor.name + ": ngOnInit");
157 this.loadingInputs = true;
158 this.loadingPolicies = true;
159 this.loadingInstances = true;
160 this.loadingProperties = true;
161 this.topologyTemplateService
162 .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
163 .subscribe(response => {
164 _.forEach(response.inputs, (input: InputBEModel) => {
165 const newInput: InputFEModel = new InputFEModel(input);
166 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
167 this.inputs.push(newInput); //only push items that were declared via SDC
169 this.loadingInputs = false;
173 this.componentServiceNg2
174 .getComponentResourcePropertiesData(this.component)
175 .subscribe(response => {
176 this.loadingPolicies = false;
178 this.instances.push(...response.componentInstances);
179 this.instances.push(...response.groupInstances);
180 this.instances.push(...response.policies);
182 if (response.componentInstances) {
183 response.componentInstances.forEach(instance => {
184 this.componentInstanceMap.set(instance.uniqueId, <InstanceFeDetails>{
186 iconClass: instance.iconClass,
187 originArchived: instance.originArchived
192 _.forEach(response.policies, (policy: any) => {
193 const newPolicy: InputFEModel = new InputFEModel(policy);
194 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
195 this.policies.push(policy);
198 // add the service self instance to the top of the list.
199 const serviceInstance = new ComponentInstance();
200 serviceInstance.name = SERVICE_SELF_TITLE;
201 serviceInstance.uniqueId = this.component.uniqueId;
202 this.instances.unshift(serviceInstance);
204 _.forEach(this.instances, (instance) => {
205 this.instancesNavigationData.push(instance);
206 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
208 iconClass: instance.iconClass,
209 originArchived: instance.originArchived
212 this.loadingInstances = false;
213 if (this.instancesNavigationData[0] == undefined) {
214 this.loadingProperties = false;
216 this.selectFirstInstanceByDefault();
218 this.loadingInstances = false;
221 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
222 // stop if has changed properties
223 if (this.hasChangedData) {
224 event.preventDefault();
225 this.showUnsavedChangesAlert().then(() => {
226 this.$state.go(toState, toParams);
232 this.loadDataTypesByComponentModel(this.component.model);
236 this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
237 this.stateChangeStartUnregister();
240 selectFirstInstanceByDefault = () => {
241 if (this.instancesNavigationData[0] !== undefined) {
242 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
246 updateViewMode = () => {
247 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
250 onCheckout = (component: ComponentData) => {
251 this.component = component;
252 this.updateViewMode();
255 isSelf = (): boolean => {
256 return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
259 showAddProperties = (): boolean => {
260 if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
263 return this.isSelf();
266 getServiceProperties() {
267 this.loadingProperties = true;
268 this.topologyTemplateService
269 .getServiceProperties(this.component.uniqueId)
270 .subscribe((response) => {
271 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
272 this.serviceBePropertiesMap[this.component.uniqueId] = response;
273 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
274 this.loadingProperties = false;
276 this.loadingProperties = false;
280 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
281 // stop if has changed properties
282 if (this.hasChangedData) {
283 this.showUnsavedChangesAlert().then((resolve) => {
284 this.changeSelectedInstance(instance)
289 this.changeSelectedInstance(instance);
292 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
293 this.selectedInstanceData = instance;
294 this.loadingProperties = true;
295 if (instance instanceof ComponentInstance) {
296 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
297 if (this.isInput(instance.originType)) {
298 this.componentInstanceServiceNg2
299 .getComponentInstanceInputs(this.component, instance)
300 .subscribe(response => {
301 instanceBePropertiesMap[instance.uniqueId] = response;
302 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
306 this.loadingProperties = false;
308 } else if (this.isSelf()) {
309 this.getServiceProperties();
311 this.componentInstanceServiceNg2
312 .getComponentInstanceProperties(this.component, instance.uniqueId)
313 .subscribe(response => {
314 instanceBePropertiesMap[instance.uniqueId] = response;
315 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
319 this.loadingProperties = false;
322 this.loadingProperties = false;
323 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
324 } else if (instance instanceof GroupInstance) {
325 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
326 this.componentInstanceServiceNg2
327 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
328 .subscribe((response) => {
329 instanceBePropertiesMap[instance.uniqueId] = response;
330 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
334 this.loadingProperties = false;
336 } else if (instance instanceof PolicyInstance) {
337 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
338 this.componentInstanceServiceNg2
339 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
340 .subscribe((response) => {
341 instanceBePropertiesMap[instance.uniqueId] = response;
342 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
346 this.loadingProperties = false;
349 this.loadingProperties = false;
352 if (this.searchPropertyName) {
355 //clear selected property from the navigation
356 this.selectedFlatProperty = new SimpleFlatProperty();
357 this.propertiesNavigationData = [];
361 * Entry point handling response from server
363 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
364 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
365 this.checkedPropertiesCount = 0;
366 this.checkedChildPropertiesCount = 0;
369 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
370 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
371 let currentUniqueId = this.selectedInstanceData.uniqueId;
372 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
373 let isCapabilityOwnedByInstance: boolean;
374 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
375 this.selectedInstance_FlattenCapabilitiesList,
376 (result, cap: Capability) => {
377 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
378 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
379 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
380 if (cap.properties && isCapabilityOwnedByInstance) {
381 _.forEach(cap.properties, prop => {
382 if (!prop.origName) {
383 prop.origName = prop.name;
384 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
387 return result.concat(cap.properties);
391 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
392 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
393 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
394 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
396 //concatenate capabilitiesProps to all props list
397 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
398 this.checkedPropertiesCount = 0;
401 isCapabilityProperty = (prop: PropertyBEModel) => {
402 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
405 /*** VALUE CHANGE EVENTS ***/
406 dataChanged = (item: PropertyFEModel | InputFEModel) => {
408 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
409 itemHasChanged = item.hasValueObjChanged();
410 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
411 itemHasChanged = item.hasChanged();
412 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
413 itemHasChanged = item.hasDefaultValueChanged();
416 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
417 if (itemHasChanged) {
418 if (dataChangedIdx === -1) {
419 this.changedData.push(item);
422 if (dataChangedIdx !== -1) {
423 this.changedData.splice(dataChangedIdx, 1);
427 if (this.isPropertiesTabSelected) {
428 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
429 } else if (this.isInputsTabSelected) {
430 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
431 } else if (this.isPoliciesTabSelected) {
432 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
434 this.updateHasChangedData();
438 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
441 * Handle select node in navigation area, and select the row in table
443 onPropertySelectedUpdate = ($event) => {
444 console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
445 this.selectedFlatProperty = $event;
446 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
447 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
451 * When user select row in table, this will prepare the hirarchy object for the tree.
453 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
454 console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
455 let property = propertyRowSelectedEvent.propertyModel;
456 let instanceName = propertyRowSelectedEvent.instanceName;
457 this.propertyStructureHeader = null;
459 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
460 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
461 let simpleFlatProperty: Array<SimpleFlatProperty>;
462 if (property instanceof PropertyFEModel) {
463 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
464 } else if (property instanceof DerivedFEProperty) {
465 // Need to find parent PropertyFEModel
466 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
467 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
469 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
471 this.propertiesNavigationData = simpleFlatProperty;
474 // Update the header in the navigation tree with property name.
475 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
477 // Set selected property in table
478 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
479 this.hierarchyNavTabs.triggerTabChange('Property Structure');
483 selectInstanceRow = ($event) => {//get instance name
484 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
485 return instance.name == $event;
487 this.hierarchyNavTabs.triggerTabChange('Composition');
490 tabChanged = (event) => {
491 // stop if has changed properties
492 if (this.hasChangedData) {
493 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
494 this.showUnsavedChangesAlert().then((proceed) => {
495 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
501 console.debug("==>" + this.constructor.name + ": tabChanged " + event);
502 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
503 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
504 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
505 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
506 this.propertyStructureHeader = null;
507 this.searchQuery = '';
511 * Select Tosca function value from defined values
513 selectToscaFunctionAndValues = (): void => {
514 const selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = this.getSelectedInstance();
515 if (!selectedInstanceData) {
518 this.openToscaGetFunctionModal();
521 private getSelectedInstance(): ComponentInstance | GroupInstance | PolicyInstance {
522 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
523 const instanceId: string = instancesIds[0];
524 return <ComponentInstance | GroupInstance | PolicyInstance> this.instances.find(instance =>
525 instance.uniqueId == instanceId && (instance instanceof ComponentInstance || instance instanceof GroupInstance || instance instanceof PolicyInstance));
528 private buildCheckedInstanceProperty(): PropertyBEModel {
529 return this.buildCheckedInstanceProperties()[0];
532 private buildCheckedInstanceProperties(): PropertyBEModel[] {
533 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
534 const instanceId: string = instancesIds[0];
535 return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
538 private openToscaGetFunctionModal() {
539 const modalTitle = this.translateService.translate('TOSCA_FUNCTION_MODAL_TITLE');
540 const modalButtons = [];
541 let disableSaveButtonFlag = true;
542 const modal = this.modalService.createCustomModal(new ModalModel(
549 modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
551 const toscaGetFunction: ToscaFunction = modal.instance.dynamicContent.instance.toscaFunctionForm.value;
552 if (toscaGetFunction) {
553 this.updateCheckedInstancePropertyFunctionValue(toscaGetFunction);
555 this.clearCheckedInstancePropertyValue();
557 this.modalService.closeCurrentModal();
559 (): boolean => { return disableSaveButtonFlag }
561 const checkedInstanceProperty = this.buildCheckedInstanceProperty();
562 modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
563 this.modalService.closeCurrentModal();
567 this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
568 'property': checkedInstanceProperty,
569 'componentInstanceMap': this.componentInstanceMap
571 modal.instance.dynamicContent.instance.onValidityChange.subscribe((validationEvent: ToscaFunctionValidationEvent) => {
572 disableSaveButtonFlag = !validationEvent.isValid;
574 modal.instance.open();
577 private clearCheckedInstancePropertyValue() {
578 const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
579 checkedInstanceProperty.getInputValues = null;
580 checkedInstanceProperty.value = null;
581 checkedInstanceProperty.toscaFunction = null;
582 if (this.selectedInstanceData instanceof ComponentInstance) {
583 this.updateInstanceProperty(checkedInstanceProperty);
584 } else if (this.selectedInstanceData instanceof GroupInstance) {
585 this.updateGroupInstanceProperty(checkedInstanceProperty);
586 } else if (this.selectedInstanceData instanceof PolicyInstance) {
587 this.updatePolicyInstanceProperty(checkedInstanceProperty);
591 private updateCheckedInstancePropertyFunctionValue(toscaFunction: ToscaFunction) {
592 const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
593 checkedProperty.toscaFunction = toscaFunction;
594 if (this.selectedInstanceData instanceof ComponentInstance) {
595 this.updateInstanceProperty(checkedProperty);
596 } else if (this.selectedInstanceData instanceof GroupInstance) {
597 this.updateGroupInstanceProperty(checkedProperty);
598 } else if (this.selectedInstanceData instanceof PolicyInstance) {
599 this.updatePolicyInstanceProperty(checkedProperty);
603 updateInstanceProperty(instanceProperty: PropertyBEModel) {
604 this.loadingProperties = true;
605 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
606 this.selectedInstanceData.uniqueId, [instanceProperty])
608 this.changeSelectedInstance(this.getSelectedInstance());
610 this.loadingProperties = false;
611 console.error(error);
613 this.loadingProperties = false;
617 updateGroupInstanceProperty(instanceProperty: PropertyBEModel) {
618 this.loadingProperties = true;
619 this.componentInstanceServiceNg2.updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId,
620 this.selectedInstanceData.uniqueId, [instanceProperty])
622 this.changeSelectedInstance(this.getSelectedInstance());
624 this.loadingProperties = false;
625 console.error(error);
627 this.loadingProperties = false;
631 updatePolicyInstanceProperty(instanceProperty: PropertyBEModel) {
632 this.loadingProperties = true;
633 this.componentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId,
634 this.selectedInstanceData.uniqueId, [instanceProperty])
636 this.changeSelectedInstance(this.getSelectedInstance());
638 this.loadingProperties = false;
639 console.error(error);
641 this.loadingProperties = false;
645 /*** DECLARE PROPERTIES/INPUTS ***/
646 declareProperties = (): void => {
647 console.debug("==>" + this.constructor.name + ": declareProperties");
649 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
650 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
651 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
652 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
653 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
655 angular.forEach(instancesIds, (instanceId: string): void => {
656 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
657 if (selectedInstanceData instanceof ComponentInstance) {
658 if (!this.isInput(selectedInstanceData.originType)) {
659 // convert Property FE model -> Property BE model, extract only checked
660 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
662 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
664 } else if (selectedInstanceData instanceof GroupInstance) {
665 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
666 } else if (selectedInstanceData instanceof PolicyInstance) {
667 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
671 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
673 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
674 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
675 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
677 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
678 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
681 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
682 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
683 prop => !this.isCapabilityProperty(prop)
685 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
686 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
689 let isCapabilityPropertyChanged = false;
691 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
692 (prop: PropertyBEModel) => {
693 prop.name = prop.origName || prop.name;
694 if (this.isCapabilityProperty(prop)) {
695 isCapabilityPropertyChanged = true;
699 this.topologyTemplateService
700 .createInput(this.component, inputsToCreate, this.isSelf())
701 .subscribe((response) => {
702 this.selectInstanceRow(SERVICE_SELF_TITLE);
703 this.onInstanceSelectedUpdate(this.instances[0]);
704 this.setInputTabIndication(response.length);
705 this.checkedPropertiesCount = 0;
706 this.checkedChildPropertiesCount = 0;
707 _.forEach(response, (input: InputBEModel) => {
708 const newInput: InputFEModel = new InputFEModel(input);
709 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
710 this.inputs.push(newInput);
711 this.updatePropertyValueAfterDeclare(newInput);
713 if (isCapabilityPropertyChanged) {
714 this.reloadInstanceCapabilities();
716 }, error => {}); //ignore error
719 declareListProperties = (): void => {
720 // get selected properties
721 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
722 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
723 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
724 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
725 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
726 let propertyNameList: Array<string> = [];
729 angular.forEach(instancesIds, (instanceId: string): void => {
731 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
732 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
734 if (selectedInstanceData instanceof ComponentInstance) {
735 if (!this.isInput(selectedInstanceData.originType)) {
736 // convert Property FE model -> Property BE model, extract only checked
737 selectedComponentInstancesProperties[instanceId] = checkedProperties;
739 selectedComponentInstancesInputs[instanceId] = checkedProperties;
741 } else if (selectedInstanceData instanceof GroupInstance) {
742 selectedGroupInstancesProperties[instanceId] = checkedProperties;
743 } else if (selectedInstanceData instanceof PolicyInstance) {
744 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
747 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
748 propertyNameList.push(property.name);
752 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
754 let modalTitle = 'Declare Properties as List Input';
755 const modal = this.modalService.createCustomModal(new ModalModel(
757 modalTitle, /* title */
762 'blue', /* css class */
763 () => { /* callback */
764 let content:any = modal.instance.dynamicContent.instance;
767 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
768 let typelist: any = PROPERTY_TYPES.LIST;
769 let uniID: any = insId;
770 let boolfalse: any = false;
771 let required: any = content.propertyModel.required;
775 "type": content.propertyModel.simpleType,
779 let schemaProp :any = {
780 "type": content.propertyModel.simpleType,
784 reglistInput.description = content.propertyModel.description;
785 reglistInput.name = content.propertyModel.name;
786 reglistInput.type = typelist;
787 reglistInput.schemaType = content.propertyModel.simpleType;
788 reglistInput.instanceUniqueId = uniID;
789 reglistInput.uniqueId = uniID;
790 reglistInput.required = required;
791 reglistInput.schema = schem;
792 reglistInput.schemaProperty = schemaProp;
795 componentInstInputsMap: content.inputsToCreate,
796 listInput: reglistInput
799 this.topologyTemplateService
800 .createListInput(this.component, input, this.isSelf())
801 .subscribe(response => {
802 this.setInputTabIndication(response.length);
803 this.checkedPropertiesCount = 0;
804 this.checkedChildPropertiesCount = 0;
805 _.forEach(response, (input: InputBEModel) => {
806 let newInput: InputFEModel = new InputFEModel(input);
807 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
808 this.inputs.push(newInput);
809 // create list input does not return updated properties info, so need to reload
810 //this.updatePropertyValueAfterDeclare(newInput);
811 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
812 this.changeSelectedInstance(this.selectedInstanceData);
814 modal.instance.close();
816 }, error => {}); //ignore error
819 /*, getDisabled: function */
821 new ButtonModel('Cancel', 'outline grey', () => {
822 modal.instance.close();
827 // 3rd arg is passed to DeclareListComponent instance
828 this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
829 modal.instance.open();
832 /*** DECLARE PROPERTIES/POLICIES ***/
833 declarePropertiesToPolicies = (): void => {
834 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
835 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
837 angular.forEach(instancesIds, (instanceId: string): void => {
838 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
839 if (selectedInstanceData instanceof ComponentInstance) {
840 if (!this.isInput(selectedInstanceData.originType)) {
841 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
846 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
847 this.loadingPolicies = true;
849 this.topologyTemplateService
850 .createPolicy(this.component, policiesToCreate, this.isSelf())
851 .subscribe(response => {
852 this.setPolicyTabIndication(response.length);
853 this.checkedPropertiesCount = 0;
854 this.displayPoliciesAsDeclared(response);
855 this.loadingPolicies = false;
860 displayPoliciesAsDeclared = (policies) => {
861 _.forEach(policies, (policy: any) => {
862 let newPolicy: InputFEModel = new InputFEModel(policy);
863 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
864 newPolicy.relatedPropertyName = policy.name;
865 newPolicy.relatedPropertyValue = policy.value;
866 this.updatePropertyValueAfterDeclare(newPolicy);
867 this.policies.push(policy);
871 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
872 return new Promise((resolve, reject) => {
873 if (!this.isValidChangedData) {
874 reject('Changed data is invalid - cannot save!');
877 if (!this.changedData.length) {
882 // make request and its handlers
884 let handleSuccess, handleError;
885 let changedInputsProperties = [], changedCapabilitiesProperties = [];
886 if (this.isPropertiesTabSelected) {
887 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
888 changedProp = <PropertyFEModel>changedProp;
889 const propBE = new PropertyBEModel(changedProp);
890 propBE.toscaPresentation = new ToscaPresentationData();
891 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
892 propBE.value = changedProp.getJSONValue();
893 propBE.name = changedProp.origName || changedProp.name;
894 delete propBE.origName;
897 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
899 if (this.selectedInstanceData instanceof ComponentInstance) {
900 if (this.isInput(this.selectedInstanceData.originType)) {
901 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
902 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
903 request = Observable.forkJoin(
904 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
905 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
906 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
909 else if (changedInputsProperties.length) {
910 request = this.componentInstanceServiceNg2
911 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
913 else if (changedCapabilitiesProperties.length) {
914 request = this.componentInstanceServiceNg2
915 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
917 handleSuccess = (response) => {
918 // reset each changed property with new value and remove it from changed properties list
919 response.forEach((resInput) => {
920 const changedProp = <PropertyFEModel>this.changedData.shift();
921 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
926 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
927 delete cp.constraints;
931 request = this.componentInstanceServiceNg2
932 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
934 handleSuccess = (response) => {
935 // reset each changed property with new value and remove it from changed properties list
936 response.forEach((resProp) => {
937 const changedProp = <PropertyFEModel>this.changedData.shift();
938 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
943 } else if (this.selectedInstanceData instanceof GroupInstance) {
944 request = this.componentInstanceServiceNg2
945 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
946 handleSuccess = (response) => {
947 // reset each changed property with new value and remove it from changed properties list
948 response.forEach((resProp) => {
949 const changedProp = <PropertyFEModel>this.changedData.shift();
950 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
954 } else if (this.selectedInstanceData instanceof PolicyInstance) {
955 request = this.componentInstanceServiceNg2
956 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
957 handleSuccess = (response) => {
958 // reset each changed property with new value and remove it from changed properties list
959 response.forEach((resProp) => {
960 const changedProp = <PropertyFEModel>this.changedData.shift();
961 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
966 } else if (this.isInputsTabSelected) {
968 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
969 changedInput = <InputFEModel>changedInput;
970 const inputBE = new InputBEModel(changedInput);
971 inputBE.defaultValue = changedInput.getJSONDefaultValue();
974 request = this.componentServiceNg2
975 .updateComponentInputs(this.component, changedInputs);
976 handleSuccess = (response) => {
977 // reset each changed property with new value and remove it from changed properties list
978 response.forEach((resInput) => {
979 const changedInput = <InputFEModel>this.changedData.shift();
980 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
981 changedInput.required = resInput.required;
982 changedInput.requiredOrig = resInput.required;
987 this.savingChangedData = true;
990 this.savingChangedData = false;
991 if (changedCapabilitiesProperties.length) {
992 this.reloadInstanceCapabilities();
994 handleSuccess && handleSuccess(response);
995 this.updateHasChangedData();
999 this.savingChangedData = false;
1000 handleError && handleError(error);
1001 this.updateHasChangedData();
1008 reloadInstanceCapabilities = (): void => {
1009 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
1010 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
1011 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
1012 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
1013 return instance.capabilities;
1016 }, new CapabilitiesGroup());
1017 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
1021 reverseChangedData = ():void => {
1022 // make reverse item handler
1023 let handleReverseItem;
1024 if (this.isPropertiesTabSelected) {
1025 handleReverseItem = (changedItem) => {
1026 changedItem = <PropertyFEModel>changedItem;
1027 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
1029 } else if (this.isInputsTabSelected) {
1030 handleReverseItem = (changedItem) => {
1031 changedItem = <InputFEModel>changedItem;
1032 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
1033 changedItem.resetMetadata();
1034 changedItem.required = changedItem.requiredOrig;
1038 this.changedData.forEach(handleReverseItem);
1039 this.changedData = [];
1040 this.updateHasChangedData();
1043 updateHasChangedData = ():boolean => {
1044 const curHasChangedData:boolean = (this.changedData.length > 0);
1045 if (curHasChangedData !== this.hasChangedData) {
1046 this.hasChangedData = curHasChangedData;
1047 if(this.hasChangedData) {
1048 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1050 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1053 return this.hasChangedData;
1056 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1057 this.saveChangedData().then(
1059 this.notification.success({
1060 message: 'Successfully saved changes',
1063 if(onSuccessFunction) onSuccessFunction();
1066 this.notification.error({
1067 message: 'Failed to save changes!',
1070 if(onError) onError();
1075 showUnsavedChangesAlert = ():Promise<any> => {
1076 let modalTitle:string;
1077 if (this.isPropertiesTabSelected) {
1078 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1079 } else if (this.isInputsTabSelected) {
1080 modalTitle = `Unsaved inputs for ${this.component.name}`;
1083 return new Promise<any>((resolve, reject) => {
1084 const modal = this.ModalServiceSdcUI.openCustomModal(
1088 type: SdcUiCommon.ModalType.custom,
1089 testId: "navigate-modal",
1092 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1093 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1094 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1095 ] as SdcUiCommon.IModalButtonComponent[]
1096 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1101 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1102 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1103 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1104 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1105 return feProperty.name == input.relatedPropertyName &&
1106 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1108 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1109 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1110 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1111 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1115 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1116 updateCheckedPropertyCount = (increment: boolean): void => {
1117 this.checkedPropertiesCount += (increment) ? 1 : -1;
1118 console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1121 updateCheckedChildPropertyCount = (increment: boolean): void => {
1122 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1125 setInputTabIndication = (numInputs: number): void => {
1126 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1129 setPolicyTabIndication = (numPolicies: number): void => {
1130 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1133 resetUnsavedChangesForInput = (input:InputFEModel) => {
1134 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1135 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1136 this.updateHasChangedData();
1139 deleteInput = (input: InputFEModel) => {
1140 //reset any unsaved changes to the input before deleting it
1141 this.resetUnsavedChangesForInput(input);
1143 console.debug("==>" + this.constructor.name + ": deleteInput");
1144 let inputToDelete = new InputBEModel(input);
1146 this.componentServiceNg2
1147 .deleteInput(this.component, inputToDelete)
1148 .subscribe(response => {
1149 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1151 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1152 this.changeSelectedInstance(this.selectedInstanceData);
1153 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1155 // if (instanceFeProperties) {
1156 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1157 // return prop.name == input.propertyName;
1160 // if (propToEnable) {
1161 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1162 // propToEnable.setNonDeclared(response.inputPath);
1163 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1164 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1167 }, error => {}); //ignore error
1170 deletePolicy = (policy: PolicyInstance) => {
1171 this.loadingPolicies = true;
1172 this.topologyTemplateService
1173 .deletePolicy(this.component, policy)
1174 .subscribe((response) => {
1175 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1176 this.changeSelectedInstance(this.selectedInstanceData);
1177 this.loadingPolicies = false;
1181 deleteProperty = (property: PropertyFEModel) => {
1182 const propertyToDelete = new PropertyFEModel(property);
1183 this.loadingProperties = true;
1184 const feMap = this.instanceFePropertiesMap;
1185 this.topologyTemplateService
1186 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1187 .subscribe((response) => {
1188 const props = feMap[this.component.uniqueId];
1189 props.splice(props.findIndex(p => p.uniqueId === response),1);
1190 this.loadingProperties = false;
1192 this.loadingProperties = false;
1193 console.error(error);
1197 /*** addProperty ***/
1198 addProperty = (model: string) => {
1199 this.loadDataTypesByComponentModel(model)
1200 let modalTitle = 'Add Property';
1201 let modal = this.modalService.createCustomModal(new ModalModel(
1206 new ButtonModel('Save', 'blue', () => {
1207 modal.instance.dynamicContent.instance.isLoading = true;
1208 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1209 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1210 .subscribe((response) => {
1211 modal.instance.dynamicContent.instance.isLoading = false;
1212 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1213 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1214 modal.instance.close();
1216 modal.instance.dynamicContent.instance.isLoading = false;
1217 this.notification.error({
1218 message: 'Failed to add property:' + error,
1222 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1223 new ButtonModel('Cancel', 'outline grey', () => {
1224 modal.instance.close();
1229 modal.instance.open();
1230 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1235 let modalTitle = 'Add Input';
1236 let modal = this.modalService.createCustomModal(new ModalModel(
1241 new ButtonModel('Save', 'blue', () => {
1242 modal.instance.dynamicContent.instance.isLoading = true;
1243 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1244 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1245 .subscribe((response) => {
1246 modal.instance.dynamicContent.instance.isLoading = false;
1247 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1248 this.inputs.push(newInputProp);
1249 modal.instance.close();
1251 modal.instance.dynamicContent.instance.isLoading = false;
1252 this.notification.error({
1253 message: 'Failed to add input:' + error,
1257 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1258 new ButtonModel('Cancel', 'outline grey', () => {
1259 modal.instance.close();
1264 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1265 modal.instance.open();
1268 /*** SEARCH RELATED FUNCTIONS ***/
1269 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1270 let instanceBePropertiesMap:InstanceBePropertiesMap;
1271 this.componentServiceNg2
1272 .filterComponentInstanceProperties(this.component, filterData)
1273 .subscribe((response) => {
1274 this.processInstancePropertiesResponse(response, false);
1275 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1276 this.searchPropertyName = filterData.propertyName;//mark in table
1277 this.hierarchyNavTabs.triggerTabChange('Composition');
1278 this.propertiesNavigationData = [];
1279 this.displayClearSearch = true;
1280 }, (error) => {}); //ignore error
1284 clearSearch = () => {
1285 this.instancesNavigationData = this.instances;
1286 this.searchPropertyName = "";
1287 this.hierarchyPropertiesDisplayOptions.searchText = "";
1288 this.displayClearSearch = false;
1289 this.advanceSearch.clearAll();
1290 this.searchQuery = '';
1293 clickOnClearSearch = () => {
1295 this.selectFirstInstanceByDefault();
1296 this.hierarchyNavTabs.triggerTabChange('Composition');
1299 private isInput = (instanceType:string):boolean =>{
1300 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1303 loadDataTypesByComponentModel(model:string) {
1304 this.propertyCreatorComponent.filterDataTypesByModel(model);