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} 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 {ToscaGetFunctionDtoBuilder} from '../../../models/tosca-get-function-dto';
70 import {ToscaGetFunction} from "../../../models/tosca-get-function";
72 const SERVICE_SELF_TITLE = "SELF";
74 templateUrl: './properties-assignment.page.component.html',
75 styleUrls: ['./properties-assignment.page.component.less']
77 export class PropertiesAssignmentComponent {
78 title = "Properties & Inputs";
80 component: ComponentData;
81 componentInstanceNamesMap: { [key: string]: InstanceFeDetails } = {}; //key is the instance uniqueId
82 componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); //key is the instance uniqueId
84 propertiesNavigationData = [];
85 instancesNavigationData = [];
87 instanceFePropertiesMap: InstanceFePropertiesMap;
88 inputs: Array<InputFEModel> = [];
89 policies: Array<PolicyInstance> = [];
90 instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
92 propertyStructureHeader: string;
94 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
95 selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
96 checkedPropertiesCount: number = 0;
97 checkedChildPropertiesCount: number = 0;
99 hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
100 hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
101 displayClearSearch = false;
102 searchPropertyName: string;
104 isInputsTabSelected: boolean;
105 isPropertiesTabSelected: boolean;
106 isPoliciesTabSelected: boolean;
108 resourceIsReadonly: boolean;
109 loadingInstances: boolean = false;
110 loadingInputs: boolean = false;
111 loadingPolicies: boolean = false;
112 loadingProperties: boolean = false;
113 changedData: Array<PropertyFEModel | InputFEModel>;
114 hasChangedData: boolean;
115 isValidChangedData: boolean;
116 savingChangedData: boolean;
117 stateChangeStartUnregister: Function;
118 serviceBePropertiesMap: InstanceBePropertiesMap;
119 serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
120 selectedInstance_FlattenCapabilitiesList: Capability[];
121 btnToscaFunctionText: 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 private propertyCreatorComponent: PropertyCreatorComponent,
134 @Inject("$stateParams") _stateParams,
135 @Inject("$scope") private $scope: ng.IScope,
136 @Inject("$state") private $state: ng.ui.IStateService,
137 @Inject("Notification") private notification: any,
138 private componentModeService: ComponentModeService,
139 private eventListenerService: EventListenerService,
140 private ModalServiceSdcUI: SdcUiServices.ModalService,
141 private modalService: ModalService,
142 private keysPipe: KeysPipe,
143 private topologyTemplateService: TopologyTemplateService,
144 private translateService: TranslateService) {
146 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
147 /* 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
148 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
149 this.component = _stateParams.component;
150 this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
151 this.updateViewMode();
152 this.changedData = [];
153 this.updateHasChangedData();
154 this.isValidChangedData = true;
158 console.debug("==>" + this.constructor.name + ": ngOnInit");
159 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
160 this.loadingInputs = true;
161 this.loadingPolicies = true;
162 this.loadingInstances = true;
163 this.loadingProperties = true;
164 this.topologyTemplateService
165 .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
166 .subscribe(response => {
167 _.forEach(response.inputs, (input: InputBEModel) => {
168 const newInput: InputFEModel = new InputFEModel(input);
169 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
170 this.inputs.push(newInput); //only push items that were declared via SDC
172 this.loadingInputs = false;
176 this.componentServiceNg2
177 .getComponentResourcePropertiesData(this.component)
178 .subscribe(response => {
179 this.loadingPolicies = false;
181 this.instances.push(...response.componentInstances);
182 this.instances.push(...response.groupInstances);
183 this.instances.push(...response.policies);
185 if (response.componentInstances) {
186 response.componentInstances.forEach(instance => {
187 this.componentInstanceMap.set(instance.uniqueId, <InstanceFeDetails>{
189 iconClass: instance.iconClass,
190 originArchived: instance.originArchived
195 _.forEach(response.policies, (policy: any) => {
196 const newPolicy: InputFEModel = new InputFEModel(policy);
197 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
198 this.policies.push(policy);
201 // add the service self instance to the top of the list.
202 const serviceInstance = new ComponentInstance();
203 serviceInstance.name = SERVICE_SELF_TITLE;
204 serviceInstance.uniqueId = this.component.uniqueId;
205 this.instances.unshift(serviceInstance);
207 _.forEach(this.instances, (instance) => {
208 this.instancesNavigationData.push(instance);
209 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
211 iconClass: instance.iconClass,
212 originArchived: instance.originArchived
215 this.loadingInstances = false;
216 if (this.instancesNavigationData[0] == undefined) {
217 this.loadingProperties = false;
219 this.selectFirstInstanceByDefault();
221 this.loadingInstances = false;
224 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
225 // stop if has changed properties
226 if (this.hasChangedData) {
227 event.preventDefault();
228 this.showUnsavedChangesAlert().then(() => {
229 this.$state.go(toState, toParams);
235 this.loadDataTypesByComponentModel(this.component.model);
239 this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
240 this.stateChangeStartUnregister();
243 selectFirstInstanceByDefault = () => {
244 if (this.instancesNavigationData[0] !== undefined) {
245 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
249 updateViewMode = () => {
250 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
253 onCheckout = (component: ComponentData) => {
254 this.component = component;
255 this.updateViewMode();
258 isSelf = (): boolean => {
259 return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
262 showAddProperties = (): boolean => {
263 if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
266 return this.isSelf();
269 getServiceProperties() {
270 this.loadingProperties = true;
271 this.topologyTemplateService
272 .getServiceProperties(this.component.uniqueId)
273 .subscribe((response) => {
274 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
275 this.serviceBePropertiesMap[this.component.uniqueId] = response;
276 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
277 this.loadingProperties = false;
279 this.loadingProperties = false;
283 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
284 // stop if has changed properties
285 if (this.hasChangedData) {
286 this.showUnsavedChangesAlert().then((resolve) => {
287 this.changeSelectedInstance(instance)
292 this.changeSelectedInstance(instance);
295 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
296 this.selectedInstanceData = instance;
297 this.loadingProperties = true;
298 if (instance instanceof ComponentInstance) {
299 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
300 if (this.isInput(instance.originType)) {
301 this.componentInstanceServiceNg2
302 .getComponentInstanceInputs(this.component, instance)
303 .subscribe(response => {
304 instanceBePropertiesMap[instance.uniqueId] = response;
305 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
309 this.loadingProperties = false;
311 } else if (this.isSelf()) {
312 this.getServiceProperties();
314 this.componentInstanceServiceNg2
315 .getComponentInstanceProperties(this.component, instance.uniqueId)
316 .subscribe(response => {
317 instanceBePropertiesMap[instance.uniqueId] = response;
318 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
322 this.loadingProperties = false;
325 this.loadingProperties = false;
326 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
327 } else if (instance instanceof GroupInstance) {
328 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
329 this.componentInstanceServiceNg2
330 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
331 .subscribe((response) => {
332 instanceBePropertiesMap[instance.uniqueId] = response;
333 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
337 this.loadingProperties = false;
339 } else if (instance instanceof PolicyInstance) {
340 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
341 this.componentInstanceServiceNg2
342 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
343 .subscribe((response) => {
344 instanceBePropertiesMap[instance.uniqueId] = response;
345 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
349 this.loadingProperties = false;
352 this.loadingProperties = false;
355 if (this.searchPropertyName) {
358 //clear selected property from the navigation
359 this.selectedFlatProperty = new SimpleFlatProperty();
360 this.propertiesNavigationData = [];
364 * Entry point handling response from server
366 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
367 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
368 this.checkedPropertiesCount = 0;
369 this.checkedChildPropertiesCount = 0;
372 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
373 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
374 let currentUniqueId = this.selectedInstanceData.uniqueId;
375 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
376 let isCapabilityOwnedByInstance: boolean;
377 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
378 this.selectedInstance_FlattenCapabilitiesList,
379 (result, cap: Capability) => {
380 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
381 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
382 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
383 if (cap.properties && isCapabilityOwnedByInstance) {
384 _.forEach(cap.properties, prop => {
385 if (!prop.origName) {
386 prop.origName = prop.name;
387 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
390 return result.concat(cap.properties);
394 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
395 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
396 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
397 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
399 //concatenate capabilitiesProps to all props list
400 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
401 this.checkedPropertiesCount = 0;
404 isCapabilityProperty = (prop: PropertyBEModel) => {
405 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
408 /*** VALUE CHANGE EVENTS ***/
409 dataChanged = (item: PropertyFEModel | InputFEModel) => {
411 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
412 itemHasChanged = item.hasValueObjChanged();
413 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
414 itemHasChanged = item.hasChanged();
415 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
416 itemHasChanged = item.hasDefaultValueChanged();
419 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
420 if (itemHasChanged) {
421 if (dataChangedIdx === -1) {
422 this.changedData.push(item);
425 if (dataChangedIdx !== -1) {
426 this.changedData.splice(dataChangedIdx, 1);
430 if (this.isPropertiesTabSelected) {
431 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
432 } else if (this.isInputsTabSelected) {
433 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
434 } else if (this.isPoliciesTabSelected) {
435 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
437 this.updateHasChangedData();
441 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
444 * Handle select node in navigation area, and select the row in table
446 onPropertySelectedUpdate = ($event) => {
447 console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
448 this.selectedFlatProperty = $event;
449 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
450 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
454 * When user select row in table, this will prepare the hirarchy object for the tree.
456 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
457 console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
458 let property = propertyRowSelectedEvent.propertyModel;
459 let instanceName = propertyRowSelectedEvent.instanceName;
460 this.propertyStructureHeader = null;
462 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
463 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
464 let simpleFlatProperty: Array<SimpleFlatProperty>;
465 if (property instanceof PropertyFEModel) {
466 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
467 } else if (property instanceof DerivedFEProperty) {
468 // Need to find parent PropertyFEModel
469 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
470 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
472 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
474 this.propertiesNavigationData = simpleFlatProperty;
477 // Update the header in the navigation tree with property name.
478 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
480 // Set selected property in table
481 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
482 this.hierarchyNavTabs.triggerTabChange('Property Structure');
486 selectInstanceRow = ($event) => {//get instance name
487 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
488 return instance.name == $event;
490 this.hierarchyNavTabs.triggerTabChange('Composition');
493 tabChanged = (event) => {
494 // stop if has changed properties
495 if (this.hasChangedData) {
496 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
497 this.showUnsavedChangesAlert().then((proceed) => {
498 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
504 console.debug("==>" + this.constructor.name + ": tabChanged " + event);
505 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
506 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
507 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
508 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
509 this.propertyStructureHeader = null;
510 this.searchQuery = '';
514 * Select Tosca function value from defined values
516 selectToscaFunctionAndValues = (): void => {
517 const selectedInstanceData: ComponentInstance = this.getSelectedComponentInstance();
518 if (!selectedInstanceData) {
521 const property: PropertyBEModel = this.buildCheckedInstanceProperty();
522 if (property.isToscaGetFunction()) {
523 this.clearCheckedInstancePropertyValue();
526 this.openToscaGetFunctionModal();
529 private getSelectedComponentInstance(): ComponentInstance {
530 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
531 const instanceId: string = instancesIds[0];
532 return <ComponentInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance);
535 private buildCheckedInstanceProperty(): PropertyBEModel {
536 return this.buildCheckedInstanceProperties()[0];
539 private buildCheckedInstanceProperties(): PropertyBEModel[] {
540 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
541 const instanceId: string = instancesIds[0];
542 return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
545 private openToscaGetFunctionModal() {
546 const modalTitle = 'Set value using TOSCA functions';
547 const modal = this.modalService.createCustomModal(new ModalModel(
552 new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
554 const toscaGetFunction: ToscaGetFunction = modal.instance.dynamicContent.instance.toscaGetFunction;
555 this.updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction);
556 modal.instance.close();
559 new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
560 modal.instance.close();
565 const checkedInstanceProperty = this.buildCheckedInstanceProperty();
566 this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
567 'property': checkedInstanceProperty,
568 'componentInstanceMap': this.componentInstanceMap
570 modal.instance.open();
573 private clearCheckedInstancePropertyValue() {
574 const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
575 checkedInstanceProperty.getInputValues = null;
576 checkedInstanceProperty.value = null;
577 checkedInstanceProperty.toscaGetFunction = null;
578 this.updateInstanceProperty(checkedInstanceProperty);
581 private updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction: ToscaGetFunction) {
582 const toscaGetFunctionBuilder: ToscaGetFunctionDtoBuilder =
583 new ToscaGetFunctionDtoBuilder()
584 .withPropertyUniqueId(toscaGetFunction.propertyUniqueId)
585 .withFunctionType(toscaGetFunction.functionType)
586 .withPropertySource(toscaGetFunction.propertySource)
587 .withPropertyName(toscaGetFunction.propertyName)
588 .withSourceName(toscaGetFunction.sourceName)
589 .withSourceUniqueId(toscaGetFunction.sourceUniqueId)
590 .withPropertyPathFromSource(toscaGetFunction.propertyPathFromSource);
592 const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
593 checkedProperty.toscaGetFunction = toscaGetFunctionBuilder.build();
594 this.updateInstanceProperty(checkedProperty);
597 updateInstanceProperty(instanceProperty: PropertyBEModel) {
598 this.loadingProperties = true;
599 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
600 this.selectedInstanceData.uniqueId, [instanceProperty])
602 this.changeSelectedInstance(this.getSelectedComponentInstance());
605 this.translateService.translate('TOSCA_FUNCTION_SELECT_ERROR', {'propertyName': instanceProperty.name, 'error': error});
606 this.notification.error({
607 title: this.translateService.translate('FAILURE_LABEL'),
610 console.error(errorMsg, error);
612 this.loadingProperties = false;
613 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
617 selectInputBtnLabel = () => {
618 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
619 angular.forEach(instancesIds, (instanceId: string): void => {
620 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
621 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
622 if(this.checkedPropertiesCount == 1) {
623 if (property.isToscaGetFunction()) {
624 this.btnToscaFunctionText = this.translateService.translate('CLEAR_VALUE_LABEL');
626 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
629 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
635 /*** DECLARE PROPERTIES/INPUTS ***/
636 declareProperties = (): void => {
637 console.debug("==>" + this.constructor.name + ": declareProperties");
639 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
640 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
641 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
642 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
643 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
645 angular.forEach(instancesIds, (instanceId: string): void => {
646 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
647 if (selectedInstanceData instanceof ComponentInstance) {
648 if (!this.isInput(selectedInstanceData.originType)) {
649 // convert Property FE model -> Property BE model, extract only checked
650 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
652 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
654 } else if (selectedInstanceData instanceof GroupInstance) {
655 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
656 } else if (selectedInstanceData instanceof PolicyInstance) {
657 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
661 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
663 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
664 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
665 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
667 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
668 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
671 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
672 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
673 prop => !this.isCapabilityProperty(prop)
675 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
676 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
679 let isCapabilityPropertyChanged = false;
681 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
682 (prop: PropertyBEModel) => {
683 prop.name = prop.origName || prop.name;
684 if (this.isCapabilityProperty(prop)) {
685 isCapabilityPropertyChanged = true;
689 this.topologyTemplateService
690 .createInput(this.component, inputsToCreate, this.isSelf())
691 .subscribe((response) => {
692 this.selectInstanceRow(SERVICE_SELF_TITLE);
693 this.onInstanceSelectedUpdate(this.instances[0]);
694 this.setInputTabIndication(response.length);
695 this.checkedPropertiesCount = 0;
696 this.checkedChildPropertiesCount = 0;
697 _.forEach(response, (input: InputBEModel) => {
698 const newInput: InputFEModel = new InputFEModel(input);
699 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
700 this.inputs.push(newInput);
701 this.updatePropertyValueAfterDeclare(newInput);
703 if (isCapabilityPropertyChanged) {
704 this.reloadInstanceCapabilities();
706 }, error => {}); //ignore error
709 declareListProperties = (): void => {
710 // get selected properties
711 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
712 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
713 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
714 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
715 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
716 let propertyNameList: Array<string> = [];
719 angular.forEach(instancesIds, (instanceId: string): void => {
721 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
722 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
724 if (selectedInstanceData instanceof ComponentInstance) {
725 if (!this.isInput(selectedInstanceData.originType)) {
726 // convert Property FE model -> Property BE model, extract only checked
727 selectedComponentInstancesProperties[instanceId] = checkedProperties;
729 selectedComponentInstancesInputs[instanceId] = checkedProperties;
731 } else if (selectedInstanceData instanceof GroupInstance) {
732 selectedGroupInstancesProperties[instanceId] = checkedProperties;
733 } else if (selectedInstanceData instanceof PolicyInstance) {
734 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
737 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
738 propertyNameList.push(property.name);
742 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
744 let modalTitle = 'Declare Properties as List Input';
745 const modal = this.modalService.createCustomModal(new ModalModel(
747 modalTitle, /* title */
752 'blue', /* css class */
753 () => { /* callback */
754 let content:any = modal.instance.dynamicContent.instance;
757 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
758 let typelist: any = PROPERTY_TYPES.LIST;
759 let uniID: any = insId;
760 let boolfalse: any = false;
761 let required: any = content.propertyModel.required;
765 "type": content.propertyModel.simpleType,
769 let schemaProp :any = {
770 "type": content.propertyModel.simpleType,
774 reglistInput.description = content.propertyModel.description;
775 reglistInput.name = content.propertyModel.name;
776 reglistInput.type = typelist;
777 reglistInput.schemaType = content.propertyModel.simpleType;
778 reglistInput.instanceUniqueId = uniID;
779 reglistInput.uniqueId = uniID;
780 reglistInput.required = required;
781 reglistInput.schema = schem;
782 reglistInput.schemaProperty = schemaProp;
785 componentInstInputsMap: content.inputsToCreate,
786 listInput: reglistInput
789 this.topologyTemplateService
790 .createListInput(this.component, input, this.isSelf())
791 .subscribe(response => {
792 this.setInputTabIndication(response.length);
793 this.checkedPropertiesCount = 0;
794 this.checkedChildPropertiesCount = 0;
795 _.forEach(response, (input: InputBEModel) => {
796 let newInput: InputFEModel = new InputFEModel(input);
797 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
798 this.inputs.push(newInput);
799 // create list input does not return updated properties info, so need to reload
800 //this.updatePropertyValueAfterDeclare(newInput);
801 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
802 this.changeSelectedInstance(this.selectedInstanceData);
804 modal.instance.close();
806 }, error => {}); //ignore error
809 /*, getDisabled: function */
811 new ButtonModel('Cancel', 'outline grey', () => {
812 modal.instance.close();
817 // 3rd arg is passed to DeclareListComponent instance
818 this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
819 modal.instance.open();
822 /*** DECLARE PROPERTIES/POLICIES ***/
823 declarePropertiesToPolicies = (): void => {
824 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
825 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
827 angular.forEach(instancesIds, (instanceId: string): void => {
828 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
829 if (selectedInstanceData instanceof ComponentInstance) {
830 if (!this.isInput(selectedInstanceData.originType)) {
831 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
836 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
837 this.loadingPolicies = true;
839 this.topologyTemplateService
840 .createPolicy(this.component, policiesToCreate, this.isSelf())
841 .subscribe(response => {
842 this.setPolicyTabIndication(response.length);
843 this.checkedPropertiesCount = 0;
844 this.displayPoliciesAsDeclared(response);
845 this.loadingPolicies = false;
850 displayPoliciesAsDeclared = (policies) => {
851 _.forEach(policies, (policy: any) => {
852 let newPolicy: InputFEModel = new InputFEModel(policy);
853 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
854 newPolicy.relatedPropertyName = policy.name;
855 newPolicy.relatedPropertyValue = policy.value;
856 this.updatePropertyValueAfterDeclare(newPolicy);
857 this.policies.push(policy);
861 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
862 return new Promise((resolve, reject) => {
863 if (!this.isValidChangedData) {
864 reject('Changed data is invalid - cannot save!');
867 if (!this.changedData.length) {
872 // make request and its handlers
874 let handleSuccess, handleError;
875 let changedInputsProperties = [], changedCapabilitiesProperties = [];
876 if (this.isPropertiesTabSelected) {
877 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
878 changedProp = <PropertyFEModel>changedProp;
879 const propBE = new PropertyBEModel(changedProp);
880 propBE.toscaPresentation = new ToscaPresentationData();
881 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
882 propBE.value = changedProp.getJSONValue();
883 propBE.name = changedProp.origName || changedProp.name;
884 delete propBE.origName;
887 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
889 if (this.selectedInstanceData instanceof ComponentInstance) {
890 if (this.isInput(this.selectedInstanceData.originType)) {
891 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
892 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
893 request = Observable.forkJoin(
894 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
895 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
896 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
899 else if (changedInputsProperties.length) {
900 request = this.componentInstanceServiceNg2
901 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
903 else if (changedCapabilitiesProperties.length) {
904 request = this.componentInstanceServiceNg2
905 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
907 handleSuccess = (response) => {
908 // reset each changed property with new value and remove it from changed properties list
909 response.forEach((resInput) => {
910 const changedProp = <PropertyFEModel>this.changedData.shift();
911 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
916 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
917 delete cp.constraints;
921 request = this.componentInstanceServiceNg2
922 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
924 handleSuccess = (response) => {
925 // reset each changed property with new value and remove it from changed properties list
926 response.forEach((resProp) => {
927 const changedProp = <PropertyFEModel>this.changedData.shift();
928 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
933 } else if (this.selectedInstanceData instanceof GroupInstance) {
934 request = this.componentInstanceServiceNg2
935 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
936 handleSuccess = (response) => {
937 // reset each changed property with new value and remove it from changed properties list
938 response.forEach((resProp) => {
939 const changedProp = <PropertyFEModel>this.changedData.shift();
940 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
944 } else if (this.selectedInstanceData instanceof PolicyInstance) {
945 request = this.componentInstanceServiceNg2
946 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
947 handleSuccess = (response) => {
948 // reset each changed property with new value and remove it from changed properties list
949 response.forEach((resProp) => {
950 const changedProp = <PropertyFEModel>this.changedData.shift();
951 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
956 } else if (this.isInputsTabSelected) {
958 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
959 changedInput = <InputFEModel>changedInput;
960 const inputBE = new InputBEModel(changedInput);
961 inputBE.defaultValue = changedInput.getJSONDefaultValue();
964 request = this.componentServiceNg2
965 .updateComponentInputs(this.component, changedInputs);
966 handleSuccess = (response) => {
967 // reset each changed property with new value and remove it from changed properties list
968 response.forEach((resInput) => {
969 const changedInput = <InputFEModel>this.changedData.shift();
970 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
971 changedInput.required = resInput.required;
972 changedInput.requiredOrig = resInput.required;
977 this.savingChangedData = true;
980 this.savingChangedData = false;
981 if (changedCapabilitiesProperties.length) {
982 this.reloadInstanceCapabilities();
984 handleSuccess && handleSuccess(response);
985 this.updateHasChangedData();
989 this.savingChangedData = false;
990 handleError && handleError(error);
991 this.updateHasChangedData();
998 reloadInstanceCapabilities = (): void => {
999 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
1000 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
1001 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
1002 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
1003 return instance.capabilities;
1006 }, new CapabilitiesGroup());
1007 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
1011 reverseChangedData = ():void => {
1012 // make reverse item handler
1013 let handleReverseItem;
1014 if (this.isPropertiesTabSelected) {
1015 handleReverseItem = (changedItem) => {
1016 changedItem = <PropertyFEModel>changedItem;
1017 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
1019 } else if (this.isInputsTabSelected) {
1020 handleReverseItem = (changedItem) => {
1021 changedItem = <InputFEModel>changedItem;
1022 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
1023 changedItem.resetMetadata();
1024 changedItem.required = changedItem.requiredOrig;
1028 this.changedData.forEach(handleReverseItem);
1029 this.changedData = [];
1030 this.updateHasChangedData();
1033 updateHasChangedData = ():boolean => {
1034 const curHasChangedData:boolean = (this.changedData.length > 0);
1035 if (curHasChangedData !== this.hasChangedData) {
1036 this.hasChangedData = curHasChangedData;
1037 if(this.hasChangedData) {
1038 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1040 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1043 return this.hasChangedData;
1046 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1047 this.saveChangedData().then(
1049 this.notification.success({
1050 message: 'Successfully saved changes',
1053 if(onSuccessFunction) onSuccessFunction();
1056 this.notification.error({
1057 message: 'Failed to save changes!',
1060 if(onError) onError();
1065 showUnsavedChangesAlert = ():Promise<any> => {
1066 let modalTitle:string;
1067 if (this.isPropertiesTabSelected) {
1068 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1069 } else if (this.isInputsTabSelected) {
1070 modalTitle = `Unsaved inputs for ${this.component.name}`;
1073 return new Promise<any>((resolve, reject) => {
1074 const modal = this.ModalServiceSdcUI.openCustomModal(
1078 type: SdcUiCommon.ModalType.custom,
1079 testId: "navigate-modal",
1082 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1083 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1084 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1085 ] as SdcUiCommon.IModalButtonComponent[]
1086 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1091 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1092 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1093 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1094 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1095 return feProperty.name == input.relatedPropertyName &&
1096 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1098 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1099 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1100 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1101 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1105 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1106 updateCheckedPropertyCount = (increment: boolean): void => {
1107 this.checkedPropertiesCount += (increment) ? 1 : -1;
1108 console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1109 this.selectInputBtnLabel();
1112 updateCheckedChildPropertyCount = (increment: boolean): void => {
1113 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1116 setInputTabIndication = (numInputs: number): void => {
1117 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1120 setPolicyTabIndication = (numPolicies: number): void => {
1121 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1124 resetUnsavedChangesForInput = (input:InputFEModel) => {
1125 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1126 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1127 this.updateHasChangedData();
1130 deleteInput = (input: InputFEModel) => {
1131 //reset any unsaved changes to the input before deleting it
1132 this.resetUnsavedChangesForInput(input);
1134 console.debug("==>" + this.constructor.name + ": deleteInput");
1135 let inputToDelete = new InputBEModel(input);
1137 this.componentServiceNg2
1138 .deleteInput(this.component, inputToDelete)
1139 .subscribe(response => {
1140 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1142 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1143 this.changeSelectedInstance(this.selectedInstanceData);
1144 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1146 // if (instanceFeProperties) {
1147 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1148 // return prop.name == input.propertyName;
1151 // if (propToEnable) {
1152 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1153 // propToEnable.setNonDeclared(response.inputPath);
1154 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1155 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1158 }, error => {}); //ignore error
1161 deletePolicy = (policy: PolicyInstance) => {
1162 this.loadingPolicies = true;
1163 this.topologyTemplateService
1164 .deletePolicy(this.component, policy)
1165 .subscribe((response) => {
1166 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1167 this.changeSelectedInstance(this.selectedInstanceData);
1168 this.loadingPolicies = false;
1172 deleteProperty = (property: PropertyFEModel) => {
1173 const propertyToDelete = new PropertyFEModel(property);
1174 this.loadingProperties = true;
1175 const feMap = this.instanceFePropertiesMap;
1176 this.topologyTemplateService
1177 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1178 .subscribe((response) => {
1179 const props = feMap[this.component.uniqueId];
1180 props.splice(props.findIndex(p => p.uniqueId === response),1);
1181 this.loadingProperties = false;
1183 this.loadingProperties = false;
1184 console.error(error);
1188 /*** addProperty ***/
1189 addProperty = (model: string) => {
1190 this.loadDataTypesByComponentModel(model)
1191 let modalTitle = 'Add Property';
1192 let modal = this.modalService.createCustomModal(new ModalModel(
1197 new ButtonModel('Save', 'blue', () => {
1198 modal.instance.dynamicContent.instance.isLoading = true;
1199 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1200 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1201 .subscribe((response) => {
1202 modal.instance.dynamicContent.instance.isLoading = false;
1203 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1204 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1205 modal.instance.close();
1207 modal.instance.dynamicContent.instance.isLoading = false;
1208 this.notification.error({
1209 message: 'Failed to add property:' + error,
1213 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1214 new ButtonModel('Cancel', 'outline grey', () => {
1215 modal.instance.close();
1220 modal.instance.open();
1221 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1226 let modalTitle = 'Add Input';
1227 let modal = this.modalService.createCustomModal(new ModalModel(
1232 new ButtonModel('Save', 'blue', () => {
1233 modal.instance.dynamicContent.instance.isLoading = true;
1234 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1235 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1236 .subscribe((response) => {
1237 modal.instance.dynamicContent.instance.isLoading = false;
1238 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1239 this.inputs.push(newInputProp);
1240 modal.instance.close();
1242 modal.instance.dynamicContent.instance.isLoading = false;
1243 this.notification.error({
1244 message: 'Failed to add input:' + error,
1248 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1249 new ButtonModel('Cancel', 'outline grey', () => {
1250 modal.instance.close();
1255 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1256 modal.instance.open();
1259 /*** SEARCH RELATED FUNCTIONS ***/
1260 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1261 let instanceBePropertiesMap:InstanceBePropertiesMap;
1262 this.componentServiceNg2
1263 .filterComponentInstanceProperties(this.component, filterData)
1264 .subscribe((response) => {
1265 this.processInstancePropertiesResponse(response, false);
1266 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1267 this.searchPropertyName = filterData.propertyName;//mark in table
1268 this.hierarchyNavTabs.triggerTabChange('Composition');
1269 this.propertiesNavigationData = [];
1270 this.displayClearSearch = true;
1271 }, (error) => {}); //ignore error
1275 clearSearch = () => {
1276 this.instancesNavigationData = this.instances;
1277 this.searchPropertyName = "";
1278 this.hierarchyPropertiesDisplayOptions.searchText = "";
1279 this.displayClearSearch = false;
1280 this.advanceSearch.clearAll();
1281 this.searchQuery = '';
1284 clickOnClearSearch = () => {
1286 this.selectFirstInstanceByDefault();
1287 this.hierarchyNavTabs.triggerTabChange('Composition');
1290 private isInput = (instanceType:string):boolean =>{
1291 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1294 loadDataTypesByComponentModel(model:string) {
1295 this.propertyCreatorComponent.filterDataTypesByModel(model);