1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
6 import { CustomStyleRulesCallback } from 'common/custom-theme';
7 import { Grid, IconButton, Link, Tooltip, Typography } from '@mui/material';
8 import { WithStyles } from '@mui/styles';
9 import withStyles from '@mui/styles/withStyles';
10 import { ApiClientAuthorization } from 'models/api-client-authorization';
11 import { CopyIcon, CloseIcon } from 'components/icon/icon';
12 import CopyToClipboard from 'react-copy-to-clipboard';
13 import { ArvadosTheme } from 'common/custom-theme';
14 import moment from 'moment';
16 type CssRules = 'sharingUrlText'
21 const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
26 color: theme.palette.grey["500"],
31 verticalAlign: 'middle',
37 marginLeft: theme.spacing(1),
38 borderBottom: `1px solid ${theme.palette.grey["300"]}`,
42 export interface SharingURLsComponentDataProps {
43 collectionUuid: string;
44 sharingTokens: ApiClientAuthorization[];
45 sharingURLsPrefix: string;
48 export interface SharingURLsComponentActionProps {
49 onDeleteSharingToken: (uuid: string) => void;
50 onCopy: (message: string) => void;
53 export type SharingURLsComponentProps = SharingURLsComponentDataProps & SharingURLsComponentActionProps;
55 export const SharingURLsComponent = withStyles(styles)((props: SharingURLsComponentProps & WithStyles<CssRules>) => <Grid container direction='column' spacing={3} className={props.classes.sharingUrlList}>
56 {props.sharingTokens.length > 0
58 .sort((a, b) => (new Date(a.expiresAt).getTime() - new Date(b.expiresAt).getTime()))
60 const url = props.sharingURLsPrefix.includes('*')
61 ? `${props.sharingURLsPrefix.replace('*', props.collectionUuid)}/t=${token.apiToken}/_/`
62 : `${props.sharingURLsPrefix}/c=${props.collectionUuid}/t=${token.apiToken}/_/`;
63 const expDate = new Date(token.expiresAt);
64 const urlLabel = !!token.expiresAt
65 ? `Token ${token.apiToken.slice(0, 8)}... expiring at: ${expDate.toLocaleString()} (${moment(expDate).fromNow()})`
66 : `Token ${token.apiToken.slice(0, 8)}... with no expiration date`;
69 <Grid container alignItems='center' key={token.uuid} className={props.classes.sharingUrlRow}>
71 <Link className={props.classes.sharingUrlText} href={url} target='_blank' rel="noopener">
77 <Tooltip title='Copy link to clipboard'>
78 <span className={props.classes.sharingUrlButton}>
79 <CopyToClipboard text={url} onCopy={() => props.onCopy('Sharing URL copied')}>
84 <span data-cy='remove-url-btn' className={props.classes.sharingUrlButton}>
85 <Tooltip title='Remove'>
86 <IconButton onClick={() => props.onDeleteSharingToken(token.uuid)} size="large">
95 : <Grid item><Typography>No sharing URLs</Typography></Grid>}