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