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} 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 {ToscaGetFunctionDtoBuilder} from '../../../models/tosca-get-function-dto';
70 import {ToscaGetFunction} from "../../../models/tosca-get-function";
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: { [key: string]: InstanceFeDetails } = {}; //key is the instance uniqueId
82 componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); //key is the instance uniqueId
84 propertiesNavigationData = [];
85 instancesNavigationData = [];
87 instanceFePropertiesMap: InstanceFePropertiesMap;
88 inputs: Array<InputFEModel> = [];
89 policies: Array<PolicyInstance> = [];
90 instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
92 propertyStructureHeader: string;
94 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
95 selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
96 checkedPropertiesCount: number = 0;
97 checkedChildPropertiesCount: number = 0;
99 hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
100 hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
101 displayClearSearch = false;
102 searchPropertyName: string;
104 isInputsTabSelected: boolean;
105 isPropertiesTabSelected: boolean;
106 isPoliciesTabSelected: boolean;
108 resourceIsReadonly: boolean;
109 loadingInstances: boolean = false;
110 loadingInputs: boolean = false;
111 loadingPolicies: boolean = false;
112 loadingProperties: boolean = false;
113 changedData: Array<PropertyFEModel | InputFEModel>;
114 hasChangedData: boolean;
115 isValidChangedData: boolean;
116 savingChangedData: boolean;
117 stateChangeStartUnregister: Function;
118 serviceBePropertiesMap: InstanceBePropertiesMap;
119 serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
120 selectedInstance_FlattenCapabilitiesList: Capability[];
122 @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
123 @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
124 @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
126 constructor(private propertiesService: PropertiesService,
127 private hierarchyNavService: HierarchyNavService,
128 private propertiesUtils: PropertiesUtils,
129 private inputsUtils: InputsUtils,
130 private componentServiceNg2: ComponentServiceNg2,
131 private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
132 private propertyCreatorComponent: PropertyCreatorComponent,
133 @Inject("$stateParams") _stateParams,
134 @Inject("$scope") private $scope: ng.IScope,
135 @Inject("$state") private $state: ng.ui.IStateService,
136 @Inject("Notification") private notification: any,
137 private componentModeService: ComponentModeService,
138 private eventListenerService: EventListenerService,
139 private ModalServiceSdcUI: SdcUiServices.ModalService,
140 private modalService: ModalService,
141 private keysPipe: KeysPipe,
142 private topologyTemplateService: TopologyTemplateService,
143 private translateService: TranslateService) {
145 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
146 /* 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
147 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
148 this.component = _stateParams.component;
149 this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
150 this.updateViewMode();
151 this.changedData = [];
152 this.updateHasChangedData();
153 this.isValidChangedData = true;
157 console.debug("==>" + this.constructor.name + ": ngOnInit");
158 this.loadingInputs = true;
159 this.loadingPolicies = true;
160 this.loadingInstances = true;
161 this.loadingProperties = true;
162 this.topologyTemplateService
163 .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
164 .subscribe(response => {
165 _.forEach(response.inputs, (input: InputBEModel) => {
166 const newInput: InputFEModel = new InputFEModel(input);
167 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
168 this.inputs.push(newInput); //only push items that were declared via SDC
170 this.loadingInputs = false;
174 this.componentServiceNg2
175 .getComponentResourcePropertiesData(this.component)
176 .subscribe(response => {
177 this.loadingPolicies = false;
179 this.instances.push(...response.componentInstances);
180 this.instances.push(...response.groupInstances);
181 this.instances.push(...response.policies);
183 if (response.componentInstances) {
184 response.componentInstances.forEach(instance => {
185 this.componentInstanceMap.set(instance.uniqueId, <InstanceFeDetails>{
187 iconClass: instance.iconClass,
188 originArchived: instance.originArchived
193 _.forEach(response.policies, (policy: any) => {
194 const newPolicy: InputFEModel = new InputFEModel(policy);
195 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
196 this.policies.push(policy);
199 // add the service self instance to the top of the list.
200 const serviceInstance = new ComponentInstance();
201 serviceInstance.name = SERVICE_SELF_TITLE;
202 serviceInstance.uniqueId = this.component.uniqueId;
203 this.instances.unshift(serviceInstance);
205 _.forEach(this.instances, (instance) => {
206 this.instancesNavigationData.push(instance);
207 this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
209 iconClass: instance.iconClass,
210 originArchived: instance.originArchived
213 this.loadingInstances = false;
214 if (this.instancesNavigationData[0] == undefined) {
215 this.loadingProperties = false;
217 this.selectFirstInstanceByDefault();
219 this.loadingInstances = false;
222 this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
223 // stop if has changed properties
224 if (this.hasChangedData) {
225 event.preventDefault();
226 this.showUnsavedChangesAlert().then(() => {
227 this.$state.go(toState, toParams);
233 this.loadDataTypesByComponentModel(this.component.model);
237 this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
238 this.stateChangeStartUnregister();
241 selectFirstInstanceByDefault = () => {
242 if (this.instancesNavigationData[0] !== undefined) {
243 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
247 updateViewMode = () => {
248 this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
251 onCheckout = (component: ComponentData) => {
252 this.component = component;
253 this.updateViewMode();
256 isSelf = (): boolean => {
257 return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
260 showAddProperties = (): boolean => {
261 if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
264 return this.isSelf();
267 getServiceProperties() {
268 this.loadingProperties = true;
269 this.topologyTemplateService
270 .getServiceProperties(this.component.uniqueId)
271 .subscribe((response) => {
272 this.serviceBePropertiesMap = new InstanceBePropertiesMap();
273 this.serviceBePropertiesMap[this.component.uniqueId] = response;
274 this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
275 this.loadingProperties = false;
277 this.loadingProperties = false;
281 onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
282 // stop if has changed properties
283 if (this.hasChangedData) {
284 this.showUnsavedChangesAlert().then((resolve) => {
285 this.changeSelectedInstance(instance)
290 this.changeSelectedInstance(instance);
293 changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
294 this.selectedInstanceData = instance;
295 this.loadingProperties = true;
296 if (instance instanceof ComponentInstance) {
297 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
298 if (this.isInput(instance.originType)) {
299 this.componentInstanceServiceNg2
300 .getComponentInstanceInputs(this.component, instance)
301 .subscribe(response => {
302 instanceBePropertiesMap[instance.uniqueId] = response;
303 this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
307 this.loadingProperties = false;
309 } else if (this.isSelf()) {
310 this.getServiceProperties();
312 this.componentInstanceServiceNg2
313 .getComponentInstanceProperties(this.component, instance.uniqueId)
314 .subscribe(response => {
315 instanceBePropertiesMap[instance.uniqueId] = response;
316 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
320 this.loadingProperties = false;
323 this.loadingProperties = false;
324 this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
325 } else if (instance instanceof GroupInstance) {
326 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
327 this.componentInstanceServiceNg2
328 .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
329 .subscribe((response) => {
330 instanceBePropertiesMap[instance.uniqueId] = response;
331 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
335 this.loadingProperties = false;
337 } else if (instance instanceof PolicyInstance) {
338 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
339 this.componentInstanceServiceNg2
340 .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
341 .subscribe((response) => {
342 instanceBePropertiesMap[instance.uniqueId] = response;
343 this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
347 this.loadingProperties = false;
350 this.loadingProperties = false;
353 if (this.searchPropertyName) {
356 //clear selected property from the navigation
357 this.selectedFlatProperty = new SimpleFlatProperty();
358 this.propertiesNavigationData = [];
362 * Entry point handling response from server
364 processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
365 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
366 this.checkedPropertiesCount = 0;
367 this.checkedChildPropertiesCount = 0;
370 processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
371 let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
372 let currentUniqueId = this.selectedInstanceData.uniqueId;
373 this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
374 let isCapabilityOwnedByInstance: boolean;
375 this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
376 this.selectedInstance_FlattenCapabilitiesList,
377 (result, cap: Capability) => {
378 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
379 selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
380 cap.ownerId === selectedComponentInstanceData.sourceModelUid;
381 if (cap.properties && isCapabilityOwnedByInstance) {
382 _.forEach(cap.properties, prop => {
383 if (!prop.origName) {
384 prop.origName = prop.name;
385 prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
388 return result.concat(cap.properties);
392 let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
393 //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
394 _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
395 prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
397 //concatenate capabilitiesProps to all props list
398 this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
399 this.checkedPropertiesCount = 0;
402 isCapabilityProperty = (prop: PropertyBEModel) => {
403 return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
406 /*** VALUE CHANGE EVENTS ***/
407 dataChanged = (item: PropertyFEModel | InputFEModel) => {
409 if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
410 itemHasChanged = item.hasValueObjChanged();
411 } else if (this.isInputsTabSelected && item instanceof InputFEModel) {
412 itemHasChanged = item.hasChanged();
413 } else if (this.isPoliciesTabSelected && item instanceof InputFEModel) {
414 itemHasChanged = item.hasDefaultValueChanged();
417 const dataChangedIdx = this.changedData.findIndex((changedItem) => changedItem === item);
418 if (itemHasChanged) {
419 if (dataChangedIdx === -1) {
420 this.changedData.push(item);
423 if (dataChangedIdx !== -1) {
424 this.changedData.splice(dataChangedIdx, 1);
428 if (this.isPropertiesTabSelected) {
429 this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
430 } else if (this.isInputsTabSelected) {
431 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
432 } else if (this.isPoliciesTabSelected) {
433 this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
435 this.updateHasChangedData();
439 /*** HEIRARCHY/NAV RELATED FUNCTIONS ***/
442 * Handle select node in navigation area, and select the row in table
444 onPropertySelectedUpdate = ($event) => {
445 console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
446 this.selectedFlatProperty = $event;
447 let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
448 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
452 * When user select row in table, this will prepare the hirarchy object for the tree.
454 selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
455 console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
456 let property = propertyRowSelectedEvent.propertyModel;
457 let instanceName = propertyRowSelectedEvent.instanceName;
458 this.propertyStructureHeader = null;
460 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
461 if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
462 let simpleFlatProperty: Array<SimpleFlatProperty>;
463 if (property instanceof PropertyFEModel) {
464 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
465 } else if (property instanceof DerivedFEProperty) {
466 // Need to find parent PropertyFEModel
467 let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
468 return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
470 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
472 this.propertiesNavigationData = simpleFlatProperty;
475 // Update the header in the navigation tree with property name.
476 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
478 // Set selected property in table
479 this.selectedFlatProperty = this.hierarchyNavService.createSimpleFlatProperty(property, instanceName);
480 this.hierarchyNavTabs.triggerTabChange('Property Structure');
484 selectInstanceRow = ($event) => {//get instance name
485 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
486 return instance.name == $event;
488 this.hierarchyNavTabs.triggerTabChange('Composition');
491 tabChanged = (event) => {
492 // stop if has changed properties
493 if (this.hasChangedData) {
494 this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
495 this.showUnsavedChangesAlert().then((proceed) => {
496 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
502 console.debug("==>" + this.constructor.name + ": tabChanged " + event);
503 this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
504 this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
505 this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
506 this.isPoliciesTabSelected = this.currentMainTab.title === "Policies";
507 this.propertyStructureHeader = null;
508 this.searchQuery = '';
512 * Select Tosca function value from defined values
514 selectToscaFunctionAndValues = (): void => {
515 const selectedInstanceData: ComponentInstance = this.getSelectedComponentInstance();
516 if (!selectedInstanceData) {
519 this.openToscaGetFunctionModal();
522 private getSelectedComponentInstance(): ComponentInstance {
523 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
524 const instanceId: string = instancesIds[0];
525 return <ComponentInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance);
528 private buildCheckedInstanceProperty(): PropertyBEModel {
529 return this.buildCheckedInstanceProperties()[0];
532 private buildCheckedInstanceProperties(): PropertyBEModel[] {
533 const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
534 const instanceId: string = instancesIds[0];
535 return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
538 private openToscaGetFunctionModal() {
539 const modalTitle = this.translateService.translate('TOSCA_FUNCTION_MODAL_TITLE');
540 const modalButtons = [];
541 let disableSaveButtonFlag = true;
542 modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
544 const toscaGetFunction: ToscaGetFunction = modal.instance.dynamicContent.instance.toscaGetFunction;
545 if (toscaGetFunction.functionType) {
546 this.updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction);
548 this.clearCheckedInstancePropertyValue();
550 modal.instance.close();
552 (): boolean => { return disableSaveButtonFlag }
554 const checkedInstanceProperty = this.buildCheckedInstanceProperty();
555 modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
556 modal.instance.close();
558 const modal = this.modalService.createCustomModal(new ModalModel(
566 this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
567 'property': checkedInstanceProperty,
568 'componentInstanceMap': this.componentInstanceMap
570 modal.instance.dynamicContent.instance.onValidityChange.subscribe(isValid => {
571 disableSaveButtonFlag = !isValid;
573 modal.instance.open();
576 private clearCheckedInstancePropertyValue() {
577 const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
578 checkedInstanceProperty.getInputValues = null;
579 checkedInstanceProperty.value = null;
580 checkedInstanceProperty.toscaGetFunction = null;
581 this.updateInstanceProperty(checkedInstanceProperty);
584 private updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction: ToscaGetFunction) {
585 const toscaGetFunctionBuilder: ToscaGetFunctionDtoBuilder =
586 new ToscaGetFunctionDtoBuilder()
587 .withPropertyUniqueId(toscaGetFunction.propertyUniqueId)
588 .withFunctionType(toscaGetFunction.functionType)
589 .withPropertySource(toscaGetFunction.propertySource)
590 .withPropertyName(toscaGetFunction.propertyName)
591 .withSourceName(toscaGetFunction.sourceName)
592 .withSourceUniqueId(toscaGetFunction.sourceUniqueId)
593 .withPropertyPathFromSource(toscaGetFunction.propertyPathFromSource);
595 const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
596 checkedProperty.toscaGetFunction = toscaGetFunctionBuilder.build();
597 this.updateInstanceProperty(checkedProperty);
600 updateInstanceProperty(instanceProperty: PropertyBEModel) {
601 this.loadingProperties = true;
602 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
603 this.selectedInstanceData.uniqueId, [instanceProperty])
605 this.changeSelectedInstance(this.getSelectedComponentInstance());
608 this.translateService.translate('TOSCA_FUNCTION_SELECT_ERROR', {'propertyName': instanceProperty.name, 'error': error});
609 this.notification.error({
610 title: this.translateService.translate('FAILURE_LABEL'),
613 console.error(errorMsg, error);
615 this.loadingProperties = false;
619 /*** DECLARE PROPERTIES/INPUTS ***/
620 declareProperties = (): void => {
621 console.debug("==>" + this.constructor.name + ": declareProperties");
623 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
624 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
625 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
626 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
627 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
629 angular.forEach(instancesIds, (instanceId: string): void => {
630 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
631 if (selectedInstanceData instanceof ComponentInstance) {
632 if (!this.isInput(selectedInstanceData.originType)) {
633 // convert Property FE model -> Property BE model, extract only checked
634 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
636 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
638 } else if (selectedInstanceData instanceof GroupInstance) {
639 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
640 } else if (selectedInstanceData instanceof PolicyInstance) {
641 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
645 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
647 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
648 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
649 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
651 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
652 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
655 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
656 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
657 prop => !this.isCapabilityProperty(prop)
659 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
660 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
663 let isCapabilityPropertyChanged = false;
665 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
666 (prop: PropertyBEModel) => {
667 prop.name = prop.origName || prop.name;
668 if (this.isCapabilityProperty(prop)) {
669 isCapabilityPropertyChanged = true;
673 this.topologyTemplateService
674 .createInput(this.component, inputsToCreate, this.isSelf())
675 .subscribe((response) => {
676 this.selectInstanceRow(SERVICE_SELF_TITLE);
677 this.onInstanceSelectedUpdate(this.instances[0]);
678 this.setInputTabIndication(response.length);
679 this.checkedPropertiesCount = 0;
680 this.checkedChildPropertiesCount = 0;
681 _.forEach(response, (input: InputBEModel) => {
682 const newInput: InputFEModel = new InputFEModel(input);
683 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
684 this.inputs.push(newInput);
685 this.updatePropertyValueAfterDeclare(newInput);
687 if (isCapabilityPropertyChanged) {
688 this.reloadInstanceCapabilities();
690 }, error => {}); //ignore error
693 declareListProperties = (): void => {
694 // get selected properties
695 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
696 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
697 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
698 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
699 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
700 let propertyNameList: Array<string> = [];
703 angular.forEach(instancesIds, (instanceId: string): void => {
705 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
706 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
708 if (selectedInstanceData instanceof ComponentInstance) {
709 if (!this.isInput(selectedInstanceData.originType)) {
710 // convert Property FE model -> Property BE model, extract only checked
711 selectedComponentInstancesProperties[instanceId] = checkedProperties;
713 selectedComponentInstancesInputs[instanceId] = checkedProperties;
715 } else if (selectedInstanceData instanceof GroupInstance) {
716 selectedGroupInstancesProperties[instanceId] = checkedProperties;
717 } else if (selectedInstanceData instanceof PolicyInstance) {
718 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
721 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
722 propertyNameList.push(property.name);
726 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
728 let modalTitle = 'Declare Properties as List Input';
729 const modal = this.modalService.createCustomModal(new ModalModel(
731 modalTitle, /* title */
736 'blue', /* css class */
737 () => { /* callback */
738 let content:any = modal.instance.dynamicContent.instance;
741 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
742 let typelist: any = PROPERTY_TYPES.LIST;
743 let uniID: any = insId;
744 let boolfalse: any = false;
745 let required: any = content.propertyModel.required;
749 "type": content.propertyModel.simpleType,
753 let schemaProp :any = {
754 "type": content.propertyModel.simpleType,
758 reglistInput.description = content.propertyModel.description;
759 reglistInput.name = content.propertyModel.name;
760 reglistInput.type = typelist;
761 reglistInput.schemaType = content.propertyModel.simpleType;
762 reglistInput.instanceUniqueId = uniID;
763 reglistInput.uniqueId = uniID;
764 reglistInput.required = required;
765 reglistInput.schema = schem;
766 reglistInput.schemaProperty = schemaProp;
769 componentInstInputsMap: content.inputsToCreate,
770 listInput: reglistInput
773 this.topologyTemplateService
774 .createListInput(this.component, input, this.isSelf())
775 .subscribe(response => {
776 this.setInputTabIndication(response.length);
777 this.checkedPropertiesCount = 0;
778 this.checkedChildPropertiesCount = 0;
779 _.forEach(response, (input: InputBEModel) => {
780 let newInput: InputFEModel = new InputFEModel(input);
781 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
782 this.inputs.push(newInput);
783 // create list input does not return updated properties info, so need to reload
784 //this.updatePropertyValueAfterDeclare(newInput);
785 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
786 this.changeSelectedInstance(this.selectedInstanceData);
788 modal.instance.close();
790 }, error => {}); //ignore error
793 /*, getDisabled: function */
795 new ButtonModel('Cancel', 'outline grey', () => {
796 modal.instance.close();
801 // 3rd arg is passed to DeclareListComponent instance
802 this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
803 modal.instance.open();
806 /*** DECLARE PROPERTIES/POLICIES ***/
807 declarePropertiesToPolicies = (): void => {
808 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
809 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
811 angular.forEach(instancesIds, (instanceId: string): void => {
812 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
813 if (selectedInstanceData instanceof ComponentInstance) {
814 if (!this.isInput(selectedInstanceData.originType)) {
815 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
820 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
821 this.loadingPolicies = true;
823 this.topologyTemplateService
824 .createPolicy(this.component, policiesToCreate, this.isSelf())
825 .subscribe(response => {
826 this.setPolicyTabIndication(response.length);
827 this.checkedPropertiesCount = 0;
828 this.displayPoliciesAsDeclared(response);
829 this.loadingPolicies = false;
834 displayPoliciesAsDeclared = (policies) => {
835 _.forEach(policies, (policy: any) => {
836 let newPolicy: InputFEModel = new InputFEModel(policy);
837 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
838 newPolicy.relatedPropertyName = policy.name;
839 newPolicy.relatedPropertyValue = policy.value;
840 this.updatePropertyValueAfterDeclare(newPolicy);
841 this.policies.push(policy);
845 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
846 return new Promise((resolve, reject) => {
847 if (!this.isValidChangedData) {
848 reject('Changed data is invalid - cannot save!');
851 if (!this.changedData.length) {
856 // make request and its handlers
858 let handleSuccess, handleError;
859 let changedInputsProperties = [], changedCapabilitiesProperties = [];
860 if (this.isPropertiesTabSelected) {
861 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
862 changedProp = <PropertyFEModel>changedProp;
863 const propBE = new PropertyBEModel(changedProp);
864 propBE.toscaPresentation = new ToscaPresentationData();
865 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
866 propBE.value = changedProp.getJSONValue();
867 propBE.name = changedProp.origName || changedProp.name;
868 delete propBE.origName;
871 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
873 if (this.selectedInstanceData instanceof ComponentInstance) {
874 if (this.isInput(this.selectedInstanceData.originType)) {
875 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
876 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
877 request = Observable.forkJoin(
878 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
879 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
880 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
883 else if (changedInputsProperties.length) {
884 request = this.componentInstanceServiceNg2
885 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
887 else if (changedCapabilitiesProperties.length) {
888 request = this.componentInstanceServiceNg2
889 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
891 handleSuccess = (response) => {
892 // reset each changed property with new value and remove it from changed properties list
893 response.forEach((resInput) => {
894 const changedProp = <PropertyFEModel>this.changedData.shift();
895 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
900 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
901 delete cp.constraints;
905 request = this.componentInstanceServiceNg2
906 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
908 handleSuccess = (response) => {
909 // reset each changed property with new value and remove it from changed properties list
910 response.forEach((resProp) => {
911 const changedProp = <PropertyFEModel>this.changedData.shift();
912 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
917 } else if (this.selectedInstanceData instanceof GroupInstance) {
918 request = this.componentInstanceServiceNg2
919 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
920 handleSuccess = (response) => {
921 // reset each changed property with new value and remove it from changed properties list
922 response.forEach((resProp) => {
923 const changedProp = <PropertyFEModel>this.changedData.shift();
924 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
928 } else if (this.selectedInstanceData instanceof PolicyInstance) {
929 request = this.componentInstanceServiceNg2
930 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
931 handleSuccess = (response) => {
932 // reset each changed property with new value and remove it from changed properties list
933 response.forEach((resProp) => {
934 const changedProp = <PropertyFEModel>this.changedData.shift();
935 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
940 } else if (this.isInputsTabSelected) {
942 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
943 changedInput = <InputFEModel>changedInput;
944 const inputBE = new InputBEModel(changedInput);
945 inputBE.defaultValue = changedInput.getJSONDefaultValue();
948 request = this.componentServiceNg2
949 .updateComponentInputs(this.component, changedInputs);
950 handleSuccess = (response) => {
951 // reset each changed property with new value and remove it from changed properties list
952 response.forEach((resInput) => {
953 const changedInput = <InputFEModel>this.changedData.shift();
954 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
955 changedInput.required = resInput.required;
956 changedInput.requiredOrig = resInput.required;
961 this.savingChangedData = true;
964 this.savingChangedData = false;
965 if (changedCapabilitiesProperties.length) {
966 this.reloadInstanceCapabilities();
968 handleSuccess && handleSuccess(response);
969 this.updateHasChangedData();
973 this.savingChangedData = false;
974 handleError && handleError(error);
975 this.updateHasChangedData();
982 reloadInstanceCapabilities = (): void => {
983 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
984 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
985 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
986 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
987 return instance.capabilities;
990 }, new CapabilitiesGroup());
991 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
995 reverseChangedData = ():void => {
996 // make reverse item handler
997 let handleReverseItem;
998 if (this.isPropertiesTabSelected) {
999 handleReverseItem = (changedItem) => {
1000 changedItem = <PropertyFEModel>changedItem;
1001 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
1003 } else if (this.isInputsTabSelected) {
1004 handleReverseItem = (changedItem) => {
1005 changedItem = <InputFEModel>changedItem;
1006 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
1007 changedItem.resetMetadata();
1008 changedItem.required = changedItem.requiredOrig;
1012 this.changedData.forEach(handleReverseItem);
1013 this.changedData = [];
1014 this.updateHasChangedData();
1017 updateHasChangedData = ():boolean => {
1018 const curHasChangedData:boolean = (this.changedData.length > 0);
1019 if (curHasChangedData !== this.hasChangedData) {
1020 this.hasChangedData = curHasChangedData;
1021 if(this.hasChangedData) {
1022 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1024 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1027 return this.hasChangedData;
1030 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1031 this.saveChangedData().then(
1033 this.notification.success({
1034 message: 'Successfully saved changes',
1037 if(onSuccessFunction) onSuccessFunction();
1040 this.notification.error({
1041 message: 'Failed to save changes!',
1044 if(onError) onError();
1049 showUnsavedChangesAlert = ():Promise<any> => {
1050 let modalTitle:string;
1051 if (this.isPropertiesTabSelected) {
1052 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1053 } else if (this.isInputsTabSelected) {
1054 modalTitle = `Unsaved inputs for ${this.component.name}`;
1057 return new Promise<any>((resolve, reject) => {
1058 const modal = this.ModalServiceSdcUI.openCustomModal(
1062 type: SdcUiCommon.ModalType.custom,
1063 testId: "navigate-modal",
1066 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1067 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1068 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1069 ] as SdcUiCommon.IModalButtonComponent[]
1070 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1075 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1076 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1077 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1078 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1079 return feProperty.name == input.relatedPropertyName &&
1080 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1082 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1083 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1084 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1085 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1089 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1090 updateCheckedPropertyCount = (increment: boolean): void => {
1091 this.checkedPropertiesCount += (increment) ? 1 : -1;
1092 console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1095 updateCheckedChildPropertyCount = (increment: boolean): void => {
1096 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1099 setInputTabIndication = (numInputs: number): void => {
1100 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1103 setPolicyTabIndication = (numPolicies: number): void => {
1104 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1107 resetUnsavedChangesForInput = (input:InputFEModel) => {
1108 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1109 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1110 this.updateHasChangedData();
1113 deleteInput = (input: InputFEModel) => {
1114 //reset any unsaved changes to the input before deleting it
1115 this.resetUnsavedChangesForInput(input);
1117 console.debug("==>" + this.constructor.name + ": deleteInput");
1118 let inputToDelete = new InputBEModel(input);
1120 this.componentServiceNg2
1121 .deleteInput(this.component, inputToDelete)
1122 .subscribe(response => {
1123 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1125 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1126 this.changeSelectedInstance(this.selectedInstanceData);
1127 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1129 // if (instanceFeProperties) {
1130 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1131 // return prop.name == input.propertyName;
1134 // if (propToEnable) {
1135 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1136 // propToEnable.setNonDeclared(response.inputPath);
1137 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1138 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1141 }, error => {}); //ignore error
1144 deletePolicy = (policy: PolicyInstance) => {
1145 this.loadingPolicies = true;
1146 this.topologyTemplateService
1147 .deletePolicy(this.component, policy)
1148 .subscribe((response) => {
1149 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1150 this.changeSelectedInstance(this.selectedInstanceData);
1151 this.loadingPolicies = false;
1155 deleteProperty = (property: PropertyFEModel) => {
1156 const propertyToDelete = new PropertyFEModel(property);
1157 this.loadingProperties = true;
1158 const feMap = this.instanceFePropertiesMap;
1159 this.topologyTemplateService
1160 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1161 .subscribe((response) => {
1162 const props = feMap[this.component.uniqueId];
1163 props.splice(props.findIndex(p => p.uniqueId === response),1);
1164 this.loadingProperties = false;
1166 this.loadingProperties = false;
1167 console.error(error);
1171 /*** addProperty ***/
1172 addProperty = (model: string) => {
1173 this.loadDataTypesByComponentModel(model)
1174 let modalTitle = 'Add Property';
1175 let modal = this.modalService.createCustomModal(new ModalModel(
1180 new ButtonModel('Save', 'blue', () => {
1181 modal.instance.dynamicContent.instance.isLoading = true;
1182 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1183 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1184 .subscribe((response) => {
1185 modal.instance.dynamicContent.instance.isLoading = false;
1186 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1187 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1188 modal.instance.close();
1190 modal.instance.dynamicContent.instance.isLoading = false;
1191 this.notification.error({
1192 message: 'Failed to add property:' + error,
1196 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1197 new ButtonModel('Cancel', 'outline grey', () => {
1198 modal.instance.close();
1203 modal.instance.open();
1204 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1209 let modalTitle = 'Add Input';
1210 let modal = this.modalService.createCustomModal(new ModalModel(
1215 new ButtonModel('Save', 'blue', () => {
1216 modal.instance.dynamicContent.instance.isLoading = true;
1217 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1218 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1219 .subscribe((response) => {
1220 modal.instance.dynamicContent.instance.isLoading = false;
1221 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1222 this.inputs.push(newInputProp);
1223 modal.instance.close();
1225 modal.instance.dynamicContent.instance.isLoading = false;
1226 this.notification.error({
1227 message: 'Failed to add input:' + error,
1231 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1232 new ButtonModel('Cancel', 'outline grey', () => {
1233 modal.instance.close();
1238 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1239 modal.instance.open();
1242 /*** SEARCH RELATED FUNCTIONS ***/
1243 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1244 let instanceBePropertiesMap:InstanceBePropertiesMap;
1245 this.componentServiceNg2
1246 .filterComponentInstanceProperties(this.component, filterData)
1247 .subscribe((response) => {
1248 this.processInstancePropertiesResponse(response, false);
1249 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1250 this.searchPropertyName = filterData.propertyName;//mark in table
1251 this.hierarchyNavTabs.triggerTabChange('Composition');
1252 this.propertiesNavigationData = [];
1253 this.displayClearSearch = true;
1254 }, (error) => {}); //ignore error
1258 clearSearch = () => {
1259 this.instancesNavigationData = this.instances;
1260 this.searchPropertyName = "";
1261 this.hierarchyPropertiesDisplayOptions.searchText = "";
1262 this.displayClearSearch = false;
1263 this.advanceSearch.clearAll();
1264 this.searchQuery = '';
1267 clickOnClearSearch = () => {
1269 this.selectFirstInstanceByDefault();
1270 this.hierarchyNavTabs.triggerTabChange('Composition');
1273 private isInput = (instanceType:string):boolean =>{
1274 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1277 loadDataTypesByComponentModel(model:string) {
1278 this.propertyCreatorComponent.filterDataTypesByModel(model);