authscape 1.0.632 → 1.0.636

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.
@@ -0,0 +1,525 @@
1
+ import React, {useEffect, useState, useRef} from 'react';
2
+ // import {apiService, authService, StripeConnect, ReactDraft, EditableDatagrid, FileUploader} from 'authscape';
3
+ import Button from '@mui/material/Button';
4
+ import { Box } from '@mui/system';
5
+ import Dialog from '@mui/material/Dialog';
6
+ import DialogActions from '@mui/material/DialogActions';
7
+ import DialogContent from '@mui/material/DialogContent';
8
+ import DialogContentText from '@mui/material/DialogContentText';
9
+ import DialogTitle from '@mui/material/DialogTitle';
10
+ import TextField from '@mui/material/TextField';
11
+ import InputLabel from '@mui/material/InputLabel';
12
+ import MenuItem from '@mui/material/MenuItem';
13
+ import FormControl from '@mui/material/FormControl';
14
+ import Select from '@mui/material/Select';
15
+ import {GridActionsCellItem} from "@mui/x-data-grid";
16
+ import DeleteRoundedIcon from "@mui/icons-material/DeleteRounded";
17
+ import ListRoundedIcon from '@mui/icons-material/ListRounded';
18
+ import PublishRoundedIcon from '@mui/icons-material/PublishRounded';
19
+ import Grid from '@mui/material/Grid';
20
+ import DownloadRoundedIcon from '@mui/icons-material/DownloadRounded';
21
+
22
+ export function ManageMappingDocuments({fileUploadName, hideDocumentManager = false, documentTypeId = null, companyId = null, locationId = null, userId = null, onManageField = null, onArchive = null}) {
23
+
24
+ const [document, setDocument] = useState(null);
25
+ const [addColumnDialog, setAddColumnDialog] = useState(false);
26
+
27
+ const [showAddNewDocument, setShowAddNewDocument] = useState(false);
28
+ const [showTrainingDocument, setShowTrainingDocument] = useState(false);
29
+
30
+ const [columnName, setColumnName] = useState('');
31
+ const [selectedAddedColumn, setSelectedAddedColumn] = useState(null);
32
+
33
+ const [documentMappingColumns, setDocumentMappingColumns] = useState(null);
34
+ const [toColumnOptions, setToColumnOptions] = useState(null);
35
+
36
+ const [removeDocument, setRemoveDocument] = useState(null);
37
+
38
+ const [selectedDocumentComponentId, setSelectedDocumentComponentId] = useState(null);
39
+
40
+ const [dataGridRefreshKey, setDataGridRefreshKey] = useState(0);
41
+ const [dataGridMappingRefreshKey, setDataGridMappingRefreshKey] = useState(0);
42
+
43
+ const [selectedDocument, setSelectedDocument] = useState(null);
44
+
45
+ const [status, setStatus] = useState(0);
46
+
47
+ const [componentTypes, setComponentTypes] = useState([]);
48
+
49
+ const refHeaderRowInput = useRef(null);
50
+ const fileUploaderRef = useRef(null);
51
+ const refNewDocumentName = useRef(null);
52
+ const refSelectDocumentType = useRef(null);
53
+ const refNewColumnFileColumn = useRef(null);
54
+
55
+ const documentColumns = [
56
+ { field: 'name', flex:1, headerName: 'Document Name', width: 150, editable: false },
57
+ { field: 'documentTypeName', flex:1, headerName: 'Document Type', width: 150, editable: false },
58
+ {
59
+ field: "actions",
60
+ type: "actions",
61
+ width: 200,
62
+ flex:1,
63
+ headerName: "",
64
+ cellClassName: "actions",
65
+ getActions: ({ id, row }) => {
66
+ return [
67
+ <Button variant="text" startIcon={<ListRoundedIcon/>} onClick={() => {
68
+
69
+ if (onManageField != null)
70
+ {
71
+ onManageField(row.id);
72
+ }
73
+
74
+ }}>
75
+ Manage Fields
76
+ </Button>,
77
+ <Button variant="text" startIcon={<DownloadRoundedIcon/>} onClick={() => {
78
+
79
+ window.open("https://view.officeapps.live.com/op/view.aspx?src=" + row.fileUri + "&wdOrigin=BROWSELINK");
80
+
81
+ }}>
82
+ Download File
83
+ </Button>,
84
+ <Button variant="text" startIcon={<DeleteRoundedIcon/>} onClick={async () => {
85
+
86
+ let documentMappingId = row.id;
87
+ setRemoveDocument({
88
+ companyId: companyId,
89
+ documentMappingId: documentMappingId
90
+ });
91
+
92
+ }}>
93
+ Remove
94
+ </Button>
95
+ ];
96
+ },
97
+ }
98
+
99
+ ];
100
+
101
+ useEffect(() => {
102
+
103
+ if (document != null)
104
+ {
105
+ const fetchData = async () => {
106
+
107
+ let response = await apiService().get("/DocumentMapping/GetMappingFieldsForDocument?documentId=" + document.id);
108
+ if (response != null)
109
+ {
110
+ setToColumnOptions(response.data);
111
+ setDocumentMappingColumns(
112
+ [
113
+ { field: 'name', flex:1, headerName: 'File Column', width: 150, editable: true },
114
+ {
115
+ field: 'toName',
116
+ headerName: 'Upload To',
117
+ flex:1,
118
+ width: 150,
119
+ editable: true,
120
+ type: 'singleSelect',
121
+ valueOptions: response.data,
122
+ },
123
+ {
124
+ field: "actions",
125
+ type: "actions",
126
+ width: 200,
127
+ headerName: "Archive Fields",
128
+ cellClassName: "actions",
129
+ getActions: ({ id, row }) => {
130
+ return [
131
+ <GridActionsCellItem key={id}
132
+ icon={<DeleteRoundedIcon />}
133
+ label="Archive"
134
+ className="textPrimary"
135
+ onClick={async () => {
136
+
137
+ let documentMappingId = row.id;
138
+ let documentComponentId = row.documentComponentId;
139
+
140
+ // archive the column
141
+ let response = await apiService()
142
+ .delete("/DocumentMapping/RemoveColumnFromDocumentComponent?documentMappingId=" +
143
+ documentMappingId + "&documentComponentId=" + documentComponentId);
144
+
145
+ if (response != null && response.status == 200)
146
+ {
147
+ setDataGridMappingRefreshKey(dataGridMappingRefreshKey + 1);
148
+ }
149
+
150
+ }}
151
+ />,
152
+ ];
153
+ },
154
+ }
155
+ ]
156
+ );
157
+ }
158
+
159
+ }
160
+ fetchData();
161
+ }
162
+
163
+ }, [document])
164
+
165
+ useEffect(() => {
166
+
167
+ if (showAddNewDocument && documentTypeId == null)
168
+ {
169
+ // get all document types
170
+ const fetchData = async () => {
171
+ let response = await apiService().post("/DocumentMapping/GetDocumentTypes");
172
+ if (response != null && response.status == 200)
173
+ {
174
+ setComponentTypes(response.data.data);
175
+ }
176
+ };
177
+ fetchData();
178
+ }
179
+
180
+ }, [showAddNewDocument, documentTypeId])
181
+
182
+ const GetHeaderRowData = async (documentComponentId) => {
183
+
184
+ let response = await apiService().get("/DocumentMapping/GetHeaderRow?documentComponentId=" + documentComponentId);
185
+ if (response != null && response.status == 200)
186
+ {
187
+ refHeaderRowInput.current.value = response.data;
188
+ }
189
+ }
190
+
191
+ useEffect(() => {
192
+
193
+ if (status != null)
194
+ {
195
+ setDataGridRefreshKey(dataGridRefreshKey + 1);
196
+ }
197
+
198
+ }, [status])
199
+
200
+ return (
201
+ <Box>
202
+ {!hideDocumentManager &&
203
+ <Box>
204
+
205
+ <Grid container spacing={2} sx={{paddingBottom:2}}>
206
+ <Grid item xs={3}>
207
+ <Box sx={{ minWidth: 120 }}>
208
+ <FormControl fullWidth>
209
+ <InputLabel id="demo-simple-select-label">Status</InputLabel>
210
+ <Select
211
+ labelId="demo-simple-select-label"
212
+ id="demo-simple-select"
213
+ value={status}
214
+ label="Status"
215
+ onChange={(event) => {
216
+ setStatus(event.target.value);
217
+ }}
218
+ >
219
+ <MenuItem value={0}>Open</MenuItem>
220
+ <MenuItem value={2}>Published</MenuItem>
221
+ <MenuItem value={1}>Archived</MenuItem>
222
+ </Select>
223
+ </FormControl>
224
+ </Box>
225
+ </Grid>
226
+ <Grid item xs={9}>
227
+
228
+
229
+ <Box sx={{textAlign:"right", marginBottom:2}}>
230
+ <Button variant="contained" onClick={() => {
231
+ setShowAddNewDocument(true);
232
+ }}>{fileUploadName}</Button>
233
+ </Box>
234
+ </Grid>
235
+ </Grid>
236
+
237
+
238
+ <EditableDatagrid key={dataGridRefreshKey} loadedUser={true} params={{
239
+ companyId: companyId,
240
+ userId: userId,
241
+ locationId: locationId,
242
+ status: status
243
+ }} url={"/DocumentMapping/GetDocumentComponents"} columns={documentColumns}/>
244
+
245
+ </Box>
246
+ }
247
+
248
+ {hideDocumentManager &&
249
+ <Button variant="contained" onClick={() => {
250
+ setShowAddNewDocument(true);
251
+ }}>{fileUploadName}</Button>
252
+ }
253
+
254
+ {/* <Box sx={{textAlign:"right"}}>
255
+ <Button variant='contained' onClick={async () => {
256
+
257
+ let response = await apiService().post("/DocumentMapping/SubmitMappedDocument", {
258
+ companyId: companyId,
259
+ documentComponentId: selectedDocumentComponentId
260
+ });
261
+
262
+ if (response != null && (response.status == 200 || response.status == 201))
263
+ {
264
+ alert("Worked!");
265
+ }
266
+
267
+ }}>Submit</Button>
268
+ </Box> */}
269
+
270
+ <Dialog
271
+ open={showAddNewDocument}
272
+ onClose={() => {
273
+ setShowAddNewDocument(false);
274
+ }}
275
+ fullWidth={true}
276
+ aria-labelledby="alert-dialog-title"
277
+ aria-describedby="alert-dialog-description">
278
+ <DialogTitle id="alert-dialog-title">Upload Document</DialogTitle>
279
+ <DialogContent>
280
+
281
+ {documentTypeId == null &&
282
+ <DialogContentText id="alert-dialog-description" sx={{paddingBottom:2}}>
283
+ Please select the type of document, then click "Choose a file"
284
+ </DialogContentText>
285
+ }
286
+
287
+ {documentTypeId == null &&
288
+ <Box sx={{marginTop:2}}>
289
+ <Box sx={{ minWidth: 120 }}>
290
+ <FormControl fullWidth>
291
+ <InputLabel id="demo-simple-select-label">Document Type</InputLabel>
292
+ <Select
293
+ labelId="demo-simple-select-label"
294
+ id="demo-simple-select"
295
+ inputRef={refSelectDocumentType}
296
+ onChange={(val) => {
297
+
298
+ var _selectedDocument = componentTypes.find(s => s.id == val.target.value);
299
+ setSelectedDocument(_selectedDocument);
300
+
301
+ }}
302
+ label="DocumentType">
303
+
304
+ {componentTypes != null && componentTypes.map((componentType) => {
305
+ return (<MenuItem value={componentType.id}>{componentType.name}</MenuItem>)
306
+ })}
307
+
308
+ </Select>
309
+ </FormControl>
310
+ </Box>
311
+ </Box>
312
+ }
313
+
314
+ {(selectedDocument != null || (selectedDocument == null && documentTypeId != null)) &&
315
+
316
+ <Box sx={{textAlign:"center", width:"100%", display:"flex", alignItems:"center", paddingTop:2}}>
317
+ <FileUploader refOveride={fileUploaderRef} params={{
318
+
319
+ documentTypeId: documentTypeId == null ? selectedDocument.id : documentTypeId,
320
+ companyId: companyId
321
+
322
+ }} url={"/DocumentMapping/SyncDocument"} multiple={true} variant='custom' onUploadCompleted={(responses) => {
323
+
324
+ if (responses.length > 0)
325
+ {
326
+ let row = responses[0].data;
327
+
328
+ if (onManageField != null)
329
+ {
330
+ onManageField(row.id);
331
+ }
332
+ }
333
+
334
+ setShowAddNewDocument(false);
335
+
336
+ }}>
337
+
338
+ <Box sx={{display:"flex", alignItems:"center"}}>
339
+ <Box htmlFor="file-upload" sx={{border:"2px dashed #aaa", padding: 20, textAlign:"center", cursor:"pointer"}}>
340
+ {'Choose a file'}
341
+ </Box>
342
+ </Box>
343
+ </FileUploader>
344
+ </Box>
345
+ }
346
+
347
+ </DialogContent>
348
+ <DialogActions>
349
+ <Button onClick={() => {
350
+ setShowAddNewDocument(false);
351
+ }}>Cancel</Button>
352
+ </DialogActions>
353
+ </Dialog>
354
+
355
+ <Dialog
356
+ open={showTrainingDocument}
357
+ onClose={() => {
358
+ setShowTrainingDocument(false);
359
+ }}
360
+ fullWidth={true}
361
+ aria-labelledby="alert-dialog-title"
362
+ aria-describedby="alert-dialog-description">
363
+ <DialogTitle id="alert-dialog-title">Setup Mapping</DialogTitle>
364
+ <DialogContent>
365
+
366
+ <DialogContentText id="alert-dialog-description">
367
+ If you'd like to submit a file, we can assist in configuring the fields to match the formatting of your document.
368
+ </DialogContentText>
369
+
370
+ {document != null &&
371
+ <>
372
+ <FileUploader refOveride={fileUploaderRef} url={"/DocumentMapping/TrainDocument"} params={{
373
+ documentComponentId: document.id,
374
+ companyId: companyId,
375
+ locationId: locationId,
376
+ userId: userId
377
+ }} multiple={false} variant='custom' onUploadCompleted={() => {
378
+
379
+ setDataGridMappingRefreshKey(dataGridMappingRefreshKey + 1);
380
+
381
+ // setUpdate(!update);
382
+ // handleClose();
383
+ }}>
384
+ <Box sx={{marginTop:2, borderRadius: 2, backgroundColor: "#f5f5f5", border:"1px solid lightgray", cursor:"pointer", padding:2}}>
385
+ <Button
386
+ id="FileUploader"
387
+ aria-controls={open ? 'demo-customized-menu' : undefined}
388
+ aria-haspopup="true"
389
+ aria-expanded={open ? 'true' : undefined}
390
+ variant="text"
391
+ disableElevation
392
+ startIcon={<PublishRoundedIcon />}
393
+ sx={{marginLeft:1}}>
394
+ Upload Sample File
395
+ </Button>
396
+ </Box>
397
+ </FileUploader>
398
+ </>
399
+ }
400
+
401
+ </DialogContent>
402
+ <DialogActions>
403
+ <Button onClick={() => {
404
+ setShowTrainingDocument(false);
405
+ }}>No, thank you</Button>
406
+ </DialogActions>
407
+ </Dialog>
408
+
409
+ <Dialog
410
+ open={addColumnDialog}
411
+ onClose={() => {
412
+ setAddColumnDialog(false);
413
+ }}
414
+ fullWidth={true}
415
+ aria-labelledby="alert-dialog-title"
416
+ aria-describedby="alert-dialog-description">
417
+ <DialogTitle id="alert-dialog-title">Add Column</DialogTitle>
418
+ <DialogContent>
419
+ <DialogContentText id="alert-dialog-description">
420
+ Include a column for document mapping
421
+ </DialogContentText>
422
+
423
+ <Box sx={{marginTop:2}}>
424
+ <TextField inputRef={refNewColumnFileColumn} id="outlined-basic" label="File Column" fullWidth={true} variant="outlined" />
425
+ </Box>
426
+
427
+ <Box sx={{marginTop:4}}>
428
+ <FormControl fullWidth>
429
+ <InputLabel id="demo-simple-select-label">Column Name</InputLabel>
430
+ <Select
431
+ labelId="demo-simple-select-label"
432
+ id="demo-simple-select"
433
+ value={selectedAddedColumn}
434
+ label="Column Name"
435
+ onChange={(data) => {
436
+ setSelectedAddedColumn(data.target.value);
437
+ }}>
438
+ {/* {toColumnOptions != null && toColumnOptions.map((column) => {
439
+ return (
440
+ <MenuItem value={column}>{column}</MenuItem>
441
+ )
442
+ })} */}
443
+
444
+ </Select>
445
+ </FormControl>
446
+ </Box>
447
+
448
+ </DialogContent>
449
+ <DialogActions>
450
+ <Button onClick={() => {
451
+ setAddColumnDialog(false);
452
+ }}>Cancel</Button>
453
+ <Button onClick={async () => {
454
+
455
+ let response = await apiService().post("/DocumentMapping/AddNewField", {
456
+ tableName: document.name,
457
+ fieldName: refNewColumnFileColumn.current.value,
458
+ fileColumn: selectedAddedColumn,
459
+ companyId: companyId,
460
+ locationId: locationId,
461
+ userId: userId
462
+ });
463
+
464
+ if (response != null && response.status == 200)
465
+ {
466
+ setDataGridMappingRefreshKey(dataGridMappingRefreshKey + 1);
467
+ setAddColumnDialog(false);
468
+ }
469
+
470
+ }} autoFocus>
471
+ Add Column
472
+ </Button>
473
+ </DialogActions>
474
+ </Dialog>
475
+
476
+ <Dialog
477
+ open={removeDocument != null ? true : false}
478
+ onClose={() => {
479
+ setRemoveDocument(null);
480
+ }}
481
+ fullWidth={true}
482
+ aria-labelledby="alert-dialog-title"
483
+ aria-describedby="alert-dialog-description">
484
+ <DialogTitle id="alert-dialog-title">Remove the document</DialogTitle>
485
+ <DialogContent>
486
+ <DialogContentText id="alert-dialog-description">
487
+ Are you sure you want to remove this document?
488
+ </DialogContentText>
489
+ </DialogContent>
490
+ <DialogActions>
491
+ <Button onClick={() => {
492
+ setRemoveDocument(null);
493
+ }}>Cancel</Button>
494
+ <Button onClick={async () => {
495
+
496
+ let response = null;
497
+ if (companyId != null)
498
+ {
499
+ response = await apiService().delete("/DocumentMapping/RemoveDocument?companyId=" + removeDocument.companyId + "&documentId=" + removeDocument.documentMappingId)
500
+ }
501
+ else
502
+ {
503
+ response = await apiService().delete("/DocumentMapping/RemoveDocument?documentId=" + removeDocument.documentMappingId)
504
+ }
505
+
506
+ if (response != null && response.status == 200)
507
+ {
508
+ setDataGridRefreshKey(dataGridRefreshKey + 1);
509
+ setRemoveDocument(null);
510
+
511
+ if (onArchive != null)
512
+ {
513
+ onArchive(removeDocument.documentMappingId);
514
+ }
515
+ }
516
+
517
+ }}>
518
+ Remove Document
519
+ </Button>
520
+ </DialogActions>
521
+ </Dialog>
522
+
523
+ </Box>
524
+ )
525
+ }
@@ -0,0 +1,70 @@
1
+ import React, {useEffect, useState, useRef} from 'react';
2
+ import Card from '@mui/material/Card';
3
+ import CardActions from '@mui/material/CardActions';
4
+ import CardContent from '@mui/material/CardContent';
5
+ import { Box } from '@mui/system';
6
+ import Button from '@mui/material/Button';
7
+ import Typography from '@mui/material/Typography';
8
+ // import NewMappingColumn from './newMappingColumn';
9
+ import LinkIcon from '@mui/icons-material/Link';
10
+ import LinkOffIcon from '@mui/icons-material/LinkOff';
11
+ import Stack from '@mui/material/Stack';
12
+ // import MatchExistingMappedColumn from './matchExisting';
13
+ // import { apiService } from 'authscape';
14
+
15
+ export function MappedColumn({companyId, documentId, documentType, documentMappingId, name, toName, isMapped, toOptions, onResponse}) {
16
+
17
+ const notMatchedColor = "#ffe5e5";
18
+ const matchedColor = "#fff";
19
+
20
+ return (
21
+ <Card sx={{marginTop:1}}>
22
+ <CardContent sx={{position:"relative", backgroundColor: isMapped ? notMatchedColor : matchedColor}}>
23
+ <Typography gutterBottom variant="h5" component="div">
24
+ {name}
25
+ </Typography>
26
+ <Box sx={{position:"absolute", top:"10px", right:"10px"}}>
27
+ {isMapped ?
28
+ <Stack direction="row" spacing={1}>
29
+ <LinkOffIcon />
30
+ <Typography variant="body2" sx={{paddingTop:0.5}}>Not Matched</Typography>
31
+ </Stack> :
32
+ <Stack direction="row" spacing={1}>
33
+ <LinkIcon />
34
+ <Typography variant="body2" sx={{paddingTop:0.5}}>Matched</Typography>
35
+ </Stack>
36
+ }
37
+ </Box>
38
+ <Typography variant="body2" color="text.secondary">
39
+ {!isMapped && <>This column is matched with {toName}</>}
40
+ {isMapped && <>This column is not matched. If not matched it will not import</>}
41
+
42
+ </Typography>
43
+ </CardContent>
44
+ <CardActions sx={{backgroundColor: isMapped ? notMatchedColor : matchedColor}}>
45
+ {!isMapped ?
46
+ <>
47
+ <Button startIcon={<LinkOffIcon />} size="small" sx={{paddingLeft:3}} onClick={async () => {
48
+
49
+ let response = await apiService().delete(
50
+ "/DocumentMapping/RemoveMatch?companyId=" + companyId +
51
+ "&documentId=" + documentId +
52
+ "&documentMappingId=" + documentMappingId);
53
+
54
+ if (response != null && response.status == 200)
55
+ {
56
+ onResponse();
57
+ }
58
+
59
+ }}>Remove Match</Button>
60
+ </>
61
+ :
62
+ <>
63
+ <MatchExistingMappedColumn companyId={companyId} documentId={documentId} documentMappingId={documentMappingId} fromName={name} toOptions={toOptions} onResponse={onResponse} />
64
+ <NewMappingColumn name={name} companyId={companyId} documentType={documentType} documentId={documentId} documentMappingId={documentMappingId} onResponse={onResponse} />
65
+ </>
66
+ }
67
+ </CardActions>
68
+ </Card>
69
+ );
70
+ }