Initial coomit for AAI-UI(sparky-fe)
[aai/sparky-fe.git] / src / app / MainScreenHeader.jsx
1 /*
2  * ============LICENSE_START===================================================
3  * SPARKY (AAI UI service)
4  * ============================================================================
5  * Copyright © 2017 AT&T Intellectual Property.
6  * Copyright © 2017 Amdocs
7  * All rights reserved.
8  * ============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=====================================================
21  *
22  * ECOMP and OpenECOMP are trademarks
23  * and service marks of AT&T Intellectual Property.
24  */
25
26 import React, {Component} from 'react';
27 import {connect} from 'react-redux';
28 import FontAwesome from 'react-fontawesome';
29 import Button from 'react-bootstrap/lib/Button.js';
30 import Modal from 'react-bootstrap/lib/Modal.js';
31 import GlobalAutoCompleteSearchBar from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBar.jsx';
32 import {postAnalyticsData} from 'app/analytics/AnalyticsActions.js';
33 import GlobalInlineMessageBar from 'app/GlobalInlineMessageBar/GlobalInlineMessageBar.jsx';
34 import {getClearGlobalMessageEvent} from 'app/GlobalInlineMessageBar/GlobalInlineMessageBarActions.js';
35
36 import {
37   Route,
38   NavLink
39 } from 'react-router-dom';
40
41 import {
42   AAI_TITLE,
43   MENU_ITEM_TIER_SUPPORT,
44   MENU_ITEM_VNF_SEARCH
45 } from './MainScreenWrapperConstants.js';
46
47 import {
48   showMainMenu
49 } from './MainScreenWrapperActionHelper.js';
50
51 import {clearSuggestionsTextField} from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBarActions.js';
52
53 import customViews from 'resources/views/customViews.json';
54
55 const mapStateToProps = ({mainWrapper}) => {
56   let {
57         showMenu = false,
58         toggleButtonActive = false
59       } = mainWrapper;
60
61   return {
62     showMenu,
63     toggleButtonActive
64   };
65 };
66
67 const mapActionsToProps = (dispatch) => {
68   return {
69     onShowMenu: () => dispatch(showMainMenu(true)),
70     onHideMenu: () => {
71       dispatch(showMainMenu(false));
72     },
73     dispatchAnalyticsData: () => dispatch(
74       postAnalyticsData(document.documentElement.outerHTML.replace('\s+', ''))),
75     onRouteChange: () => {
76       dispatch(getClearGlobalMessageEvent());
77       dispatch(clearSuggestionsTextField());
78     }
79   };
80 };
81
82 class MainScreenHeader extends Component {
83   static propTypes = {
84     showMenu: React.PropTypes.bool,
85     toggleButtonActive: React.PropTypes.bool
86   };
87
88   navigationLinkAndCurrentPathMatch(location, to) {
89     let linkPathElements = to.split('/');
90     let locationElements = location.pathname.split('/');
91
92     // the element arrays above will have the route at index 1 ... need to
93     // verify if the routes match
94     return locationElements[1] === linkPathElements[1];
95   }
96
97   hasRouteChanged(currentPath, nextPath) {
98     let currentPathParts = currentPath.split('/');
99     let nextPathParts = nextPath.split('/');
100
101     if (currentPathParts[1] !== nextPathParts[1]) {
102       return true;
103     } else {
104       return false;
105     }
106   }
107
108   componentWillReceiveProps(nextProps) {
109     if (this.props.location &&
110       this.props.location.pathname !== nextProps.location.pathname) {
111       // update analytics
112       this.props.dispatchAnalyticsData();
113
114       if (this.hasRouteChanged(this.props.location.pathname,
115           nextProps.location.pathname)) {
116         this.props.onRouteChange();
117       }
118     }
119   }
120
121   render() {
122     let {
123           showMenu,
124           onShowMenu,
125           onHideMenu,
126           toggleButtonActive
127         } = this.props;
128
129     let menuOptions = [];
130
131     const MenuItem = ({label, iconClass, to}) => (
132       <Route path={to} children={({location}) => (
133         <NavLink to={to} onClick={onHideMenu}>
134           <div className={this.navigationLinkAndCurrentPathMatch(location, to) ? 'main-menu-button-active' : 'main-menu-button'}>
135             <div className={iconClass}/>
136             <div className='button-icon'>{label}</div>
137           </div>
138         </NavLink>
139       )}/>
140     );
141
142     // add Tier Support view
143     menuOptions.push(
144       <MenuItem to='/viewInspect' label={MENU_ITEM_TIER_SUPPORT}
145                 iconClass='button-icon view-inspect-button-icon'/>
146     );
147
148     // add VNF view
149     // 2172a3c25ae56e4995038ffbc1f055692bfc76c0b8ceda1205bc745a9f7a805d is
150     // the hash for 'VNFs' ... ensures VNF Search screen defaults to the
151     // aggregate VNF results
152     menuOptions.push(
153       <MenuItem
154         to='/vnfSearch/2172a3c25ae56e4995038ffbc1f055692bfc76c0b8ceda1205bc745a9f7a805d'
155         label={MENU_ITEM_VNF_SEARCH}
156         iconClass='button-icon vnf-search-button-icon'/>
157     );
158
159     // add all custom view menu options
160     for (let view in customViews) {
161       menuOptions.push(
162         <MenuItem to={customViews[view]['viewName']}
163                   label={customViews[view]['displayName']}
164                   iconClass='button-icon inventory-button-icon'/>
165       );
166     }
167
168     return (
169       <div>
170         <div className='header'>
171           <div>
172             <Button
173               bsClass={(toggleButtonActive)
174               ? 'toggle-view-button-active'
175               : 'toggle-view-button'}
176               onClick={onShowMenu}>
177               <FontAwesome name='bars'/>
178             </Button>
179             <Modal show={showMenu} onHide={onHideMenu}
180                    dialogClassName='modal-main-menu'>
181               <Modal.Body>
182                 {menuOptions}
183               </Modal.Body>
184             </Modal>
185             <span className='application-title'>{AAI_TITLE}</span>
186             <GlobalAutoCompleteSearchBar history={this.props.history}/>
187           </div>
188           <GlobalInlineMessageBar />
189         </div>
190       </div>
191
192     );
193   }
194 }
195
196 export default connect(mapStateToProps, mapActionsToProps)(MainScreenHeader);