2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 import * as _ from "lodash";
22 import {Component, Inject, ViewChild} from "@angular/core";
23 import {PropertiesService} from "../../services/properties.service";
26 Component as ComponentData,
29 FilterPropertiesAssignmentData,
33 InstanceBePropertiesMap,
34 InstanceFePropertiesMap,
35 InstancePropertiesAPIMap,
43 import {ResourceType} from "app/utils";
44 import {ComponentServiceNg2} from "../../services/component-services/component.service";
45 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
46 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
47 import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
48 import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
49 import {EventListenerService} from "app/services/event-listener-service"
50 import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
51 import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
52 import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component";
53 import {HierarchyNavService} from "./services/hierarchy-nav.service";
54 import {PropertiesUtils} from "./services/properties.utils";
55 import {ComponentModeService} from "../../services/component-services/component-mode.service";
56 import {Tab, Tabs} from "../../components/ui/tabs/tabs.component";
57 import {InputsUtils} from "./services/inputs.utils";
58 import {InstanceFeDetails} from "../../../models/instance-fe-details";
59 import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
60 import {UnsavedChangesComponent} from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
61 import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
62 import {ModalService} from "../../services/modal.service";
63 import {DeclareListComponent} from "./declare-list/declare-list.component";
64 import {ToscaFunctionComponent, ToscaFunctionValidationEvent} from "./tosca-function/tosca-function.component";
65 import {CapabilitiesGroup, Capability} from "../../../models/capability";
66 import {ToscaPresentationData} from "../../../models/tosca-presentation";
67 import {Observable} from "rxjs";
68 import {TranslateService} from "../../shared/translator/translate.service";
69 import {ToscaFunction} from "../../../models/tosca-function";
71 const SERVICE_SELF_TITLE = "SELF";
73 templateUrl: './properties-assignment.page.component.html',
74 styleUrls: ['./properties-assignment.page.component.less']
76 export class PropertiesAssignmentComponent {
77 title = "Properties & Inputs";
79 component: ComponentData;
80 componentInstanceNamesMap: { [key: string]: InstanceFeDetails } = {}; //key is the instance uniqueId
81 componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); //key is the instance uniqueId
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 isPoliciesTabSelected: boolean;
107 resourceIsReadonly: boolean;
108 loadingInstances: boolean = false;
109 loadingInputs: boolean = false;
110 loadingPolicies: boolean = false;
111 loadingProperties: boolean = false;
112 changedData: Array<PropertyFEModel | InputFEModel>;
113 hasChangedData: boolean;
114 isValidChangedData: boolean;
115 savingChangedData: boolean;
116 stateChangeStartUnregister: Function;
117 serviceBePropertiesMap: InstanceBePropertiesMap;
118 serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
119 selectedInstance_FlattenCapabilitiesList: Capability[];
121 @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
122 @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
123 @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
125 constructor(private propertiesService: PropertiesService,
126 private hierarchyNavService: HierarchyNavService,
127 private propertiesUtils: PropertiesUtils,
128 private inputsUtils: InputsUtils,
129 private componentServiceNg2: ComponentServiceNg2,
130 private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
131 private propertyCreatorComponent: PropertyCreatorComponent,
132 @Inject("$stateParams") _stateParams,
133 @Inject("$scope") private $scope: ng.IScope,
134 @Inject("$state") private $state: ng.ui.IStateService,
135 @Inject("Notification") private notification: any,
136 private componentModeService: ComponentModeService,
137 private eventListenerService: EventListenerService,
138 private ModalServiceSdcUI: SdcUiServices.ModalService,
139 private modalService: ModalService,
140 private keysPipe: KeysPipe,
141 private topologyTemplateService: TopologyTemplateService,
142 private translateService: TranslateService) {
144 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
145 /* 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
146 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
147 this.component = _stateParams.component;
148 this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
149 this.updateViewMode();
150 this.changedData = [];
151 this.updateHasChangedData();
152 this.isValidChangedData = true;
156 console.debug("==>" + this.constructor.name + ": ngOnInit");
157 this.loadingInputs = true;
158 this.loadingPolicies = true;
159 this.loadingInstances = true;
160 this.loadingProperties = true;
161 this.topologyTemplateService
162 .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
163 .subscribe(response => {
164 _.forEach(response.inputs, (input: InputBEModel) => {
165 const newInput: InputFEModel = new InputFEModel(input);
166 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
167 this.inputs.push(newInput); //only push items that were declared via SDC
169 this.loadingInputs = false;
173 this.componentServiceNg2
174 .getComponentResourcePropertiesData(this.component)
175 .subscribe(response => {
176 this.loadingPolicies = false;
178 this.instances.push(...response.componentInstances);
179 this.instances.push(...response.groupInstances);
180 this.instances.push(...response.policies);
182 if (response.componentInstances) {
183 response.componentInstances.forEach(instance => {
184 this.componentInstanceMap.set(instance.uniqueId, <InstanceFeDetails>{
186 iconClass: instance.iconClass,
187 originArchived: instance.originArchived
192 _.forEach(response.policies, (policy: any) => {
193 const newPolicy: InputFEModel = new InputFEModel(policy);
194 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
195 this.policies.push(policy);
198 // add the service self instance to the top of the list.
199 const serviceInstance = new ComponentInstance();
200 serviceInstance.name = SERVICE_SELF_TITLE;
201 serviceInstance.uniqueId = this.component.uniqueId;
202 this.instances.unshift(serviceInstance);
204 _.forEach(this.instances, (instance) => {
205 this.instancesNavigationData.push(instance);
206 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
208 iconClass: instance.iconClass,
209 originArchived: instance.originArchived
212 this.loadingInstances = false;
213 if (this.instancesNavigationData[0] == undefined) {
214 this.loadingProperties = false;
216 this.selectFirstInstanceByDefault();
218 this.loadingInstances = false;
221 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
222 // stop if has changed properties
223 if (this.hasChangedData) {
224 event.preventDefault();
225 this.showUnsavedChangesAlert().then(() => {
226 this.$state.go(toState, toParams);
232 this.loadDataTypesByComponentModel(this.component.model);
236 this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
237 this.stateChangeStartUnregister();
240 selectFirstInstanceByDefault = () => {
241 if (this.instancesNavigationData[0] !== undefined) {
242 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
246 updateViewMode = () => {
247 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
250 onCheckout = (component: ComponentData) => {
251 this.component = component;
252 this.updateViewMode();
255 isSelf = (): boolean => {
256 return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
259 showAddProperties = (): boolean => {
260 if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
263 return this.isSelf();
266 getServiceProperties() {
267 this.loadingProperties = true;
268 this.topologyTemplateService
269 .getServiceProperties(this.component.uniqueId)
270 .subscribe((response) => {
271 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
272 this.serviceBePropertiesMap[this.component.uniqueId] = response;
273 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
274 this.loadingProperties = false;
276 this.loadingProperties = false;
280 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
281 // stop if has changed properties
282 if (this.hasChangedData) {
283 this.showUnsavedChangesAlert().then((resolve) => {
284 this.changeSelectedInstance(instance)
289 this.changeSelectedInstance(instance);
292 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
293 this.selectedInstanceData = instance;
294 this.loadingProperties = true;
295 if (instance instanceof ComponentInstance) {
296 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
297 if (this.isInput(instance.originType)) {
298 this.componentInstanceServiceNg2
299 .getComponentInstanceInputs(this.component, instance)
300 .subscribe(response => {
301 instanceBePropertiesMap[instance.uniqueId] = response;
302 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
306 this.loadingProperties = false;
308 } else if (this.isSelf()) {
309 this.getServiceProperties();
311 this.componentInstanceServiceNg2
312 .getComponentInstanceProperties(this.component, instance.uniqueId)
313 .subscribe(response => {
314 instanceBePropertiesMap[instance.uniqueId] = response;
315 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
319 this.loadingProperties = false;
322 this.loadingProperties = false;
323 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
324 } else if (instance instanceof GroupInstance) {
325 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
326 this.componentInstanceServiceNg2
327 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
328 .subscribe((response) => {
329 instanceBePropertiesMap[instance.uniqueId] = response;
330 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
334 this.loadingProperties = false;
336 } else if (instance instanceof PolicyInstance) {
337 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
338 this.componentInstanceServiceNg2
339 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
340 .subscribe((response) => {
341 instanceBePropertiesMap[instance.uniqueId] = response;
342 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
346 this.loadingProperties = false;
349 this.loadingProperties = false;
352 if (this.searchPropertyName) {
355 //clear selected property from the navigation
356 this.selectedFlatProperty = new SimpleFlatProperty();
357 this.propertiesNavigationData = [];
361 * Entry point handling response from server
363 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
364 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
365 this.checkedPropertiesCount = 0;
366 this.checkedChildPropertiesCount = 0;
369 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
370 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
371 let currentUniqueId = this.selectedInstanceData.uniqueId;
372 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
373 let isCapabilityOwnedByInstance: boolean;
374 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
375 this.selectedInstance_FlattenCapabilitiesList,
376 (result, cap: Capability) => {
377 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
378 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
379 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
380 if (cap.properties && isCapabilityOwnedByInstance) {
381 _.forEach(cap.properties, prop => {
382 if (!prop.origName) {
383 prop.origName = prop.name;
384 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
387 return result.concat(cap.properties);
391 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
392 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
393 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
394 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
396 //concatenate capabilitiesProps to all props list
397 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
398 this.checkedPropertiesCount = 0;
401 isCapabilityProperty = (prop: PropertyBEModel) => {
402 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
405 /*** VALUE CHANGE EVENTS ***/
406 dataChanged = (item: PropertyFEModel | InputFEModel) => {
408 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
409 itemHasChanged = item.hasValueObjChanged();
410 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
411 itemHasChanged = item.hasChanged();
412 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
413 itemHasChanged = item.hasDefaultValueChanged();
416 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
417 if (itemHasChanged) {
418 if (dataChangedIdx === -1) {
419 this.changedData.push(item);
422 if (dataChangedIdx !== -1) {
423 this.changedData.splice(dataChangedIdx, 1);
427 if (this.isPropertiesTabSelected) {
428 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
429 } else if (this.isInputsTabSelected) {
430 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
431 } else if (this.isPoliciesTabSelected) {
432 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
434 this.updateHasChangedData();
438 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
441 * Handle select node in navigation area, and select the row in table
443 onPropertySelectedUpdate = ($event) => {
444 console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
445 this.selectedFlatProperty = $event;
446 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
447 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
451 * When user select row in table, this will prepare the hirarchy object for the tree.
453 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
454 console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
455 let property = propertyRowSelectedEvent.propertyModel;
456 let instanceName = propertyRowSelectedEvent.instanceName;
457 this.propertyStructureHeader = null;
459 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
460 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
461 let simpleFlatProperty: Array<SimpleFlatProperty>;
462 if (property instanceof PropertyFEModel) {
463 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
464 } else if (property instanceof DerivedFEProperty) {
465 // Need to find parent PropertyFEModel
466 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
467 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
469 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
471 this.propertiesNavigationData = simpleFlatProperty;
474 // Update the header in the navigation tree with property name.
475 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
477 // Set selected property in table
478 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
479 this.hierarchyNavTabs.triggerTabChange('Property Structure');
483 selectInstanceRow = ($event) => {//get instance name
484 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
485 return instance.name == $event;
487 this.hierarchyNavTabs.triggerTabChange('Composition');
490 tabChanged = (event) => {
491 // stop if has changed properties
492 if (this.hasChangedData) {
493 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
494 this.showUnsavedChangesAlert().then((proceed) => {
495 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
501 console.debug("==>" + this.constructor.name + ": tabChanged " + event);
502 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
503 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
504 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
505 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
506 this.propertyStructureHeader = null;
507 this.searchQuery = '';
511 * Select Tosca function value from defined values
513 selectToscaFunctionAndValues = (): void => {
514 const selectedInstanceData: ComponentInstance = this.getSelectedComponentInstance();
515 if (!selectedInstanceData) {
518 this.openToscaGetFunctionModal();
521 private getSelectedComponentInstance(): ComponentInstance {
522 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
523 const instanceId: string = instancesIds[0];
524 return <ComponentInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance);
527 private buildCheckedInstanceProperty(): PropertyBEModel {
528 return this.buildCheckedInstanceProperties()[0];
531 private buildCheckedInstanceProperties(): PropertyBEModel[] {
532 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
533 const instanceId: string = instancesIds[0];
534 return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
537 private openToscaGetFunctionModal() {
538 const modalTitle = this.translateService.translate('TOSCA_FUNCTION_MODAL_TITLE');
539 const modalButtons = [];
540 let disableSaveButtonFlag = true;
541 const modal = this.modalService.createCustomModal(new ModalModel(
548 modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
550 const toscaGetFunction: ToscaFunction = modal.instance.dynamicContent.instance.toscaFunctionForm.value;
551 if (toscaGetFunction) {
552 this.updateCheckedInstancePropertyFunctionValue(toscaGetFunction);
554 this.clearCheckedInstancePropertyValue();
556 this.modalService.closeCurrentModal();
558 (): boolean => { return disableSaveButtonFlag }
560 const checkedInstanceProperty = this.buildCheckedInstanceProperty();
561 modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
562 this.modalService.closeCurrentModal();
566 this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
567 'property': checkedInstanceProperty,
568 'componentInstanceMap': this.componentInstanceMap
570 modal.instance.dynamicContent.instance.onValidityChange.subscribe((validationEvent: ToscaFunctionValidationEvent) => {
571 disableSaveButtonFlag = !validationEvent.isValid;
573 modal.instance.open();
576 private clearCheckedInstancePropertyValue() {
577 const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
578 checkedInstanceProperty.getInputValues = null;
579 checkedInstanceProperty.value = null;
580 checkedInstanceProperty.toscaFunction = null;
581 this.updateInstanceProperty(checkedInstanceProperty);
584 private updateCheckedInstancePropertyFunctionValue(toscaFunction: ToscaFunction) {
585 const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
586 checkedProperty.toscaFunction = toscaFunction;
587 this.updateInstanceProperty(checkedProperty);
590 updateInstanceProperty(instanceProperty: PropertyBEModel) {
591 this.loadingProperties = true;
592 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
593 this.selectedInstanceData.uniqueId, [instanceProperty])
595 this.changeSelectedInstance(this.getSelectedComponentInstance());
597 this.loadingProperties = false;
598 console.error(error);
600 this.loadingProperties = false;
604 /*** DECLARE PROPERTIES/INPUTS ***/
605 declareProperties = (): void => {
606 console.debug("==>" + this.constructor.name + ": declareProperties");
608 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
609 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
610 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
611 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
612 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
614 angular.forEach(instancesIds, (instanceId: string): void => {
615 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
616 if (selectedInstanceData instanceof ComponentInstance) {
617 if (!this.isInput(selectedInstanceData.originType)) {
618 // convert Property FE model -> Property BE model, extract only checked
619 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
621 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
623 } else if (selectedInstanceData instanceof GroupInstance) {
624 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
625 } else if (selectedInstanceData instanceof PolicyInstance) {
626 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
630 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
632 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
633 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
634 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
636 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
637 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
640 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
641 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
642 prop => !this.isCapabilityProperty(prop)
644 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
645 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
648 let isCapabilityPropertyChanged = false;
650 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
651 (prop: PropertyBEModel) => {
652 prop.name = prop.origName || prop.name;
653 if (this.isCapabilityProperty(prop)) {
654 isCapabilityPropertyChanged = true;
658 this.topologyTemplateService
659 .createInput(this.component, inputsToCreate, this.isSelf())
660 .subscribe((response) => {
661 this.selectInstanceRow(SERVICE_SELF_TITLE);
662 this.onInstanceSelectedUpdate(this.instances[0]);
663 this.setInputTabIndication(response.length);
664 this.checkedPropertiesCount = 0;
665 this.checkedChildPropertiesCount = 0;
666 _.forEach(response, (input: InputBEModel) => {
667 const newInput: InputFEModel = new InputFEModel(input);
668 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
669 this.inputs.push(newInput);
670 this.updatePropertyValueAfterDeclare(newInput);
672 if (isCapabilityPropertyChanged) {
673 this.reloadInstanceCapabilities();
675 }, error => {}); //ignore error
678 declareListProperties = (): void => {
679 // get selected properties
680 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
681 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
682 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
683 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
684 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
685 let propertyNameList: Array<string> = [];
688 angular.forEach(instancesIds, (instanceId: string): void => {
690 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
691 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
693 if (selectedInstanceData instanceof ComponentInstance) {
694 if (!this.isInput(selectedInstanceData.originType)) {
695 // convert Property FE model -> Property BE model, extract only checked
696 selectedComponentInstancesProperties[instanceId] = checkedProperties;
698 selectedComponentInstancesInputs[instanceId] = checkedProperties;
700 } else if (selectedInstanceData instanceof GroupInstance) {
701 selectedGroupInstancesProperties[instanceId] = checkedProperties;
702 } else if (selectedInstanceData instanceof PolicyInstance) {
703 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
706 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
707 propertyNameList.push(property.name);
711 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
713 let modalTitle = 'Declare Properties as List Input';
714 const modal = this.modalService.createCustomModal(new ModalModel(
716 modalTitle, /* title */
721 'blue', /* css class */
722 () => { /* callback */
723 let content:any = modal.instance.dynamicContent.instance;
726 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
727 let typelist: any = PROPERTY_TYPES.LIST;
728 let uniID: any = insId;
729 let boolfalse: any = false;
730 let required: any = content.propertyModel.required;
734 "type": content.propertyModel.simpleType,
738 let schemaProp :any = {
739 "type": content.propertyModel.simpleType,
743 reglistInput.description = content.propertyModel.description;
744 reglistInput.name = content.propertyModel.name;
745 reglistInput.type = typelist;
746 reglistInput.schemaType = content.propertyModel.simpleType;
747 reglistInput.instanceUniqueId = uniID;
748 reglistInput.uniqueId = uniID;
749 reglistInput.required = required;
750 reglistInput.schema = schem;
751 reglistInput.schemaProperty = schemaProp;
754 componentInstInputsMap: content.inputsToCreate,
755 listInput: reglistInput
758 this.topologyTemplateService
759 .createListInput(this.component, input, this.isSelf())
760 .subscribe(response => {
761 this.setInputTabIndication(response.length);
762 this.checkedPropertiesCount = 0;
763 this.checkedChildPropertiesCount = 0;
764 _.forEach(response, (input: InputBEModel) => {
765 let newInput: InputFEModel = new InputFEModel(input);
766 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
767 this.inputs.push(newInput);
768 // create list input does not return updated properties info, so need to reload
769 //this.updatePropertyValueAfterDeclare(newInput);
770 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
771 this.changeSelectedInstance(this.selectedInstanceData);
773 modal.instance.close();
775 }, error => {}); //ignore error
778 /*, getDisabled: function */
780 new ButtonModel('Cancel', 'outline grey', () => {
781 modal.instance.close();
786 // 3rd arg is passed to DeclareListComponent instance
787 this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
788 modal.instance.open();
791 /*** DECLARE PROPERTIES/POLICIES ***/
792 declarePropertiesToPolicies = (): void => {
793 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
794 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
796 angular.forEach(instancesIds, (instanceId: string): void => {
797 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
798 if (selectedInstanceData instanceof ComponentInstance) {
799 if (!this.isInput(selectedInstanceData.originType)) {
800 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
805 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
806 this.loadingPolicies = true;
808 this.topologyTemplateService
809 .createPolicy(this.component, policiesToCreate, this.isSelf())
810 .subscribe(response => {
811 this.setPolicyTabIndication(response.length);
812 this.checkedPropertiesCount = 0;
813 this.displayPoliciesAsDeclared(response);
814 this.loadingPolicies = false;
819 displayPoliciesAsDeclared = (policies) => {
820 _.forEach(policies, (policy: any) => {
821 let newPolicy: InputFEModel = new InputFEModel(policy);
822 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
823 newPolicy.relatedPropertyName = policy.name;
824 newPolicy.relatedPropertyValue = policy.value;
825 this.updatePropertyValueAfterDeclare(newPolicy);
826 this.policies.push(policy);
830 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
831 return new Promise((resolve, reject) => {
832 if (!this.isValidChangedData) {
833 reject('Changed data is invalid - cannot save!');
836 if (!this.changedData.length) {
841 // make request and its handlers
843 let handleSuccess, handleError;
844 let changedInputsProperties = [], changedCapabilitiesProperties = [];
845 if (this.isPropertiesTabSelected) {
846 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
847 changedProp = <PropertyFEModel>changedProp;
848 const propBE = new PropertyBEModel(changedProp);
849 propBE.toscaPresentation = new ToscaPresentationData();
850 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
851 propBE.value = changedProp.getJSONValue();
852 propBE.name = changedProp.origName || changedProp.name;
853 delete propBE.origName;
856 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
858 if (this.selectedInstanceData instanceof ComponentInstance) {
859 if (this.isInput(this.selectedInstanceData.originType)) {
860 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
861 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
862 request = Observable.forkJoin(
863 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
864 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
865 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
868 else if (changedInputsProperties.length) {
869 request = this.componentInstanceServiceNg2
870 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
872 else if (changedCapabilitiesProperties.length) {
873 request = this.componentInstanceServiceNg2
874 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
876 handleSuccess = (response) => {
877 // reset each changed property with new value and remove it from changed properties list
878 response.forEach((resInput) => {
879 const changedProp = <PropertyFEModel>this.changedData.shift();
880 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
885 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
886 delete cp.constraints;
890 request = this.componentInstanceServiceNg2
891 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
893 handleSuccess = (response) => {
894 // reset each changed property with new value and remove it from changed properties list
895 response.forEach((resProp) => {
896 const changedProp = <PropertyFEModel>this.changedData.shift();
897 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
902 } else if (this.selectedInstanceData instanceof GroupInstance) {
903 request = this.componentInstanceServiceNg2
904 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
905 handleSuccess = (response) => {
906 // reset each changed property with new value and remove it from changed properties list
907 response.forEach((resProp) => {
908 const changedProp = <PropertyFEModel>this.changedData.shift();
909 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
913 } else if (this.selectedInstanceData instanceof PolicyInstance) {
914 request = this.componentInstanceServiceNg2
915 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
916 handleSuccess = (response) => {
917 // reset each changed property with new value and remove it from changed properties list
918 response.forEach((resProp) => {
919 const changedProp = <PropertyFEModel>this.changedData.shift();
920 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
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;
946 this.savingChangedData = true;
949 this.savingChangedData = false;
950 if (changedCapabilitiesProperties.length) {
951 this.reloadInstanceCapabilities();
953 handleSuccess && handleSuccess(response);
954 this.updateHasChangedData();
958 this.savingChangedData = false;
959 handleError && handleError(error);
960 this.updateHasChangedData();
967 reloadInstanceCapabilities = (): void => {
968 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
969 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
970 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
971 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
972 return instance.capabilities;
975 }, new CapabilitiesGroup());
976 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
980 reverseChangedData = ():void => {
981 // make reverse item handler
982 let handleReverseItem;
983 if (this.isPropertiesTabSelected) {
984 handleReverseItem = (changedItem) => {
985 changedItem = <PropertyFEModel>changedItem;
986 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
988 } else if (this.isInputsTabSelected) {
989 handleReverseItem = (changedItem) => {
990 changedItem = <InputFEModel>changedItem;
991 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
992 changedItem.resetMetadata();
993 changedItem.required = changedItem.requiredOrig;
997 this.changedData.forEach(handleReverseItem);
998 this.changedData = [];
999 this.updateHasChangedData();
1002 updateHasChangedData = ():boolean => {
1003 const curHasChangedData:boolean = (this.changedData.length > 0);
1004 if (curHasChangedData !== this.hasChangedData) {
1005 this.hasChangedData = curHasChangedData;
1006 if(this.hasChangedData) {
1007 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1009 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1012 return this.hasChangedData;
1015 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1016 this.saveChangedData().then(
1018 this.notification.success({
1019 message: 'Successfully saved changes',
1022 if(onSuccessFunction) onSuccessFunction();
1025 this.notification.error({
1026 message: 'Failed to save changes!',
1029 if(onError) onError();
1034 showUnsavedChangesAlert = ():Promise<any> => {
1035 let modalTitle:string;
1036 if (this.isPropertiesTabSelected) {
1037 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1038 } else if (this.isInputsTabSelected) {
1039 modalTitle = `Unsaved inputs for ${this.component.name}`;
1042 return new Promise<any>((resolve, reject) => {
1043 const modal = this.ModalServiceSdcUI.openCustomModal(
1047 type: SdcUiCommon.ModalType.custom,
1048 testId: "navigate-modal",
1051 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1052 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1053 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1054 ] as SdcUiCommon.IModalButtonComponent[]
1055 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1060 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1061 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1062 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1063 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1064 return feProperty.name == input.relatedPropertyName &&
1065 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1067 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1068 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1069 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1070 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1074 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1075 updateCheckedPropertyCount = (increment: boolean): void => {
1076 this.checkedPropertiesCount += (increment) ? 1 : -1;
1077 console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
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.debug("==>" + 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 this.changeSelectedInstance(this.selectedInstanceData);
1136 this.loadingPolicies = false;
1140 deleteProperty = (property: PropertyFEModel) => {
1141 const propertyToDelete = new PropertyFEModel(property);
1142 this.loadingProperties = true;
1143 const feMap = this.instanceFePropertiesMap;
1144 this.topologyTemplateService
1145 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1146 .subscribe((response) => {
1147 const props = feMap[this.component.uniqueId];
1148 props.splice(props.findIndex(p => p.uniqueId === response),1);
1149 this.loadingProperties = false;
1151 this.loadingProperties = false;
1152 console.error(error);
1156 /*** addProperty ***/
1157 addProperty = (model: string) => {
1158 this.loadDataTypesByComponentModel(model)
1159 let modalTitle = 'Add Property';
1160 let modal = this.modalService.createCustomModal(new ModalModel(
1165 new ButtonModel('Save', 'blue', () => {
1166 modal.instance.dynamicContent.instance.isLoading = true;
1167 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1168 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1169 .subscribe((response) => {
1170 modal.instance.dynamicContent.instance.isLoading = false;
1171 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1172 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1173 modal.instance.close();
1175 modal.instance.dynamicContent.instance.isLoading = false;
1176 this.notification.error({
1177 message: 'Failed to add property:' + error,
1181 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1182 new ButtonModel('Cancel', 'outline grey', () => {
1183 modal.instance.close();
1188 modal.instance.open();
1189 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1194 let modalTitle = 'Add Input';
1195 let modal = this.modalService.createCustomModal(new ModalModel(
1200 new ButtonModel('Save', 'blue', () => {
1201 modal.instance.dynamicContent.instance.isLoading = true;
1202 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1203 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1204 .subscribe((response) => {
1205 modal.instance.dynamicContent.instance.isLoading = false;
1206 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1207 this.inputs.push(newInputProp);
1208 modal.instance.close();
1210 modal.instance.dynamicContent.instance.isLoading = false;
1211 this.notification.error({
1212 message: 'Failed to add input:' + error,
1216 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1217 new ButtonModel('Cancel', 'outline grey', () => {
1218 modal.instance.close();
1223 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1224 modal.instance.open();
1227 /*** SEARCH RELATED FUNCTIONS ***/
1228 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1229 let instanceBePropertiesMap:InstanceBePropertiesMap;
1230 this.componentServiceNg2
1231 .filterComponentInstanceProperties(this.component, filterData)
1232 .subscribe((response) => {
1233 this.processInstancePropertiesResponse(response, false);
1234 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1235 this.searchPropertyName = filterData.propertyName;//mark in table
1236 this.hierarchyNavTabs.triggerTabChange('Composition');
1237 this.propertiesNavigationData = [];
1238 this.displayClearSearch = true;
1239 }, (error) => {}); //ignore error
1243 clearSearch = () => {
1244 this.instancesNavigationData = this.instances;
1245 this.searchPropertyName = "";
1246 this.hierarchyPropertiesDisplayOptions.searchText = "";
1247 this.displayClearSearch = false;
1248 this.advanceSearch.clearAll();
1249 this.searchQuery = '';
1252 clickOnClearSearch = () => {
1254 this.selectFirstInstanceByDefault();
1255 this.hierarchyNavTabs.triggerTabChange('Composition');
1258 private isInput = (instanceType:string):boolean =>{
1259 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1262 loadDataTypesByComponentModel(model:string) {
1263 this.propertyCreatorComponent.filterDataTypesByModel(model);