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,
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 {InputListComponent} from "./input-list/input-list.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";
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 showAddProperties = (): boolean => {
254 if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
257 return this.isSelf();
260 getServiceProperties() {
261 this.loadingProperties = true;
262 this.topologyTemplateService
263 .getServiceProperties(this.component.uniqueId)
264 .subscribe((response) => {
265 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
266 this.serviceBePropertiesMap[this.component.uniqueId] = response;
267 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
268 this.loadingProperties = false;
270 this.loadingProperties = false;
274 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
275 // stop if has changed properties
276 if (this.hasChangedData) {
277 this.showUnsavedChangesAlert().then((resolve) => {
278 this.changeSelectedInstance(instance)
283 this.changeSelectedInstance(instance);
286 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
287 this.selectedInstanceData = instance;
288 this.loadingProperties = true;
289 if (instance instanceof ComponentInstance) {
290 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
291 if (this.isInput(instance.originType)) {
292 this.componentInstanceServiceNg2
293 .getComponentInstanceInputs(this.component, instance)
294 .subscribe(response => {
295 instanceBePropertiesMap[instance.uniqueId] = response;
296 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
300 this.loadingProperties = false;
302 } else if (this.isSelf()) {
303 this.getServiceProperties();
305 this.componentInstanceServiceNg2
306 .getComponentInstanceProperties(this.component, instance.uniqueId)
307 .subscribe(response => {
308 instanceBePropertiesMap[instance.uniqueId] = response;
309 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
313 this.loadingProperties = false;
316 this.loadingProperties = false;
317 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
318 } else if (instance instanceof GroupInstance) {
319 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
320 this.componentInstanceServiceNg2
321 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
322 .subscribe((response) => {
323 instanceBePropertiesMap[instance.uniqueId] = response;
324 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
328 this.loadingProperties = false;
330 } else if (instance instanceof PolicyInstance) {
331 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
332 this.componentInstanceServiceNg2
333 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
334 .subscribe((response) => {
335 instanceBePropertiesMap[instance.uniqueId] = response;
336 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
340 this.loadingProperties = false;
343 this.loadingProperties = false;
346 if (this.searchPropertyName) {
349 //clear selected property from the navigation
350 this.selectedFlatProperty = new SimpleFlatProperty();
351 this.propertiesNavigationData = [];
355 * Entry point handling response from server
357 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
358 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
359 this.checkedPropertiesCount = 0;
360 this.checkedChildPropertiesCount = 0;
363 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
364 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
365 let currentUniqueId = this.selectedInstanceData.uniqueId;
366 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
367 let isCapabilityOwnedByInstance: boolean;
368 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
369 this.selectedInstance_FlattenCapabilitiesList,
370 (result, cap: Capability) => {
371 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
372 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
373 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
374 if (cap.properties && isCapabilityOwnedByInstance) {
375 _.forEach(cap.properties, prop => {
376 if (!prop.origName) {
377 prop.origName = prop.name;
378 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
381 return result.concat(cap.properties);
385 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
386 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
387 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
388 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
390 //concatenate capabilitiesProps to all props list
391 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
392 this.checkedPropertiesCount = 0;
395 isCapabilityProperty = (prop: PropertyBEModel) => {
396 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
399 /*** VALUE CHANGE EVENTS ***/
400 dataChanged = (item: PropertyFEModel | InputFEModel) => {
402 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
403 itemHasChanged = item.hasValueObjChanged();
404 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
405 itemHasChanged = item.hasChanged();
406 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
407 itemHasChanged = item.hasDefaultValueChanged();
410 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
411 if (itemHasChanged) {
412 if (dataChangedIdx === -1) {
413 this.changedData.push(item);
416 if (dataChangedIdx !== -1) {
417 this.changedData.splice(dataChangedIdx, 1);
421 if (this.isPropertiesTabSelected) {
422 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
423 } else if (this.isInputsTabSelected) {
424 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
425 } else if (this.isPoliciesTabSelected) {
426 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
428 this.updateHasChangedData();
432 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
435 * Handle select node in navigation area, and select the row in table
437 onPropertySelectedUpdate = ($event) => {
438 console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
439 this.selectedFlatProperty = $event;
440 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
441 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
445 * When user select row in table, this will prepare the hirarchy object for the tree.
447 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
448 console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
449 let property = propertyRowSelectedEvent.propertyModel;
450 let instanceName = propertyRowSelectedEvent.instanceName;
451 this.propertyStructureHeader = null;
453 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
454 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
455 let simpleFlatProperty: Array<SimpleFlatProperty>;
456 if (property instanceof PropertyFEModel) {
457 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
458 } else if (property instanceof DerivedFEProperty) {
459 // Need to find parent PropertyFEModel
460 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
461 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
463 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
465 this.propertiesNavigationData = simpleFlatProperty;
468 // Update the header in the navigation tree with property name.
469 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
471 // Set selected property in table
472 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
473 this.hierarchyNavTabs.triggerTabChange('Property Structure');
477 selectInstanceRow = ($event) => {//get instance name
478 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
479 return instance.name == $event;
481 this.hierarchyNavTabs.triggerTabChange('Composition');
484 tabChanged = (event) => {
485 // stop if has changed properties
486 if (this.hasChangedData) {
487 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
488 this.showUnsavedChangesAlert().then((proceed) => {
489 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
495 console.log("==>" + this.constructor.name + ": tabChanged " + event);
496 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
497 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
498 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
499 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
500 this.propertyStructureHeader = null;
501 this.searchQuery = '';
504 /**Select Properties value from defined input values**/
505 selectInput = (): void => {
506 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
507 angular.forEach(instancesIds, (instanceId: string): void => {
508 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId
509 && instance instanceof ComponentInstance);
510 if (selectedInstanceData) {
511 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
512 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
513 this.propertiesService.setCheckedPropertyType(property.type);
514 if (property.toscaGetFunctionType != null) {
515 this.loadingProperties = true;
516 property.getInputValues = null;
517 property.value = null;
518 property.toscaGetFunctionType = null;
519 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
521 let modalTitle = 'Select value from Input';
522 const modal = this.ModalService.createCustomModal(new ModalModel(
527 new ButtonModel('Save', 'blue',
529 this.loadingProperties = true;
530 let selectInputValue: InputFEModel = modal.instance.dynamicContent.instance.selectInputValue;
531 property.getInputValues = [];
532 const propertyInputDetail = new PropertyInputDetail();
533 propertyInputDetail.inputId = selectInputValue.uniqueId;
534 propertyInputDetail.inputName = selectInputValue.name;
535 propertyInputDetail.inputType = selectInputValue.type;
536 property.getInputValues.push(propertyInputDetail);
537 property.value = selectInputValue.name.indexOf("->") !== -1
538 ? '{"get_input":[' + selectInputValue.name.replace("->", ", ") + ']}'
539 : '{"get_input":"' + selectInputValue.name+ '"}' ;
540 property.toscaGetFunctionType = ToscaGetFunctionType.GET_INPUT;
541 this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
542 modal.instance.close();
545 new ButtonModel('Cancel', 'outline grey', () => {
546 modal.instance.close();
551 this.ModalService.addDynamicContentToModal(modal, InputListComponent);
552 modal.instance.open();
559 updateInstancePropertiesWithInput(checkedProperties: PropertyBEModel[], selectedInstanceData: any) {
560 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
561 this.selectedInstanceData.uniqueId, checkedProperties)
563 this.changeSelectedInstance(selectedInstanceData);
565 this.Notification.error({
566 message: 'Failed to select/deselect get_input call: ' + error,
570 this.loadingProperties = false;
571 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
575 selectInputBtnLabel = () => {
576 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
577 angular.forEach(instancesIds, (instanceId: string): void => {
578 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
579 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
580 if(this.checkedPropertiesCount == 1) {
581 if (property.toscaGetFunctionType == null) {
582 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
584 this.btnSelectInputText = this.translateService.translate('DESELECT_INPUT_LABEL');
587 this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
594 /*** DECLARE PROPERTIES/INPUTS ***/
595 declareProperties = (): void => {
596 console.log("==>" + this.constructor.name + ": declareProperties");
598 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
599 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
600 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
601 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
602 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
604 angular.forEach(instancesIds, (instanceId: string): void => {
605 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
606 if (selectedInstanceData instanceof ComponentInstance) {
607 if (!this.isInput(selectedInstanceData.originType)) {
608 // convert Property FE model -> Property BE model, extract only checked
609 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
611 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
613 } else if (selectedInstanceData instanceof GroupInstance) {
614 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
615 } else if (selectedInstanceData instanceof PolicyInstance) {
616 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
620 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
622 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
623 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
624 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
626 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
627 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
630 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
631 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
632 prop => !this.isCapabilityProperty(prop)
634 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
635 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
638 let isCapabilityPropertyChanged = false;
640 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
641 (prop: PropertyBEModel) => {
642 prop.name = prop.origName || prop.name;
643 if (this.isCapabilityProperty(prop)) {
644 isCapabilityPropertyChanged = true;
648 this.topologyTemplateService
649 .createInput(this.component, inputsToCreate, this.isSelf())
650 .subscribe((response) => {
651 this.selectInstanceRow(SERVICE_SELF_TITLE);
652 this.onInstanceSelectedUpdate(this.instances[0]);
653 this.setInputTabIndication(response.length);
654 this.checkedPropertiesCount = 0;
655 this.checkedChildPropertiesCount = 0;
656 _.forEach(response, (input: InputBEModel) => {
657 const newInput: InputFEModel = new InputFEModel(input);
658 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
659 this.inputs.push(newInput);
660 this.updatePropertyValueAfterDeclare(newInput);
662 if (isCapabilityPropertyChanged) {
663 this.reloadInstanceCapabilities();
665 }, error => {}); //ignore error
668 declareListProperties = (): void => {
669 console.log('declareListProperties() - enter');
671 // get selected properties
672 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
673 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
674 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
675 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
676 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
677 let propertyNameList: Array<string> = [];
680 angular.forEach(instancesIds, (instanceId: string): void => {
681 console.log("instanceId="+instanceId);
683 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
684 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
686 if (selectedInstanceData instanceof ComponentInstance) {
687 if (!this.isInput(selectedInstanceData.originType)) {
688 // convert Property FE model -> Property BE model, extract only checked
689 selectedComponentInstancesProperties[instanceId] = checkedProperties;
691 selectedComponentInstancesInputs[instanceId] = checkedProperties;
693 } else if (selectedInstanceData instanceof GroupInstance) {
694 selectedGroupInstancesProperties[instanceId] = checkedProperties;
695 } else if (selectedInstanceData instanceof PolicyInstance) {
696 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
699 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
700 propertyNameList.push(property.name);
704 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
706 let modalTitle = 'Declare Properties as List Input';
707 const modal = this.ModalService.createCustomModal(new ModalModel(
709 modalTitle, /* title */
714 'blue', /* css class */
715 () => { /* callback */
716 let content:any = modal.instance.dynamicContent.instance;
719 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
720 let typelist: any = PROPERTY_TYPES.LIST;
721 let uniID: any = insId;
722 let boolfalse: any = false;
723 let required: any = content.propertyModel.required;
727 "type": content.propertyModel.simpleType,
731 let schemaProp :any = {
732 "type": content.propertyModel.simpleType,
736 reglistInput.description = content.propertyModel.description;
737 reglistInput.name = content.propertyModel.name;
738 reglistInput.type = typelist;
739 reglistInput.schemaType = content.propertyModel.simpleType;
740 reglistInput.instanceUniqueId = uniID;
741 reglistInput.uniqueId = uniID;
742 reglistInput.required = required;
743 reglistInput.schema = schem;
744 reglistInput.schemaProperty = schemaProp;
747 componentInstInputsMap: content.inputsToCreate,
748 listInput: reglistInput
750 console.log("save button clicked. input=", input);
752 this.topologyTemplateService
753 .createListInput(this.component, input, this.isSelf())
754 .subscribe(response => {
755 this.setInputTabIndication(response.length);
756 this.checkedPropertiesCount = 0;
757 this.checkedChildPropertiesCount = 0;
758 _.forEach(response, (input: InputBEModel) => {
759 let newInput: InputFEModel = new InputFEModel(input);
760 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
761 this.inputs.push(newInput);
762 // create list input does not return updated properties info, so need to reload
763 //this.updatePropertyValueAfterDeclare(newInput);
764 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
765 this.changeSelectedInstance(this.selectedInstanceData);
767 modal.instance.close();
769 }, error => {}); //ignore error
772 /*, getDisabled: function */
774 new ButtonModel('Cancel', 'outline grey', () => {
775 modal.instance.close();
780 // 3rd arg is passed to DeclareListComponent instance
781 this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
782 modal.instance.open();
783 console.log('declareListProperties() - leave');
786 /*** DECLARE PROPERTIES/POLICIES ***/
787 declarePropertiesToPolicies = (): void => {
788 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
789 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
791 angular.forEach(instancesIds, (instanceId: string): void => {
792 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
793 if (selectedInstanceData instanceof ComponentInstance) {
794 if (!this.isInput(selectedInstanceData.originType)) {
795 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
800 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
801 this.loadingPolicies = true;
803 this.topologyTemplateService
804 .createPolicy(this.component, policiesToCreate, this.isSelf())
805 .subscribe(response => {
806 this.setPolicyTabIndication(response.length);
807 this.checkedPropertiesCount = 0;
808 this.displayPoliciesAsDeclared(response);
809 this.loadingPolicies = false;
814 displayPoliciesAsDeclared = (policies) => {
815 _.forEach(policies, (policy: any) => {
816 let newPolicy: InputFEModel = new InputFEModel(policy);
817 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
818 newPolicy.relatedPropertyName = policy.name;
819 newPolicy.relatedPropertyValue = policy.value;
820 this.updatePropertyValueAfterDeclare(newPolicy);
821 this.policies.push(policy);
825 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
826 return new Promise((resolve, reject) => {
827 if (!this.isValidChangedData) {
828 reject('Changed data is invalid - cannot save!');
831 if (!this.changedData.length) {
836 // make request and its handlers
838 let handleSuccess, handleError;
839 let changedInputsProperties = [], changedCapabilitiesProperties = [];
840 if (this.isPropertiesTabSelected) {
841 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
842 changedProp = <PropertyFEModel>changedProp;
843 const propBE = new PropertyBEModel(changedProp);
844 propBE.toscaPresentation = new ToscaPresentationData();
845 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
846 propBE.value = changedProp.getJSONValue();
847 propBE.name = changedProp.origName || changedProp.name;
848 delete propBE.origName;
851 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
853 if (this.selectedInstanceData instanceof ComponentInstance) {
854 if (this.isInput(this.selectedInstanceData.originType)) {
855 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
856 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
857 request = Observable.forkJoin(
858 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
859 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
860 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
863 else if (changedInputsProperties.length) {
864 request = this.componentInstanceServiceNg2
865 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
867 else if (changedCapabilitiesProperties.length) {
868 request = this.componentInstanceServiceNg2
869 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
871 handleSuccess = (response) => {
872 // reset each changed property with new value and remove it from changed properties list
873 response.forEach((resInput) => {
874 const changedProp = <PropertyFEModel>this.changedData.shift();
875 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
877 console.log('updated instance inputs:', response);
881 console.log("changedProperties", changedProperties);
882 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
883 delete cp.constraints;
887 request = this.componentInstanceServiceNg2
888 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
890 handleSuccess = (response) => {
891 // reset each changed property with new value and remove it from changed properties list
892 response.forEach((resProp) => {
893 const changedProp = <PropertyFEModel>this.changedData.shift();
894 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
897 console.log("updated instance properties: ", response);
900 } else if (this.selectedInstanceData instanceof GroupInstance) {
901 request = this.componentInstanceServiceNg2
902 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
903 handleSuccess = (response) => {
904 // reset each changed property with new value and remove it from changed properties list
905 response.forEach((resProp) => {
906 const changedProp = <PropertyFEModel>this.changedData.shift();
907 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
910 console.log("updated group instance properties: ", response);
912 } else if (this.selectedInstanceData instanceof PolicyInstance) {
913 request = this.componentInstanceServiceNg2
914 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
915 handleSuccess = (response) => {
916 // reset each changed property with new value and remove it from changed properties list
917 response.forEach((resProp) => {
918 const changedProp = <PropertyFEModel>this.changedData.shift();
919 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
922 console.log("updated policy instance properties: ", response);
925 } else if (this.isInputsTabSelected) {
927 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
928 changedInput = <InputFEModel>changedInput;
929 const inputBE = new InputBEModel(changedInput);
930 inputBE.defaultValue = changedInput.getJSONDefaultValue();
933 request = this.componentServiceNg2
934 .updateComponentInputs(this.component, changedInputs);
935 handleSuccess = (response) => {
936 // reset each changed property with new value and remove it from changed properties list
937 response.forEach((resInput) => {
938 const changedInput = <InputFEModel>this.changedData.shift();
939 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
940 changedInput.required = resInput.required;
941 changedInput.requiredOrig = resInput.required;
943 console.log("updated the component inputs and got this response: ", response);
947 this.savingChangedData = true;
950 this.savingChangedData = false;
951 if (changedCapabilitiesProperties.length) {
952 this.reloadInstanceCapabilities();
954 handleSuccess && handleSuccess(response);
955 this.updateHasChangedData();
959 this.savingChangedData = false;
960 handleError && handleError(error);
961 this.updateHasChangedData();
968 reloadInstanceCapabilities = (): void => {
969 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
970 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
971 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
972 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
973 return instance.capabilities;
976 }, new CapabilitiesGroup());
977 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
981 reverseChangedData = ():void => {
982 // make reverse item handler
983 let handleReverseItem;
984 if (this.isPropertiesTabSelected) {
985 handleReverseItem = (changedItem) => {
986 changedItem = <PropertyFEModel>changedItem;
987 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
989 } else if (this.isInputsTabSelected) {
990 handleReverseItem = (changedItem) => {
991 changedItem = <InputFEModel>changedItem;
992 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
993 changedItem.resetMetadata();
994 changedItem.required = changedItem.requiredOrig;
998 this.changedData.forEach(handleReverseItem);
999 this.changedData = [];
1000 this.updateHasChangedData();
1003 updateHasChangedData = ():boolean => {
1004 const curHasChangedData:boolean = (this.changedData.length > 0);
1005 if (curHasChangedData !== this.hasChangedData) {
1006 this.hasChangedData = curHasChangedData;
1007 if(this.hasChangedData) {
1008 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1010 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1013 return this.hasChangedData;
1016 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1017 this.saveChangedData().then(
1019 this.Notification.success({
1020 message: 'Successfully saved changes',
1023 if(onSuccessFunction) onSuccessFunction();
1026 this.Notification.error({
1027 message: 'Failed to save changes!',
1030 if(onError) onError();
1035 showUnsavedChangesAlert = ():Promise<any> => {
1036 let modalTitle:string;
1037 if (this.isPropertiesTabSelected) {
1038 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1039 } else if (this.isInputsTabSelected) {
1040 modalTitle = `Unsaved inputs for ${this.component.name}`;
1043 return new Promise<any>((resolve, reject) => {
1044 const modal = this.ModalServiceSdcUI.openCustomModal(
1048 type: SdcUiCommon.ModalType.custom,
1049 testId: "navigate-modal",
1052 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1053 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1054 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1055 ] as SdcUiCommon.IModalButtonComponent[]
1056 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1061 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1062 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1063 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1064 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1065 return feProperty.name == input.relatedPropertyName &&
1066 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1068 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1069 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1070 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1071 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1075 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1076 updateCheckedPropertyCount = (increment: boolean): void => {
1077 this.checkedPropertiesCount += (increment) ? 1 : -1;
1078 console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1079 this.selectInputBtnLabel();
1082 updateCheckedChildPropertyCount = (increment: boolean): void => {
1083 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1086 setInputTabIndication = (numInputs: number): void => {
1087 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1090 setPolicyTabIndication = (numPolicies: number): void => {
1091 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1094 resetUnsavedChangesForInput = (input:InputFEModel) => {
1095 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1096 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1097 this.updateHasChangedData();
1100 deleteInput = (input: InputFEModel) => {
1101 //reset any unsaved changes to the input before deleting it
1102 this.resetUnsavedChangesForInput(input);
1104 console.log("==>" + this.constructor.name + ": deleteInput");
1105 let inputToDelete = new InputBEModel(input);
1107 this.componentServiceNg2
1108 .deleteInput(this.component, inputToDelete)
1109 .subscribe(response => {
1110 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1112 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1113 this.changeSelectedInstance(this.selectedInstanceData);
1114 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1116 // if (instanceFeProperties) {
1117 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1118 // return prop.name == input.propertyName;
1121 // if (propToEnable) {
1122 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1123 // propToEnable.setNonDeclared(response.inputPath);
1124 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1125 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1128 }, error => {}); //ignore error
1131 deletePolicy = (policy: PolicyInstance) => {
1132 this.loadingPolicies = true;
1133 this.topologyTemplateService
1134 .deletePolicy(this.component, policy)
1135 .subscribe((response) => {
1136 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1137 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1138 this.changeSelectedInstance(this.selectedInstanceData);
1139 this.loadingPolicies = false;
1143 deleteProperty = (property: PropertyFEModel) => {
1144 const propertyToDelete = new PropertyFEModel(property);
1145 this.loadingProperties = true;
1146 const feMap = this.instanceFePropertiesMap;
1147 this.topologyTemplateService
1148 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1149 .subscribe((response) => {
1150 const props = feMap[this.component.uniqueId];
1151 props.splice(props.findIndex(p => p.uniqueId === response),1);
1152 this.loadingProperties = false;
1154 this.loadingProperties = false;
1155 console.error(error);
1159 /*** addProperty ***/
1160 addProperty = (model: string) => {
1161 this.loadDataTypesByComponentModel(model)
1162 let modalTitle = 'Add Property';
1163 let modal = this.ModalService.createCustomModal(new ModalModel(
1168 new ButtonModel('Save', 'blue', () => {
1169 modal.instance.dynamicContent.instance.isLoading = true;
1170 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1171 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1172 .subscribe((response) => {
1173 modal.instance.dynamicContent.instance.isLoading = false;
1174 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1175 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1176 modal.instance.close();
1178 modal.instance.dynamicContent.instance.isLoading = false;
1179 this.Notification.error({
1180 message: 'Failed to add property:' + error,
1184 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1185 new ButtonModel('Cancel', 'outline grey', () => {
1186 modal.instance.close();
1191 modal.instance.open();
1192 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1197 let modalTitle = 'Add Input';
1198 let modal = this.ModalService.createCustomModal(new ModalModel(
1203 new ButtonModel('Save', 'blue', () => {
1204 modal.instance.dynamicContent.instance.isLoading = true;
1205 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1206 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1207 .subscribe((response) => {
1208 modal.instance.dynamicContent.instance.isLoading = false;
1209 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1210 this.inputs.push(newInputProp);
1211 modal.instance.close();
1213 modal.instance.dynamicContent.instance.isLoading = false;
1214 this.Notification.error({
1215 message: 'Failed to add input:' + error,
1219 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1220 new ButtonModel('Cancel', 'outline grey', () => {
1221 modal.instance.close();
1226 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1227 modal.instance.open();
1230 /*** SEARCH RELATED FUNCTIONS ***/
1231 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1232 let instanceBePropertiesMap:InstanceBePropertiesMap;
1233 this.componentServiceNg2
1234 .filterComponentInstanceProperties(this.component, filterData)
1235 .subscribe((response) => {
1236 this.processInstancePropertiesResponse(response, false);
1237 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1238 this.searchPropertyName = filterData.propertyName;//mark in table
1239 this.hierarchyNavTabs.triggerTabChange('Composition');
1240 this.propertiesNavigationData = [];
1241 this.displayClearSearch = true;
1242 }, (error) => {}); //ignore error
1246 clearSearch = () => {
1247 this.instancesNavigationData = this.instances;
1248 this.searchPropertyName = "";
1249 this.hierarchyPropertiesDisplayOptions.searchText = "";
1250 this.displayClearSearch = false;
1251 this.advanceSearch.clearAll();
1252 this.searchQuery = '';
1255 clickOnClearSearch = () => {
1257 this.selectFirstInstanceByDefault();
1258 this.hierarchyNavTabs.triggerTabChange('Composition');
1261 private isInput = (instanceType:string):boolean =>{
1262 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1265 loadDataTypesByComponentModel(model:string) {
1266 this.propertyCreatorComponent.filterDataTypesByModel(model);