Correcting spinner
[aai/sparky-fe.git] / src / app / tierSupport / TierSupport.jsx
1 /*
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23
24 import React, {Component} from 'react';
25 import {connect} from 'react-redux';
26 import SplitPane from 'react-split-pane';
27 import Spinner from 'utils/SpinnerContainer.jsx';
28
29 import {setSecondaryTitle} from 'app/MainScreenWrapperActionHelper.js';
30 import ForceDirectedGraph from 'generic-components/graph/ForceDirectedGraph.jsx';
31 import SelectedNodeDetails from 'app/tierSupport/selectedNodeDetails/SelectedNodeDetails.jsx';
32
33
34 import overlaysDetails from 'resources/overlays/overlaysDetails.json';
35 import * as Overlays from 'app/overlays/OverlayImports.js';
36
37 import i18n from 'utils/i18n/i18n';
38 import {
39   onNodeDetailsChange,
40   onNodeMenuChange,
41   splitPaneResize,
42   querySelectedNodeElement,
43   setNotificationText,
44   clearVIData
45 } from 'app/tierSupport/TierSupportActions.js';
46 import {
47   TSUI_TITLE,
48   TSUI_NODE_DETAILS_INITIAL_WIDTH,
49   TSUI_NODE_DETAILS_MIN_WIDTH,
50   TSUI_GRAPH_MENU_NODE_DETAILS,
51 } from './TierSupportConstants.js';
52
53 let mapStateToProps = (
54   {
55     tierSupport:
56       {
57         tierSupportReducer,
58         globalAutoCompleteSearchBar
59       }
60   }) => {
61
62   let {
63         forceDirectedGraphRawData = {
64           graphCounter: -1,
65           nodeDataArray: [],
66           linkDataArray: [],
67           graphMeta: {}
68         }, windowWidth = 500,
69         windowHeight = 500,
70         graphNodeSelectedMenu = TSUI_GRAPH_MENU_NODE_DETAILS,
71         feedbackMsgText = '',
72         feedbackMsgSeverity = '',
73         nodeData = {},
74         enableBusyFeedback = false
75       } = tierSupportReducer;
76
77   let {
78         performPrepareVisualization = false,
79         selectedSuggestion = {}
80       } = globalAutoCompleteSearchBar;
81   return {
82     forceDirectedGraphRawData,
83     windowWidth,
84     windowHeight,
85     graphNodeSelectedMenu,
86     performPrepareVisualization,
87     selectedSuggestion,
88     feedbackMsgText,
89     feedbackMsgSeverity,
90     nodeData,
91     enableBusyFeedback
92   };
93 };
94
95 let mapActionToProps = (dispatch) => {
96   return {
97     onSetViewTitle: (title) => {
98       dispatch(setSecondaryTitle(title));
99     },
100     onNodeSelected: (requestObject) => {
101       dispatch(onNodeDetailsChange(requestObject));
102     },
103     onNodeMenuSelect: (selectedMenu) => {
104       dispatch(onNodeMenuChange(selectedMenu.buttonId));
105     },
106     onSplitPaneResize: (initialLoad) => {
107       dispatch(splitPaneResize(initialLoad));
108     },
109     onNewVIParam: (param) => {
110       dispatch(querySelectedNodeElement(param));
111     },
112     onMessageStateChange: (msgText, msgSeverity) => {
113       dispatch(setNotificationText(msgText, msgSeverity));
114     },
115     onRequestClearData: () => {
116       dispatch(clearVIData());
117     }
118   };
119 };
120
121 class TierSupport extends Component {
122   static propTypes = {
123     forceDirectedGraphRawData: React.PropTypes.object,
124     windowWidth: React.PropTypes.number,
125     windowHeight: React.PropTypes.number,
126     graphNodeSelectedMenu: React.PropTypes.string,
127     feedbackMsgText: React.PropTypes.string,
128     feedbackMsgSeverity: React.PropTypes.string,
129     nodeData: React.PropTypes.object,
130     enableBusyFeedback: React.PropTypes.bool
131   };
132
133   componentWillReceiveProps(nextProps) {
134     if (nextProps.match.params.viParam &&
135       nextProps.match.params.viParam !==
136       this.props.match.params.viParam) {
137       this.props.onNewVIParam(nextProps.match.params.viParam);
138     }
139     if(nextProps.match.params.viParam && nextProps.match.params.viParam !==
140       this.props.match.params.viParam) {
141       this.props.onRequestClearData();
142     }
143
144     if (nextProps.feedbackMsgText !== this.props.feedbackMsgText) {
145       this.props.onMessageStateChange(nextProps.feedbackMsgText,
146         nextProps.feedbackMsgSeverity);
147     }
148   }
149
150   componentWillMount() {
151     this.props.onSetViewTitle(i18n(TSUI_TITLE));
152     if (this.props.match.params.viParam) {
153       this.props.onNewVIParam(this.props.match.params.viParam);
154     } else {
155       this.props.onRequestClearData();
156     }
157   }
158
159   componentDidMount() {
160     this.props.onSplitPaneResize(true);
161   }
162
163   componentWillUnmount() {
164     // resetting to default (empty screen)
165     this.props.onRequestClearData();
166   }
167
168   render() {
169
170     const {
171             forceDirectedGraphRawData,
172             onNodeSelected,
173             windowWidth,
174             windowHeight,
175             onSplitPaneResize,
176             onNodeMenuSelect,
177             enableBusyFeedback
178           } = this.props;
179     let availableOverlay;
180     let overlayComponent;
181     // Currently only ONE overlay can be added to each view.
182     // todo: need to make it array if more than one overlay can be used. No need now.
183     overlaysDetails.forEach(function(overlay){
184       if(overlay.view === 'schema') {
185         availableOverlay = overlay.key;
186         overlayComponent = overlay.componentName;
187       }
188     });
189
190     //Temp code for a demo, will be removed as Vis library is updated
191     let currentNodeButton;
192     if(this.props.graphNodeSelectedMenu ===
193       TSUI_GRAPH_MENU_NODE_DETAILS ) {
194       currentNodeButton = 'NODE_DETAILS';
195     } else if(availableOverlay) {
196       currentNodeButton = availableOverlay;
197     }
198     // End temp code
199     let dataOverlayButtons = ['NODE_DETAILS'];
200     if(availableOverlay) {
201       dataOverlayButtons.push(availableOverlay);
202     }
203     let currentSelectedMenu = this.getCurrentSelectedMenu(overlayComponent);
204     return (
205       <div className='tier-support-ui'>
206           <Spinner loading={enableBusyFeedback}>
207             <SplitPane
208               split='vertical'
209               enableResizing='true'
210               onDragFinished={ () => {
211                 onSplitPaneResize(false);
212               } }
213               defaultSize={TSUI_NODE_DETAILS_INITIAL_WIDTH}
214               minSize={TSUI_NODE_DETAILS_MIN_WIDTH}
215               maxSize={-200}
216               primary='second'>
217               <div>
218                 <ForceDirectedGraph
219                   viewWidth={windowWidth}
220                   viewHeight={windowHeight}
221                   graphData={forceDirectedGraphRawData}
222                   nodeSelectedCallback={(nodeData) => {
223                     onNodeSelected(nodeData);
224                   }}
225                   nodeButtonSelectedCallback={(selectedMenuId) => {
226                     onNodeMenuSelect(selectedMenuId);
227                   }}
228                   dataOverlayButtons={dataOverlayButtons}
229                   currentlySelectedNodeView={currentNodeButton}/>
230
231               </div>
232               <div>
233                 {currentSelectedMenu}
234               </div>
235             </SplitPane>
236           </Spinner>
237       </div>
238     );
239   }
240
241   isNotEmpty(obj) {
242     for(var prop in obj) {
243       if(obj.hasOwnProperty(prop)) {
244         return true;
245       }
246     }
247     return false;
248   }
249
250   getCurrentSelectedMenu(overlayComponent) {
251     let secondOverlay;
252     if (this.props.graphNodeSelectedMenu === TSUI_GRAPH_MENU_NODE_DETAILS) {
253       if (!this.nodeDetails) {
254         this.nodeDetails = <SelectedNodeDetails/>;
255       }
256       return this.nodeDetails;
257     }
258     else {
259       if (this.isNotEmpty(this.props.nodeData) && overlayComponent) {
260         if (Overlays.default.hasOwnProperty(overlayComponent)) {
261           let OverlayComponent = Overlays.default[overlayComponent];
262           secondOverlay = <OverlayComponent nodeDetails={this.props.nodeData}/>;
263         }
264       }
265       return secondOverlay;
266     }
267   }
268
269 }
270
271 export default connect(mapStateToProps, mapActionToProps)(TierSupport);