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