added-attributes-dialog-and-init-creating-repos
[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, openRepositoryCreateDialog } from '~/store/repositories/repositories-actions';
15 import { RepositoryResource } 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' | 'openRepositoryCreateDialog'> => ({
67     loadRepositories: () => dispatch<any>(loadRepositoriesData()),
68     onOptionsMenuOpen: (event, index, repository) => {
69         dispatch<any>(openRepositoryContextMenu(event, index, repository));
70     },
71     openRepositoriesSampleGitDialog: () => dispatch<any>(openRepositoriesSampleGitDialog()),
72     openRepositoryCreateDialog: () => dispatch<any>(openRepositoryCreateDialog())
73 });
74
75 interface RepositoriesActionProps {
76     loadRepositories: () => void;
77     onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, index: number, repository: RepositoryResource) => void;
78     openRepositoriesSampleGitDialog: () => void;
79     openRepositoryCreateDialog: () => void;
80 }
81
82 interface RepositoriesDataProps {
83     repositories: RepositoryResource[];
84 }
85
86
87 type RepositoriesProps = RepositoriesDataProps & RepositoriesActionProps & WithStyles<CssRules>;
88
89 export const RepositoriesPanel = compose(
90     withStyles(styles),
91     connect(mapStateToProps, mapDispatchToProps))(
92         class extends React.Component<RepositoriesProps> {
93             componentDidMount() {
94                 this.props.loadRepositories();
95             }
96             render() {
97                 const { classes, repositories, onOptionsMenuOpen, openRepositoriesSampleGitDialog, openRepositoryCreateDialog } = this.props;
98                 return (
99                     <Card>
100                         <CardContent>
101                             <Grid container direction="row">
102                                 <Grid item xs={8}>
103                                     <Typography variant="body2">
104                                         When you are using an Arvados virtual machine, you should clone the https:// URLs. This will authenticate automatically using your API token. <br />
105                                         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.
106                                     </Typography>
107                                 </Grid>
108                                 <Grid item xs={4} className={classes.button}>
109                                     <Button variant="contained" color="primary" onClick={openRepositoryCreateDialog}>
110                                         <AddIcon /> NEW REPOSITORY
111                                     </Button>
112                                 </Grid>
113                             </Grid>
114                             <Grid item xs={12}>
115                                 <div className={classes.iconRow}>
116                                     <Tooltip title="Sample git quick start">
117                                         <IconButton className={classes.moreOptionsButton} onClick={openRepositoriesSampleGitDialog}>
118                                             <HelpIcon className={classes.icon} />
119                                         </IconButton>
120                                     </Tooltip>
121                                 </div>
122                             </Grid>
123                             <Grid item xs={12}>
124                                 {repositories && <Table>
125                                     <TableHead>
126                                         <TableRow>
127                                             <TableCell>Name</TableCell>
128                                             <TableCell>URL</TableCell>
129                                             <TableCell />
130                                         </TableRow>
131                                     </TableHead>
132                                     <TableBody>
133                                         {repositories.map((repository, index) =>
134                                             <TableRow key={index}>
135                                                 <TableCell>{repository.name}</TableCell>
136                                                 <TableCell className={classes.cloneUrls}>{repository.cloneUrls.join("\n")}</TableCell>
137                                                 <TableCell className={classes.moreOptions}>
138                                                     <Tooltip title="More options" disableFocusListener>
139                                                         <IconButton onClick={event => onOptionsMenuOpen(event, index, repository)} className={classes.moreOptionsButton}>
140                                                             <MoreOptionsIcon />
141                                                         </IconButton>
142                                                     </Tooltip>
143                                                 </TableCell>
144                                             </TableRow>)}
145                                     </TableBody>
146                                 </Table>}
147                             </Grid>
148                         </CardContent>
149                     </Card>
150                 );
151             }
152         }
153     );