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); //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.setInputTabIndication(response.length);
652 this.checkedPropertiesCount = 0;
653 this.checkedChildPropertiesCount = 0;
654 _.forEach(response, (input: InputBEModel) => {
655 const newInput: InputFEModel = new InputFEModel(input);
656 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
657 this.inputs.push(newInput);
658 this.updatePropertyValueAfterDeclare(newInput);
660 if (isCapabilityPropertyChanged) {
661 this.reloadInstanceCapabilities();
663 }, error => {}); //ignore error
666 declareListProperties = (): void => {
667 console.log('declareListProperties() - enter');
669 // get selected properties
670 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
671 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
672 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
673 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
674 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
675 let propertyNameList: Array<string> = [];
678 angular.forEach(instancesIds, (instanceId: string): void => {
679 console.log("instanceId="+instanceId);
681 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
682 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
684 if (selectedInstanceData instanceof ComponentInstance) {
685 if (!this.isInput(selectedInstanceData.originType)) {
686 // convert Property FE model -> Property BE model, extract only checked
687 selectedComponentInstancesProperties[instanceId] = checkedProperties;
689 selectedComponentInstancesInputs[instanceId] = checkedProperties;
691 } else if (selectedInstanceData instanceof GroupInstance) {
692 selectedGroupInstancesProperties[instanceId] = checkedProperties;
693 } else if (selectedInstanceData instanceof PolicyInstance) {
694 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
697 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
698 propertyNameList.push(property.name);
702 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
704 let modalTitle = 'Declare Properties as List Input';
705 const modal = this.ModalService.createCustomModal(new ModalModel(
707 modalTitle, /* title */
712 'blue', /* css class */
713 () => { /* callback */
714 let content:any = modal.instance.dynamicContent.instance;
717 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
718 let typelist: any = PROPERTY_TYPES.LIST;
719 let uniID: any = insId;
720 let boolfalse: any = false;
721 let required: any = content.propertyModel.required;
725 "type": content.propertyModel.simpleType,
729 let schemaProp :any = {
730 "type": content.propertyModel.simpleType,
734 reglistInput.description = content.propertyModel.description;
735 reglistInput.name = content.propertyModel.name;
736 reglistInput.type = typelist;
737 reglistInput.schemaType = content.propertyModel.simpleType;
738 reglistInput.instanceUniqueId = uniID;
739 reglistInput.uniqueId = uniID;
740 reglistInput.required = required;
741 reglistInput.schema = schem;
742 reglistInput.schemaProperty = schemaProp;
745 componentInstInputsMap: content.inputsToCreate,
746 listInput: reglistInput
748 console.log("save button clicked. input=", input);
750 this.topologyTemplateService
751 .createListInput(this.component, input, this.isSelf())
752 .subscribe(response => {
753 this.setInputTabIndication(response.length);
754 this.checkedPropertiesCount = 0;
755 this.checkedChildPropertiesCount = 0;
756 _.forEach(response, (input: InputBEModel) => {
757 let newInput: InputFEModel = new InputFEModel(input);
758 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
759 this.inputs.push(newInput);
760 // create list input does not return updated properties info, so need to reload
761 //this.updatePropertyValueAfterDeclare(newInput);
762 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
763 this.changeSelectedInstance(this.selectedInstanceData);
765 modal.instance.close();
767 }, error => {}); //ignore error
770 /*, getDisabled: function */
772 new ButtonModel('Cancel', 'outline grey', () => {
773 modal.instance.close();
778 // 3rd arg is passed to DeclareListComponent instance
779 this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
780 modal.instance.open();
781 console.log('declareListProperties() - leave');
784 /*** DECLARE PROPERTIES/POLICIES ***/
785 declarePropertiesToPolicies = (): void => {
786 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
787 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
789 angular.forEach(instancesIds, (instanceId: string): void => {
790 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
791 if (selectedInstanceData instanceof ComponentInstance) {
792 if (!this.isInput(selectedInstanceData.originType)) {
793 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
798 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
799 this.loadingPolicies = true;
801 this.topologyTemplateService
802 .createPolicy(this.component, policiesToCreate, this.isSelf())
803 .subscribe(response => {
804 this.setPolicyTabIndication(response.length);
805 this.checkedPropertiesCount = 0;
806 this.displayPoliciesAsDeclared(response);
807 this.loadingPolicies = false;
812 displayPoliciesAsDeclared = (policies) => {
813 _.forEach(policies, (policy: any) => {
814 let newPolicy: InputFEModel = new InputFEModel(policy);
815 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
816 newPolicy.relatedPropertyName = policy.name;
817 newPolicy.relatedPropertyValue = policy.value;
818 this.updatePropertyValueAfterDeclare(newPolicy);
819 this.policies.push(policy);
823 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
824 return new Promise((resolve, reject) => {
825 if (!this.isValidChangedData) {
826 reject('Changed data is invalid - cannot save!');
829 if (!this.changedData.length) {
834 // make request and its handlers
836 let handleSuccess, handleError;
837 let changedInputsProperties = [], changedCapabilitiesProperties = [];
838 if (this.isPropertiesTabSelected) {
839 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
840 changedProp = <PropertyFEModel>changedProp;
841 const propBE = new PropertyBEModel(changedProp);
842 propBE.toscaPresentation = new ToscaPresentationData();
843 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
844 propBE.value = changedProp.getJSONValue();
845 propBE.name = changedProp.origName || changedProp.name;
846 delete propBE.origName;
849 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
851 if (this.selectedInstanceData instanceof ComponentInstance) {
852 if (this.isInput(this.selectedInstanceData.originType)) {
853 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
854 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
855 request = Observable.forkJoin(
856 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
857 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
858 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
861 else if (changedInputsProperties.length) {
862 request = this.componentInstanceServiceNg2
863 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
865 else if (changedCapabilitiesProperties.length) {
866 request = this.componentInstanceServiceNg2
867 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
869 handleSuccess = (response) => {
870 // reset each changed property with new value and remove it from changed properties list
871 response.forEach((resInput) => {
872 const changedProp = <PropertyFEModel>this.changedData.shift();
873 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
875 console.log('updated instance inputs:', response);
879 console.log("changedProperties", changedProperties);
880 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
881 delete cp.constraints;
885 request = this.componentInstanceServiceNg2
886 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
888 handleSuccess = (response) => {
889 // reset each changed property with new value and remove it from changed properties list
890 response.forEach((resProp) => {
891 const changedProp = <PropertyFEModel>this.changedData.shift();
892 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
895 console.log("updated instance properties: ", response);
898 } else if (this.selectedInstanceData instanceof GroupInstance) {
899 request = this.componentInstanceServiceNg2
900 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
901 handleSuccess = (response) => {
902 // reset each changed property with new value and remove it from changed properties list
903 response.forEach((resProp) => {
904 const changedProp = <PropertyFEModel>this.changedData.shift();
905 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
908 console.log("updated group instance properties: ", response);
910 } else if (this.selectedInstanceData instanceof PolicyInstance) {
911 request = this.componentInstanceServiceNg2
912 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
913 handleSuccess = (response) => {
914 // reset each changed property with new value and remove it from changed properties list
915 response.forEach((resProp) => {
916 const changedProp = <PropertyFEModel>this.changedData.shift();
917 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
920 console.log("updated policy instance properties: ", response);
923 } else if (this.isInputsTabSelected) {
925 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
926 changedInput = <InputFEModel>changedInput;
927 const inputBE = new InputBEModel(changedInput);
928 inputBE.defaultValue = changedInput.getJSONDefaultValue();
931 request = this.componentServiceNg2
932 .updateComponentInputs(this.component, changedInputs);
933 handleSuccess = (response) => {
934 // reset each changed property with new value and remove it from changed properties list
935 response.forEach((resInput) => {
936 const changedInput = <InputFEModel>this.changedData.shift();
937 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
938 changedInput.required = resInput.required;
939 changedInput.requiredOrig = resInput.required;
941 console.log("updated the component inputs and got this response: ", response);
945 this.savingChangedData = true;
948 this.savingChangedData = false;
949 if (changedCapabilitiesProperties.length) {
950 this.reloadInstanceCapabilities();
952 handleSuccess && handleSuccess(response);
953 this.updateHasChangedData();
957 this.savingChangedData = false;
958 handleError && handleError(error);
959 this.updateHasChangedData();
966 reloadInstanceCapabilities = (): void => {
967 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
968 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
969 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
970 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
971 return instance.capabilities;
974 }, new CapabilitiesGroup());
975 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
979 reverseChangedData = ():void => {
980 // make reverse item handler
981 let handleReverseItem;
982 if (this.isPropertiesTabSelected) {
983 handleReverseItem = (changedItem) => {
984 changedItem = <PropertyFEModel>changedItem;
985 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
987 } else if (this.isInputsTabSelected) {
988 handleReverseItem = (changedItem) => {
989 changedItem = <InputFEModel>changedItem;
990 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
991 changedItem.resetMetadata();
992 changedItem.required = changedItem.requiredOrig;
996 this.changedData.forEach(handleReverseItem);
997 this.changedData = [];
998 this.updateHasChangedData();
1001 updateHasChangedData = ():boolean => {
1002 const curHasChangedData:boolean = (this.changedData.length > 0);
1003 if (curHasChangedData !== this.hasChangedData) {
1004 this.hasChangedData = curHasChangedData;
1005 if(this.hasChangedData) {
1006 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1008 this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1011 return this.hasChangedData;
1014 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1015 this.saveChangedData().then(
1017 this.Notification.success({
1018 message: 'Successfully saved changes',
1021 if(onSuccessFunction) onSuccessFunction();
1024 this.Notification.error({
1025 message: 'Failed to save changes!',
1028 if(onError) onError();
1033 showUnsavedChangesAlert = ():Promise<any> => {
1034 let modalTitle:string;
1035 if (this.isPropertiesTabSelected) {
1036 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1037 } else if (this.isInputsTabSelected) {
1038 modalTitle = `Unsaved inputs for ${this.component.name}`;
1041 return new Promise<any>((resolve, reject) => {
1042 const modal = this.ModalServiceSdcUI.openCustomModal(
1046 type: SdcUiCommon.ModalType.custom,
1047 testId: "navigate-modal",
1050 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1051 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1052 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1053 ] as SdcUiCommon.IModalButtonComponent[]
1054 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1059 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1060 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1061 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1062 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1063 return feProperty.name == input.relatedPropertyName &&
1064 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1066 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1067 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1068 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1069 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1073 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1074 updateCheckedPropertyCount = (increment: boolean): void => {
1075 this.checkedPropertiesCount += (increment) ? 1 : -1;
1076 console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1077 this.selectInputBtnLabel();
1080 updateCheckedChildPropertyCount = (increment: boolean): void => {
1081 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1084 setInputTabIndication = (numInputs: number): void => {
1085 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1088 setPolicyTabIndication = (numPolicies: number): void => {
1089 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1092 resetUnsavedChangesForInput = (input:InputFEModel) => {
1093 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1094 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1095 this.updateHasChangedData();
1098 deleteInput = (input: InputFEModel) => {
1099 //reset any unsaved changes to the input before deleting it
1100 this.resetUnsavedChangesForInput(input);
1102 console.log("==>" + this.constructor.name + ": deleteInput");
1103 let inputToDelete = new InputBEModel(input);
1105 this.componentServiceNg2
1106 .deleteInput(this.component, inputToDelete)
1107 .subscribe(response => {
1108 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1110 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1111 this.changeSelectedInstance(this.selectedInstanceData);
1112 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1114 // if (instanceFeProperties) {
1115 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1116 // return prop.name == input.propertyName;
1119 // if (propToEnable) {
1120 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1121 // propToEnable.setNonDeclared(response.inputPath);
1122 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1123 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1126 }, error => {}); //ignore error
1129 deletePolicy = (policy: PolicyInstance) => {
1130 this.loadingPolicies = true;
1131 this.topologyTemplateService
1132 .deletePolicy(this.component, policy)
1133 .subscribe((response) => {
1134 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1135 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1136 this.changeSelectedInstance(this.selectedInstanceData);
1137 this.loadingPolicies = false;
1141 deleteProperty = (property: PropertyFEModel) => {
1142 const propertyToDelete = new PropertyFEModel(property);
1143 this.loadingProperties = true;
1144 const feMap = this.instanceFePropertiesMap;
1145 this.topologyTemplateService
1146 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1147 .subscribe((response) => {
1148 const props = feMap[this.component.uniqueId];
1149 props.splice(props.findIndex(p => p.uniqueId === response),1);
1150 this.loadingProperties = false;
1152 this.loadingProperties = false;
1153 console.error(error);
1157 /*** addProperty ***/
1158 addProperty = (model: string) => {
1159 this.loadDataTypesByComponentModel(model)
1160 let modalTitle = 'Add Property';
1161 let modal = this.ModalService.createCustomModal(new ModalModel(
1166 new ButtonModel('Save', 'blue', () => {
1167 modal.instance.dynamicContent.instance.isLoading = true;
1168 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1169 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1170 .subscribe((response) => {
1171 modal.instance.dynamicContent.instance.isLoading = false;
1172 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1173 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1174 modal.instance.close();
1176 modal.instance.dynamicContent.instance.isLoading = false;
1177 this.Notification.error({
1178 message: 'Failed to add property:' + error,
1182 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1183 new ButtonModel('Cancel', 'outline grey', () => {
1184 modal.instance.close();
1189 modal.instance.open();
1190 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1195 let modalTitle = 'Add Input';
1196 let modal = this.ModalService.createCustomModal(new ModalModel(
1201 new ButtonModel('Save', 'blue', () => {
1202 modal.instance.dynamicContent.instance.isLoading = true;
1203 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1204 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1205 .subscribe((response) => {
1206 modal.instance.dynamicContent.instance.isLoading = false;
1207 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1208 this.inputs.push(newInputProp);
1209 modal.instance.close();
1211 modal.instance.dynamicContent.instance.isLoading = false;
1212 this.Notification.error({
1213 message: 'Failed to add input:' + error,
1217 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1218 new ButtonModel('Cancel', 'outline grey', () => {
1219 modal.instance.close();
1224 this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1225 modal.instance.open();
1228 /*** SEARCH RELATED FUNCTIONS ***/
1229 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1230 let instanceBePropertiesMap:InstanceBePropertiesMap;
1231 this.componentServiceNg2
1232 .filterComponentInstanceProperties(this.component, filterData)
1233 .subscribe((response) => {
1234 this.processInstancePropertiesResponse(response, false);
1235 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1236 this.searchPropertyName = filterData.propertyName;//mark in table
1237 this.hierarchyNavTabs.triggerTabChange('Composition');
1238 this.propertiesNavigationData = [];
1239 this.displayClearSearch = true;
1240 }, (error) => {}); //ignore error
1244 clearSearch = () => {
1245 this.instancesNavigationData = this.instances;
1246 this.searchPropertyName = "";
1247 this.hierarchyPropertiesDisplayOptions.searchText = "";
1248 this.displayClearSearch = false;
1249 this.advanceSearch.clearAll();
1250 this.searchQuery = '';
1253 clickOnClearSearch = () => {
1255 this.selectFirstInstanceByDefault();
1256 this.hierarchyNavTabs.triggerTabChange('Composition');
1259 private isInput = (instanceType:string):boolean =>{
1260 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1263 loadDataTypesByComponentModel(model:string) {
1264 this.propertyCreatorComponent.filterDataTypesByModel(model);