advanced-tab-and-sample-git-start-for-repositories
[arvados-workbench2.git] / src / views / repositories-panel / repositories-panel.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 import { connect } from 'react-redux';
7 import { Grid, Typography, Button, Card, CardContent, TableBody, TableCell, TableHead, TableRow, Table, Tooltip, IconButton } from '@material-ui/core';
8 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
9 import { ArvadosTheme } from '~/common/custom-theme';
10 import { Link } from 'react-router-dom';
11 import { Dispatch, compose } from 'redux';
12 import { RootState } from '~/store/store';
13 import { HelpIcon, AddIcon, MoreOptionsIcon } from '~/components/icon/icon';
14 import { loadRepositoriesData, openRepositoriesSampleGitDialog } from '~/store/repositories/repositories-actions';
15 import { RepositoriesResource } from '~/models/repositories';
16 import { openRepositoryContextMenu } from '~/store/context-menu/context-menu-actions';
17
18
19 type CssRules = 'link' | 'button' | 'icon' | 'iconRow' | 'moreOptionsButton' | 'moreOptions' | 'cloneUrls';
20
21 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
22     link: {
23         textDecoration: 'none',
24         color: theme.palette.primary.main,
25         "&:hover": {
26             color: theme.palette.primary.dark,
27             transition: 'all 0.5s ease'
28         }
29     },
30     button: {
31         textAlign: 'right',
32         alignSelf: 'center'
33     },
34     icon: {
35         cursor: 'pointer',
36         color: theme.palette.grey["500"],
37         "&:hover": {
38             color: theme.palette.common.black,
39             transition: 'all 0.5s ease'
40         }
41     },
42     iconRow: {
43         paddingTop: theme.spacing.unit * 2,
44         textAlign: 'right'
45     },
46     moreOptionsButton: {
47         padding: 0
48     },
49     moreOptions: {
50         textAlign: 'right',
51         '&:last-child': {
52             paddingRight: 0
53         }
54     },
55     cloneUrls: {
56         whiteSpace: 'pre-wrap'
57     }
58 });
59
60 const mapStateToProps = (state: RootState) => {
61     return {
62         repositories: state.repositories.items
63     };
64 };
65
66 const mapDispatchToProps = (dispatch: Dispatch): Pick<RepositoriesActionProps, 'onOptionsMenuOpen' | 'loadRepositories' | 'openRepositoriesSampleGitDialog'> => ({
67     loadRepositories: () => dispatch<any>(loadRepositoriesData()),
68     onOptionsMenuOpen: (event, index, repository) => {
69         dispatch<any>(openRepositoryContextMenu(event, index, repository));
70     },
71     openRepositoriesSampleGitDialog: () => dispatch<any>(openRepositoriesSampleGitDialog())
72 });
73
74 interface RepositoriesActionProps {
75     loadRepositories: () => void;
76     onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, index: number, repository: RepositoriesResource) => void;
77     openRepositoriesSampleGitDialog: () => void;
78 }
79
80 interface RepositoriesDataProps {
81     repositories: RepositoriesResource[];
82 }
83
84
85 type RepositoriesProps = RepositoriesDataProps & RepositoriesActionProps & WithStyles<CssRules>;
86
87 export const RepositoriesPanel = compose(
88     withStyles(styles),
89     connect(mapStateToProps, mapDispatchToProps))(
90         class extends React.Component<RepositoriesProps> {
91             componentDidMount() {
92                 this.props.loadRepositories();
93             }
94             render() {
95                 const { classes, repositories, onOptionsMenuOpen, openRepositoriesSampleGitDialog } = this.props;
96                 console.log(repositories);
97                 return (
98                     <Card>
99                         <CardContent>
100                             <Grid container direction="row">
101                                 <Grid item xs={8}>
102                                     <Typography variant="body2">
103                                         When you are using an Arvados virtual machine, you should clone the https:// URLs. This will authenticate automatically using your API token. <br />
104                                         In order to clone git repositories using SSH, <Link to='' className={classes.link}>add an SSH key to your account</Link> and clone the git@ URLs.
105                                     </Typography>
106                                 </Grid>
107                                 <Grid item xs={4} className={classes.button}>
108                                     <Button variant="contained" color="primary">
109                                         <AddIcon /> NEW REPOSITORY
110                                     </Button>
111                                 </Grid>
112                             </Grid>
113                             <Grid item xs={12}>
114                                 <div className={classes.iconRow}>
115                                     <Tooltip title="Sample git quick start">
116                                         <IconButton className={classes.moreOptionsButton} onClick={openRepositoriesSampleGitDialog}>
117                                             <HelpIcon className={classes.icon} />
118                                         </IconButton>
119                                     </Tooltip>
120                                 </div>
121                             </Grid>
122                             <Grid item xs={12}>
123                                 {repositories && <Table>
124                                     <TableHead>
125                                         <TableRow>
126                                             <TableCell>Name</TableCell>
127                                             <TableCell>URL</TableCell>
128                                             <TableCell />
129                                         </TableRow>
130                                     </TableHead>
131                                     <TableBody>
132                                         {repositories.map((repository, index) =>
133                                             <TableRow key={index}>
134                                                 <TableCell>{repository.name}</TableCell>
135                                                 <TableCell className={classes.cloneUrls}>{repository.cloneUrls.join("\n")}</TableCell>
136                                                 <TableCell className={classes.moreOptions}>
137                                                     <Tooltip title="More options" disableFocusListener>
138                                                         <IconButton onClick={event => onOptionsMenuOpen(event, index, repository)} className={classes.moreOptionsButton}>
139                                                             <MoreOptionsIcon />
140                                                         </IconButton>
141                                                     </Tooltip>
142                                                 </TableCell>
143                                             </TableRow>)}
144                                     </TableBody>
145                                 </Table>}
146                             </Grid>
147                         </CardContent>
148                     </Card>
149                 );
150             }
151         }
152     );