1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
19 } from '@material-ui/core';
24 } from '@material-ui/core/styles';
25 import { DialogActions } from 'components/dialog-actions/dialog-actions';
26 import { SharingURLsContent } from './sharing-urls';
28 extractUuidObjectType,
30 } from 'models/resource';
31 import { SharingInvitationForm } from './sharing-invitation-form';
32 import { SharingManagementForm } from './sharing-management-form';
36 MuiPickersUtilsProvider,
38 } from 'material-ui-pickers';
39 import DateFnsUtils from "@date-io/date-fns";
40 import moment from 'moment';
41 import { SharingPublicAccessForm } from './sharing-public-access-form';
43 export interface SharingDialogDataProps {
47 sharedResourceUuid: string;
48 sharingURLsNr: number;
49 privateAccess: boolean;
50 sharingURLsDisabled: boolean;
53 export interface SharingDialogActionProps {
56 onCreateSharingToken: (d: Date | undefined) => () => void;
57 refreshPermissions: () => void;
59 enum SharingDialogTab {
63 export type SharingDialogComponentProps = SharingDialogDataProps & SharingDialogActionProps;
65 export default (props: SharingDialogComponentProps) => {
66 const { open, loading, saveEnabled, sharedResourceUuid,
67 sharingURLsNr, privateAccess, sharingURLsDisabled,
68 onClose, onSave, onCreateSharingToken, refreshPermissions } = props;
69 const showTabs = !sharingURLsDisabled && extractUuidObjectType(sharedResourceUuid) === ResourceObjectType.COLLECTION;
70 const [tabNr, setTabNr] = React.useState<number>(SharingDialogTab.PERMISSIONS);
71 const [expDate, setExpDate] = React.useState<Date>();
72 const [withExpiration, setWithExpiration] = React.useState<boolean>(false);
74 // Sets up the dialog depending on the resource type
75 if (!showTabs && tabNr !== SharingDialogTab.PERMISSIONS) {
76 setTabNr(SharingDialogTab.PERMISSIONS);
79 React.useEffect(() => {
80 if (!withExpiration) {
81 setExpDate(undefined);
83 setExpDate(moment().add(2, 'hour').minutes(0).seconds(0).toDate());
88 {...{ open, onClose }}
89 className="sharing-dialog"
92 disableBackdropClick={saveEnabled}
93 disableEscapeKeyDown={saveEnabled}>
99 onChange={(_, tb) => {
100 if (tb === SharingDialogTab.PERMISSIONS) {
101 refreshPermissions();
106 <Tab label="With users/groups" />
107 <Tab label={`Sharing URLs ${sharingURLsNr > 0 ? '(' + sharingURLsNr + ')' : ''}`} disabled={saveEnabled} />
111 {tabNr === SharingDialogTab.PERMISSIONS &&
112 <Grid container direction='column' spacing={24}>
114 <SharingInvitationForm onSave={onSave} saveEnabled={saveEnabled} />
117 <SharingManagementForm onSave={onSave} />
120 <SharingPublicAccessForm onSave={onSave} />
124 {tabNr === SharingDialogTab.URLS &&
125 <SharingURLsContent uuid={sharedResourceUuid} />
129 <Grid container spacing={8}>
130 {tabNr === SharingDialogTab.URLS && withExpiration && <>
131 <Grid item container direction='row' md={12}>
132 <MuiPickersUtilsProvider utils={DateFnsUtils}>
133 <BasePicker autoOk value={expDate} onChange={setExpDate}>
134 {({ date, handleChange }) => (<>
136 <Calendar date={date} minDate={new Date()} maxDate={undefined}
137 onChange={handleChange} />
140 <TimePickerView type="hours" date={date} ampm={false}
141 onMinutesChange={() => { }}
142 onSecondsChange={() => { }}
143 onHourChange={handleChange}
148 </MuiPickersUtilsProvider>
151 <Typography variant='caption' align='center'>
152 Maximum expiration date may be limited by the cluster configuration.
157 {tabNr === SharingDialogTab.PERMISSIONS && !sharingURLsDisabled &&
158 privateAccess && sharingURLsNr > 0 &&
160 <Typography variant='caption' align='center' color='error'>
161 Although there aren't specific permissions set, this is publicly accessible via Sharing URL(s).
166 {tabNr === SharingDialogTab.URLS && <>
167 <Grid item><FormControlLabel
168 control={<Checkbox color="primary" checked={withExpiration}
169 onChange={(e) => setWithExpiration(e.target.checked)} />}
170 label="With expiration" />
173 <Button variant="contained" color="primary"
174 disabled={expDate !== undefined && expDate <= new Date()}
175 onClick={onCreateSharingToken(expDate)}>
182 <Button onClick={() => {
184 setWithExpiration(false);
192 loading && <LoadingIndicator />
197 const loadingIndicatorStyles: StyleRulesCallback<'root'> = theme => ({
199 position: 'absolute',
205 alignItems: 'center',
206 justifyContent: 'center',
207 backgroundColor: 'rgba(255, 255, 255, 0.8)',
211 const LoadingIndicator = withStyles(loadingIndicatorStyles)(
212 (props: WithStyles<'root'>) =>
213 <Paper classes={props.classes}>