authscape 1.0.245 → 1.0.248

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "authscape",
3
- "version": "1.0.245",
3
+ "version": "1.0.248",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,423 @@
1
+ import { AppBar, Box, Button, Toolbar, Typography, Grid, Paper } from '@mui/material';
2
+ import React, {useEffect, useState, useRef} from 'react';
3
+ import AddRoundedIcon from '@mui/icons-material/AddRounded';
4
+ import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded';
5
+ import FolderIcon from '@mui/icons-material/Folder';
6
+ import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
7
+ import { styled, alpha } from '@mui/material/styles';
8
+ import Menu from '@mui/material/Menu';
9
+ import MenuItem from '@mui/material/MenuItem';
10
+ import Divider from '@mui/material/Divider';
11
+ import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
12
+ import InsertDriveFileOutlinedIcon from '@mui/icons-material/InsertDriveFileOutlined';
13
+ import Breadcrumbs from '@mui/material/Breadcrumbs';
14
+ import Link from '@mui/material/Link';
15
+ import PublishRoundedIcon from '@mui/icons-material/PublishRounded';
16
+ import Dialog from '@mui/material/Dialog';
17
+ import DialogActions from '@mui/material/DialogActions';
18
+ import DialogContent from '@mui/material/DialogContent';
19
+ import DialogContentText from '@mui/material/DialogContentText';
20
+ import DialogTitle from '@mui/material/DialogTitle';
21
+ import LockRoundedIcon from '@mui/icons-material/LockRounded';
22
+ import Tooltip from '@mui/material/Tooltip';
23
+
24
+ export function DocumentManager({loadedUser, setIsLoading, viewDocumentType = 1, apiDownloadEnforced = false, overrideLockMessage = "The directory cannot be removed."}) {
25
+
26
+ const fileUploaderRef = useRef();
27
+ const [files, setFiles] = useState(null);
28
+ const [update, setUpdate] = useState(false);
29
+ const [folderParent, setFolderParent] = useState(null);
30
+ const [breadCrumb, setBreadCrumb] = useState([]);
31
+
32
+ const [contextMenu, setContextMenu] = useState(null);
33
+ const [contextFile, setContextFile] = useState(null);
34
+
35
+ const [dialogDelete, setDialogDelete] = useState(false);
36
+
37
+ const handleContextMenu = (event, file) => {
38
+ event.preventDefault();
39
+
40
+ setContextFile(file);
41
+
42
+ if (!file.isLocked)
43
+ {
44
+ setContextMenu(
45
+ contextMenu === null
46
+ ? {
47
+ mouseX: event.clientX + 2,
48
+ mouseY: event.clientY - 6,
49
+ }
50
+ : // repeated contextmenu when it is already open closes it with Chrome 84 on Ubuntu
51
+ // Other native context menus might behave different.
52
+ // With this behavior we prevent contextmenu from the backdrop to re-locale existing context menus.
53
+ null,
54
+ );
55
+ }
56
+
57
+ };
58
+
59
+ useEffect(() => {
60
+
61
+ if (loadedUser)
62
+ {
63
+ const fetchDocuments = async () => {
64
+
65
+ if (folderParent != null)
66
+ {
67
+ let response = await apiService().get("/Document/GetDocumentsAndFiles?parentFolderId=" + folderParent.id + "&ViewDocumentType=" + viewDocumentType);
68
+ if (response != null && response.status == 200)
69
+ {
70
+ setFiles(response.data);
71
+ }
72
+ }
73
+ else
74
+ {
75
+ let response = await apiService().get("/Document/GetDocumentsAndFiles?ViewDocumentType=" + viewDocumentType);
76
+ if (response != null && response.status == 200)
77
+ {
78
+ setFiles(response.data);
79
+ }
80
+ }
81
+
82
+ };
83
+ fetchDocuments();
84
+ }
85
+
86
+ }, [loadedUser, folderParent, update])
87
+
88
+ const [anchorEl, setAnchorEl] = useState(null);
89
+ const open = Boolean(anchorEl);
90
+ const handleClick = (event) => {
91
+ setAnchorEl(event.currentTarget);
92
+ };
93
+ const handleClose = () => {
94
+ setAnchorEl(null);
95
+ setContextMenu(null);
96
+ };
97
+
98
+ const StyledMenu = styled((props) => (
99
+ <Menu
100
+ elevation={0}
101
+ anchorOrigin={{
102
+ vertical: 'bottom',
103
+ horizontal: 'right',
104
+ }}
105
+ transformOrigin={{
106
+ vertical: 'top',
107
+ horizontal: 'right',
108
+ }}
109
+ {...props}
110
+ />
111
+ ))(({ theme }) => ({
112
+ '& .MuiPaper-root': {
113
+ borderRadius: 6,
114
+ marginTop: theme.spacing(1),
115
+ minWidth: 180,
116
+ color:
117
+ theme.palette.mode === 'light' ? 'rgb(55, 65, 81)' : theme.palette.grey[300],
118
+ boxShadow:
119
+ 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px',
120
+ '& .MuiMenu-list': {
121
+ padding: '4px 0',
122
+ },
123
+ '& .MuiMenuItem-root': {
124
+ '& .MuiSvgIcon-root': {
125
+ fontSize: 18,
126
+ color: theme.palette.text.secondary,
127
+ marginRight: theme.spacing(1.5),
128
+ },
129
+ '&:active': {
130
+ backgroundColor: alpha(
131
+ theme.palette.primary.main,
132
+ theme.palette.action.selectedOpacity,
133
+ ),
134
+ },
135
+ },
136
+ },
137
+ }));
138
+
139
+ const handleFileClick = async (file, addToBread = true) => {
140
+
141
+ if (file.type == "folder")
142
+ {
143
+ setFolderParent(file);
144
+
145
+ if (addToBread)
146
+ {
147
+ let newBC = [...breadCrumb];
148
+ newBC.push(file);
149
+ setBreadCrumb(newBC);
150
+ }
151
+ else
152
+ {
153
+ let newList = [];
154
+ let hasBeenFound = false;
155
+ for (let index = 0; index < breadCrumb.length; index++) {
156
+
157
+ const element = breadCrumb[index];
158
+ if (element.id == file.id)
159
+ {
160
+ hasBeenFound = true;
161
+ newList.push(element);
162
+ break;
163
+ }
164
+
165
+ if (!hasBeenFound)
166
+ {
167
+ newList.push(element);
168
+ }
169
+
170
+ }
171
+
172
+ setBreadCrumb(newList);
173
+
174
+ }
175
+
176
+ }
177
+ else
178
+ {
179
+ setIsLoading(true);
180
+
181
+ await apiService().DownloadFile("/Document/DownloadDocument?documentId=" + file.id + "&ViewDocumentType=" + viewDocumentType, file.name, () => {
182
+ setIsLoading(false);
183
+ });
184
+
185
+ }
186
+ }
187
+
188
+ const dialogDeleteClosed = () => {
189
+ setContextFile(null);
190
+ setContextMenu(null);
191
+ setDialogDelete(false);
192
+ }
193
+
194
+ return (
195
+ <>
196
+ <Box sx={{ flexGrow: 1 }}>
197
+ <AppBar position="static" color='inherit' elevation={0}>
198
+ <Toolbar>
199
+ <Box>
200
+ <Button
201
+ id="demo-customized-button"
202
+ aria-controls={open ? 'demo-customized-menu' : undefined}
203
+ aria-haspopup="true"
204
+ aria-expanded={open ? 'true' : undefined}
205
+ variant="contained"
206
+ disableElevation
207
+ onClick={handleClick}
208
+ startIcon={<AddRoundedIcon />}
209
+ endIcon={<KeyboardArrowDownIcon />}
210
+ >
211
+ New
212
+ </Button>
213
+ <StyledMenu
214
+ id="demo-customized-menu"
215
+ MenuListProps={{
216
+ 'aria-labelledby': 'demo-customized-button',
217
+ }}
218
+ anchorEl={anchorEl}
219
+ open={open}
220
+ onClose={handleClose}
221
+ >
222
+ <MenuItem onClick={async () => {
223
+
224
+ let newDocumentName = prompt("New folder name");
225
+ if (newDocumentName != null && newDocumentName != "")
226
+ {
227
+ let response = await apiService().post("/Document/CreateFolder", {
228
+ folderName: newDocumentName,
229
+ parentFolderId: folderParent != null ? folderParent.id : null,
230
+ viewDocumentType: viewDocumentType
231
+ });
232
+
233
+ if (response != null && response.status == 200)
234
+ {
235
+ // refresh
236
+ setUpdate(!update);
237
+ }
238
+
239
+ }
240
+
241
+ handleClose();
242
+ }} disableRipple>
243
+ <InsertDriveFileIcon />
244
+ New Folder
245
+ </MenuItem>
246
+ </StyledMenu>
247
+ </Box>
248
+
249
+
250
+ <FileUploader refOveride={fileUploaderRef} url={"/Document/UploadFile"} params={{
251
+ parentFolderId: (folderParent != null ? folderParent.id : null),
252
+ viewDocumentType: viewDocumentType
253
+
254
+ }} multiple={true} variant='custom' onUploadCompleted={() => {
255
+ setUpdate(!update);
256
+ handleClose();
257
+ }}>
258
+
259
+ <Button
260
+ id="FileUploader"
261
+ aria-controls={open ? 'demo-customized-menu' : undefined}
262
+ aria-haspopup="true"
263
+ aria-expanded={open ? 'true' : undefined}
264
+ variant="text"
265
+ disableElevation
266
+ startIcon={<PublishRoundedIcon />}
267
+ sx={{marginLeft:1}}>
268
+ Upload File(s)
269
+ </Button>
270
+
271
+ </FileUploader>
272
+ </Toolbar>
273
+ </AppBar>
274
+
275
+ <Divider />
276
+
277
+ <Breadcrumbs aria-label="breadcrumb" separator={">"} sx={{marginLeft:1, marginBottom:2, marginTop:2}}>
278
+ <Link underline="hover" color="inherit" sx={{cursor:"pointer", fontWeight:"bold"}} onClick={() => {
279
+
280
+ setFolderParent(null);
281
+ setBreadCrumb([]);
282
+
283
+ }}>
284
+ My Files
285
+ </Link>
286
+ {breadCrumb.map((bread, index) => {
287
+ return (
288
+ <Link
289
+ key={index}
290
+ underline="hover"
291
+ sx={{cursor:"pointer"}}
292
+ color="inherit" onClick={() => {
293
+ handleFileClick(bread, false);
294
+ }}>
295
+ {bread.name}
296
+ </Link>
297
+ )
298
+ })}
299
+ </Breadcrumbs>
300
+ </Box>
301
+
302
+ <Box sx={{height: "85vh", width: '100%' }}>
303
+ <Grid container spacing={2}>
304
+ {files != null && files.map((file, index) => (
305
+
306
+ <Grid onContextMenu={(event) => {
307
+ handleContextMenu(event, file);
308
+ }} item key={index} xs={12} sm={6} md={4} lg={2} onClick={() => handleFileClick(file)}>
309
+ <Paper
310
+ sx={{
311
+ padding: 2,
312
+ display: 'flex',
313
+ flexDirection: 'column',
314
+ alignItems: 'center',
315
+ cursor: 'pointer',
316
+ position:"relative",
317
+ '&:hover': {
318
+ backgroundColor: '#F5F5F5'
319
+ }
320
+ }}>
321
+
322
+ {file.type === 'folder' &&
323
+ <Box sx={{position:"absolute", top:45, color:"white"}}>
324
+ {file.count}
325
+ </Box>}
326
+
327
+ {file.isLocked &&
328
+ <Box sx={{position:"absolute", top:10, right: 10, color:"black"}}>
329
+ <Tooltip title={overrideLockMessage}>
330
+ <LockRoundedIcon />
331
+ </Tooltip>
332
+ </Box>
333
+ }
334
+
335
+ {file.type === 'folder' ? (
336
+ <FolderIcon sx={{ fontSize: 80, color:"orange" }} />
337
+ ) : (
338
+
339
+ file.documentFileExtentionType == 0 || apiDownloadEnforced ? <InsertDriveFileOutlinedIcon sx={{ fontSize: 60 }} /> : <NextImage src={file.uri} alt={"Image"} width={80} height={80} />
340
+
341
+ )}
342
+ <Typography variant="subtitle1" sx={{paddingTop:1}}>{file.name}</Typography>
343
+ <Typography variant="subtitle2" sx={{paddingTop:0, fontSize:11}}>{file.lastUpdated}</Typography>
344
+ </Paper>
345
+ </Grid>
346
+
347
+ ))}
348
+ </Grid>
349
+
350
+ <Menu
351
+ open={contextMenu !== null}
352
+ onClose={handleClose}
353
+ anchorReference="anchorPosition"
354
+ anchorPosition={
355
+ contextMenu !== null
356
+ ? { top: contextMenu.mouseY, left: contextMenu.mouseX }
357
+ : undefined
358
+ }>
359
+ {/* <MenuItem onClick={handleClose}>Move</MenuItem>
360
+ <MenuItem onClick={handleClose}>Copy</MenuItem>
361
+ <Divider /> */}
362
+ <MenuItem startIcon={<DeleteRoundedIcon />} onClick={() => {
363
+
364
+ setDialogDelete(true);
365
+ handleClose();
366
+
367
+ }}>Delete</MenuItem>
368
+ </Menu>
369
+ </Box>
370
+
371
+
372
+ <Dialog
373
+ open={dialogDelete}
374
+ onClose={() => {
375
+ dialogDeleteClosed();
376
+ }}
377
+ aria-labelledby="alert-dialog-title"
378
+ aria-describedby="alert-dialog-description">
379
+ <DialogTitle id="alert-dialog-title">
380
+ Are you sure you wan to delete {contextFile != null ? contextFile.name : ""}?
381
+ </DialogTitle>
382
+ <DialogContent>
383
+ <DialogContentText id="alert-dialog-description">
384
+
385
+ {(contextFile != null && contextFile.type != null && contextFile.type == 'folder') &&
386
+ <>
387
+ If you delete {contextFile != null ? contextFile.name : ""}, you will delete all files and folders within {contextFile != null ? contextFile.name : ""}.
388
+ </>
389
+ }
390
+
391
+ {(contextFile != null && contextFile.type != null && contextFile.type != 'folder') &&
392
+ <>
393
+ If you delete {contextFile != null ? contextFile.name : ""} this file will be gone forever.
394
+ </>
395
+ }
396
+
397
+
398
+ </DialogContentText>
399
+ </DialogContent>
400
+ <DialogActions>
401
+ <Button onClick={() => {
402
+
403
+ dialogDeleteClosed();
404
+
405
+ }}>Cancel</Button>
406
+ <Button onClick={async () => {
407
+ dialogDeleteClosed();
408
+
409
+ let response = await apiService().delete("/Document/DeleteFolder?documentId=" + contextFile.id);
410
+ if (response != null && response.status == 200)
411
+ {
412
+ setUpdate(!update);
413
+ }
414
+
415
+ }} autoFocus>
416
+ Delete
417
+ </Button>
418
+ </DialogActions>
419
+ </Dialog>
420
+ </>
421
+ );
422
+
423
+ };