b50d680811d08191504393dafb17d99075ae4588
[ccsdk/features.git] / sdnr / wt / odlux / framework / src / components / navigationMenu.tsx
1 /**\r
2  * ============LICENSE_START========================================================================\r
3  * ONAP : ccsdk feature sdnr wt odlux\r
4  * =================================================================================================\r
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.\r
6  * =================================================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except\r
8  * in compliance with the License. You may obtain a copy of the License at\r
9  *\r
10  * http://www.apache.org/licenses/LICENSE-2.0\r
11  *\r
12  * Unless required by applicable law or agreed to in writing, software distributed under the License\r
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\r
14  * or implied. See the License for the specific language governing permissions and limitations under\r
15  * the License.\r
16  * ============LICENSE_END==========================================================================\r
17  */\r
18 import * as React from 'react';\r
19 import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';\r
20 \r
21 import { faHome, faAddressBook } from '@fortawesome/free-solid-svg-icons';\r
22 \r
23 import Drawer from '@material-ui/core/Drawer';\r
24 import List from '@material-ui/core/List';\r
25 \r
26 import Divider from '@material-ui/core/Divider';\r
27 \r
28 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r
29 import { faProjectDiagram } from '@fortawesome/free-solid-svg-icons';\r
30 \r
31 import ListItemLink from '../components/material-ui/listItemLink';\r
32 \r
33 import connect, { Connect } from '../flux/connect';\r
34 import { MenuAction } from '../actions/menuAction';\r
35 import * as classNames from 'classnames';\r
36 import { transportPCEUrl } from '../app';\r
37 \r
38 \r
39 const drawerWidth = 240;\r
40 \r
41 const extraLinks = (window as any)._odluxExtraLinks as [string, string][];\r
42 \r
43 const styles = (theme: Theme) => createStyles({\r
44   drawerPaper: {\r
45     position: 'relative',\r
46     width: drawerWidth,\r
47   },\r
48   toolbar: theme.mixins.toolbar as any,\r
49 \r
50   drawerOpen: {\r
51     width: drawerWidth,\r
52     transition: theme.transitions.create('width', {\r
53       easing: theme.transitions.easing.sharp,\r
54       duration: theme.transitions.duration.enteringScreen,\r
55     }),\r
56   },\r
57   drawerClose: {\r
58     transition: theme.transitions.create('width', {\r
59       easing: theme.transitions.easing.sharp,\r
60       duration: theme.transitions.duration.leavingScreen,\r
61     }),\r
62     overflowX: 'hidden',\r
63     width: theme.spacing(7) + 1,\r
64     [theme.breakpoints.up('sm')]: {\r
65       width: theme.spacing(9) + 1,\r
66     },\r
67   },\r
68   drawer: {\r
69 \r
70   },\r
71   menu: {\r
72     flex: "1 0 0%",\r
73   },\r
74   optLinks: {\r
75     borderTop: "2px solid #cfcfcf",\r
76     display: "flex",\r
77     flexDirection: "row",\r
78     flexWrap: "wrap",\r
79     justifyContent: "space-around"\r
80   },\r
81   link: {\r
82     margin: theme.spacing(1)+1,\r
83     fontSize: theme.typography.fontSize-2,\r
84   },\r
85 });\r
86 \r
87 const tabletWidthBreakpoint = 768;\r
88 \r
89 export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, dispatch }: WithStyles<typeof styles> & Connect & Connect) => {\r
90   const { user } = state.framework.authenticationState;\r
91   const isOpen = state.framework.applicationState.isMenuOpen;\r
92   const closedByUser = state.framework.applicationState.isMenuClosedByUser;\r
93   const transportUrl = state.framework.applicationState.transportpceUrl;\r
94 \r
95   const [responsive, setResponsive] = React.useState(false);\r
96 \r
97   //collapse menu on mount if necessary\r
98   React.useEffect(()=>{\r
99 \r
100     if(isOpen && window.innerWidth < tabletWidthBreakpoint){\r
101 \r
102       setResponsive(true);\r
103       dispatch(new MenuAction(false));\r
104     }\r
105 \r
106   },[]);\r
107 \r
108   React.useEffect(() => {\r
109 \r
110     function handleResize() {\r
111       if (user && user.isValid) {\r
112         if (window.innerWidth < tabletWidthBreakpoint && !responsive) {\r
113           setResponsive(true);\r
114           if (!closedByUser) {\r
115             console.log("responsive menu collapsed")\r
116             dispatch(new MenuAction(false));\r
117           }\r
118 \r
119         } else if (window.innerWidth > tabletWidthBreakpoint && responsive) {\r
120           setResponsive(false);\r
121           if (!closedByUser) {\r
122             console.log("responsive menu restored")\r
123             dispatch(new MenuAction(true));\r
124           }\r
125 \r
126         }\r
127       }\r
128     }\r
129     window.addEventListener("resize", handleResize);\r
130 \r
131 \r
132     return () => {\r
133       window.removeEventListener("resize", handleResize);\r
134     }\r
135   })\r
136 \r
137   React.useEffect(()=>{\r
138     // trigger a resize if menu changed in case elements have to re-arrange\r
139     window.dispatchEvent(new Event('menu-resized'));\r
140   }, [isOpen])\r
141 \r
142   let menuItems = state.framework.applicationRegistraion && Object.keys(state.framework.applicationRegistraion).map(key => {\r
143     const reg = state.framework.applicationRegistraion[key];\r
144     return reg && (\r
145       <ListItemLink\r
146         key={reg.name}\r
147         to={reg.path || `/${reg.name}`}\r
148         primary={reg.menuEntry || reg.name}\r
149         secondary={reg.subMenuEntry}\r
150         icon={reg.icon && <FontAwesomeIcon icon={reg.icon} /> || null} />\r
151     ) || null;\r
152   }) || null;\r
153 \r
154   if(transportUrl.length>0){\r
155 \r
156     const transportPCELink = <ListItemLink\r
157       key={"transportPCE"}\r
158       to={transportUrl}\r
159       primary={"TransportPCE"}\r
160       icon={<FontAwesomeIcon icon={faProjectDiagram} />}\r
161       external />;\r
162 \r
163     const linkFound = menuItems.find(obj => obj.key === "linkCalculation");\r
164     \r
165     if (linkFound) {\r
166       const index = menuItems.indexOf(linkFound);\r
167       menuItems.splice(index + 1, 0, transportPCELink);\r
168     } else {\r
169       menuItems.push(transportPCELink);\r
170     }\r
171   }\r
172   \r
173 \r
174   return (\r
175     <Drawer\r
176       variant="permanent"\r
177       className={\r
178         classNames(classes.drawer, {\r
179           [classes.drawerOpen]: isOpen,\r
180           [classes.drawerClose]: !isOpen\r
181         })\r
182       }\r
183       classes={{\r
184         paper: classes.drawerPaper,\r
185       }}\r
186     >\r
187       {user && user.isValid && <>\r
188         <div className={classes.toolbar} />\r
189         { /* https://fiffty.github.io/react-treeview-mui/ */}\r
190         <List className={classes.menu} component="nav">\r
191           <ListItemLink exact to="/" primary="Home" icon={<FontAwesomeIcon icon={faHome} />} />\r
192           <Divider />\r
193           {\r
194           menuItems\r
195           }\r
196           <Divider />\r
197           <ListItemLink to="/about" primary="About" icon={<FontAwesomeIcon icon={faAddressBook} />} />\r
198           {(false && process.env.NODE_ENV === "development")\r
199             ? <>\r
200               <Divider />\r
201               <ListItemLink to="/test" primary="Test" icon={<FontAwesomeIcon icon={faHome} />} />\r
202             </>\r
203             : null\r
204           }\r
205         </List>\r
206         {isOpen && extraLinks && <div className={classes.optLinks}>\r
207           {extraLinks.map(linkInfo => (<a className={classes.link} href={linkInfo[1]}>{linkInfo[0]}</a>))}\r
208         </div> || null}\r
209       </> || null\r
210       }\r
211     </Drawer>)\r
212 }));\r
213 \r
214 export default NavigationMenu;