af71a973db4e7fff848db34ca43fb33303ee9afb
[aai/sparky-fe.git] / src / app / MainScreenHeader.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 import React, {Component} from 'react';
24 import {connect} from 'react-redux';
25 import FontAwesome from 'react-fontawesome';
26 import Button from 'react-bootstrap/lib/Button.js';
27 import Modal from 'react-bootstrap/lib/Modal.js';
28 import GlobalAutoCompleteSearchBar from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBar.jsx';
29 import {postAnalyticsData} from 'app/analytics/AnalyticsActions.js';
30 import GlobalInlineMessageBar from 'app/GlobalInlineMessageBar/GlobalInlineMessageBar.jsx';
31 import {getClearGlobalMessageEvent} from 'app/GlobalInlineMessageBar/GlobalInlineMessageBarActions.js';
32
33 import {
34   Route,
35   NavLink
36 } from 'react-router-dom';
37
38 import {
39   AAI_TITLE,
40   MENU_ITEM_TIER_SUPPORT,
41   MENU_ITEM_VNF_SEARCH
42 } from './MainScreenWrapperConstants.js';
43
44 import {
45   showMainMenu
46 } from './MainScreenWrapperActionHelper.js';
47
48 import {clearSuggestionsTextField} from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBarActions.js';
49
50 import customViews from 'resources/views/customViews.json';
51
52 const mapStateToProps = ({mainWrapper}) => {
53   let {
54         showMenu = false,
55         toggleButtonActive = false
56       } = mainWrapper;
57
58   return {
59     showMenu,
60     toggleButtonActive
61   };
62 };
63
64 const mapActionsToProps = (dispatch) => {
65   return {
66     onShowMenu: () => dispatch(showMainMenu(true)),
67     onHideMenu: () => {
68       dispatch(showMainMenu(false));
69     },
70     dispatchAnalyticsData: () => dispatch(
71       postAnalyticsData(document.documentElement.outerHTML.replace('\s+', ''))),
72     onRouteChange: () => {
73       dispatch(getClearGlobalMessageEvent());
74       dispatch(clearSuggestionsTextField());
75     }
76   };
77 };
78
79 class MainScreenHeader extends Component {
80   static propTypes = {
81     showMenu: React.PropTypes.bool,
82     toggleButtonActive: React.PropTypes.bool
83   };
84
85   navigationLinkAndCurrentPathMatch(location, to) {
86     let linkPathElements = to.split('/');
87     let locationElements = location.pathname.split('/');
88
89     // the element arrays above will have the route at index 1 ... need to
90     // verify if the routes match
91     return locationElements[1] === linkPathElements[1];
92   }
93
94   hasRouteChanged(currentPath, nextPath) {
95     let currentPathParts = currentPath.split('/');
96     let nextPathParts = nextPath.split('/');
97
98     if (currentPathParts[1] !== nextPathParts[1]) {
99       return true;
100     } else {
101       return false;
102     }
103   }
104
105   componentWillReceiveProps(nextProps) {
106     if (this.props.location &&
107       this.props.location.pathname !== nextProps.location.pathname) {
108       // update analytics
109       this.props.dispatchAnalyticsData();
110
111       if (this.hasRouteChanged(this.props.location.pathname,
112           nextProps.location.pathname)) {
113         this.props.onRouteChange();
114       }
115     }
116   }
117
118   render() {
119     let {
120           showMenu,
121           onShowMenu,
122           onHideMenu,
123           toggleButtonActive
124         } = this.props;
125
126     let menuOptions = [];
127
128     const MenuItem = ({label, iconClass, to}) => (
129       <Route path={to} children={({location}) => (
130         <NavLink to={to} onClick={onHideMenu}>
131           <div className={this.navigationLinkAndCurrentPathMatch(location, to) ? 'main-menu-button-active' : 'main-menu-button'}>
132             <div className={iconClass}/>
133             <div className='button-icon'>{label}</div>
134           </div>
135         </NavLink>
136       )}/>
137     );
138
139     // add Tier Support view
140     menuOptions.push(
141       <MenuItem to='/viewInspect' label={MENU_ITEM_TIER_SUPPORT}
142                 iconClass='button-icon view-inspect-button-icon'/>
143     );
144
145     // add VNF view
146     // 2172a3c25ae56e4995038ffbc1f055692bfc76c0b8ceda1205bc745a9f7a805d is
147     // the hash for 'VNFs' ... ensures VNF Search screen defaults to the
148     // aggregate VNF results
149     menuOptions.push(
150       <MenuItem
151         to='/vnfSearch/2172a3c25ae56e4995038ffbc1f055692bfc76c0b8ceda1205bc745a9f7a805d'
152         label={MENU_ITEM_VNF_SEARCH}
153         iconClass='button-icon vnf-search-button-icon'/>
154     );
155
156     // add all custom view menu options
157     for (let view in customViews) {
158       menuOptions.push(
159         <MenuItem to={customViews[view]['viewName']}
160                   label={customViews[view]['displayName']}
161                   iconClass='button-icon inventory-button-icon'/>
162       );
163     }
164
165     return (
166       <div>
167         <div className='header'>
168           <div>
169             <Button
170               bsClass={(toggleButtonActive)
171               ? 'toggle-view-button-active'
172               : 'toggle-view-button'}
173               onClick={onShowMenu}>
174               <FontAwesome name='bars'/>
175             </Button>
176             <Modal show={showMenu} onHide={onHideMenu}
177                    dialogClassName='modal-main-menu'>
178               <Modal.Body>
179                 {menuOptions}
180               </Modal.Body>
181             </Modal>
182             <span className='application-title'>{AAI_TITLE}</span>
183             <GlobalAutoCompleteSearchBar history={this.props.history}/>
184           </div>
185           <GlobalInlineMessageBar />
186         </div>
187       </div>
188
189     );
190   }
191 }
192
193 export default connect(mapStateToProps, mapActionsToProps)(MainScreenHeader);