16115: Adds collection's sharing URL management component and actions.
[arvados-workbench2.git] / src / views-components / sharing-dialog / sharing-urls-component.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 {
7     Grid,
8     IconButton,
9     Link,
10     StyleRulesCallback,
11     Tooltip,
12     WithStyles,
13     withStyles
14 } from '@material-ui/core';
15 import { ApiClientAuthorization } from 'models/api-client-authorization';
16 import { CopyIcon, RemoveIcon } from 'components/icon/icon';
17 import CopyToClipboard from 'react-copy-to-clipboard';
18 import { ArvadosTheme } from 'common/custom-theme';
19 import moment from 'moment';
20
21 type CssRules = 'sharingUrlText'
22     | 'sharingUrlButton'
23     | 'sharingUrlList'
24     | 'sharingUrlRow';
25
26 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
27     sharingUrlText: {
28         fontSize: '1rem',
29     },
30     sharingUrlButton: {
31         color: theme.palette.grey["500"],
32         cursor: 'pointer',
33         '& svg': {
34             fontSize: '1rem'
35         },
36         verticalAlign: 'middle',
37     },
38     sharingUrlList: {
39         marginTop: '1rem',
40     },
41     sharingUrlRow: {
42         borderBottom: `1px solid ${theme.palette.grey["300"]}`,
43     },
44 });
45
46 export interface SharingURLsComponentDataProps {
47     collectionUuid: string;
48     sharingTokens: ApiClientAuthorization[];
49     sharingURLsPrefix: string;
50 }
51
52 export interface SharingURLsComponentActionProps {
53     onDeleteSharingToken: (uuid: string) => void;
54     onCopy: (message: string) => void;
55 }
56
57 type SharingURLsComponentProps = SharingURLsComponentDataProps & SharingURLsComponentActionProps;
58
59 export const SharingURLsComponent = withStyles(styles)((props: SharingURLsComponentProps & WithStyles<CssRules>) => <Grid container direction='column' spacing={24} className={props.classes.sharingUrlList}>
60     { props.sharingTokens
61     .sort((a, b) => (new Date(a.expiresAt).getTime() - new Date(b.expiresAt).getTime()))
62     .map(token => {
63         const url = `${props.sharingURLsPrefix}/c=${props.collectionUuid}/t=${token.apiToken}/_/`
64         const expDate = new Date(token.expiresAt);
65         const urlLabel = `Token ${token.apiToken.slice(0, 8)}... expiring at: ${expDate.toLocaleString()} (${moment(expDate).fromNow()})`;
66
67         return <Grid container alignItems='center' key={token.uuid}  className={props.classes.sharingUrlRow}>
68             <Grid item>
69             <Link className={props.classes.sharingUrlText} href={url} target='_blank'>
70                 {urlLabel}
71             </Link>
72             </Grid>
73             <Grid item xs />
74             <Grid item>
75             <span className={props.classes.sharingUrlButton}><Tooltip title='Copy to clipboard'>
76                 <CopyToClipboard text={url} onCopy={() => props.onCopy('Sharing URL copied')}>
77                     <CopyIcon />
78                 </CopyToClipboard>
79             </Tooltip></span>
80             <span className={props.classes.sharingUrlButton}><Tooltip title='Remove'>
81                 <IconButton onClick={() => props.onDeleteSharingToken(token.uuid)}>
82                     <RemoveIcon />
83                 </IconButton>
84             </Tooltip></span>
85             </Grid>
86         </Grid>
87     }) }
88 </Grid>);