dce-reactkit 3.9.0-beta.1 → 3.9.1

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.
Files changed (39) hide show
  1. package/dist/cjs/index.js +564 -257
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/Dropdown.d.ts +32 -0
  4. package/dist/cjs/types/components/Modal/ModalProps.d.ts +0 -2
  5. package/dist/cjs/types/helpers/validators/ChicagoTitleCase.d.ts +9 -0
  6. package/dist/cjs/types/helpers/validators/validURL.d.ts +8 -0
  7. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/index.d.ts +24 -0
  8. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +33 -0
  9. package/dist/cjs/types/index.d.ts +4 -1
  10. package/dist/cjs/types/types/DropdownItemType.d.ts +6 -0
  11. package/dist/cjs/types/types/ReactKitErrorCode.d.ts +4 -1
  12. package/dist/esm/index.js +562 -259
  13. package/dist/esm/index.js.map +1 -1
  14. package/dist/esm/types/components/Dropdown.d.ts +32 -0
  15. package/dist/esm/types/components/Modal/ModalProps.d.ts +0 -2
  16. package/dist/esm/types/helpers/validators/ChicagoTitleCase.d.ts +9 -0
  17. package/dist/esm/types/helpers/validators/validURL.d.ts +8 -0
  18. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/index.d.ts +24 -0
  19. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +33 -0
  20. package/dist/esm/types/index.d.ts +4 -1
  21. package/dist/esm/types/types/DropdownItemType.d.ts +6 -0
  22. package/dist/esm/types/types/ReactKitErrorCode.d.ts +4 -1
  23. package/dist/index.d.ts +107 -46
  24. package/package.json +2 -1
  25. package/src/components/Dropdown.tsx +317 -0
  26. package/src/components/Modal/ModalProps.ts +0 -4
  27. package/src/components/Modal/index.tsx +3 -39
  28. package/src/components/MultiSwitch.tsx +1 -1
  29. package/src/helpers/validators/ChicagoTitleCase.test.ts +85 -0
  30. package/src/helpers/validators/ChicagoTitleCase.ts +32 -0
  31. package/src/helpers/validators/findURL.test.ts +83 -0
  32. package/src/helpers/validators/findURL.ts +43 -0
  33. package/src/helpers/validators/validURL.test.ts +90 -0
  34. package/src/helpers/validators/validURL.ts +18 -0
  35. package/src/helpers/visitEndpointOnAnotherServer/index.ts +93 -0
  36. package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +164 -0
  37. package/src/index.ts +6 -0
  38. package/src/types/DropdownItemType.ts +11 -0
  39. package/src/types/ReactKitErrorCode.tsx +6 -1
package/dist/esm/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useState, useRef, useEffect, useReducer, forwardRef, useContext, useLayoutEffect, createContext, useMemo, useCallback, Component, Fragment } from 'react';
3
- import { faExclamationTriangle, faCircle, faHourglassEnd, faDotCircle, faCheckSquare, faHourglass, faClipboard, faChevronDown, faChevronRight, faCloudDownloadAlt, faMinus, faCheckCircle, faXmarkCircle, faSort, faSortDown, faSortUp, faCalendar, faTag, faHammer, faList, faTimes, faSave, faTrash, faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
3
+ import { faExclamationTriangle, faHourglassEnd, faCircle, faDotCircle, faCheckSquare, faHourglass, faClipboard, faChevronDown, faChevronRight, faCloudDownloadAlt, faMinus, faCheckCircle, faXmarkCircle, faSort, faSortDown, faSortUp, faCalendar, faTag, faHammer, faList, faTimes, faSave, faTrash, faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
4
4
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5
5
  import ReactDOM, { createPortal } from 'react-dom';
6
6
  import { faCircle as faCircle$1, faSquareMinus, faSquare } from '@fortawesome/free-regular-svg-icons';
7
+ import qs from 'qs';
7
8
 
8
9
  /******************************************************************************
9
10
  Copyright (c) Microsoft Corporation.
@@ -30,7 +31,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
30
31
  });
31
32
  }
32
33
 
33
- // Highest error code = DRK13
34
+ // Highest error code = DRK16
34
35
  /**
35
36
  * List of error codes built into the react kit
36
37
  * @author Gabe Abrams
@@ -50,6 +51,10 @@ var ReactKitErrorCode;
50
51
  ReactKitErrorCode["NotAllowedToReviewLogs"] = "DRK11";
51
52
  ReactKitErrorCode["ThemeCheckedBeforeReactKitReady"] = "DRK12";
52
53
  ReactKitErrorCode["SessionExpiredMessageGottenBeforeReactKitReady"] = "DRK13";
54
+ // Server-to-server requests
55
+ ReactKitErrorCode["NotConnected"] = "DRK14";
56
+ ReactKitErrorCode["SelfSigned"] = "DRK15";
57
+ ReactKitErrorCode["ResponseParseError"] = "DRK16";
53
58
  })(ReactKitErrorCode || (ReactKitErrorCode = {}));
54
59
  var ReactKitErrorCode$1 = ReactKitErrorCode;
55
60
 
@@ -191,98 +196,6 @@ const waitMs = (ms = 0) => __awaiter(void 0, void 0, void 0, function* () {
191
196
  });
192
197
  });
193
198
 
194
- /**
195
- * Loading spinner/indicator
196
- * @author Gabe Abrams
197
- */
198
- /*------------------------------------------------------------------------*/
199
- /* -------------------------------- Style ------------------------------- */
200
- /*------------------------------------------------------------------------*/
201
- const style$a = `
202
- /* Container fades in */
203
- .LoadingSpinner-container {
204
- animation-name: LoadingSpinner-container-fade-in;
205
- animation-duration: 0.3s;
206
- animation-delay: 0.4s;
207
- animation-fill-mode: both;
208
- animation-timing-function: ease-out;
209
- }
210
- @keyframes LoadingSpinner-container-fade-in {
211
- 0% {
212
- opacity: 0;
213
- }
214
- 100% {
215
- opacity: 1;
216
- }
217
- }
218
-
219
- /* Blips */
220
- .LoadingSpinner-blip-1,
221
- .LoadingSpinner-blip-2,
222
- .LoadingSpinner-blip-3,
223
- .LoadingSpinner-blip-4 {
224
- font-size: 1.8rem;
225
- opacity: 0.6;
226
- margin-top: 1rem;
227
- margin-bottom: 1rem;
228
- }
229
-
230
- /* First Blip */
231
- .LoadingSpinner-blip-1 {
232
- animation: LoadingSpinner-pop-animation 2s infinite;
233
- }
234
-
235
- /* Second Blip */
236
- .LoadingSpinner-blip-2 {
237
- animation: LoadingSpinner-pop-animation 2s infinite;
238
- -webkit-animation-delay: 0.1s;
239
- animation-delay: 0.1s;
240
- }
241
-
242
- /* Third Blip */
243
- .LoadingSpinner-blip-3 {
244
- animation: LoadingSpinner-pop-animation 2s infinite;
245
- animation-delay: 0.2s;
246
- }
247
-
248
- /* Fourth Blip */
249
- .LoadingSpinner-blip-4 {
250
- animation: LoadingSpinner-pop-animation 2s infinite;
251
- animation-delay: 0.3s;
252
- }
253
-
254
- /* Pop Animation for Each Blip */
255
- @keyframes LoadingSpinner-pop-animation {
256
- 0% {
257
- transform: scale(1.0);
258
- }
259
- 10% {
260
- transform: scale(1.5);
261
- }
262
- 30% {
263
- transform: scale(1.0);
264
- }
265
- 100% {
266
- transform: scale(1.0);
267
- }
268
- }
269
- `;
270
- /*------------------------------------------------------------------------*/
271
- /* ------------------------------ Component ----------------------------- */
272
- /*------------------------------------------------------------------------*/
273
- const LoadingSpinner = () => {
274
- /*------------------------------------------------------------------------*/
275
- /* ------------------------------- Render ------------------------------- */
276
- /*------------------------------------------------------------------------*/
277
- // Add all four blips to a container
278
- return (React__default.createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
279
- React__default.createElement("style", null, style$a),
280
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-1 me-1" }),
281
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-2 me-1" }),
282
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-3 me-1" }),
283
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-4" })));
284
- };
285
-
286
199
  /**
287
200
  * Modal sizes
288
201
  * @author Gabe Abrams
@@ -502,7 +415,7 @@ const getNextUniqueId = () => {
502
415
  /*------------------------------------------------------------------------*/
503
416
  /* -------------------------------- Style ------------------------------- */
504
417
  /*------------------------------------------------------------------------*/
505
- const style$9 = `
418
+ const style$a = `
506
419
  .Modal-backdrop {
507
420
  position: fixed;
508
421
  top: 0;
@@ -574,14 +487,13 @@ const Modal = (props) => {
574
487
  /*------------------------------------------------------------------------*/
575
488
  var _a;
576
489
  /* -------------- Props ------------- */
577
- const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, isLoading, isLoadingCancelable, } = props;
490
+ const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, } = props;
578
491
  // Determine if no header either
579
492
  const noHeader = (!title && type === ModalType$1.NoButtons);
580
493
  /* -------------- State ------------- */
581
494
  // True if animation is in use
582
495
  const [animatingIn, setAnimatingIn] = useState(true);
583
496
  const [animatingPop, setAnimatingPop] = useState(false);
584
- const [showModal, setShowModal] = useState(false);
585
497
  /* -------------- Refs -------------- */
586
498
  // Keep track of whether modal is still mounted
587
499
  const mounted = useRef(false);
@@ -607,14 +519,6 @@ const Modal = (props) => {
607
519
  // Update to state after animated in
608
520
  if (mounted.current) {
609
521
  setAnimatingIn(false);
610
- if (isLoading) {
611
- // wait 1 second before showing modal
612
- yield waitMs(1000);
613
- setShowModal(true);
614
- }
615
- else {
616
- setShowModal(true);
617
- }
618
522
  }
619
523
  }))();
620
524
  return () => {
@@ -690,7 +594,7 @@ const Modal = (props) => {
690
594
  left: 0,
691
595
  right: 0,
692
596
  } },
693
- React__default.createElement("style", null, style$9),
597
+ React__default.createElement("style", null, style$a),
694
598
  React__default.createElement("div", { className: `Modal-backdrop ${backdropAnimationClass}`, style: {
695
599
  zIndex: baseZIndex + 1,
696
600
  }, onClick: () => __awaiter(void 0, void 0, void 0, function* () {
@@ -708,11 +612,11 @@ const Modal = (props) => {
708
612
  // Handle close
709
613
  handleClose(ModalButtonType$1.Cancel);
710
614
  }) }),
711
- showModal && (React__default.createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
615
+ React__default.createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
712
616
  zIndex: baseZIndex + 2,
713
617
  // Override sizes for even larger for XL
714
618
  width: (size === ModalSize$1.ExtraLarge
715
- ? 'calc(100vw - 3rem)'
619
+ ? 'calc(100vw - 1rem)'
716
620
  : undefined),
717
621
  maxWidth: (size === ModalSize$1.ExtraLarge
718
622
  ? '80rem'
@@ -740,7 +644,7 @@ const Modal = (props) => {
740
644
  ? '1.6rem'
741
645
  : undefined),
742
646
  } }, title),
743
- (onClose && !dontShowXButton && !(isLoading && !isLoadingCancelable)) && (React__default.createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: {
647
+ (onClose && !dontShowXButton) && (React__default.createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: {
744
648
  backgroundColor: (isDarkModeOn()
745
649
  ? 'white'
746
650
  : undefined),
@@ -748,17 +652,7 @@ const Modal = (props) => {
748
652
  // Handle close
749
653
  handleClose(ModalButtonType$1.Cancel);
750
654
  } })))),
751
- isLoading && (React__default.createElement("div", { className: "modal-body", style: {
752
- color: (isDarkModeOn()
753
- ? 'white'
754
- : undefined),
755
- backgroundColor: (isDarkModeOn()
756
- ? '#444'
757
- : undefined),
758
- } },
759
- React__default.createElement(LoadingSpinner, null),
760
- React__default.createElement("span", { className: "sr-only" }, "Content loading"))),
761
- children && !isLoading && (React__default.createElement("div", { className: "modal-body", style: {
655
+ children && (React__default.createElement("div", { className: "modal-body", style: {
762
656
  color: (isDarkModeOn()
763
657
  ? 'white'
764
658
  : undefined),
@@ -776,7 +670,7 @@ const Modal = (props) => {
776
670
  borderTop: (isDarkModeOn()
777
671
  ? '0.1rem solid gray'
778
672
  : undefined),
779
- } }, footer)))))));
673
+ } }, footer))))));
780
674
  // Determine which portal to use
781
675
  const portalNumber = id.current % NUM_MODAL_PORTALS;
782
676
  // Render in a portal
@@ -1256,7 +1150,7 @@ const showSessionExpiredMessage = () => __awaiter(void 0, void 0, void 0, functi
1256
1150
  /*------------------------------------------------------------------------*/
1257
1151
  /* -------------------------------- Style ------------------------------- */
1258
1152
  /*------------------------------------------------------------------------*/
1259
- const style$8 = `
1153
+ const style$9 = `
1260
1154
  .AppWrapper-leave-to-url-notice {
1261
1155
  opacity: 0;
1262
1156
 
@@ -1431,13 +1325,105 @@ const AppWrapper = (props) => {
1431
1325
  /* --------------- Main UI -------------- */
1432
1326
  /*----------------------------------------*/
1433
1327
  return (React__default.createElement(React__default.Fragment, null,
1434
- React__default.createElement("style", null, style$8),
1328
+ React__default.createElement("style", null, style$9),
1435
1329
  React__default.createElement("style", null, tooltipStyle),
1436
1330
  modal,
1437
1331
  customModalPortals,
1438
1332
  body));
1439
1333
  };
1440
1334
 
1335
+ /**
1336
+ * Loading spinner/indicator
1337
+ * @author Gabe Abrams
1338
+ */
1339
+ /*------------------------------------------------------------------------*/
1340
+ /* -------------------------------- Style ------------------------------- */
1341
+ /*------------------------------------------------------------------------*/
1342
+ const style$8 = `
1343
+ /* Container fades in */
1344
+ .LoadingSpinner-container {
1345
+ animation-name: LoadingSpinner-container-fade-in;
1346
+ animation-duration: 0.3s;
1347
+ animation-delay: 0.4s;
1348
+ animation-fill-mode: both;
1349
+ animation-timing-function: ease-out;
1350
+ }
1351
+ @keyframes LoadingSpinner-container-fade-in {
1352
+ 0% {
1353
+ opacity: 0;
1354
+ }
1355
+ 100% {
1356
+ opacity: 1;
1357
+ }
1358
+ }
1359
+
1360
+ /* Blips */
1361
+ .LoadingSpinner-blip-1,
1362
+ .LoadingSpinner-blip-2,
1363
+ .LoadingSpinner-blip-3,
1364
+ .LoadingSpinner-blip-4 {
1365
+ font-size: 1.8rem;
1366
+ opacity: 0.6;
1367
+ margin-top: 1rem;
1368
+ margin-bottom: 1rem;
1369
+ }
1370
+
1371
+ /* First Blip */
1372
+ .LoadingSpinner-blip-1 {
1373
+ animation: LoadingSpinner-pop-animation 2s infinite;
1374
+ }
1375
+
1376
+ /* Second Blip */
1377
+ .LoadingSpinner-blip-2 {
1378
+ animation: LoadingSpinner-pop-animation 2s infinite;
1379
+ -webkit-animation-delay: 0.1s;
1380
+ animation-delay: 0.1s;
1381
+ }
1382
+
1383
+ /* Third Blip */
1384
+ .LoadingSpinner-blip-3 {
1385
+ animation: LoadingSpinner-pop-animation 2s infinite;
1386
+ animation-delay: 0.2s;
1387
+ }
1388
+
1389
+ /* Fourth Blip */
1390
+ .LoadingSpinner-blip-4 {
1391
+ animation: LoadingSpinner-pop-animation 2s infinite;
1392
+ animation-delay: 0.3s;
1393
+ }
1394
+
1395
+ /* Pop Animation for Each Blip */
1396
+ @keyframes LoadingSpinner-pop-animation {
1397
+ 0% {
1398
+ transform: scale(1.0);
1399
+ }
1400
+ 10% {
1401
+ transform: scale(1.5);
1402
+ }
1403
+ 30% {
1404
+ transform: scale(1.0);
1405
+ }
1406
+ 100% {
1407
+ transform: scale(1.0);
1408
+ }
1409
+ }
1410
+ `;
1411
+ /*------------------------------------------------------------------------*/
1412
+ /* ------------------------------ Component ----------------------------- */
1413
+ /*------------------------------------------------------------------------*/
1414
+ const LoadingSpinner = () => {
1415
+ /*------------------------------------------------------------------------*/
1416
+ /* ------------------------------- Render ------------------------------- */
1417
+ /*------------------------------------------------------------------------*/
1418
+ // Add all four blips to a container
1419
+ return (React__default.createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
1420
+ React__default.createElement("style", null, style$8),
1421
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-1 me-1" }),
1422
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-2 me-1" }),
1423
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-3 me-1" }),
1424
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-4" })));
1425
+ };
1426
+
1441
1427
  /**
1442
1428
  * A box with a tab on the top that holds buttons and other content
1443
1429
  * @author Gabe Abrams
@@ -2229,27 +2215,27 @@ const PopPendingMark = (props) => {
2229
2215
  */
2230
2216
  /* ------------- Actions ------------ */
2231
2217
  // Types of actions
2232
- var ActionType$8;
2218
+ var ActionType$9;
2233
2219
  (function (ActionType) {
2234
2220
  // Indicate that the text was recently copied
2235
2221
  ActionType["IndicateRecentlyCopied"] = "indicate-recently-copied";
2236
2222
  // Clear the status
2237
2223
  ActionType["ClearRecentlyCopiedStatus"] = "clear-recently-copied-status";
2238
- })(ActionType$8 || (ActionType$8 = {}));
2224
+ })(ActionType$9 || (ActionType$9 = {}));
2239
2225
  /**
2240
2226
  * Reducer that executes actions
2241
2227
  * @author Gabe Abrams
2242
2228
  * @param state current state
2243
2229
  * @param action action to execute
2244
2230
  */
2245
- const reducer$9 = (state, action) => {
2231
+ const reducer$a = (state, action) => {
2246
2232
  switch (action.type) {
2247
- case ActionType$8.IndicateRecentlyCopied: {
2233
+ case ActionType$9.IndicateRecentlyCopied: {
2248
2234
  return {
2249
2235
  recentlyCopied: true,
2250
2236
  };
2251
2237
  }
2252
- case ActionType$8.ClearRecentlyCopiedStatus: {
2238
+ case ActionType$9.ClearRecentlyCopiedStatus: {
2253
2239
  return {
2254
2240
  recentlyCopied: false,
2255
2241
  };
@@ -2275,7 +2261,7 @@ const CopiableBox = (props) => {
2275
2261
  recentlyCopied: false,
2276
2262
  };
2277
2263
  // Initialize state
2278
- const [state, dispatch] = useReducer(reducer$9, initialState);
2264
+ const [state, dispatch] = useReducer(reducer$a, initialState);
2279
2265
  // Destructure common state
2280
2266
  const { recentlyCopied, } = state;
2281
2267
  /*------------------------------------------------------------------------*/
@@ -2295,13 +2281,13 @@ const CopiableBox = (props) => {
2295
2281
  }
2296
2282
  // Show copied notice
2297
2283
  dispatch({
2298
- type: ActionType$8.IndicateRecentlyCopied,
2284
+ type: ActionType$9.IndicateRecentlyCopied,
2299
2285
  });
2300
2286
  // Wait a moment
2301
2287
  yield waitMs(4000);
2302
2288
  // Hide copied notice
2303
2289
  dispatch({
2304
- type: ActionType$8.ClearRecentlyCopiedStatus,
2290
+ type: ActionType$9.ClearRecentlyCopiedStatus,
2305
2291
  });
2306
2292
  });
2307
2293
  /*------------------------------------------------------------------------*/
@@ -2357,20 +2343,20 @@ const CopiableBox = (props) => {
2357
2343
  */
2358
2344
  /* ------------- Actions ------------ */
2359
2345
  // Types of actions
2360
- var ActionType$7;
2346
+ var ActionType$8;
2361
2347
  (function (ActionType) {
2362
2348
  // Toggle whether a child are being shown
2363
2349
  ActionType["ToggleChild"] = "toggle-child";
2364
- })(ActionType$7 || (ActionType$7 = {}));
2350
+ })(ActionType$8 || (ActionType$8 = {}));
2365
2351
  /**
2366
2352
  * Reducer that executes actions
2367
2353
  * @author Gabe Abrams
2368
2354
  * @param state current state
2369
2355
  * @param action action to execute
2370
2356
  */
2371
- const reducer$8 = (state, action) => {
2357
+ const reducer$9 = (state, action) => {
2372
2358
  switch (action.type) {
2373
- case ActionType$7.ToggleChild: {
2359
+ case ActionType$8.ToggleChild: {
2374
2360
  return Object.assign(Object.assign({}, state), { childExpanded: Object.assign(Object.assign({}, state.childExpanded), { [String(action.id)]: !state.childExpanded[String(action.id)] }) });
2375
2361
  }
2376
2362
  default: {
@@ -2399,7 +2385,7 @@ const NestableItemList = (props) => {
2399
2385
  childExpanded: initChildExpanded,
2400
2386
  };
2401
2387
  // Initialize state
2402
- const [state, dispatch] = useReducer(reducer$8, initialState);
2388
+ const [state, dispatch] = useReducer(reducer$9, initialState);
2403
2389
  // Destructure common state
2404
2390
  const { childExpanded, } = state;
2405
2391
  /*------------------------------------------------------------------------*/
@@ -2489,7 +2475,7 @@ const NestableItemList = (props) => {
2489
2475
  backgroundColor: 'transparent',
2490
2476
  }, type: "button", onClick: () => {
2491
2477
  dispatch({
2492
- type: ActionType$7.ToggleChild,
2478
+ type: ActionType$8.ToggleChild,
2493
2479
  id: item.id,
2494
2480
  });
2495
2481
  }, "aria-label": `${childExpanded[item.id] ? 'Hide' : 'Show'} items in ${item.name}` },
@@ -2773,7 +2759,7 @@ var SortType;
2773
2759
  })(SortType || (SortType = {}));
2774
2760
  /* ------------- Actions ------------ */
2775
2761
  // Types of actions
2776
- var ActionType$6;
2762
+ var ActionType$7;
2777
2763
  (function (ActionType) {
2778
2764
  // Toggle sort column param
2779
2765
  ActionType["ToggleSortColumn"] = "toggle-sort-column";
@@ -2785,16 +2771,16 @@ var ActionType$6;
2785
2771
  ActionType["ShowAllColumns"] = "show-all-columns";
2786
2772
  // Hide all columns
2787
2773
  ActionType["HideAllColumns"] = "hide-all-columns";
2788
- })(ActionType$6 || (ActionType$6 = {}));
2774
+ })(ActionType$7 || (ActionType$7 = {}));
2789
2775
  /**
2790
2776
  * Reducer that executes actions
2791
2777
  * @author Gabe Abrams
2792
2778
  * @param state current state
2793
2779
  * @param action action to execute
2794
2780
  */
2795
- const reducer$7 = (state, action) => {
2781
+ const reducer$8 = (state, action) => {
2796
2782
  switch (action.type) {
2797
- case ActionType$6.ToggleSortColumn: {
2783
+ case ActionType$7.ToggleSortColumn: {
2798
2784
  if (action.param !== state.sortColumnParam) {
2799
2785
  // Different column param
2800
2786
  return Object.assign(Object.assign({}, state), { sortColumnParam: action.param, sortType: SortType.Ascending });
@@ -2806,22 +2792,22 @@ const reducer$7 = (state, action) => {
2806
2792
  // Stop sorting by column
2807
2793
  return Object.assign(Object.assign({}, state), { sortColumnParam: undefined, sortType: SortType.Ascending });
2808
2794
  }
2809
- case ActionType$6.UpdateColumnVisibility: {
2795
+ case ActionType$7.UpdateColumnVisibility: {
2810
2796
  const { columnVisibilityMap } = state;
2811
2797
  columnVisibilityMap[action.param] = action.visible;
2812
2798
  return Object.assign(Object.assign({}, state), { columnVisibilityMap });
2813
2799
  }
2814
- case ActionType$6.ToggleColVisCusModalVisibility: {
2800
+ case ActionType$7.ToggleColVisCusModalVisibility: {
2815
2801
  return Object.assign(Object.assign({}, state), { columnVisibilityCustomizationModalVisible: !state.columnVisibilityCustomizationModalVisible });
2816
2802
  }
2817
- case ActionType$6.ShowAllColumns: {
2803
+ case ActionType$7.ShowAllColumns: {
2818
2804
  const { columnVisibilityMap } = state;
2819
2805
  Object.keys(columnVisibilityMap).forEach((param) => {
2820
2806
  columnVisibilityMap[param] = true;
2821
2807
  });
2822
2808
  return Object.assign(Object.assign({}, state), { columnVisibilityMap });
2823
2809
  }
2824
- case ActionType$6.HideAllColumns: {
2810
+ case ActionType$7.HideAllColumns: {
2825
2811
  const { columnVisibilityMap } = state;
2826
2812
  Object.keys(columnVisibilityMap).forEach((param) => {
2827
2813
  columnVisibilityMap[param] = false;
@@ -2868,7 +2854,7 @@ const IntelliTable = (props) => {
2868
2854
  columnVisibilityCustomizationModalVisible: false,
2869
2855
  };
2870
2856
  // Initialize state
2871
- const [state, dispatch] = useReducer(reducer$7, initialState);
2857
+ const [state, dispatch] = useReducer(reducer$8, initialState);
2872
2858
  // Destructure common state
2873
2859
  const { sortColumnParam, sortType, columnVisibilityMap, columnVisibilityCustomizationModalVisible, } = state;
2874
2860
  /*------------------------------------------------------------------------*/
@@ -2891,13 +2877,13 @@ const IntelliTable = (props) => {
2891
2877
  return alert('Choose at least one column', 'To continue, you have to choose at least one column to show');
2892
2878
  }
2893
2879
  dispatch({
2894
- type: ActionType$6.ToggleColVisCusModalVisibility,
2880
+ type: ActionType$7.ToggleColVisCusModalVisibility,
2895
2881
  });
2896
2882
  }, okayVariant: Variant$1.Light },
2897
2883
  columns.map((column) => {
2898
2884
  return (React__default.createElement(CheckboxButton, { key: column.param, id: `IntelliTable-${id}-toggle-visibility-${column.param}`, className: "mb-2", text: column.title, onChanged: (checked) => {
2899
2885
  dispatch({
2900
- type: ActionType$6.UpdateColumnVisibility,
2886
+ type: ActionType$7.UpdateColumnVisibility,
2901
2887
  param: column.param,
2902
2888
  visible: checked,
2903
2889
  });
@@ -2906,12 +2892,12 @@ const IntelliTable = (props) => {
2906
2892
  React__default.createElement("div", { className: "mt-3" }, "Or you can:"),
2907
2893
  React__default.createElement("button", { type: "button", id: `IntelliTable-${id}-select-all-columns`, className: "btn btn-secondary me-2", "aria-label": `show all columns in the ${title} table`, onClick: () => {
2908
2894
  dispatch({
2909
- type: ActionType$6.ShowAllColumns,
2895
+ type: ActionType$7.ShowAllColumns,
2910
2896
  });
2911
2897
  } }, "Select All"),
2912
2898
  React__default.createElement("button", { type: "button", id: `IntelliTable-${id}-select-none-columns`, className: "btn btn-secondary", "aria-label": `hide all columns in the ${title} table`, onClick: () => {
2913
2899
  dispatch({
2914
- type: ActionType$6.HideAllColumns,
2900
+ type: ActionType$7.HideAllColumns,
2915
2901
  });
2916
2902
  } }, "Deselect All")));
2917
2903
  }
@@ -2962,7 +2948,7 @@ const IntelliTable = (props) => {
2962
2948
  React__default.createElement("div", null,
2963
2949
  React__default.createElement("button", { type: "button", id: `IntelliTable-${id}-sort-by-${column.param}-button`, className: `btn btn-${sortingByThisColumn ? 'light' : 'secondary'} btn-sm ms-1 ps-1 pe-1 pt-0 pb-0`, "aria-label": sortButtonAriaLabel, onClick: () => {
2964
2950
  dispatch({
2965
- type: ActionType$6.ToggleSortColumn,
2951
+ type: ActionType$7.ToggleSortColumn,
2966
2952
  param: column.param,
2967
2953
  });
2968
2954
  } },
@@ -3151,7 +3137,7 @@ const IntelliTable = (props) => {
3151
3137
  React__default.createElement(CSVDownloadButton, { "aria-label": `download data as csv for ${title}`, id: `IntelliTable-${id}-download-as-csv`, filename: filename, csv: csv }),
3152
3138
  React__default.createElement("button", { type: "button", className: "btn btn-secondary ms-2", "aria-label": `show panel for customizing which columns show in table ${title}`, id: `IntelliTable-${id}-show-column-customization-modal`, onClick: () => {
3153
3139
  dispatch({
3154
- type: ActionType$6.ToggleColVisCusModalVisibility,
3140
+ type: ActionType$7.ToggleColVisCusModalVisibility,
3155
3141
  });
3156
3142
  } },
3157
3143
  "Show/Hide Cols",
@@ -3517,7 +3503,7 @@ const genHumanReadableName = (machineReadableName) => {
3517
3503
  };
3518
3504
  /* ------------- Actions ------------ */
3519
3505
  // Types of actions
3520
- var ActionType$5;
3506
+ var ActionType$6;
3521
3507
  (function (ActionType) {
3522
3508
  // Show the loading bar
3523
3509
  ActionType["StartLoading"] = "start-loading";
@@ -3539,45 +3525,45 @@ var ActionType$5;
3539
3525
  ActionType["UpdateActionErrorFilterState"] = "update-action-error-filter-state";
3540
3526
  // Update the advanced filter state
3541
3527
  ActionType["UpdateAdvancedFilterState"] = "update-advanced-filter-state";
3542
- })(ActionType$5 || (ActionType$5 = {}));
3528
+ })(ActionType$6 || (ActionType$6 = {}));
3543
3529
  /**
3544
3530
  * Reducer that executes actions
3545
3531
  * @author Gabe Abrams
3546
3532
  * @param state current state
3547
3533
  * @param action action to execute
3548
3534
  */
3549
- const reducer$6 = (state, action) => {
3535
+ const reducer$7 = (state, action) => {
3550
3536
  switch (action.type) {
3551
- case ActionType$5.StartLoading: {
3537
+ case ActionType$6.StartLoading: {
3552
3538
  return Object.assign(Object.assign({}, state), { loading: true });
3553
3539
  }
3554
- case ActionType$5.FinishLoading: {
3540
+ case ActionType$6.FinishLoading: {
3555
3541
  return Object.assign(Object.assign({}, state), { loading: false, logMap: action.logMap });
3556
3542
  }
3557
- case ActionType$5.ToggleFilterDrawer: {
3543
+ case ActionType$6.ToggleFilterDrawer: {
3558
3544
  return Object.assign(Object.assign({}, state), { expandedFilterDrawer: (state.expandedFilterDrawer === action.filterDrawer
3559
3545
  ? undefined // hide
3560
3546
  : action.filterDrawer) });
3561
3547
  }
3562
- case ActionType$5.HideFilterDrawer: {
3548
+ case ActionType$6.HideFilterDrawer: {
3563
3549
  return Object.assign(Object.assign({}, state), { expandedFilterDrawer: undefined });
3564
3550
  }
3565
- case ActionType$5.ResetFilters: {
3551
+ case ActionType$6.ResetFilters: {
3566
3552
  return Object.assign(Object.assign({}, state), { dateFilterState: action.initDateFilterState, contextFilterState: action.initContextFilterState, tagFilterState: action.initTagFilterState, actionErrorFilterState: action.initActionErrorFilterState, advancedFilterState: action.initAdvancedFilterState });
3567
3553
  }
3568
- case ActionType$5.UpdateDateFilterState: {
3554
+ case ActionType$6.UpdateDateFilterState: {
3569
3555
  return Object.assign(Object.assign({}, state), { dateFilterState: action.dateFilterState });
3570
3556
  }
3571
- case ActionType$5.UpdateContextFilterState: {
3557
+ case ActionType$6.UpdateContextFilterState: {
3572
3558
  return Object.assign(Object.assign({}, state), { contextFilterState: action.contextFilterState });
3573
3559
  }
3574
- case ActionType$5.UpdateTagFilterState: {
3560
+ case ActionType$6.UpdateTagFilterState: {
3575
3561
  return Object.assign(Object.assign({}, state), { tagFilterState: action.tagFilterState });
3576
3562
  }
3577
- case ActionType$5.UpdateActionErrorFilterState: {
3563
+ case ActionType$6.UpdateActionErrorFilterState: {
3578
3564
  return Object.assign(Object.assign({}, state), { actionErrorFilterState: action.actionErrorFilterState });
3579
3565
  }
3580
- case ActionType$5.UpdateAdvancedFilterState: {
3566
+ case ActionType$6.UpdateAdvancedFilterState: {
3581
3567
  return Object.assign(Object.assign({}, state), { advancedFilterState: action.advancedFilterState });
3582
3568
  }
3583
3569
  default: {
@@ -3706,7 +3692,7 @@ const LogReviewer = (props) => {
3706
3692
  advancedFilterState: initAdvancedFilterState,
3707
3693
  };
3708
3694
  // Initialize state
3709
- const [state, dispatch] = useReducer(reducer$6, initialState);
3695
+ const [state, dispatch] = useReducer(reducer$7, initialState);
3710
3696
  // Destructure common state
3711
3697
  const { loading, logMap, expandedFilterDrawer, dateFilterState, contextFilterState, tagFilterState, actionErrorFilterState, advancedFilterState, } = state;
3712
3698
  /*------------------------------------------------------------------------*/
@@ -3756,7 +3742,7 @@ const LogReviewer = (props) => {
3756
3742
  const handleDateRangeUpdated = (newDateFilterState) => __awaiter(void 0, void 0, void 0, function* () {
3757
3743
  // Update state
3758
3744
  dispatch({
3759
- type: ActionType$5.UpdateDateFilterState,
3745
+ type: ActionType$6.UpdateDateFilterState,
3760
3746
  dateFilterState: newDateFilterState,
3761
3747
  });
3762
3748
  // Check which year/month combos we need to load
@@ -3767,7 +3753,7 @@ const LogReviewer = (props) => {
3767
3753
  }
3768
3754
  // Start loading
3769
3755
  dispatch({
3770
- type: ActionType$5.StartLoading,
3756
+ type: ActionType$6.StartLoading,
3771
3757
  });
3772
3758
  // Load required months
3773
3759
  try {
@@ -3791,7 +3777,7 @@ const LogReviewer = (props) => {
3791
3777
  }
3792
3778
  // Finish loading
3793
3779
  dispatch({
3794
- type: ActionType$5.FinishLoading,
3780
+ type: ActionType$6.FinishLoading,
3795
3781
  logMap,
3796
3782
  });
3797
3783
  });
@@ -3830,7 +3816,7 @@ const LogReviewer = (props) => {
3830
3816
  React__default.createElement("div", { className: "LogReviewer-filter-toggle-buttons alert alert-secondary p-2 m-0" },
3831
3817
  React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-date-filter-drawer", className: `btn btn-${FilterDrawer.Date === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle date filter drawer", onClick: () => {
3832
3818
  dispatch({
3833
- type: ActionType$5.ToggleFilterDrawer,
3819
+ type: ActionType$6.ToggleFilterDrawer,
3834
3820
  filterDrawer: FilterDrawer.Date,
3835
3821
  });
3836
3822
  } },
@@ -3838,7 +3824,7 @@ const LogReviewer = (props) => {
3838
3824
  "Date"),
3839
3825
  React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-context-filter-drawer", className: `btn btn-${FilterDrawer.Context === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle context filter drawer", onClick: () => {
3840
3826
  dispatch({
3841
- type: ActionType$5.ToggleFilterDrawer,
3827
+ type: ActionType$6.ToggleFilterDrawer,
3842
3828
  filterDrawer: FilterDrawer.Context,
3843
3829
  });
3844
3830
  } },
@@ -3846,7 +3832,7 @@ const LogReviewer = (props) => {
3846
3832
  "Context"),
3847
3833
  (LogMetadata.Tag && Object.keys(LogMetadata.Tag).length > 0) && (React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-tag-filter-drawer", className: `btn btn-${FilterDrawer.Tag === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle tag filter drawer", onClick: () => {
3848
3834
  dispatch({
3849
- type: ActionType$5.ToggleFilterDrawer,
3835
+ type: ActionType$6.ToggleFilterDrawer,
3850
3836
  filterDrawer: FilterDrawer.Tag,
3851
3837
  });
3852
3838
  } },
@@ -3854,7 +3840,7 @@ const LogReviewer = (props) => {
3854
3840
  "Tag")),
3855
3841
  React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-action-filter-drawer", className: `btn btn-${FilterDrawer.Action === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle action and error filter drawer", onClick: () => {
3856
3842
  dispatch({
3857
- type: ActionType$5.ToggleFilterDrawer,
3843
+ type: ActionType$6.ToggleFilterDrawer,
3858
3844
  filterDrawer: FilterDrawer.Action,
3859
3845
  });
3860
3846
  } },
@@ -3862,7 +3848,7 @@ const LogReviewer = (props) => {
3862
3848
  "Action"),
3863
3849
  React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-advanced-filter-drawer", className: `btn btn-${FilterDrawer.Advanced === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle advanced filter drawer", onClick: () => {
3864
3850
  dispatch({
3865
- type: ActionType$5.ToggleFilterDrawer,
3851
+ type: ActionType$6.ToggleFilterDrawer,
3866
3852
  filterDrawer: FilterDrawer.Advanced,
3867
3853
  });
3868
3854
  } },
@@ -3870,7 +3856,7 @@ const LogReviewer = (props) => {
3870
3856
  "Advanced"),
3871
3857
  React__default.createElement("button", { type: "button", id: "LogReviewer-reset-filters-button", className: "btn btn-light", "aria-label": "reset filters", onClick: () => {
3872
3858
  dispatch({
3873
- type: ActionType$5.ResetFilters,
3859
+ type: ActionType$6.ResetFilters,
3874
3860
  initActionErrorFilterState,
3875
3861
  initAdvancedFilterState,
3876
3862
  initContextFilterState,
@@ -3992,7 +3978,7 @@ const LogReviewer = (props) => {
3992
3978
  }
3993
3979
  });
3994
3980
  dispatch({
3995
- type: ActionType$5.UpdateContextFilterState,
3981
+ type: ActionType$6.UpdateContextFilterState,
3996
3982
  contextFilterState,
3997
3983
  });
3998
3984
  } }));
@@ -4007,7 +3993,7 @@ const LogReviewer = (props) => {
4007
3993
  return (React__default.createElement(CheckboxButton, { key: tag, id: `LogReviewer-tag-${tag}-checkbox`, text: description, ariaLabel: `require that logs be tagged with "${description}" or any other selected tag`, checked: tagFilterState[tag], onChanged: (checked) => {
4008
3994
  tagFilterState[tag] = checked;
4009
3995
  dispatch({
4010
- type: ActionType$5.UpdateTagFilterState,
3996
+ type: ActionType$6.UpdateTagFilterState,
4011
3997
  tagFilterState,
4012
3998
  });
4013
3999
  } }));
@@ -4020,21 +4006,21 @@ const LogReviewer = (props) => {
4020
4006
  React__default.createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
4021
4007
  actionErrorFilterState.type = undefined;
4022
4008
  dispatch({
4023
- type: ActionType$5.UpdateActionErrorFilterState,
4009
+ type: ActionType$6.UpdateActionErrorFilterState,
4024
4010
  actionErrorFilterState,
4025
4011
  });
4026
4012
  }, ariaLabel: "show logs of all types", selected: actionErrorFilterState.type === undefined }),
4027
4013
  React__default.createElement(RadioButton, { id: "LogReviewer-type-action-only", text: "Action Logs Only", onSelected: () => {
4028
4014
  actionErrorFilterState.type = LogType$1.Action;
4029
4015
  dispatch({
4030
- type: ActionType$5.UpdateActionErrorFilterState,
4016
+ type: ActionType$6.UpdateActionErrorFilterState,
4031
4017
  actionErrorFilterState,
4032
4018
  });
4033
4019
  }, ariaLabel: "only show action logs", selected: actionErrorFilterState.type === LogType$1.Action }),
4034
4020
  React__default.createElement(RadioButton, { id: "LogReviewer-type-error-only", text: "Action Error Only", onSelected: () => {
4035
4021
  actionErrorFilterState.type = LogType$1.Error;
4036
4022
  dispatch({
4037
- type: ActionType$5.UpdateActionErrorFilterState,
4023
+ type: ActionType$6.UpdateActionErrorFilterState,
4038
4024
  actionErrorFilterState,
4039
4025
  });
4040
4026
  }, ariaLabel: "only show error logs", selected: actionErrorFilterState.type === LogType$1.Error, noMarginOnRight: true })),
@@ -4046,7 +4032,7 @@ const LogReviewer = (props) => {
4046
4032
  return (React__default.createElement(CheckboxButton, { key: action, id: `LogReviewer-action-${action}-checkbox`, text: description, ariaLabel: `include logs with action type "${description}" in results`, noMarginOnRight: true, checked: actionErrorFilterState.action[action], onChanged: (checked) => {
4047
4033
  actionErrorFilterState.action[action] = checked;
4048
4034
  dispatch({
4049
- type: ActionType$5.UpdateActionErrorFilterState,
4035
+ type: ActionType$6.UpdateActionErrorFilterState,
4050
4036
  actionErrorFilterState,
4051
4037
  });
4052
4038
  } }));
@@ -4057,7 +4043,7 @@ const LogReviewer = (props) => {
4057
4043
  return (React__default.createElement(CheckboxButton, { key: target, id: `LogReviewer-target-${target}-checkbox`, text: description, ariaLabel: `include logs with target "${description}" in results`, checked: actionErrorFilterState.target[target], noMarginOnRight: true, onChanged: (checked) => {
4058
4044
  actionErrorFilterState.target[target] = checked;
4059
4045
  dispatch({
4060
- type: ActionType$5.UpdateActionErrorFilterState,
4046
+ type: ActionType$6.UpdateActionErrorFilterState,
4061
4047
  actionErrorFilterState,
4062
4048
  });
4063
4049
  } }));
@@ -4069,7 +4055,7 @@ const LogReviewer = (props) => {
4069
4055
  React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for error message", value: actionErrorFilterState.errorMessage, placeholder: "e.g. undefined is not a function", onChange: (e) => {
4070
4056
  actionErrorFilterState.errorMessage = e.target.value;
4071
4057
  dispatch({
4072
- type: ActionType$5.UpdateActionErrorFilterState,
4058
+ type: ActionType$6.UpdateActionErrorFilterState,
4073
4059
  actionErrorFilterState,
4074
4060
  });
4075
4061
  } })),
@@ -4080,7 +4066,7 @@ const LogReviewer = (props) => {
4080
4066
  .trim()
4081
4067
  .toUpperCase());
4082
4068
  dispatch({
4083
- type: ActionType$5.UpdateActionErrorFilterState,
4069
+ type: ActionType$6.UpdateActionErrorFilterState,
4084
4070
  actionErrorFilterState,
4085
4071
  });
4086
4072
  } }))))));
@@ -4094,7 +4080,7 @@ const LogReviewer = (props) => {
4094
4080
  React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user first name", value: advancedFilterState.userFirstName, placeholder: "e.g. Divardo", onChange: (e) => {
4095
4081
  advancedFilterState.userFirstName = e.target.value;
4096
4082
  dispatch({
4097
- type: ActionType$5.UpdateAdvancedFilterState,
4083
+ type: ActionType$6.UpdateAdvancedFilterState,
4098
4084
  advancedFilterState,
4099
4085
  });
4100
4086
  } })),
@@ -4103,7 +4089,7 @@ const LogReviewer = (props) => {
4103
4089
  React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user last name", value: advancedFilterState.userLastName, placeholder: "e.g. Calicci", onChange: (e) => {
4104
4090
  advancedFilterState.userLastName = e.target.value;
4105
4091
  dispatch({
4106
- type: ActionType$5.UpdateAdvancedFilterState,
4092
+ type: ActionType$6.UpdateAdvancedFilterState,
4107
4093
  advancedFilterState,
4108
4094
  });
4109
4095
  } })),
@@ -4113,7 +4099,7 @@ const LogReviewer = (props) => {
4113
4099
  advancedFilterState.userEmail = ((e.target.value)
4114
4100
  .trim());
4115
4101
  dispatch({
4116
- type: ActionType$5.UpdateAdvancedFilterState,
4102
+ type: ActionType$6.UpdateAdvancedFilterState,
4117
4103
  advancedFilterState,
4118
4104
  });
4119
4105
  } })),
@@ -4127,7 +4113,7 @@ const LogReviewer = (props) => {
4127
4113
  .trim());
4128
4114
  }
4129
4115
  dispatch({
4130
- type: ActionType$5.UpdateAdvancedFilterState,
4116
+ type: ActionType$6.UpdateAdvancedFilterState,
4131
4117
  advancedFilterState,
4132
4118
  });
4133
4119
  } })),
@@ -4135,21 +4121,21 @@ const LogReviewer = (props) => {
4135
4121
  React__default.createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
4136
4122
  advancedFilterState.includeLearners = checked;
4137
4123
  dispatch({
4138
- type: ActionType$5.UpdateAdvancedFilterState,
4124
+ type: ActionType$6.UpdateAdvancedFilterState,
4139
4125
  advancedFilterState,
4140
4126
  });
4141
4127
  }, checked: advancedFilterState.includeLearners, ariaLabel: "show logs from students" }),
4142
4128
  React__default.createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
4143
4129
  advancedFilterState.includeTTMs = checked;
4144
4130
  dispatch({
4145
- type: ActionType$5.UpdateAdvancedFilterState,
4131
+ type: ActionType$6.UpdateAdvancedFilterState,
4146
4132
  advancedFilterState,
4147
4133
  });
4148
4134
  }, checked: advancedFilterState.includeTTMs, ariaLabel: "show logs from teaching team members" }),
4149
4135
  React__default.createElement(CheckboxButton, { text: "Admins", onChanged: (checked) => {
4150
4136
  advancedFilterState.includeAdmins = checked;
4151
4137
  dispatch({
4152
- type: ActionType$5.UpdateAdvancedFilterState,
4138
+ type: ActionType$6.UpdateAdvancedFilterState,
4153
4139
  advancedFilterState,
4154
4140
  });
4155
4141
  }, checked: advancedFilterState.includeAdmins, ariaLabel: "show logs from admins" }))),
@@ -4159,7 +4145,7 @@ const LogReviewer = (props) => {
4159
4145
  React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for course name", value: advancedFilterState.courseName, placeholder: "e.g. GLC 200", onChange: (e) => {
4160
4146
  advancedFilterState.courseName = e.target.value;
4161
4147
  dispatch({
4162
- type: ActionType$5.UpdateAdvancedFilterState,
4148
+ type: ActionType$6.UpdateAdvancedFilterState,
4163
4149
  advancedFilterState,
4164
4150
  });
4165
4151
  } })),
@@ -4173,7 +4159,7 @@ const LogReviewer = (props) => {
4173
4159
  .trim());
4174
4160
  }
4175
4161
  dispatch({
4176
- type: ActionType$5.UpdateAdvancedFilterState,
4162
+ type: ActionType$6.UpdateAdvancedFilterState,
4177
4163
  advancedFilterState,
4178
4164
  });
4179
4165
  } }))),
@@ -4182,21 +4168,21 @@ const LogReviewer = (props) => {
4182
4168
  React__default.createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: advancedFilterState.isMobile === undefined, onSelected: () => {
4183
4169
  advancedFilterState.isMobile = undefined;
4184
4170
  dispatch({
4185
- type: ActionType$5.UpdateAdvancedFilterState,
4171
+ type: ActionType$6.UpdateAdvancedFilterState,
4186
4172
  advancedFilterState,
4187
4173
  });
4188
4174
  } }),
4189
4175
  React__default.createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: advancedFilterState.isMobile === true, onSelected: () => {
4190
4176
  advancedFilterState.isMobile = true;
4191
4177
  dispatch({
4192
- type: ActionType$5.UpdateAdvancedFilterState,
4178
+ type: ActionType$6.UpdateAdvancedFilterState,
4193
4179
  advancedFilterState,
4194
4180
  });
4195
4181
  } }),
4196
4182
  React__default.createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: advancedFilterState.isMobile === false, onSelected: () => {
4197
4183
  advancedFilterState.isMobile = false;
4198
4184
  dispatch({
4199
- type: ActionType$5.UpdateAdvancedFilterState,
4185
+ type: ActionType$6.UpdateAdvancedFilterState,
4200
4186
  advancedFilterState,
4201
4187
  });
4202
4188
  }, noMarginOnRight: true }))),
@@ -4205,21 +4191,21 @@ const LogReviewer = (props) => {
4205
4191
  React__default.createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: advancedFilterState.source === undefined, onSelected: () => {
4206
4192
  advancedFilterState.source = undefined;
4207
4193
  dispatch({
4208
- type: ActionType$5.UpdateAdvancedFilterState,
4194
+ type: ActionType$6.UpdateAdvancedFilterState,
4209
4195
  advancedFilterState,
4210
4196
  });
4211
4197
  } }),
4212
4198
  React__default.createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: advancedFilterState.source === LogSource$1.Client, onSelected: () => {
4213
4199
  advancedFilterState.source = LogSource$1.Client;
4214
4200
  dispatch({
4215
- type: ActionType$5.UpdateAdvancedFilterState,
4201
+ type: ActionType$6.UpdateAdvancedFilterState,
4216
4202
  advancedFilterState,
4217
4203
  });
4218
4204
  } }),
4219
4205
  React__default.createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: advancedFilterState.source === LogSource$1.Server, onSelected: () => {
4220
4206
  advancedFilterState.source = LogSource$1.Server;
4221
4207
  dispatch({
4222
- type: ActionType$5.UpdateAdvancedFilterState,
4208
+ type: ActionType$6.UpdateAdvancedFilterState,
4223
4209
  advancedFilterState,
4224
4210
  });
4225
4211
  }, noMarginOnRight: true })),
@@ -4230,7 +4216,7 @@ const LogReviewer = (props) => {
4230
4216
  advancedFilterState.courseName = ((e.target.value)
4231
4217
  .trim());
4232
4218
  dispatch({
4233
- type: ActionType$5.UpdateAdvancedFilterState,
4219
+ type: ActionType$6.UpdateAdvancedFilterState,
4234
4220
  advancedFilterState,
4235
4221
  });
4236
4222
  } })),
@@ -4240,7 +4226,7 @@ const LogReviewer = (props) => {
4240
4226
  advancedFilterState.courseName = ((e.target.value)
4241
4227
  .trim());
4242
4228
  dispatch({
4243
- type: ActionType$5.UpdateAdvancedFilterState,
4229
+ type: ActionType$6.UpdateAdvancedFilterState,
4244
4230
  advancedFilterState,
4245
4231
  });
4246
4232
  } })))))));
@@ -12060,11 +12046,11 @@ var CreatableSelect$1 = CreatableSelect;
12060
12046
  */
12061
12047
  /* ------------- Actions ------------ */
12062
12048
  // Types of actions
12063
- var ActionType$4;
12049
+ var ActionType$5;
12064
12050
  (function (ActionType) {
12065
12051
  // Update the input value
12066
12052
  ActionType["SetInputValue"] = "SetInputValue";
12067
- })(ActionType$4 || (ActionType$4 = {}));
12053
+ })(ActionType$5 || (ActionType$5 = {}));
12068
12054
  /**
12069
12055
  * Reducer that executes actions
12070
12056
  * @author Yuen Ler Chow
@@ -12072,9 +12058,9 @@ var ActionType$4;
12072
12058
  * @param action action to execute
12073
12059
  * @returns updated state
12074
12060
  */
12075
- const reducer$5 = (state, action) => {
12061
+ const reducer$6 = (state, action) => {
12076
12062
  switch (action.type) {
12077
- case ActionType$4.SetInputValue: {
12063
+ case ActionType$5.SetInputValue: {
12078
12064
  return Object.assign(Object.assign({}, state), { inputValue: action.value });
12079
12065
  }
12080
12066
  default: {
@@ -12094,7 +12080,7 @@ const CreatableMultiselect = (props) => {
12094
12080
  inputValue: '',
12095
12081
  };
12096
12082
  // Initialize state
12097
- const [state, dispatch] = useReducer(reducer$5, initialState);
12083
+ const [state, dispatch] = useReducer(reducer$6, initialState);
12098
12084
  // Destructure common state
12099
12085
  const { inputValue } = state;
12100
12086
  /*------------------------------------------------------------------------*/
@@ -12171,7 +12157,7 @@ const CreatableMultiselect = (props) => {
12171
12157
  }
12172
12158
  // Reset text field to empty because the values have been added
12173
12159
  dispatch({
12174
- type: ActionType$4.SetInputValue,
12160
+ type: ActionType$5.SetInputValue,
12175
12161
  value: '',
12176
12162
  });
12177
12163
  };
@@ -12210,7 +12196,7 @@ const CreatableMultiselect = (props) => {
12210
12196
  else {
12211
12197
  // simply update the input value to the new input value
12212
12198
  dispatch({
12213
- type: ActionType$4.SetInputValue,
12199
+ type: ActionType$5.SetInputValue,
12214
12200
  value: newValue,
12215
12201
  });
12216
12202
  }
@@ -12262,13 +12248,13 @@ const style$1 = `
12262
12248
  `;
12263
12249
  /* ------------- Actions ------------ */
12264
12250
  // Types of actions
12265
- var ActionType$3;
12251
+ var ActionType$4;
12266
12252
  (function (ActionType) {
12267
12253
  // Update the DBEntry
12268
12254
  ActionType["UpdateDBEntry"] = "UpdateDBEntry";
12269
12255
  // Start the save spinner
12270
12256
  ActionType["StartSave"] = "StartSave";
12271
- })(ActionType$3 || (ActionType$3 = {}));
12257
+ })(ActionType$4 || (ActionType$4 = {}));
12272
12258
  /**
12273
12259
  * Reducer that executes actions
12274
12260
  * @author Yuen Ler Chow
@@ -12276,12 +12262,12 @@ var ActionType$3;
12276
12262
  * @param action action to execute
12277
12263
  * @returns updated state
12278
12264
  */
12279
- const reducer$4 = (state, action) => {
12265
+ const reducer$5 = (state, action) => {
12280
12266
  switch (action.type) {
12281
- case ActionType$3.UpdateDBEntry: {
12267
+ case ActionType$4.UpdateDBEntry: {
12282
12268
  return Object.assign(Object.assign({}, state), { entry: action.dbEntry });
12283
12269
  }
12284
- case ActionType$3.StartSave: {
12270
+ case ActionType$4.StartSave: {
12285
12271
  return Object.assign(Object.assign({}, state), { saving: true });
12286
12272
  }
12287
12273
  default: {
@@ -12306,7 +12292,7 @@ const AddOrEditDBEntry = (props) => {
12306
12292
  saving: false,
12307
12293
  };
12308
12294
  // Initialize state
12309
- const [state, dispatch] = useReducer(reducer$4, initialState);
12295
+ const [state, dispatch] = useReducer(reducer$5, initialState);
12310
12296
  // Destructure common state
12311
12297
  const { entry, saving, } = state;
12312
12298
  /*------------------------------------------------------------------------*/
@@ -12318,7 +12304,7 @@ const AddOrEditDBEntry = (props) => {
12318
12304
  */
12319
12305
  const save = () => __awaiter(void 0, void 0, void 0, function* () {
12320
12306
  // Start the save loading indicator
12321
- dispatch({ type: ActionType$3.StartSave });
12307
+ dispatch({ type: ActionType$4.StartSave });
12322
12308
  // add all default values to the entry
12323
12309
  entryFields.forEach((field) => {
12324
12310
  if (field.defaultValue && !entry[field.objectKey]) {
@@ -12501,7 +12487,7 @@ const AddOrEditDBEntry = (props) => {
12501
12487
  return (React__default.createElement(RadioButton, { key: choice.value, text: choice.title, selected: entry[field.objectKey] === choice.value, onSelected: () => {
12502
12488
  entry[field.objectKey] = choice.value;
12503
12489
  dispatch({
12504
- type: ActionType$3.UpdateDBEntry,
12490
+ type: ActionType$4.UpdateDBEntry,
12505
12491
  dbEntry: entry,
12506
12492
  });
12507
12493
  }, ariaLabel: choice.title }));
@@ -12513,7 +12499,7 @@ const AddOrEditDBEntry = (props) => {
12513
12499
  React__default.createElement("input", { disabled: disabled, type: "text", className: "form-control", placeholder: field.placeholder, "aria-describedby": "AddOrEditDBEntry-form-name-label", value: entry[field.objectKey] || '', onChange: (e) => {
12514
12500
  entry[field.objectKey] = (e.target.value);
12515
12501
  dispatch({
12516
- type: ActionType$3.UpdateDBEntry,
12502
+ type: ActionType$4.UpdateDBEntry,
12517
12503
  dbEntry: entry,
12518
12504
  });
12519
12505
  } }))));
@@ -12526,7 +12512,7 @@ const AddOrEditDBEntry = (props) => {
12526
12512
  entry[field.objectKey] = (e.target.value
12527
12513
  .replace(/[^0-9]/g, ''));
12528
12514
  dispatch({
12529
- type: ActionType$3.UpdateDBEntry,
12515
+ type: ActionType$4.UpdateDBEntry,
12530
12516
  dbEntry: entry,
12531
12517
  });
12532
12518
  } }))));
@@ -12556,7 +12542,7 @@ const AddOrEditDBEntry = (props) => {
12556
12542
  }
12557
12543
  // Save
12558
12544
  dispatch({
12559
- type: ActionType$3.UpdateDBEntry,
12545
+ type: ActionType$4.UpdateDBEntry,
12560
12546
  dbEntry: entry,
12561
12547
  });
12562
12548
  }, ariaLabel: choice.title }));
@@ -12571,7 +12557,7 @@ const AddOrEditDBEntry = (props) => {
12571
12557
  // Update entry and save
12572
12558
  entry[field.objectKey] = values;
12573
12559
  dispatch({
12574
- type: ActionType$3.UpdateDBEntry,
12560
+ type: ActionType$4.UpdateDBEntry,
12575
12561
  dbEntry: entry,
12576
12562
  });
12577
12563
  } })))));
@@ -12584,7 +12570,7 @@ const AddOrEditDBEntry = (props) => {
12584
12570
  React__default.createElement(CreatableMultiselect, { disabled: disabled, type: DBEntryFieldType$1.NumberArray, values: entry[field.objectKey] || [], onChange: (values) => {
12585
12571
  entry[field.objectKey] = values;
12586
12572
  dispatch({
12587
- type: ActionType$3.UpdateDBEntry,
12573
+ type: ActionType$4.UpdateDBEntry,
12588
12574
  dbEntry: entry,
12589
12575
  });
12590
12576
  } })))));
@@ -12658,7 +12644,7 @@ const generateEndpointPath = (collectionName, adminsOnly) => {
12658
12644
  */
12659
12645
  /* ------------- Actions ------------ */
12660
12646
  // Types of actions
12661
- var ActionType$2;
12647
+ var ActionType$3;
12662
12648
  (function (ActionType) {
12663
12649
  // Show adder
12664
12650
  ActionType["ShowAdder"] = "ShowAdder";
@@ -12672,7 +12658,7 @@ var ActionType$2;
12672
12658
  ActionType["StartDelete"] = "StartDelete";
12673
12659
  // Finish deletion process
12674
12660
  ActionType["FinishDelete"] = "FinishDelete";
12675
- })(ActionType$2 || (ActionType$2 = {}));
12661
+ })(ActionType$3 || (ActionType$3 = {}));
12676
12662
  /**
12677
12663
  * Reducer that executes actions
12678
12664
  * @author Yuen Ler Chow
@@ -12680,18 +12666,18 @@ var ActionType$2;
12680
12666
  * @param action action to execute
12681
12667
  * @returns updated state
12682
12668
  */
12683
- const reducer$3 = (state, action) => {
12669
+ const reducer$4 = (state, action) => {
12684
12670
  switch (action.type) {
12685
- case ActionType$2.FinishLoading: {
12671
+ case ActionType$3.FinishLoading: {
12686
12672
  return Object.assign(Object.assign({}, state), { loading: false, dbEntries: action.dbEntries });
12687
12673
  }
12688
- case ActionType$2.ShowAdder: {
12674
+ case ActionType$3.ShowAdder: {
12689
12675
  return Object.assign(Object.assign({}, state), { adding: true, dbEntryToEdit: undefined });
12690
12676
  }
12691
- case ActionType$2.ShowEditor: {
12677
+ case ActionType$3.ShowEditor: {
12692
12678
  return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: action.dbEntry });
12693
12679
  }
12694
- case ActionType$2.FinishAdd: {
12680
+ case ActionType$3.FinishAdd: {
12695
12681
  // Handle cancel
12696
12682
  const finishedEntry = action.dbEntry;
12697
12683
  if (!finishedEntry) {
@@ -12715,10 +12701,10 @@ const reducer$3 = (state, action) => {
12715
12701
  // Update the state
12716
12702
  return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: undefined, dbEntries: updatedDbEntries });
12717
12703
  }
12718
- case ActionType$2.StartDelete: {
12704
+ case ActionType$3.StartDelete: {
12719
12705
  return Object.assign(Object.assign({}, state), { loading: true });
12720
12706
  }
12721
- case ActionType$2.FinishDelete: {
12707
+ case ActionType$3.FinishDelete: {
12722
12708
  return Object.assign(Object.assign({}, state), { loading: false,
12723
12709
  // Remove the deleted entry from the list
12724
12710
  dbEntries: state.dbEntries.filter((entry) => {
@@ -12744,7 +12730,7 @@ const DBEntryManagerPanel = (props) => {
12744
12730
  loading: true,
12745
12731
  };
12746
12732
  // Initialize state
12747
- const [state, dispatch] = useReducer(reducer$3, initialState);
12733
+ const [state, dispatch] = useReducer(reducer$4, initialState);
12748
12734
  // Destructure common state
12749
12735
  const { adding, dbEntryToEdit, dbEntries, loading, } = state;
12750
12736
  /*------------------------------------------------------------------------*/
@@ -12770,7 +12756,7 @@ const DBEntryManagerPanel = (props) => {
12770
12756
  try {
12771
12757
  // Start loader
12772
12758
  dispatch({
12773
- type: ActionType$2.StartDelete,
12759
+ type: ActionType$3.StartDelete,
12774
12760
  });
12775
12761
  // Perform deletion
12776
12762
  yield visitServerEndpoint({
@@ -12779,7 +12765,7 @@ const DBEntryManagerPanel = (props) => {
12779
12765
  });
12780
12766
  // Finish loader
12781
12767
  dispatch({
12782
- type: ActionType$2.FinishDelete,
12768
+ type: ActionType$3.FinishDelete,
12783
12769
  dbEntry: entry,
12784
12770
  idPropName,
12785
12771
  });
@@ -12808,7 +12794,7 @@ const DBEntryManagerPanel = (props) => {
12808
12794
  });
12809
12795
  // Save loaded data
12810
12796
  dispatch({
12811
- type: ActionType$2.FinishLoading,
12797
+ type: ActionType$3.FinishLoading,
12812
12798
  dbEntries: data,
12813
12799
  });
12814
12800
  }
@@ -12851,7 +12837,7 @@ const DBEntryManagerPanel = (props) => {
12851
12837
  React__default.createElement("span", { className: "d-none d-md-inline ms-1" }, "Remove")),
12852
12838
  !disableEdit && (React__default.createElement("button", { type: "button", id: `DBEntryManagerPanel-edit-with-id-${entry[idPropName]}`, className: "btn btn-primary", "aria-label": `edit db entry: ${entry[titlePropName]}`, onClick: () => {
12853
12839
  dispatch({
12854
- type: ActionType$2.ShowEditor,
12840
+ type: ActionType$3.ShowEditor,
12855
12841
  dbEntry: entry,
12856
12842
  });
12857
12843
  } },
@@ -12861,7 +12847,7 @@ const DBEntryManagerPanel = (props) => {
12861
12847
  React__default.createElement("div", { className: "d-grid" },
12862
12848
  React__default.createElement("button", { type: "button", id: "DBEntryManagerPanel-add-entry", className: "btn btn-lg btn-primary", "aria-label": `add a new ${itemName} entry to the list of entries`, onClick: () => {
12863
12849
  dispatch({
12864
- type: ActionType$2.ShowAdder,
12850
+ type: ActionType$3.ShowAdder,
12865
12851
  });
12866
12852
  } },
12867
12853
  React__default.createElement(FontAwesomeIcon, { icon: faPlus, className: "me-2" }),
@@ -12873,7 +12859,7 @@ const DBEntryManagerPanel = (props) => {
12873
12859
  if (!loading && (adding || dbEntryToEdit)) {
12874
12860
  body = (React__default.createElement(AddOrEditDBEntry, { saveEndpointPath: endpoint, validateEntry: validateEntry, modifyEntry: modifyEntry, entryFields: entryFields, dbEntryToEdit: dbEntryToEdit, idPropName: idPropName, entries: dbEntries, itemName: itemName, onFinished: (entry) => {
12875
12861
  dispatch({
12876
- type: ActionType$2.FinishAdd,
12862
+ type: ActionType$3.FinishAdd,
12877
12863
  dbEntry: entry,
12878
12864
  idPropName,
12879
12865
  });
@@ -13070,25 +13056,25 @@ const getItemIds = (items) => {
13070
13056
  };
13071
13057
  /* ------------- Actions ------------ */
13072
13058
  // Types of actions
13073
- var ActionType$1;
13059
+ var ActionType$2;
13074
13060
  (function (ActionType) {
13075
13061
  // Hide the "jump to bottom" button
13076
13062
  ActionType["HideJumpToBottomButton"] = "HideJumpToBottomButton";
13077
13063
  // Show the "jump to bottom" button
13078
13064
  ActionType["ShowJumpToBottomButton"] = "ShowJumpToBottomButton";
13079
- })(ActionType$1 || (ActionType$1 = {}));
13065
+ })(ActionType$2 || (ActionType$2 = {}));
13080
13066
  /**
13081
13067
  * Reducer that executes actions
13082
13068
  * @author Gabe Abrams
13083
13069
  * @param state current state
13084
13070
  * @param action action to execute
13085
13071
  */
13086
- const reducer$2 = (state, action) => {
13072
+ const reducer$3 = (state, action) => {
13087
13073
  switch (action.type) {
13088
- case ActionType$1.HideJumpToBottomButton: {
13074
+ case ActionType$2.HideJumpToBottomButton: {
13089
13075
  return Object.assign(Object.assign({}, state), { jumpToBottomButtonVisible: false });
13090
13076
  }
13091
- case ActionType$1.ShowJumpToBottomButton: {
13077
+ case ActionType$2.ShowJumpToBottomButton: {
13092
13078
  return Object.assign(Object.assign({}, state), { jumpToBottomButtonVisible: true });
13093
13079
  }
13094
13080
  default: {
@@ -13112,7 +13098,7 @@ const AutoscrollToBottomContainer = (props) => {
13112
13098
  jumpToBottomButtonVisible: false,
13113
13099
  };
13114
13100
  // Initialize state
13115
- const [state, dispatch] = useReducer(reducer$2, initialState);
13101
+ const [state, dispatch] = useReducer(reducer$3, initialState);
13116
13102
  // Destructure common state
13117
13103
  const { jumpToBottomButtonVisible, } = state;
13118
13104
  /* -------------- Refs -------------- */
@@ -13158,7 +13144,7 @@ const AutoscrollToBottomContainer = (props) => {
13158
13144
  }
13159
13145
  // Update state
13160
13146
  dispatch({
13161
- type: ActionType$1.HideJumpToBottomButton,
13147
+ type: ActionType$2.HideJumpToBottomButton,
13162
13148
  });
13163
13149
  // Scroll to bottom
13164
13150
  container.current.scrollTop = (container.current.scrollHeight
@@ -13182,7 +13168,7 @@ const AutoscrollToBottomContainer = (props) => {
13182
13168
  if (isScrolledToBottom()) {
13183
13169
  // Hide button
13184
13170
  dispatch({
13185
- type: ActionType$1.HideJumpToBottomButton,
13171
+ type: ActionType$2.HideJumpToBottomButton,
13186
13172
  });
13187
13173
  }
13188
13174
  };
@@ -13224,7 +13210,7 @@ const AutoscrollToBottomContainer = (props) => {
13224
13210
  else {
13225
13211
  // Not scrolled to bottom. Show "jump to bottom" button.
13226
13212
  dispatch({
13227
- type: ActionType$1.ShowJumpToBottomButton,
13213
+ type: ActionType$2.ShowJumpToBottomButton,
13228
13214
  });
13229
13215
  }
13230
13216
  }, [items]);
@@ -13294,25 +13280,25 @@ const combineClassNames = (classNames) => {
13294
13280
  */
13295
13281
  /* ------------- Actions ------------ */
13296
13282
  // Types of actions
13297
- var ActionType;
13283
+ var ActionType$1;
13298
13284
  (function (ActionType) {
13299
13285
  // Start hovering on an option
13300
13286
  ActionType["StartHover"] = "StartHover";
13301
13287
  // Stop hovering on an option
13302
13288
  ActionType["StopHover"] = "StopHover";
13303
- })(ActionType || (ActionType = {}));
13289
+ })(ActionType$1 || (ActionType$1 = {}));
13304
13290
  /**
13305
13291
  * Reducer that executes actions
13306
13292
  * @author Gabe Abrams
13307
13293
  * @param state current state
13308
13294
  * @param action action to execute
13309
13295
  */
13310
- const reducer$1 = (state, action) => {
13296
+ const reducer$2 = (state, action) => {
13311
13297
  switch (action.type) {
13312
- case ActionType.StartHover: {
13298
+ case ActionType$1.StartHover: {
13313
13299
  return Object.assign(Object.assign({}, state), { hoveredOptionId: action.hoveredOptionId });
13314
13300
  }
13315
- case ActionType.StopHover: {
13301
+ case ActionType$1.StopHover: {
13316
13302
  return Object.assign(Object.assign({}, state), { hoveredOptionId: undefined });
13317
13303
  }
13318
13304
  default: {
@@ -13336,7 +13322,7 @@ const MultiSwitch = (props) => {
13336
13322
  hoveredOptionId: undefined,
13337
13323
  };
13338
13324
  // Initialize state
13339
- const [state, dispatch] = useReducer(reducer$1, initialState);
13325
+ const [state, dispatch] = useReducer(reducer$2, initialState);
13340
13326
  // Destructure common state
13341
13327
  const { hoveredOptionId, } = state;
13342
13328
  /*------------------------------------------------------------------------*/
@@ -13348,7 +13334,7 @@ const MultiSwitch = (props) => {
13348
13334
  });
13349
13335
  // Constants
13350
13336
  const gutterRems = heightRem * 0.1;
13351
- const itemWidthRems = heightRem * 1.3;
13337
+ const itemWidthRems = heightRem * 2.2;
13352
13338
  const textFontSize = heightRem / 3.5;
13353
13339
  const iconFontSize = heightRem / 2;
13354
13340
  const borderWidthRems = 0.05;
@@ -13468,27 +13454,27 @@ const MultiSwitch = (props) => {
13468
13454
  : `click to select option "${option.label}"`), onClick: () => {
13469
13455
  // Remove hover
13470
13456
  dispatch({
13471
- type: ActionType.StopHover,
13457
+ type: ActionType$1.StopHover,
13472
13458
  });
13473
13459
  // Notify parent
13474
13460
  onChange(option.id);
13475
13461
  }, onMouseEnter: () => {
13476
13462
  dispatch({
13477
- type: ActionType.StartHover,
13463
+ type: ActionType$1.StartHover,
13478
13464
  hoveredOptionId: option.id,
13479
13465
  });
13480
13466
  }, onMouseLeave: () => {
13481
13467
  dispatch({
13482
- type: ActionType.StopHover,
13468
+ type: ActionType$1.StopHover,
13483
13469
  });
13484
13470
  }, onFocus: () => {
13485
13471
  dispatch({
13486
- type: ActionType.StartHover,
13472
+ type: ActionType$1.StartHover,
13487
13473
  hoveredOptionId: option.id,
13488
13474
  });
13489
13475
  }, onBlur: () => {
13490
13476
  dispatch({
13491
- type: ActionType.StopHover,
13477
+ type: ActionType$1.StopHover,
13492
13478
  });
13493
13479
  }, style: {
13494
13480
  pointerEvents: ((option.id === selectedOptionId)
@@ -13507,6 +13493,147 @@ const MultiSwitch = (props) => {
13507
13493
  React__default.createElement("div", { className: "MultiSwitch-highlight-container" }, highlight)));
13508
13494
  };
13509
13495
 
13496
+ // Types of dropdown items
13497
+ var DropdownItemType;
13498
+ (function (DropdownItemType) {
13499
+ // Dropdown header
13500
+ DropdownItemType["Header"] = "Header";
13501
+ // Dropdown divider
13502
+ DropdownItemType["Divider"] = "Divider";
13503
+ // Dropdown item
13504
+ DropdownItemType["Item"] = "Item";
13505
+ })(DropdownItemType || (DropdownItemType = {}));
13506
+ var DropdownItemType$1 = DropdownItemType;
13507
+
13508
+ /**
13509
+ * A simple dropdown menu
13510
+ * @author Alessandra De Lucas
13511
+ * @author Yuen Ler Chow
13512
+ * @author Gabe Abrams
13513
+ */
13514
+ /* ------------- Actions ------------ */
13515
+ // Types of actions
13516
+ var ActionType;
13517
+ (function (ActionType) {
13518
+ // Toggle opening the dropdown menu
13519
+ ActionType["ToggleDropdown"] = "ToggleDropdown";
13520
+ // Close the dropdown menu
13521
+ ActionType["CloseDropdown"] = "CloseDropdown";
13522
+ })(ActionType || (ActionType = {}));
13523
+ /**
13524
+ * Reducer that executes actions
13525
+ * @author Alessandra De Lucas
13526
+ * @author Yuen Ler Chow
13527
+ * @param state current state
13528
+ * @param action action to execute
13529
+ */
13530
+ const reducer$1 = (state, action) => {
13531
+ switch (action.type) {
13532
+ case ActionType.ToggleDropdown: {
13533
+ return Object.assign(Object.assign({}, state), { isDropdownOpen: !state.isDropdownOpen });
13534
+ }
13535
+ case ActionType.CloseDropdown: {
13536
+ return Object.assign(Object.assign({}, state), { isDropdownOpen: false });
13537
+ }
13538
+ default: {
13539
+ return state;
13540
+ }
13541
+ }
13542
+ };
13543
+ /*------------------------------------------------------------------------*/
13544
+ /* ------------------------------ Component ----------------------------- */
13545
+ /*------------------------------------------------------------------------*/
13546
+ const Dropdown = (props) => {
13547
+ /*------------------------------------------------------------------------*/
13548
+ /* -------------------------------- Setup ------------------------------- */
13549
+ /*------------------------------------------------------------------------*/
13550
+ /* -------------- Props ------------- */
13551
+ // Destructure all props
13552
+ const { dropdownButton, items, } = props;
13553
+ /* -------------- State ------------- */
13554
+ // Initial state
13555
+ const initialState = {
13556
+ isDropdownOpen: false,
13557
+ };
13558
+ // Initialize state
13559
+ const [state, dispatch] = useReducer(reducer$1, initialState);
13560
+ // Destructure common state
13561
+ const { isDropdownOpen, } = state;
13562
+ /* -------------- Refs -------------- */
13563
+ // Initialize refs
13564
+ const dropdownRef = useRef(null);
13565
+ /*------------------------------------------------------------------------*/
13566
+ /* ------------------------- Component Functions ------------------------ */
13567
+ /*------------------------------------------------------------------------*/
13568
+ /**
13569
+ * Handle clicking outside of the dropdown menu to close it
13570
+ * @author Yuen Ler Chow
13571
+ * @param event the mouse event
13572
+ */
13573
+ const handleClickOutside = (event) => {
13574
+ if (
13575
+ // Dropdown has been rendered
13576
+ dropdownRef.current
13577
+ // Click occurred outside the dropdown
13578
+ && !dropdownRef.current.contains(event.target)) {
13579
+ dispatch({ type: ActionType.CloseDropdown });
13580
+ }
13581
+ };
13582
+ /*------------------------------------------------------------------------*/
13583
+ /* ------------------------- Lifecycle Functions ------------------------ */
13584
+ /*------------------------------------------------------------------------*/
13585
+ /**
13586
+ * Mount
13587
+ * @author Yuen Ler Chow
13588
+ */
13589
+ useEffect(() => {
13590
+ // Add event listener to close dropdown when clicking outside
13591
+ document.addEventListener('mousedown', handleClickOutside);
13592
+ // Cleanup
13593
+ return () => {
13594
+ document.removeEventListener('mousedown', handleClickOutside);
13595
+ };
13596
+ }, []);
13597
+ /*----------------------------------------*/
13598
+ /* --------------- Main UI -------------- */
13599
+ /*----------------------------------------*/
13600
+ return (React__default.createElement("div", { className: "dropdown", ref: dropdownRef, "data-bs-theme": isDarkModeOn() ? 'dark' : undefined },
13601
+ React__default.createElement("button", { className: combineClassNames([
13602
+ 'btn dropdown-toggle border',
13603
+ isDropdownOpen && 'show',
13604
+ `btn-${dropdownButton.variant}`,
13605
+ dropdownButton.variant === Variant$1.Light && 'text-dark',
13606
+ ]), type: "button", id: dropdownButton.id, "aria-expanded": isDropdownOpen, "aria-label": dropdownButton.ariaLabel, onClick: () => {
13607
+ dispatch({
13608
+ type: ActionType.ToggleDropdown,
13609
+ });
13610
+ } }, dropdownButton.content),
13611
+ React__default.createElement("ul", { className: combineClassNames([
13612
+ 'dropdown-menu',
13613
+ isDarkModeOn() && 'dropdown-menu-dark',
13614
+ isDropdownOpen && 'show',
13615
+ ]) }, Object.values(items).map((item) => {
13616
+ if (item.type === DropdownItemType$1.Header) {
13617
+ return (
13618
+ // TODO: Implement header
13619
+ React__default.createElement("span", null));
13620
+ }
13621
+ if (item.type === DropdownItemType$1.Divider) {
13622
+ return (
13623
+ // TODO: Implement divider
13624
+ React__default.createElement("span", null));
13625
+ }
13626
+ return (React__default.createElement("li", { key: item.id },
13627
+ React__default.createElement("button", { type: "button", "aria-label": item.ariaLabel, className: "dropdown-item", onClick: (e) => {
13628
+ e.preventDefault();
13629
+ dispatch({
13630
+ type: ActionType.CloseDropdown,
13631
+ });
13632
+ item.onClick();
13633
+ } }, item.content)));
13634
+ }))));
13635
+ };
13636
+
13510
13637
  /**
13511
13638
  * One minute in ms
13512
13639
  * @author Gabe Abrams
@@ -15816,6 +15943,182 @@ const shuffleArray = (arr) => {
15816
15943
  return newArr;
15817
15944
  };
15818
15945
 
15946
+ /**
15947
+ * Sends and retries an http request
15948
+ * @author Gabriel Abrams
15949
+ * @param opts object containing all arguments
15950
+ * @param opts.path path to send request to
15951
+ * @param [opts.host] host to send request to
15952
+ * @param [opts.method=GET] http method to use
15953
+ * @param [opts.params] body/data to include in the request
15954
+ * @param [opts.headers] headers to include in the request
15955
+ * @param [opts.sendCrossDomainCredentials=true if in development mode] if true,
15956
+ * send cross-domain credentials even if not in dev mode
15957
+ * @param [opts.responseType=JSON] expected response type
15958
+ * @returns { body, status, headers } on success
15959
+ */
15960
+ const sendServerToServerRequest = (opts) => __awaiter(void 0, void 0, void 0, function* () {
15961
+ var _a;
15962
+ // Process method
15963
+ const method = (opts.method || 'GET');
15964
+ // Encode objects within params
15965
+ let params;
15966
+ if (opts.params) {
15967
+ params = {};
15968
+ Object.entries(opts.params).forEach(([key, val]) => {
15969
+ if (typeof val === 'object' && !Array.isArray(val)) {
15970
+ params[key] = JSON.stringify(val);
15971
+ }
15972
+ else {
15973
+ params[key] = val;
15974
+ }
15975
+ });
15976
+ }
15977
+ // Stringify parameters
15978
+ const stringifiedParams = qs.stringify(params || {}, {
15979
+ encodeValuesOnly: true,
15980
+ arrayFormat: 'brackets',
15981
+ });
15982
+ // Create url (include query if GET)
15983
+ const query = (method === 'GET' ? `?${stringifiedParams}` : '');
15984
+ let url;
15985
+ if (!opts.host) {
15986
+ // No host included at all. Just send to a path
15987
+ url = `${opts.path}${query}`;
15988
+ }
15989
+ else {
15990
+ url = `https://${opts.host}${opts.path}${query}`;
15991
+ }
15992
+ // Update headers
15993
+ const headers = opts.headers || {};
15994
+ let data = null;
15995
+ if (!headers['Content-Type']) {
15996
+ // Form encoded
15997
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
15998
+ // Add data if applicable
15999
+ data = (method !== 'GET' ? stringifiedParams : null);
16000
+ }
16001
+ else {
16002
+ // JSON encode
16003
+ data = params;
16004
+ }
16005
+ // Encode data
16006
+ let encodedData;
16007
+ if (data) {
16008
+ if (headers['Content-Type'] === 'application/x-www-form-urlencoded') {
16009
+ encodedData = new URLSearchParams(params);
16010
+ }
16011
+ else {
16012
+ encodedData = JSON.stringify(data);
16013
+ }
16014
+ }
16015
+ // Send request
16016
+ try {
16017
+ const response = yield fetch(url, {
16018
+ method,
16019
+ mode: 'cors',
16020
+ headers: headers !== null && headers !== void 0 ? headers : {},
16021
+ body: ((method !== 'GET' && encodedData)
16022
+ ? encodedData
16023
+ : undefined),
16024
+ redirect: 'follow',
16025
+ });
16026
+ // Get headers map
16027
+ const responseHeaders = {};
16028
+ response.headers.forEach((value, key) => {
16029
+ responseHeaders[key] = value;
16030
+ });
16031
+ // Process response based on responseType
16032
+ try {
16033
+ // Parse response
16034
+ let responseBody;
16035
+ if (opts.responseType
16036
+ && opts.responseType === 'Text') {
16037
+ // Response type is text
16038
+ responseBody = yield response.text();
16039
+ }
16040
+ else {
16041
+ // Response type is JSON
16042
+ responseBody = yield response.json();
16043
+ }
16044
+ // Return response
16045
+ return {
16046
+ body: responseBody,
16047
+ status: response.status,
16048
+ headers: responseHeaders,
16049
+ };
16050
+ }
16051
+ catch (err) {
16052
+ throw new ErrorWithCode(`Failed to parse response as ${opts.responseType}: ${err === null || err === void 0 ? void 0 : err.message}`, ReactKitErrorCode$1.ResponseParseError);
16053
+ }
16054
+ }
16055
+ catch (err) {
16056
+ // Self-signed certificate error:
16057
+ if ((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes('self signed certificate')) {
16058
+ throw new ErrorWithCode('We refused to send a request because the receiver has self-signed certificates.', ReactKitErrorCode$1.SelfSigned);
16059
+ }
16060
+ // No tries left
16061
+ throw new ErrorWithCode(`We encountered an error when trying to send a network request. If this issue persists, contact an admin. Error: ${err === null || err === void 0 ? void 0 : err.message}`, ReactKitErrorCode$1.NotConnected);
16062
+ }
16063
+ });
16064
+
16065
+ /**
16066
+ * Send a server-to-server request from this sever to another server that uses
16067
+ * dce-reactkit [for server only]
16068
+ * @author Gabe Abrams
16069
+ * @param opts object containing all arguments
16070
+ * @param opts.host - the host of the other server
16071
+ * @param opts.path - the path of the other server's endpoint
16072
+ * @param [opts.method=GET] - the method of the endpoint
16073
+ * @param [opts.params] - query/body parameters to include
16074
+ * @param [opts.headers] - headers to include
16075
+ * @returns response from server
16076
+ */
16077
+ const visitEndpointOnAnotherServer = (opts) => __awaiter(void 0, void 0, void 0, function* () {
16078
+ var _a;
16079
+ // Remove properties with undefined values
16080
+ let params;
16081
+ if (opts.params) {
16082
+ params = Object.fromEntries(Object
16083
+ .entries(opts.params)
16084
+ .filter(([, value]) => {
16085
+ return value !== undefined;
16086
+ }));
16087
+ }
16088
+ // Automatically JSONify arrays and objects
16089
+ if (params) {
16090
+ params = Object.fromEntries(Object
16091
+ .entries(params)
16092
+ .map(([key, value]) => {
16093
+ if (Array.isArray(value) || typeof value === 'object') {
16094
+ return [key, JSON.stringify(value)];
16095
+ }
16096
+ return [key, value];
16097
+ }));
16098
+ }
16099
+ // Send the request
16100
+ const response = yield sendServerToServerRequest({
16101
+ host: opts.host,
16102
+ path: opts.path,
16103
+ method: (_a = opts.method) !== null && _a !== void 0 ? _a : 'GET',
16104
+ params,
16105
+ });
16106
+ // Check for failure
16107
+ if (!response || !response.body) {
16108
+ throw new ErrorWithCode('We didn\'t get a response from the server. Please check your internet connection.', ReactKitErrorCode$1.NoResponse);
16109
+ }
16110
+ if (!response.body.success) {
16111
+ // Other errors
16112
+ throw new ErrorWithCode((response.body.message
16113
+ || 'An unknown error occurred. Please contact an admin.'), (response.body.code
16114
+ || ReactKitErrorCode$1.NoCode));
16115
+ }
16116
+ // Success! Extract the body
16117
+ const { body } = response.body;
16118
+ // Return
16119
+ return body;
16120
+ });
16121
+
15819
16122
  /**
15820
16123
  * Days of the week
15821
16124
  * @author Gabe Abrams
@@ -15832,5 +16135,5 @@ var DayOfWeek;
15832
16135
  })(DayOfWeek || (DayOfWeek = {}));
15833
16136
  var DayOfWeek$1 = DayOfWeek;
15834
16137
 
15835
- export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
16138
+ export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, Dropdown, DropdownItemType$1 as DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitEndpointOnAnotherServer, visitServerEndpoint, waitMs };
15836
16139
  //# sourceMappingURL=index.js.map