21720: ran codemods, updated spacing, minor layout fixes
[arvados.git] / services / workbench2 / src / views / ssh-key-panel / ssh-key-panel-root.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import { CustomStyleRulesCallback } from 'common/custom-theme';
7 import {
8     Card,
9     CardContent,
10     Button,
11     Typography,
12     Grid,
13     Table,
14     TableHead,
15     TableRow,
16     TableCell,
17     TableBody,
18     Tooltip,
19     IconButton,
20 } from '@mui/material';
21 import { WithStyles } from '@mui/styles';
22 import withStyles from '@mui/styles/withStyles';
23 import { ArvadosTheme } from 'common/custom-theme';
24 import { SshKeyResource } from 'models/ssh-key';
25 import { AddIcon, MoreVerticalIcon, KeyIcon } from 'components/icon/icon';
26
27 type CssRules = 'root' | 'link' | 'buttonContainer' | 'table' | 'tableRow' | 'keyIcon';
28
29 const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
30     root: {
31         width: '100%',
32         overflow: 'auto'
33     },
34     link: {
35         color: theme.palette.primary.main,
36         textDecoration: 'none',
37         margin: '0px 4px'
38     },
39     buttonContainer: {
40         textAlign: 'right'
41     },
42     table: {
43         marginTop: theme.spacing(1)
44     },
45     tableRow: {
46         '& td, th': {
47             whiteSpace: 'nowrap'
48         }
49     },
50     keyIcon: {
51         color: theme.palette.primary.main
52     }
53 });
54
55 export interface SshKeyPanelRootActionProps {
56     openSshKeyCreateDialog: () => void;
57     openRowOptions: (event: React.MouseEvent<HTMLElement>, sshKey: SshKeyResource) => void;
58     openPublicKeyDialog: (name: string, publicKey: string) => void;
59 }
60
61 export interface SshKeyPanelRootDataProps {
62     sshKeys: SshKeyResource[];
63     hasKeys: boolean;
64 }
65
66 type SshKeyPanelRootProps = SshKeyPanelRootDataProps & SshKeyPanelRootActionProps & WithStyles<CssRules>;
67
68 export const SshKeyPanelRoot = withStyles(styles)(
69     ({ classes, sshKeys, openSshKeyCreateDialog, openPublicKeyDialog, hasKeys, openRowOptions }: SshKeyPanelRootProps) =>
70         <Card className={classes.root}>
71             <CardContent>
72                 <Grid container direction="row">
73                     <Grid item xs={8}>
74                         {!hasKeys && <Typography paragraph={true} >
75                             You have not yet set up an SSH public key for use with Arvados.
76                             <a href='https://doc.arvados.org/user/getting_started/ssh-access-unix.html'
77                                 target='blank' rel="noopener" className={classes.link}>
78                                 Learn more.
79                             </a>
80                         </Typography>}
81                         {!hasKeys && <Typography paragraph={true}>
82                             When you have an SSH key you would like to use, add it using button below.
83                         </Typography>}
84                     </Grid>
85                     <Grid item xs={4} className={classes.buttonContainer}>
86                         <Button onClick={openSshKeyCreateDialog} color="primary" variant="contained">
87                             <AddIcon /> Add New Ssh Key
88                         </Button>
89                     </Grid>
90                 </Grid>
91                 <Grid item xs={12}>
92                     {hasKeys && <Table className={classes.table}>
93                         <TableHead>
94                             <TableRow className={classes.tableRow}>
95                                 <TableCell>Name</TableCell>
96                                 <TableCell>UUID</TableCell>
97                                 <TableCell>Authorized user</TableCell>
98                                 <TableCell>Expires at</TableCell>
99                                 <TableCell>Key type</TableCell>
100                                 <TableCell>Public Key</TableCell>
101                                 <TableCell />
102                             </TableRow>
103                         </TableHead>
104                         <TableBody>
105                             {sshKeys.map((sshKey, index) =>
106                                 <TableRow key={index} className={classes.tableRow}>
107                                     <TableCell>{sshKey.name}</TableCell>
108                                     <TableCell>{sshKey.uuid}</TableCell>
109                                     <TableCell>{sshKey.authorizedUserUuid}</TableCell>
110                                     <TableCell>{sshKey.expiresAt || '(none)'}</TableCell>
111                                     <TableCell>{sshKey.keyType}</TableCell>
112                                     <TableCell>
113                                         <Tooltip title="Public Key" disableFocusListener>
114                                             <IconButton
115                                                 onClick={() => openPublicKeyDialog(sshKey.name, sshKey.publicKey)}
116                                                 size="large">
117                                                 <KeyIcon className={classes.keyIcon} />
118                                             </IconButton>
119                                         </Tooltip>
120                                     </TableCell>
121                                     <TableCell>
122                                         <Tooltip title="More options" disableFocusListener>
123                                             <IconButton onClick={event => openRowOptions(event, sshKey)} size="large">
124                                                 <MoreVerticalIcon />
125                                             </IconButton>
126                                         </Tooltip>
127                                     </TableCell>
128                                 </TableRow>)}
129                         </TableBody>
130                     </Table>}
131                 </Grid>
132             </CardContent>
133         </Card>
134 );