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());
607 this.loadingProperties = false;
608 console.error(error);
610 this.loadingProperties = false;
614 /*** DECLARE PROPERTIES/INPUTS ***/
615 declareProperties = (): void => {
616 console.debug("==>" + this.constructor.name + ": declareProperties");
618 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
619 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
620 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
621 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
622 let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
624 angular.forEach(instancesIds, (instanceId: string): void => {
625 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
626 if (selectedInstanceData instanceof ComponentInstance) {
627 if (!this.isInput(selectedInstanceData.originType)) {
628 // convert Property FE model -> Property BE model, extract only checked
629 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
631 selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
633 } else if (selectedInstanceData instanceof GroupInstance) {
634 selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
635 } else if (selectedInstanceData instanceof PolicyInstance) {
636 selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
640 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
642 //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
643 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
644 (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
646 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
647 (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
650 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
651 inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
652 prop => !this.isCapabilityProperty(prop)
654 if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
655 delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
658 let isCapabilityPropertyChanged = false;
660 inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
661 (prop: PropertyBEModel) => {
662 prop.name = prop.origName || prop.name;
663 if (this.isCapabilityProperty(prop)) {
664 isCapabilityPropertyChanged = true;
668 this.topologyTemplateService
669 .createInput(this.component, inputsToCreate, this.isSelf())
670 .subscribe((response) => {
671 this.selectInstanceRow(SERVICE_SELF_TITLE);
672 this.onInstanceSelectedUpdate(this.instances[0]);
673 this.setInputTabIndication(response.length);
674 this.checkedPropertiesCount = 0;
675 this.checkedChildPropertiesCount = 0;
676 _.forEach(response, (input: InputBEModel) => {
677 const newInput: InputFEModel = new InputFEModel(input);
678 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
679 this.inputs.push(newInput);
680 this.updatePropertyValueAfterDeclare(newInput);
682 if (isCapabilityPropertyChanged) {
683 this.reloadInstanceCapabilities();
685 }, error => {}); //ignore error
688 declareListProperties = (): void => {
689 // get selected properties
690 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
691 let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
692 let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
693 let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
694 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
695 let propertyNameList: Array<string> = [];
698 angular.forEach(instancesIds, (instanceId: string): void => {
700 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
701 let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
703 if (selectedInstanceData instanceof ComponentInstance) {
704 if (!this.isInput(selectedInstanceData.originType)) {
705 // convert Property FE model -> Property BE model, extract only checked
706 selectedComponentInstancesProperties[instanceId] = checkedProperties;
708 selectedComponentInstancesInputs[instanceId] = checkedProperties;
710 } else if (selectedInstanceData instanceof GroupInstance) {
711 selectedGroupInstancesProperties[instanceId] = checkedProperties;
712 } else if (selectedInstanceData instanceof PolicyInstance) {
713 selectedPolicyInstancesProperties[instanceId] = checkedProperties;
716 angular.forEach(checkedProperties, (property: PropertyBEModel) => {
717 propertyNameList.push(property.name);
721 let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
723 let modalTitle = 'Declare Properties as List Input';
724 const modal = this.modalService.createCustomModal(new ModalModel(
726 modalTitle, /* title */
731 'blue', /* css class */
732 () => { /* callback */
733 let content:any = modal.instance.dynamicContent.instance;
736 let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
737 let typelist: any = PROPERTY_TYPES.LIST;
738 let uniID: any = insId;
739 let boolfalse: any = false;
740 let required: any = content.propertyModel.required;
744 "type": content.propertyModel.simpleType,
748 let schemaProp :any = {
749 "type": content.propertyModel.simpleType,
753 reglistInput.description = content.propertyModel.description;
754 reglistInput.name = content.propertyModel.name;
755 reglistInput.type = typelist;
756 reglistInput.schemaType = content.propertyModel.simpleType;
757 reglistInput.instanceUniqueId = uniID;
758 reglistInput.uniqueId = uniID;
759 reglistInput.required = required;
760 reglistInput.schema = schem;
761 reglistInput.schemaProperty = schemaProp;
764 componentInstInputsMap: content.inputsToCreate,
765 listInput: reglistInput
768 this.topologyTemplateService
769 .createListInput(this.component, input, this.isSelf())
770 .subscribe(response => {
771 this.setInputTabIndication(response.length);
772 this.checkedPropertiesCount = 0;
773 this.checkedChildPropertiesCount = 0;
774 _.forEach(response, (input: InputBEModel) => {
775 let newInput: InputFEModel = new InputFEModel(input);
776 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
777 this.inputs.push(newInput);
778 // create list input does not return updated properties info, so need to reload
779 //this.updatePropertyValueAfterDeclare(newInput);
780 // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
781 this.changeSelectedInstance(this.selectedInstanceData);
783 modal.instance.close();
785 }, error => {}); //ignore error
788 /*, getDisabled: function */
790 new ButtonModel('Cancel', 'outline grey', () => {
791 modal.instance.close();
796 // 3rd arg is passed to DeclareListComponent instance
797 this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
798 modal.instance.open();
801 /*** DECLARE PROPERTIES/POLICIES ***/
802 declarePropertiesToPolicies = (): void => {
803 let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
804 let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
806 angular.forEach(instancesIds, (instanceId: string): void => {
807 let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
808 if (selectedInstanceData instanceof ComponentInstance) {
809 if (!this.isInput(selectedInstanceData.originType)) {
810 selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
815 let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null);
816 this.loadingPolicies = true;
818 this.topologyTemplateService
819 .createPolicy(this.component, policiesToCreate, this.isSelf())
820 .subscribe(response => {
821 this.setPolicyTabIndication(response.length);
822 this.checkedPropertiesCount = 0;
823 this.displayPoliciesAsDeclared(response);
824 this.loadingPolicies = false;
829 displayPoliciesAsDeclared = (policies) => {
830 _.forEach(policies, (policy: any) => {
831 let newPolicy: InputFEModel = new InputFEModel(policy);
832 this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
833 newPolicy.relatedPropertyName = policy.name;
834 newPolicy.relatedPropertyValue = policy.value;
835 this.updatePropertyValueAfterDeclare(newPolicy);
836 this.policies.push(policy);
840 saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => {
841 return new Promise((resolve, reject) => {
842 if (!this.isValidChangedData) {
843 reject('Changed data is invalid - cannot save!');
846 if (!this.changedData.length) {
851 // make request and its handlers
853 let handleSuccess, handleError;
854 let changedInputsProperties = [], changedCapabilitiesProperties = [];
855 if (this.isPropertiesTabSelected) {
856 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
857 changedProp = <PropertyFEModel>changedProp;
858 const propBE = new PropertyBEModel(changedProp);
859 propBE.toscaPresentation = new ToscaPresentationData();
860 propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
861 propBE.value = changedProp.getJSONValue();
862 propBE.name = changedProp.origName || changedProp.name;
863 delete propBE.origName;
866 changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
868 if (this.selectedInstanceData instanceof ComponentInstance) {
869 if (this.isInput(this.selectedInstanceData.originType)) {
870 changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
871 if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
872 request = Observable.forkJoin(
873 this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
874 this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
875 this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
878 else if (changedInputsProperties.length) {
879 request = this.componentInstanceServiceNg2
880 .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
882 else if (changedCapabilitiesProperties.length) {
883 request = this.componentInstanceServiceNg2
884 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
886 handleSuccess = (response) => {
887 // reset each changed property with new value and remove it from changed properties list
888 response.forEach((resInput) => {
889 const changedProp = <PropertyFEModel>this.changedData.shift();
890 this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
895 request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
896 delete cp.constraints;
900 request = this.componentInstanceServiceNg2
901 .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
903 handleSuccess = (response) => {
904 // reset each changed property with new value and remove it from changed properties list
905 response.forEach((resProp) => {
906 const changedProp = <PropertyFEModel>this.changedData.shift();
907 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
912 } else if (this.selectedInstanceData instanceof GroupInstance) {
913 request = this.componentInstanceServiceNg2
914 .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
915 handleSuccess = (response) => {
916 // reset each changed property with new value and remove it from changed properties list
917 response.forEach((resProp) => {
918 const changedProp = <PropertyFEModel>this.changedData.shift();
919 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
923 } else if (this.selectedInstanceData instanceof PolicyInstance) {
924 request = this.componentInstanceServiceNg2
925 .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties);
926 handleSuccess = (response) => {
927 // reset each changed property with new value and remove it from changed properties list
928 response.forEach((resProp) => {
929 const changedProp = <PropertyFEModel>this.changedData.shift();
930 this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
935 } else if (this.isInputsTabSelected) {
937 const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => {
938 changedInput = <InputFEModel>changedInput;
939 const inputBE = new InputBEModel(changedInput);
940 inputBE.defaultValue = changedInput.getJSONDefaultValue();
943 request = this.componentServiceNg2
944 .updateComponentInputs(this.component, changedInputs);
945 handleSuccess = (response) => {
946 // reset each changed property with new value and remove it from changed properties list
947 response.forEach((resInput) => {
948 const changedInput = <InputFEModel>this.changedData.shift();
949 this.inputsUtils.resetInputDefaultValue(changedInput, resInput.defaultValue);
950 changedInput.required = resInput.required;
951 changedInput.requiredOrig = resInput.required;
956 this.savingChangedData = true;
959 this.savingChangedData = false;
960 if (changedCapabilitiesProperties.length) {
961 this.reloadInstanceCapabilities();
963 handleSuccess && handleSuccess(response);
964 this.updateHasChangedData();
968 this.savingChangedData = false;
969 handleError && handleError(error);
970 this.updateHasChangedData();
977 reloadInstanceCapabilities = (): void => {
978 let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
979 this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
980 let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
981 if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
982 return instance.capabilities;
985 }, new CapabilitiesGroup());
986 (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
990 reverseChangedData = ():void => {
991 // make reverse item handler
992 let handleReverseItem;
993 if (this.isPropertiesTabSelected) {
994 handleReverseItem = (changedItem) => {
995 changedItem = <PropertyFEModel>changedItem;
996 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
998 } else if (this.isInputsTabSelected) {
999 handleReverseItem = (changedItem) => {
1000 changedItem = <InputFEModel>changedItem;
1001 this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
1002 changedItem.resetMetadata();
1003 changedItem.required = changedItem.requiredOrig;
1007 this.changedData.forEach(handleReverseItem);
1008 this.changedData = [];
1009 this.updateHasChangedData();
1012 updateHasChangedData = ():boolean => {
1013 const curHasChangedData:boolean = (this.changedData.length > 0);
1014 if (curHasChangedData !== this.hasChangedData) {
1015 this.hasChangedData = curHasChangedData;
1016 if(this.hasChangedData) {
1017 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
1019 this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
1022 return this.hasChangedData;
1025 doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
1026 this.saveChangedData().then(
1028 this.notification.success({
1029 message: 'Successfully saved changes',
1032 if(onSuccessFunction) onSuccessFunction();
1035 this.notification.error({
1036 message: 'Failed to save changes!',
1039 if(onError) onError();
1044 showUnsavedChangesAlert = ():Promise<any> => {
1045 let modalTitle:string;
1046 if (this.isPropertiesTabSelected) {
1047 modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
1048 } else if (this.isInputsTabSelected) {
1049 modalTitle = `Unsaved inputs for ${this.component.name}`;
1052 return new Promise<any>((resolve, reject) => {
1053 const modal = this.ModalServiceSdcUI.openCustomModal(
1057 type: SdcUiCommon.ModalType.custom,
1058 testId: "navigate-modal",
1061 {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()},
1062 {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}},
1063 {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
1064 ] as SdcUiCommon.IModalButtonComponent[]
1065 } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
1070 updatePropertyValueAfterDeclare = (input: InputFEModel) => {
1071 if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
1072 const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
1073 const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
1074 return feProperty.name == input.relatedPropertyName &&
1075 (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
1077 const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
1078 propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
1079 this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath);
1080 this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath);
1084 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
1085 updateCheckedPropertyCount = (increment: boolean): void => {
1086 this.checkedPropertiesCount += (increment) ? 1 : -1;
1087 console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
1090 updateCheckedChildPropertyCount = (increment: boolean): void => {
1091 this.checkedChildPropertiesCount += (increment) ? 1 : -1;
1094 setInputTabIndication = (numInputs: number): void => {
1095 this.propertyInputTabs.setTabIndication('Inputs', numInputs);
1098 setPolicyTabIndication = (numPolicies: number): void => {
1099 this.propertyInputTabs.setTabIndication('Policies', numPolicies);
1102 resetUnsavedChangesForInput = (input:InputFEModel) => {
1103 this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
1104 this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
1105 this.updateHasChangedData();
1108 deleteInput = (input: InputFEModel) => {
1109 //reset any unsaved changes to the input before deleting it
1110 this.resetUnsavedChangesForInput(input);
1112 console.debug("==>" + this.constructor.name + ": deleteInput");
1113 let inputToDelete = new InputBEModel(input);
1115 this.componentServiceNg2
1116 .deleteInput(this.component, inputToDelete)
1117 .subscribe(response => {
1118 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
1120 //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
1121 this.changeSelectedInstance(this.selectedInstanceData);
1122 // let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
1124 // if (instanceFeProperties) {
1125 // let propToEnable: PropertyFEModel = instanceFeProperties.find((prop) => {
1126 // return prop.name == input.propertyName;
1129 // if (propToEnable) {
1130 // if (propToEnable.name == response.inputPath) response.inputPath = null;
1131 // propToEnable.setNonDeclared(response.inputPath);
1132 // //this.propertiesUtils.resetPropertyValue(propToEnable, newValue, response.inputPath);
1133 // this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
1136 }, error => {}); //ignore error
1139 deletePolicy = (policy: PolicyInstance) => {
1140 this.loadingPolicies = true;
1141 this.topologyTemplateService
1142 .deletePolicy(this.component, policy)
1143 .subscribe((response) => {
1144 this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
1145 this.changeSelectedInstance(this.selectedInstanceData);
1146 this.loadingPolicies = false;
1150 deleteProperty = (property: PropertyFEModel) => {
1151 const propertyToDelete = new PropertyFEModel(property);
1152 this.loadingProperties = true;
1153 const feMap = this.instanceFePropertiesMap;
1154 this.topologyTemplateService
1155 .deleteServiceProperty(this.component.uniqueId, propertyToDelete)
1156 .subscribe((response) => {
1157 const props = feMap[this.component.uniqueId];
1158 props.splice(props.findIndex(p => p.uniqueId === response),1);
1159 this.loadingProperties = false;
1161 this.loadingProperties = false;
1162 console.error(error);
1166 /*** addProperty ***/
1167 addProperty = (model: string) => {
1168 this.loadDataTypesByComponentModel(model)
1169 let modalTitle = 'Add Property';
1170 let modal = this.modalService.createCustomModal(new ModalModel(
1175 new ButtonModel('Save', 'blue', () => {
1176 modal.instance.dynamicContent.instance.isLoading = true;
1177 const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel;
1178 this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty)
1179 .subscribe((response) => {
1180 modal.instance.dynamicContent.instance.isLoading = false;
1181 const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response);
1182 this.instanceFePropertiesMap[this.component.uniqueId].push(newProp);
1183 modal.instance.close();
1185 modal.instance.dynamicContent.instance.isLoading = false;
1186 this.notification.error({
1187 message: 'Failed to add property:' + error,
1191 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1192 new ButtonModel('Cancel', 'outline grey', () => {
1193 modal.instance.close();
1198 modal.instance.open();
1199 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1204 let modalTitle = 'Add Input';
1205 let modal = this.modalService.createCustomModal(new ModalModel(
1210 new ButtonModel('Save', 'blue', () => {
1211 modal.instance.dynamicContent.instance.isLoading = true;
1212 const newInput: InputBEModel = modal.instance.dynamicContent.instance.propertyModel;
1213 this.topologyTemplateService.createServiceInput(this.component.uniqueId, newInput)
1214 .subscribe((response) => {
1215 modal.instance.dynamicContent.instance.isLoading = false;
1216 const newInputProp: InputFEModel = this.inputsUtils.convertInputBEToInputFE(response);
1217 this.inputs.push(newInputProp);
1218 modal.instance.close();
1220 modal.instance.dynamicContent.instance.isLoading = false;
1221 this.notification.error({
1222 message: 'Failed to add input:' + error,
1226 }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()),
1227 new ButtonModel('Cancel', 'outline grey', () => {
1228 modal.instance.close();
1233 this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
1234 modal.instance.open();
1237 /*** SEARCH RELATED FUNCTIONS ***/
1238 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
1239 let instanceBePropertiesMap:InstanceBePropertiesMap;
1240 this.componentServiceNg2
1241 .filterComponentInstanceProperties(this.component, filterData)
1242 .subscribe((response) => {
1243 this.processInstancePropertiesResponse(response, false);
1244 this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
1245 this.searchPropertyName = filterData.propertyName;//mark in table
1246 this.hierarchyNavTabs.triggerTabChange('Composition');
1247 this.propertiesNavigationData = [];
1248 this.displayClearSearch = true;
1249 }, (error) => {}); //ignore error
1253 clearSearch = () => {
1254 this.instancesNavigationData = this.instances;
1255 this.searchPropertyName = "";
1256 this.hierarchyPropertiesDisplayOptions.searchText = "";
1257 this.displayClearSearch = false;
1258 this.advanceSearch.clearAll();
1259 this.searchQuery = '';
1262 clickOnClearSearch = () => {
1264 this.selectFirstInstanceByDefault();
1265 this.hierarchyNavTabs.triggerTabChange('Composition');
1268 private isInput = (instanceType:string):boolean =>{
1269 return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
1272 loadDataTypesByComponentModel(model:string) {
1273 this.propertyCreatorComponent.filterDataTypesByModel(model);