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