1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
20 } from '@material-ui/core';
25 } from '@material-ui/core/styles';
26 import { DialogActions } from 'components/dialog-actions/dialog-actions';
27 import { SharingURLsContent } from './sharing-urls';
29 extractUuidObjectType,
31 } from 'models/resource';
32 import { SharingInvitationForm } from './sharing-invitation-form';
33 import { SharingManagementForm } from './sharing-management-form';
37 MuiPickersUtilsProvider,
39 } from 'material-ui-pickers';
40 import DateFnsUtils from "@date-io/date-fns";
41 import moment from 'moment';
42 import { SharingPublicAccessForm } from './sharing-public-access-form';
43 import { AddIcon } from 'components/icon/icon';
45 export interface SharingDialogDataProps {
49 sharedResourceUuid: string;
50 sharingURLsNr: number;
51 privateAccess: boolean;
52 sharingURLsDisabled: boolean;
55 export interface SharingDialogActionProps {
58 onCreateSharingToken: (d: Date | undefined) => () => void;
59 refreshPermissions: () => void;
61 enum SharingDialogTab {
65 export type SharingDialogComponentProps = SharingDialogDataProps & SharingDialogActionProps;
67 export default (props: SharingDialogComponentProps) => {
68 const { open, loading, saveEnabled, sharedResourceUuid,
69 sharingURLsNr, privateAccess, sharingURLsDisabled, permissions,
70 onClose, onSave, onCreateSharingToken, refreshPermissions } = props;
71 const showTabs = !sharingURLsDisabled && extractUuidObjectType(sharedResourceUuid) === ResourceObjectType.COLLECTION;
72 const [tabNr, setTabNr] = React.useState<number>(SharingDialogTab.PERMISSIONS);
73 const [expDate, setExpDate] = React.useState<Date>();
74 const [withExpiration, setWithExpiration] = React.useState<boolean>(false);
75 const [permissionsCount, setPermissionsCount] = React.useState<number>(0);
77 // Sets up the dialog depending on the resource type
78 if (!showTabs && tabNr !== SharingDialogTab.PERMISSIONS) {
79 setTabNr(SharingDialogTab.PERMISSIONS);
82 React.useEffect(() => {
83 if (permissions && permissions.length !== permissionsCount) {
84 if (permissionsCount > permissions.length) {
85 setTimeout(onSave, 0);
88 setPermissionsCount(permissions.length);
90 }, [permissions, onSave, setPermissionsCount, permissionsCount])
92 React.useEffect(() => {
93 if (!withExpiration) {
94 setExpDate(undefined);
96 setExpDate(moment().add(2, 'hour').minutes(0).seconds(0).toDate());
101 {...{ open, onClose }}
102 className="sharing-dialog"
105 disableBackdropClick={saveEnabled}
106 disableEscapeKeyDown={saveEnabled}>
112 onChange={(_, tb) => {
113 if (tb === SharingDialogTab.PERMISSIONS) {
114 refreshPermissions();
118 <Tab label="With users/groups" />
119 <Tab label={`Sharing URLs ${sharingURLsNr > 0 ? '('+sharingURLsNr+')' : ''}`} disabled={saveEnabled} />
123 { tabNr === SharingDialogTab.PERMISSIONS &&
124 <Grid container direction='column' spacing={24}>
126 <SharingPublicAccessForm />
129 <SharingManagementForm />
133 { tabNr === SharingDialogTab.URLS &&
134 <SharingURLsContent uuid={sharedResourceUuid} />
138 <Grid container spacing={8}>
139 { tabNr === SharingDialogTab.PERMISSIONS &&
141 <SharingInvitationForm />
144 { tabNr === SharingDialogTab.URLS && withExpiration && <>
145 <Grid item container direction='row' md={12}>
146 <MuiPickersUtilsProvider utils={DateFnsUtils}>
147 <BasePicker autoOk value={expDate} onChange={setExpDate}>
148 {({ date, handleChange }) => (<>
150 <Calendar date={date} minDate={new Date()} maxDate={undefined}
151 onChange={handleChange} />
154 <TimePickerView type="hours" date={date} ampm={false}
155 onMinutesChange={() => {}}
156 onSecondsChange={() => {}}
157 onHourChange={handleChange}
162 </MuiPickersUtilsProvider>
165 <Typography variant='caption' align='center'>
166 Maximum expiration date may be limited by the cluster configuration.
171 { tabNr === SharingDialogTab.PERMISSIONS && !sharingURLsDisabled &&
172 privateAccess && sharingURLsNr > 0 &&
174 <Typography variant='caption' align='center' color='error'>
175 Although there aren't specific permissions set, this is publicly accessible via Sharing URL(s).
180 { tabNr === SharingDialogTab.URLS && <>
181 <Grid item><FormControlLabel
182 control={<Checkbox color="primary" checked={withExpiration}
183 onChange={(e) => setWithExpiration(e.target.checked)} />}
184 label="With expiration" />
187 <Button variant="contained" color="primary"
188 disabled={expDate !== undefined && expDate <= new Date()}
189 onClick={onCreateSharingToken(expDate)}>
195 { tabNr === SharingDialogTab.PERMISSIONS &&
197 <Tooltip title="Add authorization">
198 <Button onClick={onSave} variant="contained" color="primary"
199 disabled={!saveEnabled}>
206 <Button onClick={() => {
208 setWithExpiration(false);
216 loading && <LoadingIndicator />
221 const loadingIndicatorStyles: StyleRulesCallback<'root'> = theme => ({
223 position: 'absolute',
229 alignItems: 'center',
230 justifyContent: 'center',
231 backgroundColor: 'rgba(255, 255, 255, 0.8)',
235 const LoadingIndicator = withStyles(loadingIndicatorStyles)(
236 (props: WithStyles<'root'>) =>
237 <Paper classes={props.classes}>