Create main app bar prototype
[arvados-workbench2.git] / src / views / workbench / workbench.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6
7 import { StyleRulesCallback, Theme, WithStyles, withStyles } from '@material-ui/core/styles';
8 import Drawer from '@material-ui/core/Drawer';
9 import AppBar from '@material-ui/core/AppBar';
10 import Toolbar from '@material-ui/core/Toolbar';
11 import Typography from '@material-ui/core/Typography';
12 import { connect, DispatchProp } from "react-redux";
13 import Tree from "../../components/tree/tree";
14 import { Project } from "../../models/project";
15 import ProjectList from "../../components/project-list/project-list";
16 import { Route, Switch } from "react-router";
17 import { Link } from "react-router-dom";
18 import Button from "@material-ui/core/Button/Button";
19 import authActions from "../../store/auth/auth-action";
20 import IconButton from "@material-ui/core/IconButton/IconButton";
21 import Menu from "@material-ui/core/Menu/Menu";
22 import MenuItem from "@material-ui/core/MenuItem/MenuItem";
23 import { AccountCircle } from "@material-ui/icons";
24 import { User } from "../../models/user";
25 import Grid from "@material-ui/core/Grid/Grid";
26 import { RootState } from "../../store/store";
27 import MainAppBar from '../../components/main-app-bar/main-app-bar';
28
29 const drawerWidth = 240;
30
31 type CssRules = 'root' | 'appBar' | 'drawerPaper' | 'content' | 'toolbar';
32
33 const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
34     root: {
35         flexGrow: 1,
36         zIndex: 1,
37         overflow: 'hidden',
38         position: 'relative',
39         display: 'flex',
40         width: '100vw',
41         height: '100vh'
42     },
43     appBar: {
44         zIndex: theme.zIndex.drawer + 1,
45         backgroundColor: '#692498'
46     },
47     drawerPaper: {
48         position: 'relative',
49         width: drawerWidth,
50     },
51     content: {
52         flexGrow: 1,
53         backgroundColor: theme.palette.background.default,
54         padding: theme.spacing.unit * 3,
55         height: '100%',
56         minWidth: 0,
57     },
58     toolbar: theme.mixins.toolbar
59 });
60
61 interface WorkbenchDataProps {
62     projects: Project[];
63     user?: User;
64 }
65
66 interface WorkbenchActionProps {
67 }
68
69 type WorkbenchProps = WorkbenchDataProps & WorkbenchActionProps & DispatchProp & WithStyles<CssRules>;
70
71 interface WorkbenchState {
72     anchorEl: any;
73 }
74
75 class Workbench extends React.Component<WorkbenchProps, WorkbenchState> {
76     constructor(props: WorkbenchProps) {
77         super(props);
78         this.state = {
79             anchorEl: null
80         }
81     }
82
83     login = () => {
84         this.props.dispatch(authActions.LOGIN());
85     };
86
87     logout = () => {
88         this.handleClose();
89         this.props.dispatch(authActions.LOGOUT());
90     };
91
92     handleOpenMenu = (event: React.MouseEvent<any>) => {
93         this.setState({
94             anchorEl: event.currentTarget
95         });
96     };
97
98     handleClose = () => {
99         this.setState({
100             anchorEl: null
101         });
102     };
103
104     render() {
105         const {classes, user} = this.props;
106         return (
107             <div className={classes.root}>
108                 <AppBar position="absolute" className={classes.appBar}>
109                     <Toolbar>
110                         <Typography variant="title" color="inherit" noWrap style={{flexGrow: 1}}>
111                             <span>Arvados</span><br/><span style={{fontSize: 12}}>Workbench 2</span>
112                         </Typography>
113                         {user ?
114                             <Grid container style={{width: 'auto'}}>
115                                 <Grid container style={{width: 'auto'}} alignItems='center'>
116                                     <Typography variant="title" color="inherit" noWrap>
117                                         {user.firstName} {user.lastName}
118                                     </Typography>
119                                 </Grid>
120                                 <Grid item>
121                                     <IconButton
122                                           aria-owns={this.state.anchorEl ? 'menu-appbar' : undefined}
123                                           aria-haspopup="true"
124                                           onClick={this.handleOpenMenu}
125                                           color="inherit">
126                                       <AccountCircle/>
127                                     </IconButton>
128                                 </Grid>
129                                 <Menu
130                                   id="menu-appbar"
131                                   anchorEl={this.state.anchorEl}
132                                   anchorOrigin={{
133                                     vertical: 'top',
134                                     horizontal: 'right',
135                                   }}
136                                   transformOrigin={{
137                                     vertical: 'top',
138                                     horizontal: 'right',
139                                   }}
140                                   open={!!this.state.anchorEl}
141                                   onClose={this.handleClose}>
142                                   <MenuItem onClick={this.logout}>Logout</MenuItem>
143                                   <MenuItem onClick={this.handleClose}>My account</MenuItem>
144                                 </Menu>
145                             </Grid>
146                             :
147                             <Button color="inherit" onClick={this.login}>Login</Button>
148                         }
149                     </Toolbar>
150                 </AppBar>
151                 {user &&
152                 <Drawer
153                     variant="permanent"
154                     classes={{
155                         paper: classes.drawerPaper,
156                     }}>
157                     <div className={classes.toolbar}/>
158                     <div className={classes.toolbar}/>
159                     <Tree items={this.props.projects} render={(p: Project) =>
160                         <Link to={`/project/${p.name}`}>{p.name}</Link>
161                     }/>
162                 </Drawer>}
163                 <main className={classes.content}>
164                     <div className={classes.toolbar}/>
165                     <div className={classes.toolbar}/>
166                     <MainAppBar/>
167                     <Switch>
168                         <Route path="/project/:name" component={ProjectList}/>
169                     </Switch>
170                 </main>
171             </div>
172         );
173     }
174 }
175
176 export default connect<WorkbenchDataProps>(
177     (state: RootState) => ({
178         projects: state.projects,
179         user: state.auth.user
180     })
181 )(
182     withStyles(styles)(Workbench)
183 );