943943f44e84af7d6105f99fa619cece9074c97d
[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 { ClipLoader } from 'react-spinners';
28 import {COLOR_BLUE} from 'utils/GlobalConstants.js';
29
30 import {setSecondaryTitle} from 'app/MainScreenWrapperActionHelper.js';
31 import ForceDirectedGraph from 'generic-components/graph/ForceDirectedGraph.jsx';
32 import SelectedNodeDetails from 'app/tierSupport/selectedNodeDetails/SelectedNodeDetails.jsx';
33
34
35 import overlaysDetails from 'resources/overlays/overlaysDetails.json';
36 import * as Overlays from 'app/overlays/OverlayImports.js';
37
38 import i18n from 'utils/i18n/i18n';
39 import {
40   onNodeDetailsChange,
41   onNodeMenuChange,
42   splitPaneResize,
43   querySelectedNodeElement,
44   setNotificationText,
45   clearVIData
46 } from 'app/tierSupport/TierSupportActions.js';
47 import {
48   TSUI_TITLE,
49   TSUI_NODE_DETAILS_INITIAL_WIDTH,
50   TSUI_NODE_DETAILS_MIN_WIDTH,
51   TSUI_GRAPH_MENU_NODE_DETAILS,
52 } from './TierSupportConstants.js';
53
54 let mapStateToProps = (
55   {
56     tierSupport:
57       {
58         tierSupportReducer,
59         globalAutoCompleteSearchBar
60       }
61   }) => {
62
63   let {
64         forceDirectedGraphRawData = {
65           graphCounter: -1,
66           nodeDataArray: [],
67           linkDataArray: [],
68           graphMeta: {}
69         }, windowWidth = 500,
70         windowHeight = 500,
71         graphNodeSelectedMenu = TSUI_GRAPH_MENU_NODE_DETAILS,
72         feedbackMsgText = '',
73         feedbackMsgSeverity = '',
74         nodeData = {},
75         enableBusyFeedback = false
76       } = tierSupportReducer;
77
78   let {
79         performPrepareVisualization = false,
80         selectedSuggestion = {}
81       } = globalAutoCompleteSearchBar;
82   return {
83     forceDirectedGraphRawData,
84     windowWidth,
85     windowHeight,
86     graphNodeSelectedMenu,
87     performPrepareVisualization,
88     selectedSuggestion,
89     feedbackMsgText,
90     feedbackMsgSeverity,
91     nodeData,
92     enableBusyFeedback
93   };
94 };
95
96 let mapActionToProps = (dispatch) => {
97   return {
98     onSetViewTitle: (title) => {
99       dispatch(setSecondaryTitle(title));
100     },
101     onNodeSelected: (requestObject) => {
102       dispatch(onNodeDetailsChange(requestObject));
103     },
104     onNodeMenuSelect: (selectedMenu) => {
105       dispatch(onNodeMenuChange(selectedMenu.buttonId));
106     },
107     onSplitPaneResize: (initialLoad) => {
108       dispatch(splitPaneResize(initialLoad));
109     },
110     onNewVIParam: (param) => {
111       dispatch(querySelectedNodeElement(param));
112     },
113     onMessageStateChange: (msgText, msgSeverity) => {
114       dispatch(setNotificationText(msgText, msgSeverity));
115     },
116     onRequestClearData: () => {
117       dispatch(clearVIData());
118     }
119   };
120 };
121
122 class TierSupport extends Component {
123   static propTypes = {
124     forceDirectedGraphRawData: React.PropTypes.object,
125     windowWidth: React.PropTypes.number,
126     windowHeight: React.PropTypes.number,
127     graphNodeSelectedMenu: React.PropTypes.string,
128     feedbackMsgText: React.PropTypes.string,
129     feedbackMsgSeverity: React.PropTypes.string,
130     nodeData: React.PropTypes.object,
131     enableBusyFeedback: React.PropTypes.bool
132   };
133
134   componentWillReceiveProps(nextProps) {
135     if (nextProps.match.params.viParam &&
136       nextProps.match.params.viParam !==
137       this.props.match.params.viParam) {
138       this.props.onNewVIParam(nextProps.match.params.viParam);
139     }
140     if(nextProps.match.params.viParam && nextProps.match.params.viParam !==
141       this.props.match.params.viParam) {
142       this.props.onRequestClearData();
143     }
144
145     if (nextProps.feedbackMsgText !== this.props.feedbackMsgText) {
146       this.props.onMessageStateChange(nextProps.feedbackMsgText,
147         nextProps.feedbackMsgSeverity);
148     }
149   }
150
151   componentWillMount() {
152     this.props.onSetViewTitle(i18n(TSUI_TITLE));
153     if (this.props.match.params.viParam) {
154       this.props.onNewVIParam(this.props.match.params.viParam);
155     } else {
156       this.props.onRequestClearData();
157     }
158   }
159
160   componentDidMount() {
161     this.props.onSplitPaneResize(true);
162   }
163
164   componentWillUnmount() {
165     // resetting to default (empty screen)
166     this.props.onRequestClearData();
167   }
168
169   render() {
170
171     const {
172             forceDirectedGraphRawData,
173             onNodeSelected,
174             windowWidth,
175             windowHeight,
176             onSplitPaneResize,
177             onNodeMenuSelect,
178             enableBusyFeedback
179           } = this.props;
180
181     let componentVisibitliyClassName = 'showContainer';
182     if(enableBusyFeedback){
183       componentVisibitliyClassName = 'hideContainer';
184     }
185     let availableOverlay;
186     let overlayComponent;
187     // Currently only ONE overlay can be added to each view.
188     // todo: need to make it array if more than one overlay can be used. No need now.
189     overlaysDetails.forEach(function(overlay){
190       if(overlay.view === 'schema') {
191         availableOverlay = overlay.key;
192         overlayComponent = overlay.componentName;
193       }
194     });
195
196     //Temp code for a demo, will be removed as Vis library is updated
197     let currentNodeButton;
198     if(this.props.graphNodeSelectedMenu ===
199       TSUI_GRAPH_MENU_NODE_DETAILS ) {
200       currentNodeButton = 'NODE_DETAILS';
201     } else if(availableOverlay) {
202       currentNodeButton = availableOverlay;
203     }
204     // End temp code
205     let dataOverlayButtons = ['NODE_DETAILS'];
206     if(availableOverlay) {
207       dataOverlayButtons.push(availableOverlay);
208     }
209     let currentSelectedMenu = this.getCurrentSelectedMenu(overlayComponent);
210     return (
211       <div className='tier-support-ui'>
212           <div className='spinner'>
213               <ClipLoader color={COLOR_BLUE} loading={enableBusyFeedback} />
214             </div>
215           <div className={componentVisibitliyClassName}>
216             <SplitPane
217               split='vertical'
218               enableResizing='true'
219               onDragFinished={ () => {
220                 onSplitPaneResize(false);
221               } }
222               defaultSize={TSUI_NODE_DETAILS_INITIAL_WIDTH}
223               minSize={TSUI_NODE_DETAILS_MIN_WIDTH}
224               maxSize={-200}
225               primary='second'>
226               <div>
227                 <ForceDirectedGraph
228                   viewWidth={windowWidth}
229                   viewHeight={windowHeight}
230                   graphData={forceDirectedGraphRawData}
231                   nodeSelectedCallback={(nodeData) => {
232                     onNodeSelected(nodeData);
233                   }}
234                   nodeButtonSelectedCallback={(selectedMenuId) => {
235                     onNodeMenuSelect(selectedMenuId);
236                   }}
237                   dataOverlayButtons={dataOverlayButtons}
238                   currentlySelectedNodeView={currentNodeButton}/>
239
240               </div>
241               <div>
242                 {currentSelectedMenu}
243               </div>
244             </SplitPane>
245           </div>
246       </div>
247     );
248   }
249
250   isNotEmpty(obj) {
251     for(var prop in obj) {
252       if(obj.hasOwnProperty(prop)) {
253         return true;
254       }
255     }
256     return false;
257   }
258
259   getCurrentSelectedMenu(overlayComponent) {
260     let secondOverlay;
261     if (this.props.graphNodeSelectedMenu === TSUI_GRAPH_MENU_NODE_DETAILS) {
262       if (!this.nodeDetails) {
263         this.nodeDetails = <SelectedNodeDetails/>;
264       }
265       return this.nodeDetails;
266     }
267     else {
268       if (this.isNotEmpty(this.props.nodeData) && overlayComponent) {
269         if (Overlays.default.hasOwnProperty(overlayComponent)) {
270           let OverlayComponent = Overlays.default[overlayComponent];
271           secondOverlay = <OverlayComponent nodeDetails={this.props.nodeData}/>;
272         }
273       }
274       return secondOverlay;
275     }
276   }
277
278 }
279
280 export default connect(mapStateToProps, mapActionToProps)(TierSupport);