1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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';
19 type CssRules = 'link' | 'button' | 'icon' | 'iconRow' | 'moreOptionsButton' | 'moreOptions' | 'cloneUrls';
21 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
23 textDecoration: 'none',
24 color: theme.palette.primary.main,
26 color: theme.palette.primary.dark,
27 transition: 'all 0.5s ease'
36 color: theme.palette.grey["500"],
38 color: theme.palette.common.black,
39 transition: 'all 0.5s ease'
43 paddingTop: theme.spacing.unit * 2,
56 whiteSpace: 'pre-wrap'
60 const mapStateToProps = (state: RootState) => {
62 repositories: state.repositories.items
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));
71 openRepositoriesSampleGitDialog: () => dispatch<any>(openRepositoriesSampleGitDialog()),
72 openRepositoryCreateDialog: () => dispatch<any>(openRepositoryCreateDialog())
75 interface RepositoriesActionProps {
76 loadRepositories: () => void;
77 onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, index: number, repository: RepositoryResource) => void;
78 openRepositoriesSampleGitDialog: () => void;
79 openRepositoryCreateDialog: () => void;
82 interface RepositoriesDataProps {
83 repositories: RepositoryResource[];
87 type RepositoriesProps = RepositoriesDataProps & RepositoriesActionProps & WithStyles<CssRules>;
89 export const RepositoriesPanel = compose(
91 connect(mapStateToProps, mapDispatchToProps))(
92 class extends React.Component<RepositoriesProps> {
94 this.props.loadRepositories();
97 const { classes, repositories, onOptionsMenuOpen, openRepositoriesSampleGitDialog, openRepositoryCreateDialog } = this.props;
101 <Grid container direction="row">
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.
108 <Grid item xs={4} className={classes.button}>
109 <Button variant="contained" color="primary" onClick={openRepositoryCreateDialog}>
110 <AddIcon /> NEW REPOSITORY
115 <div className={classes.iconRow}>
116 <Tooltip title="Sample git quick start">
117 <IconButton className={classes.moreOptionsButton} onClick={openRepositoriesSampleGitDialog}>
118 <HelpIcon className={classes.icon} />
124 {repositories && <Table>
127 <TableCell>Name</TableCell>
128 <TableCell>URL</TableCell>
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}>