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