authscape 1.0.456 → 1.0.460

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.456",
3
+ "version": "1.0.460",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -290,6 +290,51 @@ export function AuthScapeApp ({Component, layout, loadingLayout, pageProps, muiT
290
290
  }
291
291
  }
292
292
 
293
+ const setInfoToastMessage = (message, options = null) => {
294
+ if (options != null)
295
+ {
296
+ toast.info(message, options);
297
+ }
298
+ else
299
+ {
300
+ toast.info(message);
301
+ }
302
+ }
303
+
304
+ const setSuccessToastMessage = (message, options = null) => {
305
+ if (options != null)
306
+ {
307
+ toast.success(message, options);
308
+ }
309
+ else
310
+ {
311
+ toast.success(message);
312
+ }
313
+ }
314
+
315
+ const setWarnToastMessage = (message, options = null) => {
316
+ if (options != null)
317
+ {
318
+ toast.warn(message, options);
319
+ }
320
+ else
321
+ {
322
+ toast.warn(message);
323
+ }
324
+ }
325
+
326
+ const setErrorToastMessage = (message, options = null) => {
327
+ if (options != null)
328
+ {
329
+ toast.error(message, options);
330
+ }
331
+ else
332
+ {
333
+ toast.error(message);
334
+ }
335
+ }
336
+
337
+
293
338
  const useStore = create((set) => (store));
294
339
 
295
340
  return (
@@ -308,18 +353,22 @@ export function AuthScapeApp ({Component, layout, loadingLayout, pageProps, muiT
308
353
  {frontEndLoadedState != null && frontEndLoadedState && pathname != "/signin-oidc" &&
309
354
  <>
310
355
  {layout != null && layout({
311
- children: <Component {...pageProps} currentUser={signedInUser.current} loadedUser={frontEndLoadedState} setIsLoading={setIsLoading} logEvent={logEvent} logPurchase={logPurchase} store={useStore} setToastMessage={setToastMessage} />,
356
+ children: <Component {...pageProps} currentUser={signedInUser.current} loadedUser={frontEndLoadedState} setIsLoading={setIsLoading} logEvent={logEvent} logPurchase={logPurchase} store={useStore} setToastMessage={setToastMessage} setInfoToastMessage={setInfoToastMessage} setSuccessToastMessage={setSuccessToastMessage} setWarnToastMessage={setWarnToastMessage} setErrorToastMessage={setErrorToastMessage} />,
312
357
  currentUser: signedInUser.current,
313
358
  logEvent: logEvent,
314
359
  setIsLoading: setIsLoading,
315
360
  toast: toast,
316
361
  store: useStore,
317
362
  setToastMessage: setToastMessage,
318
- pageProps: pageProps
363
+ pageProps: pageProps,
364
+ setInfoToastMessage: setInfoToastMessage,
365
+ setSuccessToastMessage: setSuccessToastMessage,
366
+ setWarnToastMessage: setWarnToastMessage,
367
+ setErrorToastMessage: setErrorToastMessage
319
368
  })}
320
369
 
321
370
  {layout == null &&
322
- <Component {...pageProps} currentUser={signedInUser.current} loadedUser={frontEndLoadedState} setIsLoading={setIsLoading} logEvent={logEvent} logPurchase={logPurchase} store={useStore} setToastMessage={setToastMessage} />
371
+ <Component {...pageProps} currentUser={signedInUser.current} loadedUser={frontEndLoadedState} setIsLoading={setIsLoading} logEvent={logEvent} logPurchase={logPurchase} store={useStore} setToastMessage={setToastMessage} setInfoToastMessage={setInfoToastMessage} setSuccessToastMessage={setSuccessToastMessage} setWarnToastMessage={setWarnToastMessage} setErrorToastMessage={setErrorToastMessage} />
323
372
  }
324
373
  </>
325
374
  }
@@ -0,0 +1,381 @@
1
+ import React, {useEffect, useState} from 'react';
2
+ import { Box } from '@mui/system';
3
+ import Grid from '@mui/material/Grid';
4
+ import Tabs from '@mui/material/Tabs';
5
+ import Tab from '@mui/material/Tab';
6
+ import Typography from '@mui/material/Typography';
7
+ import InputLabel from '@mui/material/InputLabel';
8
+ import MenuItem from '@mui/material/MenuItem';
9
+ import FormControl from '@mui/material/FormControl';
10
+ import Select from '@mui/material/Select';
11
+ // import { apiService } from 'authscape';
12
+ import TextField from '@mui/material/TextField';
13
+ import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
14
+ import Comments from '../comments';
15
+ import { Button, Card, CardActions, CardContent, CardMedia, Stack } from "@mui/material";
16
+ import InsertDriveFileRoundedIcon from '@mui/icons-material/InsertDriveFileRounded';
17
+ import ArrowBackIosRoundedIcon from '@mui/icons-material/ArrowBackIosRounded';
18
+
19
+ const TicketDetail = ({ticketId, setIsLoading, currentUser, GoBackToViewTickets = null, customTabName = null, customTabElement = null}) => {
20
+
21
+ const [value, setValue] = useState(0);
22
+ const [status, setStatus] = useState(null);
23
+ const [ticketType, setTicketType] = useState(null);
24
+ const [ticket, setTicket] = useState(null);
25
+ const [priorty, setPriority] = useState(0);
26
+ const [participants, setParticipants] = useState([]);
27
+ const [ticketAttachments, setTicketAttachments] = useState([]);
28
+ const [customTabPayload, setCustomTabPayload] = useState(null);
29
+
30
+ const [createdByList, setCreatedByList] = useState([]);
31
+ const [selectedCreatedBy, setSelectedCreatedBy] = useState(null);
32
+
33
+
34
+ useEffect(() => {
35
+
36
+ const fetchData = async () => {
37
+ setIsLoading(true);
38
+ let response = await apiService().get("/Ticket/GetTicket?ticketId=" + ticketId);
39
+ if (response != null && response.status == 200)
40
+ {
41
+ setTicket(response.data);
42
+
43
+ setIsLoading(false);
44
+ setStatus(response.data.selectedTicketStatusId);
45
+ setTicketType(response.data.selectedTicketTypeId);
46
+ setPriority(response.data.selectedPriortyId);
47
+ setSelectedCreatedBy(response.data.selectedCreatedBy);
48
+ setParticipants(response.data.participants);
49
+ setTicketAttachments(response.data.attachments);
50
+ setCustomTabPayload(response.data.customTabPayload)
51
+ }
52
+ }
53
+
54
+ fetchData();
55
+
56
+ }, []);
57
+
58
+ function TabPanel(props) {
59
+ const { children, value, index, ...other } = props;
60
+
61
+ return (
62
+ <div
63
+ role="tabpanel"
64
+ hidden={value !== index}
65
+ id={`simple-tabpanel-${index}`}
66
+ aria-labelledby={`simple-tab-${index}`}
67
+ {...other}
68
+ >
69
+ {value === index && (
70
+ <Box sx={{ p: 3 }}>
71
+ <Typography>{children}</Typography>
72
+ </Box>
73
+ )}
74
+ </div>
75
+ );
76
+ }
77
+
78
+ function a11yProps(index) {
79
+ return {
80
+ id: `simple-tab-${index}`,
81
+ 'aria-controls': `simple-tabpanel-${index}`,
82
+ };
83
+ }
84
+
85
+ const handleChange = (event, newValue) => {
86
+ setValue(newValue);
87
+ };
88
+
89
+ const refreshCreatedByList = async (query) => {
90
+
91
+ let response = await apiService().get("/ticket/findUser?query=" + query);
92
+ if (response != null && response.status == 200)
93
+ {
94
+ setCreatedByList(response.data);
95
+ }
96
+ }
97
+
98
+ const DownloadFile = ({fileName, uri}) => {
99
+
100
+ return (
101
+ <Card
102
+ sx={{
103
+ border: "1px solid black",
104
+ padding: "10px",
105
+ margin: "10px",
106
+ width: "200px",
107
+ textAlign:"center",
108
+ // display: "flex",
109
+ // alignItems: "center",
110
+ justifyContent: "space-between",
111
+ }}>
112
+ <Stack spacing={2}>
113
+ <Box sx={{textAlign:"center"}}>
114
+ <InsertDriveFileRoundedIcon sx={{fontSize:50}} />
115
+ </Box>
116
+ <Typography variant="h6" component="div">
117
+ {fileName}
118
+ </Typography>
119
+ <Button variant="contained" color="primary" onClick={() => {
120
+ window.open(uri);
121
+ }}>
122
+ Download
123
+ </Button>
124
+ </Stack>
125
+ </Card>
126
+ )
127
+ }
128
+
129
+ return (
130
+ <div>
131
+
132
+ <Box sx={{width: '100%' }}>
133
+
134
+ <Button variant="contained" startIcon={<ArrowBackIosRoundedIcon />} onClick={() => {
135
+
136
+ if (GoBackToViewTickets != null)
137
+ {
138
+ GoBackToViewTickets();
139
+ }
140
+
141
+ }}>Go Back</Button>
142
+
143
+
144
+ <Box>
145
+ <h2>{ticket != null && ticket.name}</h2>
146
+ </Box>
147
+
148
+ <Grid container spacing={2}>
149
+ <Grid item xs={4}>
150
+
151
+ <Box sx={{ minWidth: 120 }}>
152
+ <Box>
153
+ Status:
154
+ </Box>
155
+ <FormControl fullWidth>
156
+ <Select
157
+ labelId="demo-simple-select-label"
158
+ id="demo-simple-select"
159
+ value={status}
160
+ displayEmpty
161
+ inputProps={{ 'aria-label': 'Without label' }}
162
+ InputLabelProps={{ shrink: true }}
163
+ onChange={async (val) =>{
164
+ setStatus(val.target.value);
165
+
166
+ await apiService().put("/ticket/UpdateStatus", {
167
+ id: ticket.id,
168
+ ticketStatusId: val.target.value
169
+ });
170
+
171
+ }}>
172
+
173
+ {ticket != null && ticket.ticketStatuses.map((status, index) => {
174
+ return (
175
+ <MenuItem key={index} value={status.id}>{status.name}</MenuItem>
176
+ )
177
+ })}
178
+
179
+ </Select>
180
+ </FormControl>
181
+ </Box>
182
+
183
+ <Box sx={{paddingTop:2}}>
184
+ <Box>
185
+ Assigned to:
186
+ </Box>
187
+
188
+ {selectedCreatedBy != null &&
189
+ <Autocomplete
190
+ disablePortal
191
+ options={createdByList}
192
+ value={selectedCreatedBy}
193
+ onChange={async (event, newValue) => {
194
+ setSelectedCreatedBy(newValue.id);
195
+ }}
196
+ renderInput={(params) => <TextField {...params} label={""} onChange={(val) => {
197
+ refreshCreatedByList(val.currentTarget.value);
198
+ }} />}
199
+ />
200
+ }
201
+
202
+ {ticket != null &&
203
+ <>
204
+ <Box sx={{paddingTop:1, fontSize:18}}>
205
+ {ticket.assignedFirstName + " " + ticket.assignedLastName} ({ticket.assignedEmail})
206
+ </Box>
207
+ </>
208
+ }
209
+
210
+ </Box>
211
+
212
+ {/* <Box>
213
+ Company
214
+ </Box> */}
215
+
216
+ <Box sx={{paddingTop:2}}>
217
+ <Box sx={{ minWidth: 120 }}>
218
+ <Box>
219
+ Priority:
220
+ </Box>
221
+ <FormControl fullWidth>
222
+ <InputLabel id="demo-simple-select-label"></InputLabel>
223
+ <Select
224
+ labelId="demo-simple-select-label"
225
+ id="demo-simple-select"
226
+ value={priorty}
227
+ label=""
228
+ onChange={async (val) =>{
229
+ setPriority(val.target.value);
230
+
231
+ await apiService().put("/ticket/UpdateTicketPriority", {
232
+ id: ticket.id,
233
+ priorityLevel: val.target.value
234
+ });
235
+
236
+ }}>
237
+ <MenuItem value={0}>None</MenuItem>
238
+ <MenuItem value={1}>Low</MenuItem>
239
+ <MenuItem value={2}>Medium</MenuItem>
240
+ <MenuItem value={3}>High</MenuItem>
241
+ <MenuItem value={4}>Urgent</MenuItem>
242
+ </Select>
243
+ </FormControl>
244
+ </Box>
245
+ </Box>
246
+
247
+
248
+ </Grid>
249
+ <Grid item xs={4}>
250
+
251
+ <Box sx={{ minWidth: 120 }}>
252
+ <Box>
253
+ Ticket Type:
254
+ </Box>
255
+ <FormControl fullWidth>
256
+ <InputLabel id="demo-simple-select-label"></InputLabel>
257
+ <Select
258
+ labelId="demo-simple-select-label"
259
+ id="ticketType"
260
+ value={ticketType}
261
+ label=""
262
+ onChange={async (val) =>{
263
+ setTicketType(val.target.value);
264
+
265
+ await apiService().put("/ticket/UpdateTicketType", {
266
+ id: ticket.id,
267
+ TicketTypeId: val.target.value
268
+ });
269
+
270
+ }}>
271
+ {ticket != null && ticket.ticketTypes.map((status, index) => {
272
+ return (
273
+ <MenuItem key={index} value={status.id}>{status.name}</MenuItem>
274
+ )
275
+ })}
276
+
277
+ </Select>
278
+ </FormControl>
279
+ </Box>
280
+
281
+ <Box sx={{paddingTop:2}}>
282
+
283
+ <Box>
284
+ Participants:
285
+ </Box>
286
+ <Autocomplete
287
+ multiple={true}
288
+ disablePortal
289
+ value={participants}
290
+ options={createdByList}
291
+ onChange={async (event, newValue) => {
292
+
293
+ // alert(JSON.stringify(newValue));
294
+
295
+ await apiService().put("/ticket/UpdateParticipants", {
296
+ ticketId: router.query.id,
297
+ participants: newValue
298
+ });
299
+
300
+ setParticipants(newValue);
301
+ }}
302
+ renderInput={(params) => <TextField {...params} label={""} onChange={(val) => {
303
+ refreshCreatedByList(val.currentTarget.value);
304
+ }} />}
305
+ />
306
+ {/* <TextField id="lastUpdated" fullWidth={true} InputLabelProps={{ shrink: true }} disabled={true} label="Participants" variant="outlined" autoFocus={true} value={(ticket != null ? ticket.lastUpdated : "")} /> */}
307
+ </Box>
308
+ </Grid>
309
+ <Grid item xs={4}>
310
+ <Box>
311
+ <Box>
312
+ Created:
313
+ </Box>
314
+ <TextField id="created" fullWidth={true} InputLabelProps={{ shrink: true }} disabled={true} label="" variant="outlined" autoFocus={true} value={(ticket != null ? ticket.created : "")} />
315
+ </Box>
316
+ <Box sx={{paddingTop:2}}>
317
+ <Box>
318
+ Last Updated:
319
+ </Box>
320
+ <TextField id="lastUpdated" fullWidth={true} InputLabelProps={{ shrink: true }} disabled={true} label="" variant="outlined" autoFocus={true} value={(ticket != null ? ticket.lastUpdated : "")} />
321
+ </Box>
322
+ </Grid>
323
+ </Grid>
324
+ </Box>
325
+
326
+ <Box sx={{ width: '100%', marginTop:2 }}>
327
+ <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
328
+ <Tabs value={value} onChange={handleChange} aria-label="basic tabs example">
329
+ <Tab label="Chat" {...a11yProps(0)} />
330
+ <Tab label="Notes" {...a11yProps(1)} />
331
+ <Tab label="Attachments" {...a11yProps(2)} />
332
+
333
+ {customTabName != null &&
334
+ <Tab label={customTabName} {...a11yProps(3)} />
335
+ }
336
+
337
+ </Tabs>
338
+ </Box>
339
+ <TabPanel value={value} index={0}>
340
+
341
+ {ticket != null &&
342
+ <Comments ticketId={ticket.id} isDisabled={false} isNote={false} currentUser={currentUser} />
343
+ }
344
+ </TabPanel>
345
+ <TabPanel value={value} index={1}>
346
+ {ticket != null &&
347
+ <Comments ticketId={ticket.id} isDisabled={false} isNote={true} currentUser={currentUser} />
348
+ }
349
+ </TabPanel>
350
+ <TabPanel value={value} index={2}>
351
+ {ticket != null &&
352
+ <>
353
+ {ticketAttachments.map((attachment) => {
354
+ return (
355
+ <DownloadFile fileName={attachment.name} uri={attachment.url} />
356
+ )
357
+ })}
358
+
359
+ {ticketAttachments.length == 0 &&
360
+ <Box>
361
+ There are no attachments
362
+ </Box>
363
+ }
364
+
365
+ </>
366
+ }
367
+ </TabPanel>
368
+
369
+ {customTabName != null &&
370
+ <TabPanel value={value} index={3}>
371
+ {customTabElement(customTabPayload)}
372
+ </TabPanel>
373
+ }
374
+
375
+ </Box>
376
+
377
+ </div>
378
+ )
379
+ }
380
+
381
+ export default TicketDetail;