16115: Refresh permission management form on tab change.
[arvados-workbench2.git] / src / views-components / sharing-dialog / sharing-dialog-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     Dialog,
8     DialogTitle,
9     Button,
10     Grid,
11     DialogContent,
12     CircularProgress,
13     Paper,
14     Tabs,
15     Tab,
16 } from '@material-ui/core';
17 import {
18     StyleRulesCallback,
19     WithStyles,
20     withStyles
21 } from '@material-ui/core/styles';
22 import { DialogActions } from 'components/dialog-actions/dialog-actions';
23 import { SharingURLsContent } from './sharing-urls';
24 import {
25     extractUuidObjectType,
26     ResourceObjectType
27 } from 'models/resource';
28 import { SharingInvitationForm } from './sharing-invitation-form';
29 import { SharingManagementForm } from './sharing-management-form';
30
31 export interface SharingDialogDataProps {
32     open: boolean;
33     loading: boolean;
34     saveEnabled: boolean;
35     sharedResourceUuid: string;
36 }
37 export interface SharingDialogActionProps {
38     onClose: () => void;
39     onSave: () => void;
40     onCreateSharingToken: () => void;
41     refreshPermissions: () => void;
42 }
43 enum SharingDialogTab {
44     PERMISSIONS = 0,
45     URLS = 1,
46 }
47 export default (props: SharingDialogDataProps & SharingDialogActionProps) => {
48     const { open, loading, saveEnabled, sharedResourceUuid,
49         onClose, onSave, onCreateSharingToken, refreshPermissions } = props;
50     const showTabs = extractUuidObjectType(sharedResourceUuid) === ResourceObjectType.COLLECTION;
51     const [tabNr, setTabNr] = React.useState<number>(SharingDialogTab.PERMISSIONS);
52
53     // Sets up the dialog depending on the resource type
54     if (!showTabs && tabNr !== SharingDialogTab.PERMISSIONS) {
55         setTabNr(SharingDialogTab.PERMISSIONS);
56     }
57
58     return <Dialog
59         {...{ open, onClose }}
60         className="sharing-dialog"
61         fullWidth
62         maxWidth='sm'
63         disableBackdropClick={saveEnabled}
64         disableEscapeKeyDown={saveEnabled}>
65         <DialogTitle>
66             Sharing settings
67         </DialogTitle>
68         { showTabs &&
69         <Tabs value={tabNr}
70             onChange={(_, tb) => {
71                 if (tb === SharingDialogTab.PERMISSIONS) {
72                     refreshPermissions();
73                 }
74                 setTabNr(tb)}
75             }>
76             <Tab label="With users/groups" />
77             <Tab label="Sharing URLs" disabled={saveEnabled} />
78         </Tabs>
79         }
80         <DialogContent>
81             { tabNr === SharingDialogTab.PERMISSIONS &&
82             <Grid container direction='column' spacing={24}>
83               <Grid item>
84                   <SharingManagementForm />
85               </Grid>
86             </Grid>
87             }
88             { tabNr === SharingDialogTab.URLS &&
89             <SharingURLsContent uuid={sharedResourceUuid} />
90             }
91         </DialogContent>
92         <DialogActions>
93             <Grid container spacing={8}>
94                 { tabNr === SharingDialogTab.PERMISSIONS &&
95                 <Grid item md={12}>
96                     <SharingInvitationForm />
97                 </Grid> }
98                 <Grid item xs />
99                 { tabNr === SharingDialogTab.URLS &&
100                 <Grid item>
101                     <Button
102                         variant="contained"
103                         color="primary"
104                         onClick={onCreateSharingToken}>
105                         Create sharing URL
106                     </Button>
107                 </Grid>
108                 }
109                 { tabNr === SharingDialogTab.PERMISSIONS &&
110                 <Grid item>
111                     <Button
112                         variant='contained'
113                         color='primary'
114                         onClick={onSave}
115                         disabled={!saveEnabled}>
116                         Save changes
117                     </Button>
118                 </Grid>
119                 }
120                 <Grid item>
121                     <Button onClick={onClose}>
122                         Close
123                     </Button>
124                 </Grid>
125             </Grid>
126         </DialogActions>
127         {
128             loading && <LoadingIndicator />
129         }
130     </Dialog>;
131 };
132
133 const loadingIndicatorStyles: StyleRulesCallback<'root'> = theme => ({
134     root: {
135         position: 'absolute',
136         top: 0,
137         right: 0,
138         bottom: 0,
139         left: 0,
140         display: 'flex',
141         alignItems: 'center',
142         justifyContent: 'center',
143         backgroundColor: 'rgba(255, 255, 255, 0.8)',
144     },
145 });
146
147 const LoadingIndicator = withStyles(loadingIndicatorStyles)(
148     (props: WithStyles<'root'>) =>
149         <Paper classes={props.classes}>
150             <CircularProgress />
151         </Paper>
152 );