2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 import * as _ from "lodash";
22 import {Component, Inject, ViewChild} from "@angular/core";
23 import {PropertiesService} from "../../services/properties.service";
26 Component as ComponentData,
29 FilterPropertiesAssignmentData,
33 InstanceBePropertiesMap,
34 InstanceFePropertiesMap,
35 InstancePropertiesAPIMap,
43 import {ResourceType} from "app/utils";
44 import {ComponentServiceNg2} from "../../services/component-services/component.service";
45 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
46 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
47 import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
48 import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
49 import {EventListenerService} from "app/services/event-listener-service"
50 import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
51 import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
52 import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component";
53 import {HierarchyNavService} from "./services/hierarchy-nav.service";
54 import {PropertiesUtils} from "./services/properties.utils";
55 import {ComponentModeService} from "../../services/component-services/component-mode.service";
56 import {Tab, Tabs} from "../../components/ui/tabs/tabs.component";
57 import {InputsUtils} from "./services/inputs.utils";
58 import {InstanceFeDetails} from "../../../models/instance-fe-details";
59 import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
60 import {UnsavedChangesComponent} from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
61 import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
62 import {ModalService} from "../../services/modal.service";
63 import {DeclareListComponent} from "./declare-list/declare-list.component";
64 import {InputListComponent} from "./input-list/input-list.component";
65 import {CapabilitiesGroup, Capability} from "../../../models/capability";
66 import {ToscaPresentationData} from "../../../models/tosca-presentation";
67 import {Observable} from "rxjs";
68 import {ToscaGetFunctionType} from "../../../models/tosca-get-function-type.enum";
69 import {TranslateService} from "../../shared/translator/translate.service";
70 import {Model} from '../../../models/model';
72 const SERVICE_SELF_TITLE = "SELF";
74 templateUrl: './properties-assignment.page.component.html',
75 styleUrls: ['./properties-assignment.page.component.less']
77 export class PropertiesAssignmentComponent {
78 title = "Properties & Inputs";
80 component: ComponentData;
81 componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
83 propertiesNavigationData = [];
84 instancesNavigationData = [];
86 instanceFePropertiesMap: InstanceFePropertiesMap;
87 inputs: Array<InputFEModel> = [];
88 policies: Array<PolicyInstance> = [];
89 instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
91 propertyStructureHeader: string;
93 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
94 selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
95 checkedPropertiesCount: number = 0;
96 checkedChildPropertiesCount: number = 0;
98 hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
99 hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
100 displayClearSearch = false;
101 searchPropertyName: string;
103 isInputsTabSelected: boolean;
104 isPropertiesTabSelected: boolean;
105 isInputValueSelected: boolean = false;
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 propertyType: string;
122 btnSelectInputText: 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.log("==>" + this.constructor.name + ": ngOnInit");
160 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_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 getServiceProperties() {
254 this.loadingProperties = true;
255 this.topologyTemplateService
256 .getServiceProperties(this.component.uniqueId)
257 .subscribe((response) => {
258 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
259 this.serviceBePropertiesMap[this.component.uniqueId] = response;
260 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
261 this.loadingProperties = false;
263 this.loadingProperties = false;
267 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
268 // stop if has changed properties
269 if (this.hasChangedData) {
270 this.showUnsavedChangesAlert().then((resolve) => {
271 this.changeSelectedInstance(instance)
276 this.changeSelectedInstance(instance);
279 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
280 this.selectedInstanceData = instance;
281 this.loadingProperties = true;
282 if (instance instanceof ComponentInstance) {
283 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
284 if (this.isInput(instance.originType)) {
285 this.componentInstanceServiceNg2
286 .getComponentInstanceInputs(this.component, instance)
287 .subscribe(response => {
288 instanceBePropertiesMap[instance.uniqueId] = response;
289 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
293 this.loadingProperties = false;
295 } else if (this.isSelf()) {
296 this.getServiceProperties();
298 this.componentInstanceServiceNg2
299 .getComponentInstanceProperties(this.component, instance.uniqueId)
300 .subscribe(response => {
301 instanceBePropertiesMap[instance.uniqueId] = response;
302 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
306 this.loadingProperties = false;
309 this.loadingProperties = false;
310 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
311 } else if (instance instanceof GroupInstance) {
312 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
313 this.componentInstanceServiceNg2
314 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
315 .subscribe((response) => {
316 instanceBePropertiesMap[instance.uniqueId] = response;
317 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
321 this.loadingProperties = false;
323 } else if (instance instanceof PolicyInstance) {
324 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
325 this.componentInstanceServiceNg2
326 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
327 .subscribe((response) => {
328 instanceBePropertiesMap[instance.uniqueId] = response;
329 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
333 this.loadingProperties = false;
336 this.loadingProperties = false;
339 if (this.searchPropertyName) {
342 //clear selected property from the navigation
343 this.selectedFlatProperty = new SimpleFlatProperty();
344 this.propertiesNavigationData = [];
348 * Entry point handling response from server
350 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
351 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
352 this.checkedPropertiesCount = 0;
353 this.checkedChildPropertiesCount = 0;
356 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
357 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
358 let currentUniqueId = this.selectedInstanceData.uniqueId;
359 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
360 let isCapabilityOwnedByInstance: boolean;
361 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
362 this.selectedInstance_FlattenCapabilitiesList,
363 (result, cap: Capability) => {
364 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
365 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
366 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
367 if (cap.properties && isCapabilityOwnedByInstance) {
368 _.forEach(cap.properties, prop => {
369 if (!prop.origName) {
370 prop.origName = prop.name;
371 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
374 return result.concat(cap.properties);
378 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
379 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
380 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
381 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
383 //concatenate capabilitiesProps to all props list
384 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
385 this.checkedPropertiesCount = 0;
388 isCapabilityProperty = (prop: PropertyBEModel) => {
389 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
392 /*** VALUE CHANGE EVENTS ***/
393 dataChanged = (item: PropertyFEModel | InputFEModel) => {
395 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
396 itemHasChanged = item.hasValueObjChanged();
397 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
398 itemHasChanged = item.hasChanged();
399 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
400 itemHasChanged = item.hasDefaultValueChanged();
403 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
404 if (itemHasChanged) {
405 if (dataChangedIdx === -1) {
406 this.changedData.push(item);
409 if (dataChangedIdx !== -1) {
410 this.changedData.splice(dataChangedIdx, 1);
414 if (this.isPropertiesTabSelected) {
415 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
416 } else if (this.isInputsTabSelected) {
417 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
418 } else if (this.isPoliciesTabSelected) {
419 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
421 this.updateHasChangedData();
425 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
428 * Handle select node in navigation area, and select the row in table
430 onPropertySelectedUpdate = ($event) => {
431 console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
432 this.selectedFlatProperty = $event;
433 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
434 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
438 * When user select row in table, this will prepare the hirarchy object for the tree.
440 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
441 console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
442 let property = propertyRowSelectedEvent.propertyModel;
443 let instanceName = propertyRowSelectedEvent.instanceName;
444 this.propertyStructureHeader = null;
446 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
447 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
448 let simpleFlatProperty: Array<SimpleFlatProperty>;
449 if (property instanceof PropertyFEModel) {
450 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
451 } else if (property instanceof DerivedFEProperty) {
452 // Need to find parent PropertyFEModel
453 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
454 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
456 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
458 this.propertiesNavigationData = simpleFlatProperty;
461 // Update the header in the navigation tree with property name.
462 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
464 // Set selected property in table
465 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
466 this.hierarchyNavTabs.triggerTabChange('Property Structure');
470 selectInstanceRow = ($event) => {//get instance name
471 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
472 return instance.name == $event;
474 this.hierarchyNavTabs.triggerTabChange('Composition');
477 tabChanged = (event) => {
478 // stop if has changed properties
479 if (this.hasChangedData) {
480 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
481 this.showUnsavedChangesAlert().then((proceed) => {
482 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
488 console.log("==>" + this.constructor.name + ": tabChanged " + event);
489 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
490 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
491 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
492 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
493 this.propertyStructureHeader = null;
494 this.searchQuery = '';
497 /**Select Properties value from defined input values**/
498 selectInput = (): void => {
499 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
500 angular.forEach(instancesIds, (instanceId: string): void => {
501 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId
502 && instance instanceof ComponentInstance);
503 if (selectedInstanceData) {
504 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
505 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
506 this.propertiesService.setCheckedPropertyType(property.type);
507 if (property.toscaGetFunctionType != null) {
508 this.loadingProperties = true;
509 property.getInputValues = null;
510 property.value = null;
511 property.toscaGetFunctionType = null;
512 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
514 let modalTitle = 'Select value from Input';
515 const modal = this.ModalService.createCustomModal(new ModalModel(
520 new ButtonModel('Save', 'blue',
522 this.loadingProperties = true;
523 let selectInputValue: InputFEModel = modal.instance.dynamicContent.instance.selectInputValue;
524 property.getInputValues = [];
525 const propertyInputDetail = new PropertyInputDetail();
526 propertyInputDetail.inputId = selectInputValue.uniqueId;
527 propertyInputDetail.inputName = selectInputValue.name;
528 propertyInputDetail.inputType = selectInputValue.type;
529 property.getInputValues.push(propertyInputDetail);
530 property.value = '{"get_input":"' + selectInputValue.name + '"}';
531 property.toscaGetFunctionType = ToscaGetFunctionType.GET_INPUT;
532 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
533 modal.instance.close();
536 new ButtonModel('Cancel', 'outline grey', () => {
537 modal.instance.close();
542 this.ModalService.addDynamicContentToModal(modal, InputListComponent);
543 modal.instance.open();
550 updateInstancePropertiesWithInput(checkedProperties: PropertyBEModel[], selectedInstanceData: any) {
551 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
552 this.selectedInstanceData.uniqueId, checkedProperties)
554 this.changeSelectedInstance(selectedInstanceData);
556 this.Notification.error({
557 message: 'Failed to select/deselect get_input call: ' + error,
561 this.loadingProperties = false;
562 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
566 selectInputBtnLabel = () => {
567 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
568 angular.forEach(instancesIds, (instanceId: string): void => {
569 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
570 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
571 if(this.checkedPropertiesCount == 1) {
572 if (property.toscaGetFunctionType == null) {
573 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
575 this.btnSelectInputText = this.translateService.translate('DESELECT_INPUT_LABEL');
578 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
585 /*** DECLARE PROPERTIES/INPUTS ***/
586 declareProperties = (): void => {
587 console.log("==>" + this.constructor.name + ": declareProperties");
589 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
590 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
591 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
592 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
593 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
595 angular.forEach(instancesIds, (instanceId: string): void => {
596 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
597 if (selectedInstanceData instanceof ComponentInstance) {
598 if (!this.isInput(selectedInstanceData.originType)) {
599 // convert Property FE model -> Property BE model, extract only checked
600 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
602 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
604 } else if (selectedInstanceData instanceof GroupInstance) {
605 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
606 } else if (selectedInstanceData instanceof PolicyInstance) {
607 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
611 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
613 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
614 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
615 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
617 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
618 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
621 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
622 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
623 prop => !this.isCapabilityProperty(prop)
625 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
626 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
629 let isCapabilityPropertyChanged = false;
631 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
632 (prop: PropertyBEModel) => {
633 prop.name = prop.origName || prop.name;
634 if (this.isCapabilityProperty(prop)) {
635 isCapabilityPropertyChanged = true;
639 this.topologyTemplateService
640 .createInput(this.component, inputsToCreate, this.isSelf())
641 .subscribe((response) => {
642 this.setInputTabIndication(response.length);
643 this.checkedPropertiesCount = 0;
644 this.checkedChildPropertiesCount = 0;
645 _.forEach(response, (input: InputBEModel) => {
646 const newInput: InputFEModel = new InputFEModel(input);
647 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
648 this.inputs.push(newInput);
649 this.updatePropertyValueAfterDeclare(newInput);
651 if (isCapabilityPropertyChanged) {
652 this.reloadInstanceCapabilities();
654 }, error => {}); //ignore error
657 declareListProperties = (): void => {
658 console.log('declareListProperties() - enter');
660 // get selected properties
661 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
662 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
663 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
664 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
665 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
666 let propertyNameList: Array<string> = [];
669 angular.forEach(instancesIds, (instanceId: string): void => {
670 console.log("instanceId="+instanceId);
672 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
673 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
675 if (selectedInstanceData instanceof ComponentInstance) {
676 if (!this.isInput(selectedInstanceData.originType)) {
677 // convert Property FE model -> Property BE model, extract only checked
678 selectedComponentInstancesProperties[instanceId] = checkedProperties;
680 selectedComponentInstancesInputs[instanceId] = checkedProperties;
682 } else if (selectedInstanceData instanceof GroupInstance) {
683 selectedGroupInstancesProperties[instanceId] = checkedProperties;
684 } else if (selectedInstanceData instanceof PolicyInstance) {
685 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
688 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
689 propertyNameList.push(property.name);
693 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
695 let modalTitle = 'Declare Properties as List Input';
696 const modal = this.ModalService.createCustomModal(new ModalModel(
698 modalTitle, /* title */
703 'blue', /* css class */
704 () => { /* callback */
705 let content:any = modal.instance.dynamicContent.instance;
708 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
709 let typelist: any = PROPERTY_TYPES.LIST;
710 let uniID: any = insId;
711 let boolfalse: any = false;
712 let required: any = content.propertyModel.required;
716 "type": content.propertyModel.simpleType,
720 let schemaProp :any = {
721 "type": content.propertyModel.simpleType,
725 reglistInput.description = content.propertyModel.description;
726 reglistInput.name = content.propertyModel.name;
727 reglistInput.type = typelist;
728 reglistInput.schemaType = content.propertyModel.simpleType;
729 reglistInput.instanceUniqueId = uniID;
730 reglistInput.uniqueId = uniID;
731 reglistInput.required = required;
732 reglistInput.schema = schem;
733 reglistInput.schemaProperty = schemaProp;
736 componentInstInputsMap: content.inputsToCreate,
737 listInput: reglistInput
739 console.log("save button clicked. input=", input);
741 this.topologyTemplateService
742 .createListInput(this.component, input, this.isSelf())
743 .subscribe(response => {
744 this.setInputTabIndication(response.length);
745 this.checkedPropertiesCount = 0;
746 this.checkedChildPropertiesCount = 0;
747 _.forEach(response, (input: InputBEModel) => {
748 let newInput: InputFEModel = new InputFEModel(input);
749 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
750 this.inputs.push(newInput);
751 // create list input does not return updated properties info, so need to reload
752 //this.updatePropertyValueAfterDeclare(newInput);
753 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
754 this.changeSelectedInstance(this.selectedInstanceData);
756 modal.instance.close();
758 }, error => {}); //ignore error
761 /*, getDisabled: function */
763 new ButtonModel('Cancel', 'outline grey', () => {
764 modal.instance.close();
769 // 3rd arg is passed to DeclareListComponent instance
770 this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
771 modal.instance.open();
772 console.log('declareListProperties() - leave');
775 /*** DECLARE PROPERTIES/POLICIES ***/
776 declarePropertiesToPolicies = (): void => {
777 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
778 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
780 angular.forEach(instancesIds, (instanceId: string): void => {
781 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
782 if (selectedInstanceData instanceof ComponentInstance) {
783 if (!this.isInput(selectedInstanceData.originType)) {
784 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
789 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
790 this.loadingPolicies = true;
792 this.topologyTemplateService
793 .createPolicy(this.component, policiesToCreate, this.isSelf())
794 .subscribe(response => {
795 this.setPolicyTabIndication(response.length);
796 this.checkedPropertiesCount = 0;
797 this.displayPoliciesAsDeclared(response);
798 this.loadingPolicies = false;
803 displayPoliciesAsDeclared = (policies) => {
804 _.forEach(policies, (policy: any) => {
805 let newPolicy: InputFEModel = new InputFEModel(policy);
806 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
807 newPolicy.relatedPropertyName = policy.name;
808 newPolicy.relatedPropertyValue = policy.value;
809 this.updatePropertyValueAfterDeclare(newPolicy);
810 this.policies.push(policy);
814 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
815 return new Promise((resolve, reject) => {
816 if (!this.isValidChangedData) {
817 reject('Changed data is invalid - cannot save!');
820 if (!this.changedData.length) {
825 // make request and its handlers
827 let handleSuccess, handleError;
828 let changedInputsProperties = [], changedCapabilitiesProperties = [];
829 if (this.isPropertiesTabSelected) {
830 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
831 changedProp = <PropertyFEModel>changedProp;
832 const propBE = new PropertyBEModel(changedProp);
833 propBE.toscaPresentation = new ToscaPresentationData();
834 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
835 propBE.value = changedProp.getJSONValue();
836 propBE.name = changedProp.origName || changedProp.name;
837 delete propBE.origName;
840 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
842 if (this.selectedInstanceData instanceof ComponentInstance) {
843 if (this.isInput(this.selectedInstanceData.originType)) {
844 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
845 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
846 request = Observable.forkJoin(
847 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
848 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
849 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
852 else if (changedInputsProperties.length) {
853 request = this.componentInstanceServiceNg2
854 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
856 else if (changedCapabilitiesProperties.length) {
857 request = this.componentInstanceServiceNg2
858 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
860 handleSuccess = (response) => {
861 // reset each changed property with new value and remove it from changed properties list
862 response.forEach((resInput) => {
863 const changedProp = <PropertyFEModel>this.changedData.shift();
864 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
866 console.log('updated instance inputs:', response);
870 console.log("changedProperties", changedProperties);
871 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
872 delete cp.constraints;
876 request = this.componentInstanceServiceNg2
877 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
879 handleSuccess = (response) => {
880 // reset each changed property with new value and remove it from changed properties list
881 response.forEach((resProp) => {
882 const changedProp = <PropertyFEModel>this.changedData.shift();
883 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
886 console.log("updated instance properties: ", response);
889 } else if (this.selectedInstanceData instanceof GroupInstance) {
890 request = this.componentInstanceServiceNg2
891 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
892 handleSuccess = (response) => {
893 // reset each changed property with new value and remove it from changed properties list
894 response.forEach((resProp) => {
895 const changedProp = <PropertyFEModel>this.changedData.shift();
896 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
899 console.log("updated group instance properties: ", response);
901 } else if (this.selectedInstanceData instanceof PolicyInstance) {
902 request = this.componentInstanceServiceNg2
903 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
904 handleSuccess = (response) => {
905 // reset each changed property with new value and remove it from changed properties list
906 response.forEach((resProp) => {
907 const changedProp = <PropertyFEModel>this.changedData.shift();
908 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
911 console.log("updated policy instance properties: ", response);
914 } else if (this.isInputsTabSelected) {
916 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
917 changedInput = <InputFEModel>changedInput;
918 const inputBE = new InputBEModel(changedInput);
919 inputBE.defaultValue = changedInput.getJSONDefaultValue();
922 request = this.componentServiceNg2
923 .updateComponentInputs(this.component, changedInputs);
924 handleSuccess = (response) => {
925 // reset each changed property with new value and remove it from changed properties list
926 response.forEach((resInput) => {
927 const changedInput = <InputFEModel>this.changedData.shift();
928 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
929 changedInput.required = resInput.required;
930 changedInput.requiredOrig = resInput.required;
932 console.log("updated the component inputs and got this response: ", response);
936 this.savingChangedData = true;
939 this.savingChangedData = false;
940 if (changedCapabilitiesProperties.length) {
941 this.reloadInstanceCapabilities();
943 handleSuccess && handleSuccess(response);
944 this.updateHasChangedData();
948 this.savingChangedData = false;
949 handleError && handleError(error);
950 this.updateHasChangedData();
957 reloadInstanceCapabilities = (): void => {
958 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
959 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
960 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
961 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
962 return instance.capabilities;
965 }, new CapabilitiesGroup());
966 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
970 reverseChangedData = ():void => {
971 // make reverse item handler
972 let handleReverseItem;
973 if (this.isPropertiesTabSelected) {
974 handleReverseItem = (changedItem) => {
975 changedItem = <PropertyFEModel>changedItem;
976 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
978 } else if (this.isInputsTabSelected) {
979 handleReverseItem = (changedItem) => {
980 changedItem = <InputFEModel>changedItem;
981 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
982 changedItem.resetMetadata();
983 changedItem.required = changedItem.requiredOrig;
987 this.changedData.forEach(handleReverseItem);
988 this.changedData = [];
989 this.updateHasChangedData();
992 updateHasChangedData = ():boolean => {
993 const curHasChangedData:boolean = (this.changedData.length > 0);
994 if (curHasChangedData !== this.hasChangedData) {
995 this.hasChangedData = curHasChangedData;
996 if(this.hasChangedData) {
997 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
999 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1002 return this.hasChangedData;
1005 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1006 this.saveChangedData().then(
1008 this.Notification.success({
1009 message: 'Successfully saved changes',
1012 if(onSuccessFunction) onSuccessFunction();
1015 this.Notification.error({
1016 message: 'Failed to save changes!',
1019 if(onError) onError();
1024 showUnsavedChangesAlert = ():Promise<any> => {
1025 let modalTitle:string;
1026 if (this.isPropertiesTabSelected) {
1027 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1028 } else if (this.isInputsTabSelected) {
1029 modalTitle = `Unsaved inputs for ${this.component.name}`;
1032 return new Promise<any>((resolve, reject) => {
1033 const modal = this.ModalServiceSdcUI.openCustomModal(
1037 type: SdcUiCommon.ModalType.custom,
1038 testId: "navigate-modal",
1041 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1042 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1043 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1044 ] as SdcUiCommon.IModalButtonComponent[]
1045 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1050 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1051 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1052 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1053 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1054 return feProperty.name == input.relatedPropertyName &&
1055 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1057 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1058 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1059 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1060 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1064 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1065 updateCheckedPropertyCount = (increment: boolean): void => {
1066 this.checkedPropertiesCount += (increment) ? 1 : -1;
1067 console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1068 this.selectInputBtnLabel();
1071 updateCheckedChildPropertyCount = (increment: boolean): void => {
1072 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1075 setInputTabIndication = (numInputs: number): void => {
1076 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1079 setPolicyTabIndication = (numPolicies: number): void => {
1080 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1083 resetUnsavedChangesForInput = (input:InputFEModel) => {
1084 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1085 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1086 this.updateHasChangedData();
1089 deleteInput = (input: InputFEModel) => {
1090 //reset any unsaved changes to the input before deleting it
1091 this.resetUnsavedChangesForInput(input);
1093 console.log("==>" + this.constructor.name + ": deleteInput");
1094 let inputToDelete = new InputBEModel(input);
1096 this.componentServiceNg2
1097 .deleteInput(this.component, inputToDelete)
1098 .subscribe(response => {
1099 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1101 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1102 this.changeSelectedInstance(this.selectedInstanceData);
1103 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1105 // if (instanceFeProperties) {
1106 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1107 // return prop.name == input.propertyName;
1110 // if (propToEnable) {
1111 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1112 // propToEnable.setNonDeclared(response.inputPath);
1113 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1114 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1117 }, error => {}); //ignore error
1120 deletePolicy = (policy: PolicyInstance) => {
1121 this.loadingPolicies = true;
1122 this.topologyTemplateService
1123 .deletePolicy(this.component, policy)
1124 .subscribe((response) => {
1125 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1126 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1127 this.changeSelectedInstance(this.selectedInstanceData);
1128 this.loadingPolicies = false;
1132 deleteProperty = (property: PropertyFEModel) => {
1133 const propertyToDelete = new PropertyFEModel(property);
1134 this.loadingProperties = true;
1135 const feMap = this.instanceFePropertiesMap;
1136 this.topologyTemplateService
1137 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1138 .subscribe((response) => {
1139 const props = feMap[this.component.uniqueId];
1140 props.splice(props.findIndex(p => p.uniqueId === response),1);
1141 this.loadingProperties = false;
1143 this.loadingProperties = false;
1144 console.error(error);
1148 /*** addProperty ***/
1149 addProperty = (model: string) => {
1150 this.loadDataTypesByComponentModel(model)
1151 let modalTitle = 'Add Property';
1152 let modal = this.ModalService.createCustomModal(new ModalModel(
1157 new ButtonModel('Save', 'blue', () => {
1158 modal.instance.dynamicContent.instance.isLoading = true;
1159 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1160 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1161 .subscribe((response) => {
1162 modal.instance.dynamicContent.instance.isLoading = false;
1163 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1164 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1165 modal.instance.close();
1167 modal.instance.dynamicContent.instance.isLoading = false;
1168 this.Notification.error({
1169 message: 'Failed to add property:' + error,
1173 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1174 new ButtonModel('Cancel', 'outline grey', () => {
1175 modal.instance.close();
1180 modal.instance.open();
1181 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1186 let modalTitle = 'Add Input';
1187 let modal = this.ModalService.createCustomModal(new ModalModel(
1192 new ButtonModel('Save', 'blue', () => {
1193 modal.instance.dynamicContent.instance.isLoading = true;
1194 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1195 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1196 .subscribe((response) => {
1197 modal.instance.dynamicContent.instance.isLoading = false;
1198 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1199 this.inputs.push(newInputProp);
1200 modal.instance.close();
1202 modal.instance.dynamicContent.instance.isLoading = false;
1203 this.Notification.error({
1204 message: 'Failed to add input:' + error,
1208 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1209 new ButtonModel('Cancel', 'outline grey', () => {
1210 modal.instance.close();
1215 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1216 modal.instance.open();
1219 /*** SEARCH RELATED FUNCTIONS ***/
1220 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1221 let instanceBePropertiesMap:InstanceBePropertiesMap;
1222 this.componentServiceNg2
1223 .filterComponentInstanceProperties(this.component, filterData)
1224 .subscribe((response) => {
1225 this.processInstancePropertiesResponse(response, false);
1226 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1227 this.searchPropertyName = filterData.propertyName;//mark in table
1228 this.hierarchyNavTabs.triggerTabChange('Composition');
1229 this.propertiesNavigationData = [];
1230 this.displayClearSearch = true;
1231 }, (error) => {}); //ignore error
1235 clearSearch = () => {
1236 this.instancesNavigationData = this.instances;
1237 this.searchPropertyName = "";
1238 this.hierarchyPropertiesDisplayOptions.searchText = "";
1239 this.displayClearSearch = false;
1240 this.advanceSearch.clearAll();
1241 this.searchQuery = '';
1244 clickOnClearSearch = () => {
1246 this.selectFirstInstanceByDefault();
1247 this.hierarchyNavTabs.triggerTabChange('Composition');
1250 private isInput = (instanceType:string):boolean =>{
1251 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1254 loadDataTypesByComponentModel(model:string) {
1255 this.propertyCreatorComponent.filterDataTypesByModel(model);