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 {PropertyDropdownValue, 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 {ToscaGetFunctionType} from "../../../models/tosca-get-function-type";
69 import {TranslateService} from "../../shared/translator/translate.service";
70 import {ToscaGetFunctionDtoBuilder} from '../../../models/tosca-get-function-dto';
71 import {PropertySource} from '../../../models/property-source';
72 import {ToscaGetFunctionTypeConverter} from '../../../models/tosca-get-function-type-converter';
74 const SERVICE_SELF_TITLE = "SELF";
76 templateUrl: './properties-assignment.page.component.html',
77 styleUrls: ['./properties-assignment.page.component.less']
79 export class PropertiesAssignmentComponent {
80 title = "Properties & Inputs";
82 component: ComponentData;
83 componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
85 propertiesNavigationData = [];
86 instancesNavigationData = [];
88 instanceFePropertiesMap: InstanceFePropertiesMap;
89 inputs: Array<InputFEModel> = [];
90 policies: Array<PolicyInstance> = [];
91 instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
93 propertyStructureHeader: string;
95 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
96 selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
97 checkedPropertiesCount: number = 0;
98 checkedChildPropertiesCount: number = 0;
100 hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
101 hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
102 displayClearSearch = false;
103 searchPropertyName: string;
105 isInputsTabSelected: boolean;
106 isPropertiesTabSelected: boolean;
107 isPoliciesTabSelected: boolean;
109 resourceIsReadonly: boolean;
110 loadingInstances: boolean = false;
111 loadingInputs: boolean = false;
112 loadingPolicies: boolean = false;
113 loadingProperties: boolean = false;
114 changedData: Array<PropertyFEModel | InputFEModel>;
115 hasChangedData: boolean;
116 isValidChangedData: boolean;
117 savingChangedData: boolean;
118 stateChangeStartUnregister: Function;
119 serviceBePropertiesMap: InstanceBePropertiesMap;
120 serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
121 selectedInstance_FlattenCapabilitiesList: Capability[];
122 btnToscaFunctionText: string;
124 @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
125 @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
126 @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
128 constructor(private propertiesService: PropertiesService,
129 private hierarchyNavService: HierarchyNavService,
130 private propertiesUtils: PropertiesUtils,
131 private inputsUtils: InputsUtils,
132 private componentServiceNg2: ComponentServiceNg2,
133 private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
134 private propertyCreatorComponent: PropertyCreatorComponent,
135 @Inject("$stateParams") _stateParams,
136 @Inject("$scope") private $scope: ng.IScope,
137 @Inject("$state") private $state: ng.ui.IStateService,
138 @Inject("Notification") private notification: any,
139 private componentModeService: ComponentModeService,
140 private eventListenerService: EventListenerService,
141 private ModalServiceSdcUI: SdcUiServices.ModalService,
142 private modalService: ModalService,
143 private keysPipe: KeysPipe,
144 private topologyTemplateService: TopologyTemplateService,
145 private translateService: TranslateService) {
147 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
148 /* 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
149 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
150 this.component = _stateParams.component;
151 this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
152 this.updateViewMode();
153 this.changedData = [];
154 this.updateHasChangedData();
155 this.isValidChangedData = true;
159 console.debug("==>" + this.constructor.name + ": ngOnInit");
160 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
161 this.loadingInputs = true;
162 this.loadingPolicies = true;
163 this.loadingInstances = true;
164 this.loadingProperties = true;
165 this.topologyTemplateService
166 .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
167 .subscribe(response => {
168 _.forEach(response.inputs, (input: InputBEModel) => {
169 const newInput: InputFEModel = new InputFEModel(input);
170 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
171 this.inputs.push(newInput); //only push items that were declared via SDC
173 this.loadingInputs = false;
177 this.componentServiceNg2
178 .getComponentResourcePropertiesData(this.component)
179 .subscribe(response => {
180 this.loadingPolicies = false;
182 this.instances.push(...response.componentInstances);
183 this.instances.push(...response.groupInstances);
184 this.instances.push(...response.policies);
186 _.forEach(response.policies, (policy: any) => {
187 const newPolicy: InputFEModel = new InputFEModel(policy);
188 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
189 this.policies.push(policy);
192 // add the service self instance to the top of the list.
193 const serviceInstance = new ComponentInstance();
194 serviceInstance.name = SERVICE_SELF_TITLE;
195 serviceInstance.uniqueId = this.component.uniqueId;
196 this.instances.unshift(serviceInstance);
198 _.forEach(this.instances, (instance) => {
199 this.instancesNavigationData.push(instance);
200 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
202 iconClass: instance.iconClass,
203 originArchived: instance.originArchived
206 this.loadingInstances = false;
207 if (this.instancesNavigationData[0] == undefined) {
208 this.loadingProperties = false;
210 this.selectFirstInstanceByDefault();
212 this.loadingInstances = false;
215 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
216 // stop if has changed properties
217 if (this.hasChangedData) {
218 event.preventDefault();
219 this.showUnsavedChangesAlert().then(() => {
220 this.$state.go(toState, toParams);
226 this.loadDataTypesByComponentModel(this.component.model);
230 this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
231 this.stateChangeStartUnregister();
234 selectFirstInstanceByDefault = () => {
235 if (this.instancesNavigationData[0] !== undefined) {
236 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
240 updateViewMode = () => {
241 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
244 onCheckout = (component: ComponentData) => {
245 this.component = component;
246 this.updateViewMode();
249 isSelf = (): boolean => {
250 return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
253 showAddProperties = (): boolean => {
254 if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
257 return this.isSelf();
260 getServiceProperties() {
261 this.loadingProperties = true;
262 this.topologyTemplateService
263 .getServiceProperties(this.component.uniqueId)
264 .subscribe((response) => {
265 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
266 this.serviceBePropertiesMap[this.component.uniqueId] = response;
267 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
268 this.loadingProperties = false;
270 this.loadingProperties = false;
274 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
275 // stop if has changed properties
276 if (this.hasChangedData) {
277 this.showUnsavedChangesAlert().then((resolve) => {
278 this.changeSelectedInstance(instance)
283 this.changeSelectedInstance(instance);
286 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
287 this.selectedInstanceData = instance;
288 this.loadingProperties = true;
289 if (instance instanceof ComponentInstance) {
290 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
291 if (this.isInput(instance.originType)) {
292 this.componentInstanceServiceNg2
293 .getComponentInstanceInputs(this.component, instance)
294 .subscribe(response => {
295 instanceBePropertiesMap[instance.uniqueId] = response;
296 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
300 this.loadingProperties = false;
302 } else if (this.isSelf()) {
303 this.getServiceProperties();
305 this.componentInstanceServiceNg2
306 .getComponentInstanceProperties(this.component, instance.uniqueId)
307 .subscribe(response => {
308 instanceBePropertiesMap[instance.uniqueId] = response;
309 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
313 this.loadingProperties = false;
316 this.loadingProperties = false;
317 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
318 } else if (instance instanceof GroupInstance) {
319 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
320 this.componentInstanceServiceNg2
321 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
322 .subscribe((response) => {
323 instanceBePropertiesMap[instance.uniqueId] = response;
324 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
328 this.loadingProperties = false;
330 } else if (instance instanceof PolicyInstance) {
331 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
332 this.componentInstanceServiceNg2
333 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
334 .subscribe((response) => {
335 instanceBePropertiesMap[instance.uniqueId] = response;
336 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
340 this.loadingProperties = false;
343 this.loadingProperties = false;
346 if (this.searchPropertyName) {
349 //clear selected property from the navigation
350 this.selectedFlatProperty = new SimpleFlatProperty();
351 this.propertiesNavigationData = [];
355 * Entry point handling response from server
357 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
358 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
359 this.checkedPropertiesCount = 0;
360 this.checkedChildPropertiesCount = 0;
363 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
364 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
365 let currentUniqueId = this.selectedInstanceData.uniqueId;
366 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
367 let isCapabilityOwnedByInstance: boolean;
368 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
369 this.selectedInstance_FlattenCapabilitiesList,
370 (result, cap: Capability) => {
371 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
372 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
373 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
374 if (cap.properties && isCapabilityOwnedByInstance) {
375 _.forEach(cap.properties, prop => {
376 if (!prop.origName) {
377 prop.origName = prop.name;
378 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
381 return result.concat(cap.properties);
385 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
386 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
387 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
388 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
390 //concatenate capabilitiesProps to all props list
391 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
392 this.checkedPropertiesCount = 0;
395 isCapabilityProperty = (prop: PropertyBEModel) => {
396 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
399 /*** VALUE CHANGE EVENTS ***/
400 dataChanged = (item: PropertyFEModel | InputFEModel) => {
402 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
403 itemHasChanged = item.hasValueObjChanged();
404 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
405 itemHasChanged = item.hasChanged();
406 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
407 itemHasChanged = item.hasDefaultValueChanged();
410 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
411 if (itemHasChanged) {
412 if (dataChangedIdx === -1) {
413 this.changedData.push(item);
416 if (dataChangedIdx !== -1) {
417 this.changedData.splice(dataChangedIdx, 1);
421 if (this.isPropertiesTabSelected) {
422 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
423 } else if (this.isInputsTabSelected) {
424 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
425 } else if (this.isPoliciesTabSelected) {
426 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
428 this.updateHasChangedData();
432 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
435 * Handle select node in navigation area, and select the row in table
437 onPropertySelectedUpdate = ($event) => {
438 console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
439 this.selectedFlatProperty = $event;
440 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
441 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
445 * When user select row in table, this will prepare the hirarchy object for the tree.
447 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
448 console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
449 let property = propertyRowSelectedEvent.propertyModel;
450 let instanceName = propertyRowSelectedEvent.instanceName;
451 this.propertyStructureHeader = null;
453 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
454 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
455 let simpleFlatProperty: Array<SimpleFlatProperty>;
456 if (property instanceof PropertyFEModel) {
457 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
458 } else if (property instanceof DerivedFEProperty) {
459 // Need to find parent PropertyFEModel
460 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
461 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
463 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
465 this.propertiesNavigationData = simpleFlatProperty;
468 // Update the header in the navigation tree with property name.
469 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
471 // Set selected property in table
472 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
473 this.hierarchyNavTabs.triggerTabChange('Property Structure');
477 selectInstanceRow = ($event) => {//get instance name
478 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
479 return instance.name == $event;
481 this.hierarchyNavTabs.triggerTabChange('Composition');
484 tabChanged = (event) => {
485 // stop if has changed properties
486 if (this.hasChangedData) {
487 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
488 this.showUnsavedChangesAlert().then((proceed) => {
489 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
495 console.debug("==>" + this.constructor.name + ": tabChanged " + event);
496 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
497 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
498 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
499 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
500 this.propertyStructureHeader = null;
501 this.searchQuery = '';
505 * Select Tosca function value from defined values
507 selectToscaFunctionAndValues = (): void => {
508 const selectedInstanceData: ComponentInstance = this.getSelectedComponentInstance();
509 if (!selectedInstanceData) {
512 const property: PropertyBEModel = this.buildCheckedInstanceProperty();
513 if (property.isToscaGetFunction()) {
514 this.clearCheckedInstancePropertyValue();
517 this.openToscaGetFunctionModal();
520 private getSelectedComponentInstance(): ComponentInstance {
521 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
522 const instanceId: string = instancesIds[0];
523 return <ComponentInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance);
526 private buildCheckedInstanceProperty(): PropertyBEModel {
527 return this.buildCheckedInstanceProperties()[0];
530 private buildCheckedInstanceProperties(): PropertyBEModel[] {
531 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
532 const instanceId: string = instancesIds[0];
533 return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
536 private openToscaGetFunctionModal() {
537 const modalTitle = 'Set value using TOSCA functions';
538 const modal = this.modalService.createCustomModal(new ModalModel(
543 new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
545 const selectedToscaFunction = modal.instance.dynamicContent.instance.selectToscaFunction;
546 const selectedPropertyFromModal:PropertyDropdownValue = modal.instance.dynamicContent.instance.selectedProperty;
547 const toscaFunctionType: ToscaGetFunctionType = ToscaGetFunctionTypeConverter.convertFromString(selectedToscaFunction);
548 this.updateCheckedInstancePropertyGetFunctionValue(selectedPropertyFromModal, toscaFunctionType);
549 modal.instance.close();
552 new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
553 modal.instance.close();
558 const checkedInstanceProperty = this.buildCheckedInstanceProperty();
559 this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
560 'property': checkedInstanceProperty,
562 modal.instance.open();
565 private clearCheckedInstancePropertyValue() {
566 const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
567 checkedInstanceProperty.getInputValues = null;
568 checkedInstanceProperty.value = null;
569 checkedInstanceProperty.toscaGetFunction = null;
570 this.updateInstanceProperty(checkedInstanceProperty);
573 private updateCheckedInstancePropertyGetFunctionValue(propertyToGet: PropertyDropdownValue, toscaGetFunctionType: ToscaGetFunctionType) {
574 const toscaGetFunctionBuilder: ToscaGetFunctionDtoBuilder =
575 new ToscaGetFunctionDtoBuilder()
576 .withPropertyUniqueId(propertyToGet.propertyId)
577 .withFunctionType(toscaGetFunctionType)
578 .withPropertySource(PropertySource.SELF)
579 .withPropertyName(propertyToGet.propertyName)
580 .withSourceName(this.component.name)
581 .withSourceUniqueId(this.component.uniqueId);
583 const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
584 if (propertyToGet.propertyPath && propertyToGet.propertyPath.length) {
585 toscaGetFunctionBuilder.withPropertyPathFromSource(propertyToGet.propertyPath);
587 checkedProperty.toscaGetFunction = toscaGetFunctionBuilder.build();
588 this.updateInstanceProperty(checkedProperty);
591 updateInstanceProperty(instanceProperty: PropertyBEModel) {
592 this.loadingProperties = true;
593 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
594 this.selectedInstanceData.uniqueId, [instanceProperty])
596 this.changeSelectedInstance(this.getSelectedComponentInstance());
599 this.translateService.translate('TOSCA_FUNCTION_SELECT_ERROR', {'propertyName': instanceProperty.name, 'error': error});
600 this.notification.error({
601 title: this.translateService.translate('FAILURE_LABEL'),
604 console.error(errorMsg, error);
606 this.loadingProperties = false;
607 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
611 selectInputBtnLabel = () => {
612 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
613 angular.forEach(instancesIds, (instanceId: string): void => {
614 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
615 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
616 if(this.checkedPropertiesCount == 1) {
617 if (property.isToscaGetFunction()) {
618 this.btnToscaFunctionText = this.translateService.translate('CLEAR_VALUE_LABEL');
620 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
623 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
629 /*** DECLARE PROPERTIES/INPUTS ***/
630 declareProperties = (): void => {
631 console.debug("==>" + this.constructor.name + ": declareProperties");
633 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
634 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
635 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
636 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
637 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
639 angular.forEach(instancesIds, (instanceId: string): void => {
640 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
641 if (selectedInstanceData instanceof ComponentInstance) {
642 if (!this.isInput(selectedInstanceData.originType)) {
643 // convert Property FE model -> Property BE model, extract only checked
644 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
646 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
648 } else if (selectedInstanceData instanceof GroupInstance) {
649 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
650 } else if (selectedInstanceData instanceof PolicyInstance) {
651 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
655 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
657 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
658 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
659 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
661 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
662 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
665 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
666 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
667 prop => !this.isCapabilityProperty(prop)
669 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
670 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
673 let isCapabilityPropertyChanged = false;
675 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
676 (prop: PropertyBEModel) => {
677 prop.name = prop.origName || prop.name;
678 if (this.isCapabilityProperty(prop)) {
679 isCapabilityPropertyChanged = true;
683 this.topologyTemplateService
684 .createInput(this.component, inputsToCreate, this.isSelf())
685 .subscribe((response) => {
686 this.selectInstanceRow(SERVICE_SELF_TITLE);
687 this.onInstanceSelectedUpdate(this.instances[0]);
688 this.setInputTabIndication(response.length);
689 this.checkedPropertiesCount = 0;
690 this.checkedChildPropertiesCount = 0;
691 _.forEach(response, (input: InputBEModel) => {
692 const newInput: InputFEModel = new InputFEModel(input);
693 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
694 this.inputs.push(newInput);
695 this.updatePropertyValueAfterDeclare(newInput);
697 if (isCapabilityPropertyChanged) {
698 this.reloadInstanceCapabilities();
700 }, error => {}); //ignore error
703 declareListProperties = (): void => {
704 // get selected properties
705 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
706 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
707 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
708 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
709 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
710 let propertyNameList: Array<string> = [];
713 angular.forEach(instancesIds, (instanceId: string): void => {
715 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
716 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
718 if (selectedInstanceData instanceof ComponentInstance) {
719 if (!this.isInput(selectedInstanceData.originType)) {
720 // convert Property FE model -> Property BE model, extract only checked
721 selectedComponentInstancesProperties[instanceId] = checkedProperties;
723 selectedComponentInstancesInputs[instanceId] = checkedProperties;
725 } else if (selectedInstanceData instanceof GroupInstance) {
726 selectedGroupInstancesProperties[instanceId] = checkedProperties;
727 } else if (selectedInstanceData instanceof PolicyInstance) {
728 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
731 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
732 propertyNameList.push(property.name);
736 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
738 let modalTitle = 'Declare Properties as List Input';
739 const modal = this.modalService.createCustomModal(new ModalModel(
741 modalTitle, /* title */
746 'blue', /* css class */
747 () => { /* callback */
748 let content:any = modal.instance.dynamicContent.instance;
751 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
752 let typelist: any = PROPERTY_TYPES.LIST;
753 let uniID: any = insId;
754 let boolfalse: any = false;
755 let required: any = content.propertyModel.required;
759 "type": content.propertyModel.simpleType,
763 let schemaProp :any = {
764 "type": content.propertyModel.simpleType,
768 reglistInput.description = content.propertyModel.description;
769 reglistInput.name = content.propertyModel.name;
770 reglistInput.type = typelist;
771 reglistInput.schemaType = content.propertyModel.simpleType;
772 reglistInput.instanceUniqueId = uniID;
773 reglistInput.uniqueId = uniID;
774 reglistInput.required = required;
775 reglistInput.schema = schem;
776 reglistInput.schemaProperty = schemaProp;
779 componentInstInputsMap: content.inputsToCreate,
780 listInput: reglistInput
783 this.topologyTemplateService
784 .createListInput(this.component, input, this.isSelf())
785 .subscribe(response => {
786 this.setInputTabIndication(response.length);
787 this.checkedPropertiesCount = 0;
788 this.checkedChildPropertiesCount = 0;
789 _.forEach(response, (input: InputBEModel) => {
790 let newInput: InputFEModel = new InputFEModel(input);
791 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
792 this.inputs.push(newInput);
793 // create list input does not return updated properties info, so need to reload
794 //this.updatePropertyValueAfterDeclare(newInput);
795 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
796 this.changeSelectedInstance(this.selectedInstanceData);
798 modal.instance.close();
800 }, error => {}); //ignore error
803 /*, getDisabled: function */
805 new ButtonModel('Cancel', 'outline grey', () => {
806 modal.instance.close();
811 // 3rd arg is passed to DeclareListComponent instance
812 this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
813 modal.instance.open();
816 /*** DECLARE PROPERTIES/POLICIES ***/
817 declarePropertiesToPolicies = (): void => {
818 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
819 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
821 angular.forEach(instancesIds, (instanceId: string): void => {
822 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
823 if (selectedInstanceData instanceof ComponentInstance) {
824 if (!this.isInput(selectedInstanceData.originType)) {
825 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
830 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
831 this.loadingPolicies = true;
833 this.topologyTemplateService
834 .createPolicy(this.component, policiesToCreate, this.isSelf())
835 .subscribe(response => {
836 this.setPolicyTabIndication(response.length);
837 this.checkedPropertiesCount = 0;
838 this.displayPoliciesAsDeclared(response);
839 this.loadingPolicies = false;
844 displayPoliciesAsDeclared = (policies) => {
845 _.forEach(policies, (policy: any) => {
846 let newPolicy: InputFEModel = new InputFEModel(policy);
847 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
848 newPolicy.relatedPropertyName = policy.name;
849 newPolicy.relatedPropertyValue = policy.value;
850 this.updatePropertyValueAfterDeclare(newPolicy);
851 this.policies.push(policy);
855 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
856 return new Promise((resolve, reject) => {
857 if (!this.isValidChangedData) {
858 reject('Changed data is invalid - cannot save!');
861 if (!this.changedData.length) {
866 // make request and its handlers
868 let handleSuccess, handleError;
869 let changedInputsProperties = [], changedCapabilitiesProperties = [];
870 if (this.isPropertiesTabSelected) {
871 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
872 changedProp = <PropertyFEModel>changedProp;
873 const propBE = new PropertyBEModel(changedProp);
874 propBE.toscaPresentation = new ToscaPresentationData();
875 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
876 propBE.value = changedProp.getJSONValue();
877 propBE.name = changedProp.origName || changedProp.name;
878 delete propBE.origName;
881 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
883 if (this.selectedInstanceData instanceof ComponentInstance) {
884 if (this.isInput(this.selectedInstanceData.originType)) {
885 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
886 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
887 request = Observable.forkJoin(
888 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
889 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
890 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
893 else if (changedInputsProperties.length) {
894 request = this.componentInstanceServiceNg2
895 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
897 else if (changedCapabilitiesProperties.length) {
898 request = this.componentInstanceServiceNg2
899 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
901 handleSuccess = (response) => {
902 // reset each changed property with new value and remove it from changed properties list
903 response.forEach((resInput) => {
904 const changedProp = <PropertyFEModel>this.changedData.shift();
905 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
910 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
911 delete cp.constraints;
915 request = this.componentInstanceServiceNg2
916 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
918 handleSuccess = (response) => {
919 // reset each changed property with new value and remove it from changed properties list
920 response.forEach((resProp) => {
921 const changedProp = <PropertyFEModel>this.changedData.shift();
922 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
927 } else if (this.selectedInstanceData instanceof GroupInstance) {
928 request = this.componentInstanceServiceNg2
929 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
930 handleSuccess = (response) => {
931 // reset each changed property with new value and remove it from changed properties list
932 response.forEach((resProp) => {
933 const changedProp = <PropertyFEModel>this.changedData.shift();
934 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
938 } else if (this.selectedInstanceData instanceof PolicyInstance) {
939 request = this.componentInstanceServiceNg2
940 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
941 handleSuccess = (response) => {
942 // reset each changed property with new value and remove it from changed properties list
943 response.forEach((resProp) => {
944 const changedProp = <PropertyFEModel>this.changedData.shift();
945 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
950 } else if (this.isInputsTabSelected) {
952 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
953 changedInput = <InputFEModel>changedInput;
954 const inputBE = new InputBEModel(changedInput);
955 inputBE.defaultValue = changedInput.getJSONDefaultValue();
958 request = this.componentServiceNg2
959 .updateComponentInputs(this.component, changedInputs);
960 handleSuccess = (response) => {
961 // reset each changed property with new value and remove it from changed properties list
962 response.forEach((resInput) => {
963 const changedInput = <InputFEModel>this.changedData.shift();
964 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
965 changedInput.required = resInput.required;
966 changedInput.requiredOrig = resInput.required;
971 this.savingChangedData = true;
974 this.savingChangedData = false;
975 if (changedCapabilitiesProperties.length) {
976 this.reloadInstanceCapabilities();
978 handleSuccess && handleSuccess(response);
979 this.updateHasChangedData();
983 this.savingChangedData = false;
984 handleError && handleError(error);
985 this.updateHasChangedData();
992 reloadInstanceCapabilities = (): void => {
993 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
994 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
995 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
996 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
997 return instance.capabilities;
1000 }, new CapabilitiesGroup());
1001 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
1005 reverseChangedData = ():void => {
1006 // make reverse item handler
1007 let handleReverseItem;
1008 if (this.isPropertiesTabSelected) {
1009 handleReverseItem = (changedItem) => {
1010 changedItem = <PropertyFEModel>changedItem;
1011 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
1013 } else if (this.isInputsTabSelected) {
1014 handleReverseItem = (changedItem) => {
1015 changedItem = <InputFEModel>changedItem;
1016 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
1017 changedItem.resetMetadata();
1018 changedItem.required = changedItem.requiredOrig;
1022 this.changedData.forEach(handleReverseItem);
1023 this.changedData = [];
1024 this.updateHasChangedData();
1027 updateHasChangedData = ():boolean => {
1028 const curHasChangedData:boolean = (this.changedData.length > 0);
1029 if (curHasChangedData !== this.hasChangedData) {
1030 this.hasChangedData = curHasChangedData;
1031 if(this.hasChangedData) {
1032 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1034 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1037 return this.hasChangedData;
1040 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1041 this.saveChangedData().then(
1043 this.notification.success({
1044 message: 'Successfully saved changes',
1047 if(onSuccessFunction) onSuccessFunction();
1050 this.notification.error({
1051 message: 'Failed to save changes!',
1054 if(onError) onError();
1059 showUnsavedChangesAlert = ():Promise<any> => {
1060 let modalTitle:string;
1061 if (this.isPropertiesTabSelected) {
1062 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1063 } else if (this.isInputsTabSelected) {
1064 modalTitle = `Unsaved inputs for ${this.component.name}`;
1067 return new Promise<any>((resolve, reject) => {
1068 const modal = this.ModalServiceSdcUI.openCustomModal(
1072 type: SdcUiCommon.ModalType.custom,
1073 testId: "navigate-modal",
1076 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1077 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1078 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1079 ] as SdcUiCommon.IModalButtonComponent[]
1080 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1085 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1086 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1087 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1088 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1089 return feProperty.name == input.relatedPropertyName &&
1090 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1092 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1093 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1094 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1095 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1099 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1100 updateCheckedPropertyCount = (increment: boolean): void => {
1101 this.checkedPropertiesCount += (increment) ? 1 : -1;
1102 console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1103 this.selectInputBtnLabel();
1106 updateCheckedChildPropertyCount = (increment: boolean): void => {
1107 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1110 setInputTabIndication = (numInputs: number): void => {
1111 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1114 setPolicyTabIndication = (numPolicies: number): void => {
1115 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1118 resetUnsavedChangesForInput = (input:InputFEModel) => {
1119 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1120 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1121 this.updateHasChangedData();
1124 deleteInput = (input: InputFEModel) => {
1125 //reset any unsaved changes to the input before deleting it
1126 this.resetUnsavedChangesForInput(input);
1128 console.debug("==>" + this.constructor.name + ": deleteInput");
1129 let inputToDelete = new InputBEModel(input);
1131 this.componentServiceNg2
1132 .deleteInput(this.component, inputToDelete)
1133 .subscribe(response => {
1134 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1136 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1137 this.changeSelectedInstance(this.selectedInstanceData);
1138 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1140 // if (instanceFeProperties) {
1141 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1142 // return prop.name == input.propertyName;
1145 // if (propToEnable) {
1146 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1147 // propToEnable.setNonDeclared(response.inputPath);
1148 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1149 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1152 }, error => {}); //ignore error
1155 deletePolicy = (policy: PolicyInstance) => {
1156 this.loadingPolicies = true;
1157 this.topologyTemplateService
1158 .deletePolicy(this.component, policy)
1159 .subscribe((response) => {
1160 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1161 this.changeSelectedInstance(this.selectedInstanceData);
1162 this.loadingPolicies = false;
1166 deleteProperty = (property: PropertyFEModel) => {
1167 const propertyToDelete = new PropertyFEModel(property);
1168 this.loadingProperties = true;
1169 const feMap = this.instanceFePropertiesMap;
1170 this.topologyTemplateService
1171 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1172 .subscribe((response) => {
1173 const props = feMap[this.component.uniqueId];
1174 props.splice(props.findIndex(p => p.uniqueId === response),1);
1175 this.loadingProperties = false;
1177 this.loadingProperties = false;
1178 console.error(error);
1182 /*** addProperty ***/
1183 addProperty = (model: string) => {
1184 this.loadDataTypesByComponentModel(model)
1185 let modalTitle = 'Add Property';
1186 let modal = this.modalService.createCustomModal(new ModalModel(
1191 new ButtonModel('Save', 'blue', () => {
1192 modal.instance.dynamicContent.instance.isLoading = true;
1193 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1194 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1195 .subscribe((response) => {
1196 modal.instance.dynamicContent.instance.isLoading = false;
1197 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1198 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1199 modal.instance.close();
1201 modal.instance.dynamicContent.instance.isLoading = false;
1202 this.notification.error({
1203 message: 'Failed to add property:' + error,
1207 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1208 new ButtonModel('Cancel', 'outline grey', () => {
1209 modal.instance.close();
1214 modal.instance.open();
1215 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1220 let modalTitle = 'Add Input';
1221 let modal = this.modalService.createCustomModal(new ModalModel(
1226 new ButtonModel('Save', 'blue', () => {
1227 modal.instance.dynamicContent.instance.isLoading = true;
1228 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1229 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1230 .subscribe((response) => {
1231 modal.instance.dynamicContent.instance.isLoading = false;
1232 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1233 this.inputs.push(newInputProp);
1234 modal.instance.close();
1236 modal.instance.dynamicContent.instance.isLoading = false;
1237 this.notification.error({
1238 message: 'Failed to add input:' + error,
1242 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1243 new ButtonModel('Cancel', 'outline grey', () => {
1244 modal.instance.close();
1249 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1250 modal.instance.open();
1253 /*** SEARCH RELATED FUNCTIONS ***/
1254 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1255 let instanceBePropertiesMap:InstanceBePropertiesMap;
1256 this.componentServiceNg2
1257 .filterComponentInstanceProperties(this.component, filterData)
1258 .subscribe((response) => {
1259 this.processInstancePropertiesResponse(response, false);
1260 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1261 this.searchPropertyName = filterData.propertyName;//mark in table
1262 this.hierarchyNavTabs.triggerTabChange('Composition');
1263 this.propertiesNavigationData = [];
1264 this.displayClearSearch = true;
1265 }, (error) => {}); //ignore error
1269 clearSearch = () => {
1270 this.instancesNavigationData = this.instances;
1271 this.searchPropertyName = "";
1272 this.hierarchyPropertiesDisplayOptions.searchText = "";
1273 this.displayClearSearch = false;
1274 this.advanceSearch.clearAll();
1275 this.searchQuery = '';
1278 clickOnClearSearch = () => {
1280 this.selectFirstInstanceByDefault();
1281 this.hierarchyNavTabs.triggerTabChange('Composition');
1284 private isInput = (instanceType:string):boolean =>{
1285 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1288 loadDataTypesByComponentModel(model:string) {
1289 this.propertyCreatorComponent.filterDataTypesByModel(model);