16115: Fixes sharing URL building for per-collection domain configs.
[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, RemoveIcon } 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 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 ${token.apiToken.slice(0, 8)}... expiring at: ${expDate.toLocaleString()} (${moment(expDate).fromNow()})`;
70
71         return <Grid container alignItems='center' key={token.uuid}  className={props.classes.sharingUrlRow}>
72             <Grid item>
73             <Link className={props.classes.sharingUrlText} href={url} target='_blank'>
74                 {urlLabel}
75             </Link>
76             </Grid>
77             <Grid item xs />
78             <Grid item>
79             <span className={props.classes.sharingUrlButton}><Tooltip title='Copy to clipboard'>
80                 <CopyToClipboard text={url} onCopy={() => props.onCopy('Sharing URL copied')}>
81                     <CopyIcon />
82                 </CopyToClipboard>
83             </Tooltip></span>
84             <span className={props.classes.sharingUrlButton}><Tooltip title='Remove'>
85                 <IconButton onClick={() => props.onDeleteSharingToken(token.uuid)}>
86                     <RemoveIcon />
87                 </IconButton>
88             </Tooltip></span>
89             </Grid>
90         </Grid>
91     })
92     : <Grid item><Typography>No sharing URLs</Typography></Grid> }
93 </Grid>);