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