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, ComponentRef} from "@angular/core";
23 import {PropertiesService} from "../../services/properties.service";
26 Component as ComponentData,
29 FilterPropertiesAssignmentData,
33 InstanceBePropertiesMap,
34 InstanceFePropertiesMap,
35 InstancePropertiesAPIMap,
44 import {ResourceType} from "app/utils";
45 import {ComponentServiceNg2} from "../../services/component-services/component.service";
46 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
47 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
48 import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
49 import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
50 import {EventListenerService} from "app/services/event-listener-service"
51 import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
52 import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
53 import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component";
54 import {HierarchyNavService} from "./services/hierarchy-nav.service";
55 import {PropertiesUtils} from "./services/properties.utils";
56 import {ComponentModeService} from "../../services/component-services/component-mode.service";
57 import {Tab, Tabs} from "../../components/ui/tabs/tabs.component";
58 import {InputsUtils} from "./services/inputs.utils";
59 import {InstanceFeDetails} from "../../../models/instance-fe-details";
60 import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
61 import {UnsavedChangesComponent} from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
62 import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
63 import {ModalService} from "../../services/modal.service";
64 import {DeclareListComponent} from "./declare-list/declare-list.component";
65 import {ToscaFunctionComponent} from "./tosca-function/tosca-function.component";
66 import {CapabilitiesGroup, Capability} from "../../../models/capability";
67 import {ToscaPresentationData} from "../../../models/tosca-presentation";
68 import {Observable} from "rxjs";
69 import {ToscaGetFunctionType} from "../../../models/tosca-get-function-type.enum";
70 import {TranslateService} from "../../shared/translator/translate.service";
71 import {ModalComponent} from "../../components/ui/modal/modal.component";
73 const SERVICE_SELF_TITLE = "SELF";
75 templateUrl: './properties-assignment.page.component.html',
76 styleUrls: ['./properties-assignment.page.component.less']
78 export class PropertiesAssignmentComponent {
79 title = "Properties & Inputs";
81 component: ComponentData;
82 componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
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.log("==>" + 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 _.forEach(response.policies, (policy: any) => {
186 const newPolicy: InputFEModel = new InputFEModel(policy);
187 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
188 this.policies.push(policy);
191 // add the service self instance to the top of the list.
192 const serviceInstance = new ComponentInstance();
193 serviceInstance.name = SERVICE_SELF_TITLE;
194 serviceInstance.uniqueId = this.component.uniqueId;
195 this.instances.unshift(serviceInstance);
197 _.forEach(this.instances, (instance) => {
198 this.instancesNavigationData.push(instance);
199 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
201 iconClass: instance.iconClass,
202 originArchived: instance.originArchived
205 this.loadingInstances = false;
206 if (this.instancesNavigationData[0] == undefined) {
207 this.loadingProperties = false;
209 this.selectFirstInstanceByDefault();
211 this.loadingInstances = false;
214 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
215 // stop if has changed properties
216 if (this.hasChangedData) {
217 event.preventDefault();
218 this.showUnsavedChangesAlert().then(() => {
219 this.$state.go(toState, toParams);
225 this.loadDataTypesByComponentModel(this.component.model);
229 this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
230 this.stateChangeStartUnregister();
233 selectFirstInstanceByDefault = () => {
234 if (this.instancesNavigationData[0] !== undefined) {
235 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
239 updateViewMode = () => {
240 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
243 onCheckout = (component: ComponentData) => {
244 this.component = component;
245 this.updateViewMode();
248 isSelf = (): boolean => {
249 return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
252 showAddProperties = (): boolean => {
253 if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
256 return this.isSelf();
259 getServiceProperties() {
260 this.loadingProperties = true;
261 this.topologyTemplateService
262 .getServiceProperties(this.component.uniqueId)
263 .subscribe((response) => {
264 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
265 this.serviceBePropertiesMap[this.component.uniqueId] = response;
266 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
267 this.loadingProperties = false;
269 this.loadingProperties = false;
273 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
274 // stop if has changed properties
275 if (this.hasChangedData) {
276 this.showUnsavedChangesAlert().then((resolve) => {
277 this.changeSelectedInstance(instance)
282 this.changeSelectedInstance(instance);
285 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
286 this.selectedInstanceData = instance;
287 this.loadingProperties = true;
288 if (instance instanceof ComponentInstance) {
289 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
290 if (this.isInput(instance.originType)) {
291 this.componentInstanceServiceNg2
292 .getComponentInstanceInputs(this.component, instance)
293 .subscribe(response => {
294 instanceBePropertiesMap[instance.uniqueId] = response;
295 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
299 this.loadingProperties = false;
301 } else if (this.isSelf()) {
302 this.getServiceProperties();
304 this.componentInstanceServiceNg2
305 .getComponentInstanceProperties(this.component, instance.uniqueId)
306 .subscribe(response => {
307 instanceBePropertiesMap[instance.uniqueId] = response;
308 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
312 this.loadingProperties = false;
315 this.loadingProperties = false;
316 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
317 } else if (instance instanceof GroupInstance) {
318 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
319 this.componentInstanceServiceNg2
320 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
321 .subscribe((response) => {
322 instanceBePropertiesMap[instance.uniqueId] = response;
323 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
327 this.loadingProperties = false;
329 } else if (instance instanceof PolicyInstance) {
330 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
331 this.componentInstanceServiceNg2
332 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
333 .subscribe((response) => {
334 instanceBePropertiesMap[instance.uniqueId] = response;
335 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
339 this.loadingProperties = false;
342 this.loadingProperties = false;
345 if (this.searchPropertyName) {
348 //clear selected property from the navigation
349 this.selectedFlatProperty = new SimpleFlatProperty();
350 this.propertiesNavigationData = [];
354 * Entry point handling response from server
356 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
357 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
358 this.checkedPropertiesCount = 0;
359 this.checkedChildPropertiesCount = 0;
362 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
363 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
364 let currentUniqueId = this.selectedInstanceData.uniqueId;
365 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
366 let isCapabilityOwnedByInstance: boolean;
367 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
368 this.selectedInstance_FlattenCapabilitiesList,
369 (result, cap: Capability) => {
370 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
371 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
372 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
373 if (cap.properties && isCapabilityOwnedByInstance) {
374 _.forEach(cap.properties, prop => {
375 if (!prop.origName) {
376 prop.origName = prop.name;
377 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
380 return result.concat(cap.properties);
384 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
385 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
386 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
387 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
389 //concatenate capabilitiesProps to all props list
390 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
391 this.checkedPropertiesCount = 0;
394 isCapabilityProperty = (prop: PropertyBEModel) => {
395 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
398 /*** VALUE CHANGE EVENTS ***/
399 dataChanged = (item: PropertyFEModel | InputFEModel) => {
401 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
402 itemHasChanged = item.hasValueObjChanged();
403 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
404 itemHasChanged = item.hasChanged();
405 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
406 itemHasChanged = item.hasDefaultValueChanged();
409 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
410 if (itemHasChanged) {
411 if (dataChangedIdx === -1) {
412 this.changedData.push(item);
415 if (dataChangedIdx !== -1) {
416 this.changedData.splice(dataChangedIdx, 1);
420 if (this.isPropertiesTabSelected) {
421 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
422 } else if (this.isInputsTabSelected) {
423 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
424 } else if (this.isPoliciesTabSelected) {
425 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
427 this.updateHasChangedData();
431 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
434 * Handle select node in navigation area, and select the row in table
436 onPropertySelectedUpdate = ($event) => {
437 console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
438 this.selectedFlatProperty = $event;
439 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
440 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
444 * When user select row in table, this will prepare the hirarchy object for the tree.
446 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
447 console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
448 let property = propertyRowSelectedEvent.propertyModel;
449 let instanceName = propertyRowSelectedEvent.instanceName;
450 this.propertyStructureHeader = null;
452 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
453 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
454 let simpleFlatProperty: Array<SimpleFlatProperty>;
455 if (property instanceof PropertyFEModel) {
456 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
457 } else if (property instanceof DerivedFEProperty) {
458 // Need to find parent PropertyFEModel
459 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
460 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
462 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
464 this.propertiesNavigationData = simpleFlatProperty;
467 // Update the header in the navigation tree with property name.
468 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
470 // Set selected property in table
471 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
472 this.hierarchyNavTabs.triggerTabChange('Property Structure');
476 selectInstanceRow = ($event) => {//get instance name
477 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
478 return instance.name == $event;
480 this.hierarchyNavTabs.triggerTabChange('Composition');
483 tabChanged = (event) => {
484 // stop if has changed properties
485 if (this.hasChangedData) {
486 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
487 this.showUnsavedChangesAlert().then((proceed) => {
488 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
494 console.log("==>" + this.constructor.name + ": tabChanged " + event);
495 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
496 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
497 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
498 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
499 this.propertyStructureHeader = null;
500 this.searchQuery = '';
503 /**Select Tosca function value from defined values**/
504 selectToscaFunctionAndValues = (): void => {
505 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
506 angular.forEach(instancesIds, (instanceId: string): void => {
507 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId
508 && instance instanceof ComponentInstance);
509 if (selectedInstanceData) {
510 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
511 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
512 this.propertiesService.setCheckedPropertyType(property.type);
513 if (property.toscaGetFunctionType != null) {
514 this.loadingProperties = true;
515 property.getInputValues = null;
516 property.value = null;
517 property.toscaGetFunctionType = null;
518 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
520 const modalTitle = 'Set value using TOSCA functions';
521 const modal = this.ModalService.createCustomModal(new ModalModel(
526 new ButtonModel('Save', 'blue',
528 const selectedToscaFunction: string = modal.instance.dynamicContent.instance.selectToscaFunction;
529 if (selectedToscaFunction === ToscaGetFunctionType.GET_INPUT.toLowerCase()) {
530 this.updateSelectInputValues(modal, property, checkedProperties, selectedInstanceData);
532 modal.instance.close();
535 new ButtonModel('Cancel', 'outline grey', () => {
536 modal.instance.close();
541 this.ModalService.addDynamicContentToModal(modal, ToscaFunctionComponent);
542 modal.instance.open();
549 private updateSelectInputValues(modal:ComponentRef<ModalComponent>, property:PropertyBEModel, checkedProperties:PropertyBEModel[], selectedInstanceData:any) {
550 this.loadingProperties = true;
551 let selectInputValue: InputFEModel = modal.instance.dynamicContent.instance.selectValue;
552 property.getInputValues = [];
553 const propertyInputDetail = new PropertyInputDetail();
554 propertyInputDetail.inputId = selectInputValue.uniqueId;
555 propertyInputDetail.inputName = selectInputValue.name;
556 propertyInputDetail.inputType = selectInputValue.type;
557 property.getInputValues.push(propertyInputDetail);
558 property.value = selectInputValue.name.indexOf("->") !== -1
559 ? '{"get_input":[' + selectInputValue.name.replace("->", ", ") + ']}'
560 : '{"get_input":"' + selectInputValue.name+ '"}' ;
561 property.toscaGetFunctionType = ToscaGetFunctionType.GET_INPUT;
562 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
565 updateInstancePropertiesWithInput(checkedProperties: PropertyBEModel[], selectedInstanceData: any) {
566 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
567 this.selectedInstanceData.uniqueId, checkedProperties)
569 this.changeSelectedInstance(selectedInstanceData);
571 this.Notification.error({
572 message: 'Failed to select/deselect get_input call: ' + error,
576 this.loadingProperties = false;
577 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
581 selectInputBtnLabel = () => {
582 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
583 angular.forEach(instancesIds, (instanceId: string): void => {
584 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
585 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
586 if(this.checkedPropertiesCount == 1) {
587 if (property.toscaGetFunctionType == null) {
588 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
590 this.btnToscaFunctionText = this.translateService.translate('DESELECT_INPUT_LABEL');
593 this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
599 /*** DECLARE PROPERTIES/INPUTS ***/
600 declareProperties = (): void => {
601 console.log("==>" + this.constructor.name + ": declareProperties");
603 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
604 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
605 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
606 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
607 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
609 angular.forEach(instancesIds, (instanceId: string): void => {
610 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
611 if (selectedInstanceData instanceof ComponentInstance) {
612 if (!this.isInput(selectedInstanceData.originType)) {
613 // convert Property FE model -> Property BE model, extract only checked
614 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
616 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
618 } else if (selectedInstanceData instanceof GroupInstance) {
619 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
620 } else if (selectedInstanceData instanceof PolicyInstance) {
621 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
625 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
627 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
628 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
629 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
631 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
632 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
635 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
636 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
637 prop => !this.isCapabilityProperty(prop)
639 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
640 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
643 let isCapabilityPropertyChanged = false;
645 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
646 (prop: PropertyBEModel) => {
647 prop.name = prop.origName || prop.name;
648 if (this.isCapabilityProperty(prop)) {
649 isCapabilityPropertyChanged = true;
653 this.topologyTemplateService
654 .createInput(this.component, inputsToCreate, this.isSelf())
655 .subscribe((response) => {
656 this.selectInstanceRow(SERVICE_SELF_TITLE);
657 this.onInstanceSelectedUpdate(this.instances[0]);
658 this.setInputTabIndication(response.length);
659 this.checkedPropertiesCount = 0;
660 this.checkedChildPropertiesCount = 0;
661 _.forEach(response, (input: InputBEModel) => {
662 const newInput: InputFEModel = new InputFEModel(input);
663 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
664 this.inputs.push(newInput);
665 this.updatePropertyValueAfterDeclare(newInput);
667 if (isCapabilityPropertyChanged) {
668 this.reloadInstanceCapabilities();
670 }, error => {}); //ignore error
673 declareListProperties = (): void => {
674 console.log('declareListProperties() - enter');
676 // get selected properties
677 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
678 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
679 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
680 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
681 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
682 let propertyNameList: Array<string> = [];
685 angular.forEach(instancesIds, (instanceId: string): void => {
686 console.log("instanceId="+instanceId);
688 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
689 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
691 if (selectedInstanceData instanceof ComponentInstance) {
692 if (!this.isInput(selectedInstanceData.originType)) {
693 // convert Property FE model -> Property BE model, extract only checked
694 selectedComponentInstancesProperties[instanceId] = checkedProperties;
696 selectedComponentInstancesInputs[instanceId] = checkedProperties;
698 } else if (selectedInstanceData instanceof GroupInstance) {
699 selectedGroupInstancesProperties[instanceId] = checkedProperties;
700 } else if (selectedInstanceData instanceof PolicyInstance) {
701 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
704 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
705 propertyNameList.push(property.name);
709 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
711 let modalTitle = 'Declare Properties as List Input';
712 const modal = this.ModalService.createCustomModal(new ModalModel(
714 modalTitle, /* title */
719 'blue', /* css class */
720 () => { /* callback */
721 let content:any = modal.instance.dynamicContent.instance;
724 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
725 let typelist: any = PROPERTY_TYPES.LIST;
726 let uniID: any = insId;
727 let boolfalse: any = false;
728 let required: any = content.propertyModel.required;
732 "type": content.propertyModel.simpleType,
736 let schemaProp :any = {
737 "type": content.propertyModel.simpleType,
741 reglistInput.description = content.propertyModel.description;
742 reglistInput.name = content.propertyModel.name;
743 reglistInput.type = typelist;
744 reglistInput.schemaType = content.propertyModel.simpleType;
745 reglistInput.instanceUniqueId = uniID;
746 reglistInput.uniqueId = uniID;
747 reglistInput.required = required;
748 reglistInput.schema = schem;
749 reglistInput.schemaProperty = schemaProp;
752 componentInstInputsMap: content.inputsToCreate,
753 listInput: reglistInput
755 console.log("save button clicked. input=", input);
757 this.topologyTemplateService
758 .createListInput(this.component, input, this.isSelf())
759 .subscribe(response => {
760 this.setInputTabIndication(response.length);
761 this.checkedPropertiesCount = 0;
762 this.checkedChildPropertiesCount = 0;
763 _.forEach(response, (input: InputBEModel) => {
764 let newInput: InputFEModel = new InputFEModel(input);
765 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
766 this.inputs.push(newInput);
767 // create list input does not return updated properties info, so need to reload
768 //this.updatePropertyValueAfterDeclare(newInput);
769 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
770 this.changeSelectedInstance(this.selectedInstanceData);
772 modal.instance.close();
774 }, error => {}); //ignore error
777 /*, getDisabled: function */
779 new ButtonModel('Cancel', 'outline grey', () => {
780 modal.instance.close();
785 // 3rd arg is passed to DeclareListComponent instance
786 this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
787 modal.instance.open();
788 console.log('declareListProperties() - leave');
791 /*** DECLARE PROPERTIES/POLICIES ***/
792 declarePropertiesToPolicies = (): void => {
793 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
794 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
796 angular.forEach(instancesIds, (instanceId: string): void => {
797 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
798 if (selectedInstanceData instanceof ComponentInstance) {
799 if (!this.isInput(selectedInstanceData.originType)) {
800 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
805 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
806 this.loadingPolicies = true;
808 this.topologyTemplateService
809 .createPolicy(this.component, policiesToCreate, this.isSelf())
810 .subscribe(response => {
811 this.setPolicyTabIndication(response.length);
812 this.checkedPropertiesCount = 0;
813 this.displayPoliciesAsDeclared(response);
814 this.loadingPolicies = false;
819 displayPoliciesAsDeclared = (policies) => {
820 _.forEach(policies, (policy: any) => {
821 let newPolicy: InputFEModel = new InputFEModel(policy);
822 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
823 newPolicy.relatedPropertyName = policy.name;
824 newPolicy.relatedPropertyValue = policy.value;
825 this.updatePropertyValueAfterDeclare(newPolicy);
826 this.policies.push(policy);
830 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
831 return new Promise((resolve, reject) => {
832 if (!this.isValidChangedData) {
833 reject('Changed data is invalid - cannot save!');
836 if (!this.changedData.length) {
841 // make request and its handlers
843 let handleSuccess, handleError;
844 let changedInputsProperties = [], changedCapabilitiesProperties = [];
845 if (this.isPropertiesTabSelected) {
846 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
847 changedProp = <PropertyFEModel>changedProp;
848 const propBE = new PropertyBEModel(changedProp);
849 propBE.toscaPresentation = new ToscaPresentationData();
850 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
851 propBE.value = changedProp.getJSONValue();
852 propBE.name = changedProp.origName || changedProp.name;
853 delete propBE.origName;
856 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
858 if (this.selectedInstanceData instanceof ComponentInstance) {
859 if (this.isInput(this.selectedInstanceData.originType)) {
860 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
861 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
862 request = Observable.forkJoin(
863 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
864 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
865 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
868 else if (changedInputsProperties.length) {
869 request = this.componentInstanceServiceNg2
870 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
872 else if (changedCapabilitiesProperties.length) {
873 request = this.componentInstanceServiceNg2
874 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
876 handleSuccess = (response) => {
877 // reset each changed property with new value and remove it from changed properties list
878 response.forEach((resInput) => {
879 const changedProp = <PropertyFEModel>this.changedData.shift();
880 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
882 console.log('updated instance inputs:', response);
886 console.log("changedProperties", changedProperties);
887 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
888 delete cp.constraints;
892 request = this.componentInstanceServiceNg2
893 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
895 handleSuccess = (response) => {
896 // reset each changed property with new value and remove it from changed properties list
897 response.forEach((resProp) => {
898 const changedProp = <PropertyFEModel>this.changedData.shift();
899 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
902 console.log("updated instance properties: ", response);
905 } else if (this.selectedInstanceData instanceof GroupInstance) {
906 request = this.componentInstanceServiceNg2
907 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
908 handleSuccess = (response) => {
909 // reset each changed property with new value and remove it from changed properties list
910 response.forEach((resProp) => {
911 const changedProp = <PropertyFEModel>this.changedData.shift();
912 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
915 console.log("updated group instance properties: ", response);
917 } else if (this.selectedInstanceData instanceof PolicyInstance) {
918 request = this.componentInstanceServiceNg2
919 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
920 handleSuccess = (response) => {
921 // reset each changed property with new value and remove it from changed properties list
922 response.forEach((resProp) => {
923 const changedProp = <PropertyFEModel>this.changedData.shift();
924 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
927 console.log("updated policy instance properties: ", response);
930 } else if (this.isInputsTabSelected) {
932 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
933 changedInput = <InputFEModel>changedInput;
934 const inputBE = new InputBEModel(changedInput);
935 inputBE.defaultValue = changedInput.getJSONDefaultValue();
938 request = this.componentServiceNg2
939 .updateComponentInputs(this.component, changedInputs);
940 handleSuccess = (response) => {
941 // reset each changed property with new value and remove it from changed properties list
942 response.forEach((resInput) => {
943 const changedInput = <InputFEModel>this.changedData.shift();
944 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
945 changedInput.required = resInput.required;
946 changedInput.requiredOrig = resInput.required;
948 console.log("updated the component inputs and got this response: ", response);
952 this.savingChangedData = true;
955 this.savingChangedData = false;
956 if (changedCapabilitiesProperties.length) {
957 this.reloadInstanceCapabilities();
959 handleSuccess && handleSuccess(response);
960 this.updateHasChangedData();
964 this.savingChangedData = false;
965 handleError && handleError(error);
966 this.updateHasChangedData();
973 reloadInstanceCapabilities = (): void => {
974 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
975 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
976 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
977 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
978 return instance.capabilities;
981 }, new CapabilitiesGroup());
982 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
986 reverseChangedData = ():void => {
987 // make reverse item handler
988 let handleReverseItem;
989 if (this.isPropertiesTabSelected) {
990 handleReverseItem = (changedItem) => {
991 changedItem = <PropertyFEModel>changedItem;
992 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
994 } else if (this.isInputsTabSelected) {
995 handleReverseItem = (changedItem) => {
996 changedItem = <InputFEModel>changedItem;
997 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
998 changedItem.resetMetadata();
999 changedItem.required = changedItem.requiredOrig;
1003 this.changedData.forEach(handleReverseItem);
1004 this.changedData = [];
1005 this.updateHasChangedData();
1008 updateHasChangedData = ():boolean => {
1009 const curHasChangedData:boolean = (this.changedData.length > 0);
1010 if (curHasChangedData !== this.hasChangedData) {
1011 this.hasChangedData = curHasChangedData;
1012 if(this.hasChangedData) {
1013 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1015 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1018 return this.hasChangedData;
1021 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1022 this.saveChangedData().then(
1024 this.Notification.success({
1025 message: 'Successfully saved changes',
1028 if(onSuccessFunction) onSuccessFunction();
1031 this.Notification.error({
1032 message: 'Failed to save changes!',
1035 if(onError) onError();
1040 showUnsavedChangesAlert = ():Promise<any> => {
1041 let modalTitle:string;
1042 if (this.isPropertiesTabSelected) {
1043 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1044 } else if (this.isInputsTabSelected) {
1045 modalTitle = `Unsaved inputs for ${this.component.name}`;
1048 return new Promise<any>((resolve, reject) => {
1049 const modal = this.ModalServiceSdcUI.openCustomModal(
1053 type: SdcUiCommon.ModalType.custom,
1054 testId: "navigate-modal",
1057 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1058 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1059 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1060 ] as SdcUiCommon.IModalButtonComponent[]
1061 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1066 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1067 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1068 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1069 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1070 return feProperty.name == input.relatedPropertyName &&
1071 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1073 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1074 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1075 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1076 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1080 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1081 updateCheckedPropertyCount = (increment: boolean): void => {
1082 this.checkedPropertiesCount += (increment) ? 1 : -1;
1083 console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1084 this.selectInputBtnLabel();
1087 updateCheckedChildPropertyCount = (increment: boolean): void => {
1088 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1091 setInputTabIndication = (numInputs: number): void => {
1092 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1095 setPolicyTabIndication = (numPolicies: number): void => {
1096 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1099 resetUnsavedChangesForInput = (input:InputFEModel) => {
1100 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1101 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1102 this.updateHasChangedData();
1105 deleteInput = (input: InputFEModel) => {
1106 //reset any unsaved changes to the input before deleting it
1107 this.resetUnsavedChangesForInput(input);
1109 console.log("==>" + this.constructor.name + ": deleteInput");
1110 let inputToDelete = new InputBEModel(input);
1112 this.componentServiceNg2
1113 .deleteInput(this.component, inputToDelete)
1114 .subscribe(response => {
1115 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1117 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1118 this.changeSelectedInstance(this.selectedInstanceData);
1119 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1121 // if (instanceFeProperties) {
1122 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1123 // return prop.name == input.propertyName;
1126 // if (propToEnable) {
1127 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1128 // propToEnable.setNonDeclared(response.inputPath);
1129 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1130 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1133 }, error => {}); //ignore error
1136 deletePolicy = (policy: PolicyInstance) => {
1137 this.loadingPolicies = true;
1138 this.topologyTemplateService
1139 .deletePolicy(this.component, policy)
1140 .subscribe((response) => {
1141 this.policies = this.policies.filter(policy => policy.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 this.loadingPolicies = false;
1148 deleteProperty = (property: PropertyFEModel) => {
1149 const propertyToDelete = new PropertyFEModel(property);
1150 this.loadingProperties = true;
1151 const feMap = this.instanceFePropertiesMap;
1152 this.topologyTemplateService
1153 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1154 .subscribe((response) => {
1155 const props = feMap[this.component.uniqueId];
1156 props.splice(props.findIndex(p => p.uniqueId === response),1);
1157 this.loadingProperties = false;
1159 this.loadingProperties = false;
1160 console.error(error);
1164 /*** addProperty ***/
1165 addProperty = (model: string) => {
1166 this.loadDataTypesByComponentModel(model)
1167 let modalTitle = 'Add Property';
1168 let modal = this.ModalService.createCustomModal(new ModalModel(
1173 new ButtonModel('Save', 'blue', () => {
1174 modal.instance.dynamicContent.instance.isLoading = true;
1175 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1176 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1177 .subscribe((response) => {
1178 modal.instance.dynamicContent.instance.isLoading = false;
1179 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1180 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1181 modal.instance.close();
1183 modal.instance.dynamicContent.instance.isLoading = false;
1184 this.Notification.error({
1185 message: 'Failed to add property:' + error,
1189 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1190 new ButtonModel('Cancel', 'outline grey', () => {
1191 modal.instance.close();
1196 modal.instance.open();
1197 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1202 let modalTitle = 'Add Input';
1203 let modal = this.ModalService.createCustomModal(new ModalModel(
1208 new ButtonModel('Save', 'blue', () => {
1209 modal.instance.dynamicContent.instance.isLoading = true;
1210 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1211 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1212 .subscribe((response) => {
1213 modal.instance.dynamicContent.instance.isLoading = false;
1214 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1215 this.inputs.push(newInputProp);
1216 modal.instance.close();
1218 modal.instance.dynamicContent.instance.isLoading = false;
1219 this.Notification.error({
1220 message: 'Failed to add input:' + error,
1224 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1225 new ButtonModel('Cancel', 'outline grey', () => {
1226 modal.instance.close();
1231 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1232 modal.instance.open();
1235 /*** SEARCH RELATED FUNCTIONS ***/
1236 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1237 let instanceBePropertiesMap:InstanceBePropertiesMap;
1238 this.componentServiceNg2
1239 .filterComponentInstanceProperties(this.component, filterData)
1240 .subscribe((response) => {
1241 this.processInstancePropertiesResponse(response, false);
1242 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1243 this.searchPropertyName = filterData.propertyName;//mark in table
1244 this.hierarchyNavTabs.triggerTabChange('Composition');
1245 this.propertiesNavigationData = [];
1246 this.displayClearSearch = true;
1247 }, (error) => {}); //ignore error
1251 clearSearch = () => {
1252 this.instancesNavigationData = this.instances;
1253 this.searchPropertyName = "";
1254 this.hierarchyPropertiesDisplayOptions.searchText = "";
1255 this.displayClearSearch = false;
1256 this.advanceSearch.clearAll();
1257 this.searchQuery = '';
1260 clickOnClearSearch = () => {
1262 this.selectFirstInstanceByDefault();
1263 this.hierarchyNavTabs.triggerTabChange('Composition');
1266 private isInput = (instanceType:string):boolean =>{
1267 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1270 loadDataTypesByComponentModel(model:string) {
1271 this.propertyCreatorComponent.filterDataTypesByModel(model);