7bb88c7f598a32fc38375cc6306222098ae0dd28
[sdc.git] /
1 import { Component, OnInit, Input, OnDestroy } from '@angular/core';
2 import { Component as TopologyTemplate, Capability, Requirement, CapabilitiesGroup, RequirementsGroup, FullComponentInstance } from "app/models";
3 import { Store } from "@ngxs/store";
4 import { GRAPH_EVENTS } from "app/utils";
5 import { ComponentGenericResponse } from "app/ng2/services/responses/component-generic-response";
6 import { TopologyTemplateService } from "app/ng2/services/component-services/topology-template.service";
7 import { EventListenerService } from "app/services";
8 import { WorkspaceService } from "app/ng2/pages/workspace/workspace.service";
9 import { CompositionService } from "app/ng2/pages/composition/composition.service";
10 import {SelectedComponentType, TogglePanelLoadingAction} from "../../../common/store/graph.actions";
11 import {ComponentInstanceServiceNg2} from "../../../../../services/component-instance-services/component-instance.service";
12
13
14 export class InstanceCapabilitiesMap {
15     [key:string]:Array<Capability>;
16 }
17
18 export class InstanceRequirementsMap {
19     [key:string]:Array<Requirement>;
20 }
21
22 @Component({
23     selector: 'req-capabilities-tab',
24     templateUrl: './req-capabilities-tab.component.html',
25     styleUrls: ['./req-capabilities-tab.component.less']
26 })
27 export class ReqAndCapabilitiesTabComponent implements OnInit, OnDestroy {
28
29     isComponentInstanceSelected: boolean;
30     capabilities:Array<Capability>;
31     requirements:Array<Requirement>;
32     capabilitiesInstancesMap:InstanceCapabilitiesMap;
33     requirementsInstancesMap:InstanceRequirementsMap;
34     objectKeys = Object.keys;
35     
36     @Input() isViewOnly: boolean;
37     @Input() componentType: SelectedComponentType;
38     @Input() component: TopologyTemplate | FullComponentInstance;
39     @Input() input: any;
40
41
42     constructor(private store: Store,
43         private topologyTemplateService:TopologyTemplateService,
44         private workspaceService: WorkspaceService,
45         private compositionService: CompositionService,
46         private eventListenerService:EventListenerService,
47         private componentInstanceService: ComponentInstanceServiceNg2) { }
48
49     ngOnInit(): void {
50
51         this.isComponentInstanceSelected = this.componentType === SelectedComponentType.COMPONENT_INSTANCE;
52
53         this.requirements = [];
54         this.capabilities = [];
55         this.initEvents();
56         this.initRequirementsAndCapabilities();
57         
58      }
59
60      private initEvents = ():void => {
61         this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_NODE_SELECTED, this.initRequirementsAndCapabilities);
62         this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.updateRequirementCapabilities);
63         this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE,  this.updateRequirementCapabilities);
64         this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE,  this.updateRequirementCapabilities);
65     }
66     
67      ngOnDestroy(): void {
68         this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_NODE_SELECTED, this.initRequirementsAndCapabilities);
69         this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.updateRequirementCapabilities);
70         this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE, this.updateRequirementCapabilities);
71         this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, this.updateRequirementCapabilities);
72      }
73
74      public isCurrentDisplayComponentIsComplex = ():boolean => {
75         
76         if (this.component instanceof FullComponentInstance) {
77             if (this.component.originType === 'VF') {
78                 return true;
79             }
80             return false;
81         } else {
82             return this.component.isComplex();
83         }
84     }
85
86     private loadComplexComponentData = () => {
87         this.store.dispatch(new TogglePanelLoadingAction({isLoading: true}));
88
89         this.topologyTemplateService.getCapabilitiesAndRequirements(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId).subscribe((response:ComponentGenericResponse) => {
90             this.workspaceService.metadata.capabilities = response.capabilities;
91             this.workspaceService.metadata.requirements = response.requirements;
92             this.setScopeCapabilitiesRequirements(response.capabilities, response.requirements);
93             this.initInstancesMap();
94             this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
95         }, (error) => { this.store.dispatch(new TogglePanelLoadingAction({isLoading: false})); });
96     }
97
98
99     private extractValuesFromMap = (map:CapabilitiesGroup | RequirementsGroup):Array<any> => {
100         let values = [];
101         _.forEach(map, (capabilitiesOrRequirements:Array<Capability> | Array<Requirement>, key) => {
102                 values = values.concat(capabilitiesOrRequirements)
103             }
104         );
105         return values;
106     }
107
108     private setScopeCapabilitiesRequirements = (capabilities:CapabilitiesGroup, requirements:RequirementsGroup) => {
109         this.capabilities = this.extractValuesFromMap(capabilities);
110         this.requirements = this.extractValuesFromMap(requirements);
111     }
112
113
114     private initInstancesMap = ():void => {
115
116         this.capabilitiesInstancesMap = new InstanceCapabilitiesMap();
117         let capabilityList: Array<Capability> = this.capabilities;
118         if (capabilityList) {
119             if (!this.isComponentInstanceSelected) {
120                 capabilityList = capabilityList.filter(value => value.external);
121             }
122             capabilityList.forEach(capability => {
123                 if (this.capabilitiesInstancesMap[capability.ownerName]) {
124                     this.capabilitiesInstancesMap[capability.ownerName] = this.capabilitiesInstancesMap[capability.ownerName].concat(capability);
125                 } else {
126                     this.capabilitiesInstancesMap[capability.ownerName] = new Array<Capability>(capability);
127                 }
128             });
129         }
130
131         this.requirementsInstancesMap = new InstanceRequirementsMap();
132         _.forEach(this.requirements, (requirement:Requirement) => {
133                 if(this.isComponentInstanceSelected || requirement.external){
134                     if (this.requirementsInstancesMap[requirement.ownerName]) {
135                         this.requirementsInstancesMap[requirement.ownerName] = this.requirementsInstancesMap[requirement.ownerName].concat(requirement);
136                     } else {
137                         this.requirementsInstancesMap[requirement.ownerName] = new Array<Requirement>(requirement);
138                     }
139             }
140         });
141     }
142
143     private initRequirementsAndCapabilities = (needUpdate?: boolean) => {
144
145         // if instance selected, we take the requirement and capabilities of the instance - always exist because we load them with the graph
146         if (this.component instanceof FullComponentInstance) {
147             this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
148             this.setScopeCapabilitiesRequirements(this.component.capabilities, this.component.requirements);
149             if (this.component.originType === 'VF') {
150                 this.initInstancesMap();
151             }
152         } else {
153             // if instance not selected, we take the requirement and capabilities of the VF/SERVICE, if not exist we call api
154             if (needUpdate || !this.component.capabilities || !this.component.requirements) {
155                 this.loadComplexComponentData();
156
157             } else {
158                 this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
159                 this.setScopeCapabilitiesRequirements(this.component.capabilities, this.component.requirements);
160                 this.initInstancesMap();
161             }
162         }
163     }
164
165     private updateRequirementCapabilities = () => {
166         if (!this.isComponentInstanceSelected) {
167             this.loadComplexComponentData();
168         }
169     }
170
171
172     onMarkCapabilityAsExternal(capability: Capability) {
173         this.store.dispatch(new TogglePanelLoadingAction({isLoading: true}));
174         capability.external = !capability.external;
175         const componentId = this.workspaceService.metadata.uniqueId;
176         const componentInstanceId = this.component.uniqueId;
177         this.componentInstanceService
178         .updateInstanceCapability(this.workspaceService.metadata.getTypeUrl(), componentId, componentInstanceId, capability)
179         .subscribe(() => {
180             this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_CAPABILITY_EXTERNAL_CHANGED, componentInstanceId, capability);
181             this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
182         } , (error) => {
183             console.error("An error has occurred while setting capability '" + capability.name + "' external", error);
184             capability.external = !capability.external;
185             this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
186         });
187     }
188 }
189