dce-reactkit 3.9.0-beta.1 → 3.9.0

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 +562 -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 +22 -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 +560 -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 +22 -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 +105 -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 +90 -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/cjs/index.js CHANGED
@@ -7,6 +7,7 @@ var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
7
7
  var reactFontawesome = require('@fortawesome/react-fontawesome');
8
8
  var ReactDOM = require('react-dom');
9
9
  var freeRegularSvgIcons = require('@fortawesome/free-regular-svg-icons');
10
+ var qs = require('qs');
10
11
 
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
13
 
@@ -31,6 +32,7 @@ function _interopNamespace(e) {
31
32
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
32
33
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
33
34
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
35
+ var qs__default = /*#__PURE__*/_interopDefaultLegacy(qs);
34
36
 
35
37
  /******************************************************************************
36
38
  Copyright (c) Microsoft Corporation.
@@ -57,7 +59,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
57
59
  });
58
60
  }
59
61
 
60
- // Highest error code = DRK13
62
+ // Highest error code = DRK16
61
63
  /**
62
64
  * List of error codes built into the react kit
63
65
  * @author Gabe Abrams
@@ -77,6 +79,10 @@ var ReactKitErrorCode;
77
79
  ReactKitErrorCode["NotAllowedToReviewLogs"] = "DRK11";
78
80
  ReactKitErrorCode["ThemeCheckedBeforeReactKitReady"] = "DRK12";
79
81
  ReactKitErrorCode["SessionExpiredMessageGottenBeforeReactKitReady"] = "DRK13";
82
+ // Server-to-server requests
83
+ ReactKitErrorCode["NotConnected"] = "DRK14";
84
+ ReactKitErrorCode["SelfSigned"] = "DRK15";
85
+ ReactKitErrorCode["ResponseParseError"] = "DRK16";
80
86
  })(ReactKitErrorCode || (ReactKitErrorCode = {}));
81
87
  var ReactKitErrorCode$1 = ReactKitErrorCode;
82
88
 
@@ -218,98 +224,6 @@ const waitMs = (ms = 0) => __awaiter(void 0, void 0, void 0, function* () {
218
224
  });
219
225
  });
220
226
 
221
- /**
222
- * Loading spinner/indicator
223
- * @author Gabe Abrams
224
- */
225
- /*------------------------------------------------------------------------*/
226
- /* -------------------------------- Style ------------------------------- */
227
- /*------------------------------------------------------------------------*/
228
- const style$a = `
229
- /* Container fades in */
230
- .LoadingSpinner-container {
231
- animation-name: LoadingSpinner-container-fade-in;
232
- animation-duration: 0.3s;
233
- animation-delay: 0.4s;
234
- animation-fill-mode: both;
235
- animation-timing-function: ease-out;
236
- }
237
- @keyframes LoadingSpinner-container-fade-in {
238
- 0% {
239
- opacity: 0;
240
- }
241
- 100% {
242
- opacity: 1;
243
- }
244
- }
245
-
246
- /* Blips */
247
- .LoadingSpinner-blip-1,
248
- .LoadingSpinner-blip-2,
249
- .LoadingSpinner-blip-3,
250
- .LoadingSpinner-blip-4 {
251
- font-size: 1.8rem;
252
- opacity: 0.6;
253
- margin-top: 1rem;
254
- margin-bottom: 1rem;
255
- }
256
-
257
- /* First Blip */
258
- .LoadingSpinner-blip-1 {
259
- animation: LoadingSpinner-pop-animation 2s infinite;
260
- }
261
-
262
- /* Second Blip */
263
- .LoadingSpinner-blip-2 {
264
- animation: LoadingSpinner-pop-animation 2s infinite;
265
- -webkit-animation-delay: 0.1s;
266
- animation-delay: 0.1s;
267
- }
268
-
269
- /* Third Blip */
270
- .LoadingSpinner-blip-3 {
271
- animation: LoadingSpinner-pop-animation 2s infinite;
272
- animation-delay: 0.2s;
273
- }
274
-
275
- /* Fourth Blip */
276
- .LoadingSpinner-blip-4 {
277
- animation: LoadingSpinner-pop-animation 2s infinite;
278
- animation-delay: 0.3s;
279
- }
280
-
281
- /* Pop Animation for Each Blip */
282
- @keyframes LoadingSpinner-pop-animation {
283
- 0% {
284
- transform: scale(1.0);
285
- }
286
- 10% {
287
- transform: scale(1.5);
288
- }
289
- 30% {
290
- transform: scale(1.0);
291
- }
292
- 100% {
293
- transform: scale(1.0);
294
- }
295
- }
296
- `;
297
- /*------------------------------------------------------------------------*/
298
- /* ------------------------------ Component ----------------------------- */
299
- /*------------------------------------------------------------------------*/
300
- const LoadingSpinner = () => {
301
- /*------------------------------------------------------------------------*/
302
- /* ------------------------------- Render ------------------------------- */
303
- /*------------------------------------------------------------------------*/
304
- // Add all four blips to a container
305
- return (React__default["default"].createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
306
- React__default["default"].createElement("style", null, style$a),
307
- React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-1 me-1" }),
308
- React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-2 me-1" }),
309
- React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-3 me-1" }),
310
- React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-4" })));
311
- };
312
-
313
227
  /**
314
228
  * Modal sizes
315
229
  * @author Gabe Abrams
@@ -529,7 +443,7 @@ const getNextUniqueId = () => {
529
443
  /*------------------------------------------------------------------------*/
530
444
  /* -------------------------------- Style ------------------------------- */
531
445
  /*------------------------------------------------------------------------*/
532
- const style$9 = `
446
+ const style$a = `
533
447
  .Modal-backdrop {
534
448
  position: fixed;
535
449
  top: 0;
@@ -601,14 +515,13 @@ const Modal = (props) => {
601
515
  /*------------------------------------------------------------------------*/
602
516
  var _a;
603
517
  /* -------------- Props ------------- */
604
- const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, isLoading, isLoadingCancelable, } = props;
518
+ const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, } = props;
605
519
  // Determine if no header either
606
520
  const noHeader = (!title && type === ModalType$1.NoButtons);
607
521
  /* -------------- State ------------- */
608
522
  // True if animation is in use
609
523
  const [animatingIn, setAnimatingIn] = React.useState(true);
610
524
  const [animatingPop, setAnimatingPop] = React.useState(false);
611
- const [showModal, setShowModal] = React.useState(false);
612
525
  /* -------------- Refs -------------- */
613
526
  // Keep track of whether modal is still mounted
614
527
  const mounted = React.useRef(false);
@@ -634,14 +547,6 @@ const Modal = (props) => {
634
547
  // Update to state after animated in
635
548
  if (mounted.current) {
636
549
  setAnimatingIn(false);
637
- if (isLoading) {
638
- // wait 1 second before showing modal
639
- yield waitMs(1000);
640
- setShowModal(true);
641
- }
642
- else {
643
- setShowModal(true);
644
- }
645
550
  }
646
551
  }))();
647
552
  return () => {
@@ -717,7 +622,7 @@ const Modal = (props) => {
717
622
  left: 0,
718
623
  right: 0,
719
624
  } },
720
- React__default["default"].createElement("style", null, style$9),
625
+ React__default["default"].createElement("style", null, style$a),
721
626
  React__default["default"].createElement("div", { className: `Modal-backdrop ${backdropAnimationClass}`, style: {
722
627
  zIndex: baseZIndex + 1,
723
628
  }, onClick: () => __awaiter(void 0, void 0, void 0, function* () {
@@ -735,11 +640,11 @@ const Modal = (props) => {
735
640
  // Handle close
736
641
  handleClose(ModalButtonType$1.Cancel);
737
642
  }) }),
738
- showModal && (React__default["default"].createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
643
+ React__default["default"].createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
739
644
  zIndex: baseZIndex + 2,
740
645
  // Override sizes for even larger for XL
741
646
  width: (size === ModalSize$1.ExtraLarge
742
- ? 'calc(100vw - 3rem)'
647
+ ? 'calc(100vw - 1rem)'
743
648
  : undefined),
744
649
  maxWidth: (size === ModalSize$1.ExtraLarge
745
650
  ? '80rem'
@@ -767,7 +672,7 @@ const Modal = (props) => {
767
672
  ? '1.6rem'
768
673
  : undefined),
769
674
  } }, title),
770
- (onClose && !dontShowXButton && !(isLoading && !isLoadingCancelable)) && (React__default["default"].createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: {
675
+ (onClose && !dontShowXButton) && (React__default["default"].createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: {
771
676
  backgroundColor: (isDarkModeOn()
772
677
  ? 'white'
773
678
  : undefined),
@@ -775,17 +680,7 @@ const Modal = (props) => {
775
680
  // Handle close
776
681
  handleClose(ModalButtonType$1.Cancel);
777
682
  } })))),
778
- isLoading && (React__default["default"].createElement("div", { className: "modal-body", style: {
779
- color: (isDarkModeOn()
780
- ? 'white'
781
- : undefined),
782
- backgroundColor: (isDarkModeOn()
783
- ? '#444'
784
- : undefined),
785
- } },
786
- React__default["default"].createElement(LoadingSpinner, null),
787
- React__default["default"].createElement("span", { className: "sr-only" }, "Content loading"))),
788
- children && !isLoading && (React__default["default"].createElement("div", { className: "modal-body", style: {
683
+ children && (React__default["default"].createElement("div", { className: "modal-body", style: {
789
684
  color: (isDarkModeOn()
790
685
  ? 'white'
791
686
  : undefined),
@@ -803,7 +698,7 @@ const Modal = (props) => {
803
698
  borderTop: (isDarkModeOn()
804
699
  ? '0.1rem solid gray'
805
700
  : undefined),
806
- } }, footer)))))));
701
+ } }, footer))))));
807
702
  // Determine which portal to use
808
703
  const portalNumber = id.current % NUM_MODAL_PORTALS;
809
704
  // Render in a portal
@@ -1283,7 +1178,7 @@ const showSessionExpiredMessage = () => __awaiter(void 0, void 0, void 0, functi
1283
1178
  /*------------------------------------------------------------------------*/
1284
1179
  /* -------------------------------- Style ------------------------------- */
1285
1180
  /*------------------------------------------------------------------------*/
1286
- const style$8 = `
1181
+ const style$9 = `
1287
1182
  .AppWrapper-leave-to-url-notice {
1288
1183
  opacity: 0;
1289
1184
 
@@ -1458,13 +1353,105 @@ const AppWrapper = (props) => {
1458
1353
  /* --------------- Main UI -------------- */
1459
1354
  /*----------------------------------------*/
1460
1355
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
1461
- React__default["default"].createElement("style", null, style$8),
1356
+ React__default["default"].createElement("style", null, style$9),
1462
1357
  React__default["default"].createElement("style", null, tooltipStyle),
1463
1358
  modal,
1464
1359
  customModalPortals,
1465
1360
  body));
1466
1361
  };
1467
1362
 
1363
+ /**
1364
+ * Loading spinner/indicator
1365
+ * @author Gabe Abrams
1366
+ */
1367
+ /*------------------------------------------------------------------------*/
1368
+ /* -------------------------------- Style ------------------------------- */
1369
+ /*------------------------------------------------------------------------*/
1370
+ const style$8 = `
1371
+ /* Container fades in */
1372
+ .LoadingSpinner-container {
1373
+ animation-name: LoadingSpinner-container-fade-in;
1374
+ animation-duration: 0.3s;
1375
+ animation-delay: 0.4s;
1376
+ animation-fill-mode: both;
1377
+ animation-timing-function: ease-out;
1378
+ }
1379
+ @keyframes LoadingSpinner-container-fade-in {
1380
+ 0% {
1381
+ opacity: 0;
1382
+ }
1383
+ 100% {
1384
+ opacity: 1;
1385
+ }
1386
+ }
1387
+
1388
+ /* Blips */
1389
+ .LoadingSpinner-blip-1,
1390
+ .LoadingSpinner-blip-2,
1391
+ .LoadingSpinner-blip-3,
1392
+ .LoadingSpinner-blip-4 {
1393
+ font-size: 1.8rem;
1394
+ opacity: 0.6;
1395
+ margin-top: 1rem;
1396
+ margin-bottom: 1rem;
1397
+ }
1398
+
1399
+ /* First Blip */
1400
+ .LoadingSpinner-blip-1 {
1401
+ animation: LoadingSpinner-pop-animation 2s infinite;
1402
+ }
1403
+
1404
+ /* Second Blip */
1405
+ .LoadingSpinner-blip-2 {
1406
+ animation: LoadingSpinner-pop-animation 2s infinite;
1407
+ -webkit-animation-delay: 0.1s;
1408
+ animation-delay: 0.1s;
1409
+ }
1410
+
1411
+ /* Third Blip */
1412
+ .LoadingSpinner-blip-3 {
1413
+ animation: LoadingSpinner-pop-animation 2s infinite;
1414
+ animation-delay: 0.2s;
1415
+ }
1416
+
1417
+ /* Fourth Blip */
1418
+ .LoadingSpinner-blip-4 {
1419
+ animation: LoadingSpinner-pop-animation 2s infinite;
1420
+ animation-delay: 0.3s;
1421
+ }
1422
+
1423
+ /* Pop Animation for Each Blip */
1424
+ @keyframes LoadingSpinner-pop-animation {
1425
+ 0% {
1426
+ transform: scale(1.0);
1427
+ }
1428
+ 10% {
1429
+ transform: scale(1.5);
1430
+ }
1431
+ 30% {
1432
+ transform: scale(1.0);
1433
+ }
1434
+ 100% {
1435
+ transform: scale(1.0);
1436
+ }
1437
+ }
1438
+ `;
1439
+ /*------------------------------------------------------------------------*/
1440
+ /* ------------------------------ Component ----------------------------- */
1441
+ /*------------------------------------------------------------------------*/
1442
+ const LoadingSpinner = () => {
1443
+ /*------------------------------------------------------------------------*/
1444
+ /* ------------------------------- Render ------------------------------- */
1445
+ /*------------------------------------------------------------------------*/
1446
+ // Add all four blips to a container
1447
+ return (React__default["default"].createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
1448
+ React__default["default"].createElement("style", null, style$8),
1449
+ React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-1 me-1" }),
1450
+ React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-2 me-1" }),
1451
+ React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-3 me-1" }),
1452
+ React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-4" })));
1453
+ };
1454
+
1468
1455
  /**
1469
1456
  * A box with a tab on the top that holds buttons and other content
1470
1457
  * @author Gabe Abrams
@@ -2256,27 +2243,27 @@ const PopPendingMark = (props) => {
2256
2243
  */
2257
2244
  /* ------------- Actions ------------ */
2258
2245
  // Types of actions
2259
- var ActionType$8;
2246
+ var ActionType$9;
2260
2247
  (function (ActionType) {
2261
2248
  // Indicate that the text was recently copied
2262
2249
  ActionType["IndicateRecentlyCopied"] = "indicate-recently-copied";
2263
2250
  // Clear the status
2264
2251
  ActionType["ClearRecentlyCopiedStatus"] = "clear-recently-copied-status";
2265
- })(ActionType$8 || (ActionType$8 = {}));
2252
+ })(ActionType$9 || (ActionType$9 = {}));
2266
2253
  /**
2267
2254
  * Reducer that executes actions
2268
2255
  * @author Gabe Abrams
2269
2256
  * @param state current state
2270
2257
  * @param action action to execute
2271
2258
  */
2272
- const reducer$9 = (state, action) => {
2259
+ const reducer$a = (state, action) => {
2273
2260
  switch (action.type) {
2274
- case ActionType$8.IndicateRecentlyCopied: {
2261
+ case ActionType$9.IndicateRecentlyCopied: {
2275
2262
  return {
2276
2263
  recentlyCopied: true,
2277
2264
  };
2278
2265
  }
2279
- case ActionType$8.ClearRecentlyCopiedStatus: {
2266
+ case ActionType$9.ClearRecentlyCopiedStatus: {
2280
2267
  return {
2281
2268
  recentlyCopied: false,
2282
2269
  };
@@ -2302,7 +2289,7 @@ const CopiableBox = (props) => {
2302
2289
  recentlyCopied: false,
2303
2290
  };
2304
2291
  // Initialize state
2305
- const [state, dispatch] = React.useReducer(reducer$9, initialState);
2292
+ const [state, dispatch] = React.useReducer(reducer$a, initialState);
2306
2293
  // Destructure common state
2307
2294
  const { recentlyCopied, } = state;
2308
2295
  /*------------------------------------------------------------------------*/
@@ -2322,13 +2309,13 @@ const CopiableBox = (props) => {
2322
2309
  }
2323
2310
  // Show copied notice
2324
2311
  dispatch({
2325
- type: ActionType$8.IndicateRecentlyCopied,
2312
+ type: ActionType$9.IndicateRecentlyCopied,
2326
2313
  });
2327
2314
  // Wait a moment
2328
2315
  yield waitMs(4000);
2329
2316
  // Hide copied notice
2330
2317
  dispatch({
2331
- type: ActionType$8.ClearRecentlyCopiedStatus,
2318
+ type: ActionType$9.ClearRecentlyCopiedStatus,
2332
2319
  });
2333
2320
  });
2334
2321
  /*------------------------------------------------------------------------*/
@@ -2384,20 +2371,20 @@ const CopiableBox = (props) => {
2384
2371
  */
2385
2372
  /* ------------- Actions ------------ */
2386
2373
  // Types of actions
2387
- var ActionType$7;
2374
+ var ActionType$8;
2388
2375
  (function (ActionType) {
2389
2376
  // Toggle whether a child are being shown
2390
2377
  ActionType["ToggleChild"] = "toggle-child";
2391
- })(ActionType$7 || (ActionType$7 = {}));
2378
+ })(ActionType$8 || (ActionType$8 = {}));
2392
2379
  /**
2393
2380
  * Reducer that executes actions
2394
2381
  * @author Gabe Abrams
2395
2382
  * @param state current state
2396
2383
  * @param action action to execute
2397
2384
  */
2398
- const reducer$8 = (state, action) => {
2385
+ const reducer$9 = (state, action) => {
2399
2386
  switch (action.type) {
2400
- case ActionType$7.ToggleChild: {
2387
+ case ActionType$8.ToggleChild: {
2401
2388
  return Object.assign(Object.assign({}, state), { childExpanded: Object.assign(Object.assign({}, state.childExpanded), { [String(action.id)]: !state.childExpanded[String(action.id)] }) });
2402
2389
  }
2403
2390
  default: {
@@ -2426,7 +2413,7 @@ const NestableItemList = (props) => {
2426
2413
  childExpanded: initChildExpanded,
2427
2414
  };
2428
2415
  // Initialize state
2429
- const [state, dispatch] = React.useReducer(reducer$8, initialState);
2416
+ const [state, dispatch] = React.useReducer(reducer$9, initialState);
2430
2417
  // Destructure common state
2431
2418
  const { childExpanded, } = state;
2432
2419
  /*------------------------------------------------------------------------*/
@@ -2516,7 +2503,7 @@ const NestableItemList = (props) => {
2516
2503
  backgroundColor: 'transparent',
2517
2504
  }, type: "button", onClick: () => {
2518
2505
  dispatch({
2519
- type: ActionType$7.ToggleChild,
2506
+ type: ActionType$8.ToggleChild,
2520
2507
  id: item.id,
2521
2508
  });
2522
2509
  }, "aria-label": `${childExpanded[item.id] ? 'Hide' : 'Show'} items in ${item.name}` },
@@ -2800,7 +2787,7 @@ var SortType;
2800
2787
  })(SortType || (SortType = {}));
2801
2788
  /* ------------- Actions ------------ */
2802
2789
  // Types of actions
2803
- var ActionType$6;
2790
+ var ActionType$7;
2804
2791
  (function (ActionType) {
2805
2792
  // Toggle sort column param
2806
2793
  ActionType["ToggleSortColumn"] = "toggle-sort-column";
@@ -2812,16 +2799,16 @@ var ActionType$6;
2812
2799
  ActionType["ShowAllColumns"] = "show-all-columns";
2813
2800
  // Hide all columns
2814
2801
  ActionType["HideAllColumns"] = "hide-all-columns";
2815
- })(ActionType$6 || (ActionType$6 = {}));
2802
+ })(ActionType$7 || (ActionType$7 = {}));
2816
2803
  /**
2817
2804
  * Reducer that executes actions
2818
2805
  * @author Gabe Abrams
2819
2806
  * @param state current state
2820
2807
  * @param action action to execute
2821
2808
  */
2822
- const reducer$7 = (state, action) => {
2809
+ const reducer$8 = (state, action) => {
2823
2810
  switch (action.type) {
2824
- case ActionType$6.ToggleSortColumn: {
2811
+ case ActionType$7.ToggleSortColumn: {
2825
2812
  if (action.param !== state.sortColumnParam) {
2826
2813
  // Different column param
2827
2814
  return Object.assign(Object.assign({}, state), { sortColumnParam: action.param, sortType: SortType.Ascending });
@@ -2833,22 +2820,22 @@ const reducer$7 = (state, action) => {
2833
2820
  // Stop sorting by column
2834
2821
  return Object.assign(Object.assign({}, state), { sortColumnParam: undefined, sortType: SortType.Ascending });
2835
2822
  }
2836
- case ActionType$6.UpdateColumnVisibility: {
2823
+ case ActionType$7.UpdateColumnVisibility: {
2837
2824
  const { columnVisibilityMap } = state;
2838
2825
  columnVisibilityMap[action.param] = action.visible;
2839
2826
  return Object.assign(Object.assign({}, state), { columnVisibilityMap });
2840
2827
  }
2841
- case ActionType$6.ToggleColVisCusModalVisibility: {
2828
+ case ActionType$7.ToggleColVisCusModalVisibility: {
2842
2829
  return Object.assign(Object.assign({}, state), { columnVisibilityCustomizationModalVisible: !state.columnVisibilityCustomizationModalVisible });
2843
2830
  }
2844
- case ActionType$6.ShowAllColumns: {
2831
+ case ActionType$7.ShowAllColumns: {
2845
2832
  const { columnVisibilityMap } = state;
2846
2833
  Object.keys(columnVisibilityMap).forEach((param) => {
2847
2834
  columnVisibilityMap[param] = true;
2848
2835
  });
2849
2836
  return Object.assign(Object.assign({}, state), { columnVisibilityMap });
2850
2837
  }
2851
- case ActionType$6.HideAllColumns: {
2838
+ case ActionType$7.HideAllColumns: {
2852
2839
  const { columnVisibilityMap } = state;
2853
2840
  Object.keys(columnVisibilityMap).forEach((param) => {
2854
2841
  columnVisibilityMap[param] = false;
@@ -2895,7 +2882,7 @@ const IntelliTable = (props) => {
2895
2882
  columnVisibilityCustomizationModalVisible: false,
2896
2883
  };
2897
2884
  // Initialize state
2898
- const [state, dispatch] = React.useReducer(reducer$7, initialState);
2885
+ const [state, dispatch] = React.useReducer(reducer$8, initialState);
2899
2886
  // Destructure common state
2900
2887
  const { sortColumnParam, sortType, columnVisibilityMap, columnVisibilityCustomizationModalVisible, } = state;
2901
2888
  /*------------------------------------------------------------------------*/
@@ -2918,13 +2905,13 @@ const IntelliTable = (props) => {
2918
2905
  return alert('Choose at least one column', 'To continue, you have to choose at least one column to show');
2919
2906
  }
2920
2907
  dispatch({
2921
- type: ActionType$6.ToggleColVisCusModalVisibility,
2908
+ type: ActionType$7.ToggleColVisCusModalVisibility,
2922
2909
  });
2923
2910
  }, okayVariant: Variant$1.Light },
2924
2911
  columns.map((column) => {
2925
2912
  return (React__default["default"].createElement(CheckboxButton, { key: column.param, id: `IntelliTable-${id}-toggle-visibility-${column.param}`, className: "mb-2", text: column.title, onChanged: (checked) => {
2926
2913
  dispatch({
2927
- type: ActionType$6.UpdateColumnVisibility,
2914
+ type: ActionType$7.UpdateColumnVisibility,
2928
2915
  param: column.param,
2929
2916
  visible: checked,
2930
2917
  });
@@ -2933,12 +2920,12 @@ const IntelliTable = (props) => {
2933
2920
  React__default["default"].createElement("div", { className: "mt-3" }, "Or you can:"),
2934
2921
  React__default["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: () => {
2935
2922
  dispatch({
2936
- type: ActionType$6.ShowAllColumns,
2923
+ type: ActionType$7.ShowAllColumns,
2937
2924
  });
2938
2925
  } }, "Select All"),
2939
2926
  React__default["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: () => {
2940
2927
  dispatch({
2941
- type: ActionType$6.HideAllColumns,
2928
+ type: ActionType$7.HideAllColumns,
2942
2929
  });
2943
2930
  } }, "Deselect All")));
2944
2931
  }
@@ -2989,7 +2976,7 @@ const IntelliTable = (props) => {
2989
2976
  React__default["default"].createElement("div", null,
2990
2977
  React__default["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: () => {
2991
2978
  dispatch({
2992
- type: ActionType$6.ToggleSortColumn,
2979
+ type: ActionType$7.ToggleSortColumn,
2993
2980
  param: column.param,
2994
2981
  });
2995
2982
  } },
@@ -3178,7 +3165,7 @@ const IntelliTable = (props) => {
3178
3165
  React__default["default"].createElement(CSVDownloadButton, { "aria-label": `download data as csv for ${title}`, id: `IntelliTable-${id}-download-as-csv`, filename: filename, csv: csv }),
3179
3166
  React__default["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: () => {
3180
3167
  dispatch({
3181
- type: ActionType$6.ToggleColVisCusModalVisibility,
3168
+ type: ActionType$7.ToggleColVisCusModalVisibility,
3182
3169
  });
3183
3170
  } },
3184
3171
  "Show/Hide Cols",
@@ -3544,7 +3531,7 @@ const genHumanReadableName = (machineReadableName) => {
3544
3531
  };
3545
3532
  /* ------------- Actions ------------ */
3546
3533
  // Types of actions
3547
- var ActionType$5;
3534
+ var ActionType$6;
3548
3535
  (function (ActionType) {
3549
3536
  // Show the loading bar
3550
3537
  ActionType["StartLoading"] = "start-loading";
@@ -3566,45 +3553,45 @@ var ActionType$5;
3566
3553
  ActionType["UpdateActionErrorFilterState"] = "update-action-error-filter-state";
3567
3554
  // Update the advanced filter state
3568
3555
  ActionType["UpdateAdvancedFilterState"] = "update-advanced-filter-state";
3569
- })(ActionType$5 || (ActionType$5 = {}));
3556
+ })(ActionType$6 || (ActionType$6 = {}));
3570
3557
  /**
3571
3558
  * Reducer that executes actions
3572
3559
  * @author Gabe Abrams
3573
3560
  * @param state current state
3574
3561
  * @param action action to execute
3575
3562
  */
3576
- const reducer$6 = (state, action) => {
3563
+ const reducer$7 = (state, action) => {
3577
3564
  switch (action.type) {
3578
- case ActionType$5.StartLoading: {
3565
+ case ActionType$6.StartLoading: {
3579
3566
  return Object.assign(Object.assign({}, state), { loading: true });
3580
3567
  }
3581
- case ActionType$5.FinishLoading: {
3568
+ case ActionType$6.FinishLoading: {
3582
3569
  return Object.assign(Object.assign({}, state), { loading: false, logMap: action.logMap });
3583
3570
  }
3584
- case ActionType$5.ToggleFilterDrawer: {
3571
+ case ActionType$6.ToggleFilterDrawer: {
3585
3572
  return Object.assign(Object.assign({}, state), { expandedFilterDrawer: (state.expandedFilterDrawer === action.filterDrawer
3586
3573
  ? undefined // hide
3587
3574
  : action.filterDrawer) });
3588
3575
  }
3589
- case ActionType$5.HideFilterDrawer: {
3576
+ case ActionType$6.HideFilterDrawer: {
3590
3577
  return Object.assign(Object.assign({}, state), { expandedFilterDrawer: undefined });
3591
3578
  }
3592
- case ActionType$5.ResetFilters: {
3579
+ case ActionType$6.ResetFilters: {
3593
3580
  return Object.assign(Object.assign({}, state), { dateFilterState: action.initDateFilterState, contextFilterState: action.initContextFilterState, tagFilterState: action.initTagFilterState, actionErrorFilterState: action.initActionErrorFilterState, advancedFilterState: action.initAdvancedFilterState });
3594
3581
  }
3595
- case ActionType$5.UpdateDateFilterState: {
3582
+ case ActionType$6.UpdateDateFilterState: {
3596
3583
  return Object.assign(Object.assign({}, state), { dateFilterState: action.dateFilterState });
3597
3584
  }
3598
- case ActionType$5.UpdateContextFilterState: {
3585
+ case ActionType$6.UpdateContextFilterState: {
3599
3586
  return Object.assign(Object.assign({}, state), { contextFilterState: action.contextFilterState });
3600
3587
  }
3601
- case ActionType$5.UpdateTagFilterState: {
3588
+ case ActionType$6.UpdateTagFilterState: {
3602
3589
  return Object.assign(Object.assign({}, state), { tagFilterState: action.tagFilterState });
3603
3590
  }
3604
- case ActionType$5.UpdateActionErrorFilterState: {
3591
+ case ActionType$6.UpdateActionErrorFilterState: {
3605
3592
  return Object.assign(Object.assign({}, state), { actionErrorFilterState: action.actionErrorFilterState });
3606
3593
  }
3607
- case ActionType$5.UpdateAdvancedFilterState: {
3594
+ case ActionType$6.UpdateAdvancedFilterState: {
3608
3595
  return Object.assign(Object.assign({}, state), { advancedFilterState: action.advancedFilterState });
3609
3596
  }
3610
3597
  default: {
@@ -3733,7 +3720,7 @@ const LogReviewer = (props) => {
3733
3720
  advancedFilterState: initAdvancedFilterState,
3734
3721
  };
3735
3722
  // Initialize state
3736
- const [state, dispatch] = React.useReducer(reducer$6, initialState);
3723
+ const [state, dispatch] = React.useReducer(reducer$7, initialState);
3737
3724
  // Destructure common state
3738
3725
  const { loading, logMap, expandedFilterDrawer, dateFilterState, contextFilterState, tagFilterState, actionErrorFilterState, advancedFilterState, } = state;
3739
3726
  /*------------------------------------------------------------------------*/
@@ -3783,7 +3770,7 @@ const LogReviewer = (props) => {
3783
3770
  const handleDateRangeUpdated = (newDateFilterState) => __awaiter(void 0, void 0, void 0, function* () {
3784
3771
  // Update state
3785
3772
  dispatch({
3786
- type: ActionType$5.UpdateDateFilterState,
3773
+ type: ActionType$6.UpdateDateFilterState,
3787
3774
  dateFilterState: newDateFilterState,
3788
3775
  });
3789
3776
  // Check which year/month combos we need to load
@@ -3794,7 +3781,7 @@ const LogReviewer = (props) => {
3794
3781
  }
3795
3782
  // Start loading
3796
3783
  dispatch({
3797
- type: ActionType$5.StartLoading,
3784
+ type: ActionType$6.StartLoading,
3798
3785
  });
3799
3786
  // Load required months
3800
3787
  try {
@@ -3818,7 +3805,7 @@ const LogReviewer = (props) => {
3818
3805
  }
3819
3806
  // Finish loading
3820
3807
  dispatch({
3821
- type: ActionType$5.FinishLoading,
3808
+ type: ActionType$6.FinishLoading,
3822
3809
  logMap,
3823
3810
  });
3824
3811
  });
@@ -3857,7 +3844,7 @@ const LogReviewer = (props) => {
3857
3844
  React__default["default"].createElement("div", { className: "LogReviewer-filter-toggle-buttons alert alert-secondary p-2 m-0" },
3858
3845
  React__default["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: () => {
3859
3846
  dispatch({
3860
- type: ActionType$5.ToggleFilterDrawer,
3847
+ type: ActionType$6.ToggleFilterDrawer,
3861
3848
  filterDrawer: FilterDrawer.Date,
3862
3849
  });
3863
3850
  } },
@@ -3865,7 +3852,7 @@ const LogReviewer = (props) => {
3865
3852
  "Date"),
3866
3853
  React__default["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: () => {
3867
3854
  dispatch({
3868
- type: ActionType$5.ToggleFilterDrawer,
3855
+ type: ActionType$6.ToggleFilterDrawer,
3869
3856
  filterDrawer: FilterDrawer.Context,
3870
3857
  });
3871
3858
  } },
@@ -3873,7 +3860,7 @@ const LogReviewer = (props) => {
3873
3860
  "Context"),
3874
3861
  (LogMetadata.Tag && Object.keys(LogMetadata.Tag).length > 0) && (React__default["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: () => {
3875
3862
  dispatch({
3876
- type: ActionType$5.ToggleFilterDrawer,
3863
+ type: ActionType$6.ToggleFilterDrawer,
3877
3864
  filterDrawer: FilterDrawer.Tag,
3878
3865
  });
3879
3866
  } },
@@ -3881,7 +3868,7 @@ const LogReviewer = (props) => {
3881
3868
  "Tag")),
3882
3869
  React__default["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: () => {
3883
3870
  dispatch({
3884
- type: ActionType$5.ToggleFilterDrawer,
3871
+ type: ActionType$6.ToggleFilterDrawer,
3885
3872
  filterDrawer: FilterDrawer.Action,
3886
3873
  });
3887
3874
  } },
@@ -3889,7 +3876,7 @@ const LogReviewer = (props) => {
3889
3876
  "Action"),
3890
3877
  React__default["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: () => {
3891
3878
  dispatch({
3892
- type: ActionType$5.ToggleFilterDrawer,
3879
+ type: ActionType$6.ToggleFilterDrawer,
3893
3880
  filterDrawer: FilterDrawer.Advanced,
3894
3881
  });
3895
3882
  } },
@@ -3897,7 +3884,7 @@ const LogReviewer = (props) => {
3897
3884
  "Advanced"),
3898
3885
  React__default["default"].createElement("button", { type: "button", id: "LogReviewer-reset-filters-button", className: "btn btn-light", "aria-label": "reset filters", onClick: () => {
3899
3886
  dispatch({
3900
- type: ActionType$5.ResetFilters,
3887
+ type: ActionType$6.ResetFilters,
3901
3888
  initActionErrorFilterState,
3902
3889
  initAdvancedFilterState,
3903
3890
  initContextFilterState,
@@ -4019,7 +4006,7 @@ const LogReviewer = (props) => {
4019
4006
  }
4020
4007
  });
4021
4008
  dispatch({
4022
- type: ActionType$5.UpdateContextFilterState,
4009
+ type: ActionType$6.UpdateContextFilterState,
4023
4010
  contextFilterState,
4024
4011
  });
4025
4012
  } }));
@@ -4034,7 +4021,7 @@ const LogReviewer = (props) => {
4034
4021
  return (React__default["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) => {
4035
4022
  tagFilterState[tag] = checked;
4036
4023
  dispatch({
4037
- type: ActionType$5.UpdateTagFilterState,
4024
+ type: ActionType$6.UpdateTagFilterState,
4038
4025
  tagFilterState,
4039
4026
  });
4040
4027
  } }));
@@ -4047,21 +4034,21 @@ const LogReviewer = (props) => {
4047
4034
  React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
4048
4035
  actionErrorFilterState.type = undefined;
4049
4036
  dispatch({
4050
- type: ActionType$5.UpdateActionErrorFilterState,
4037
+ type: ActionType$6.UpdateActionErrorFilterState,
4051
4038
  actionErrorFilterState,
4052
4039
  });
4053
4040
  }, ariaLabel: "show logs of all types", selected: actionErrorFilterState.type === undefined }),
4054
4041
  React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-action-only", text: "Action Logs Only", onSelected: () => {
4055
4042
  actionErrorFilterState.type = LogType$1.Action;
4056
4043
  dispatch({
4057
- type: ActionType$5.UpdateActionErrorFilterState,
4044
+ type: ActionType$6.UpdateActionErrorFilterState,
4058
4045
  actionErrorFilterState,
4059
4046
  });
4060
4047
  }, ariaLabel: "only show action logs", selected: actionErrorFilterState.type === LogType$1.Action }),
4061
4048
  React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-error-only", text: "Action Error Only", onSelected: () => {
4062
4049
  actionErrorFilterState.type = LogType$1.Error;
4063
4050
  dispatch({
4064
- type: ActionType$5.UpdateActionErrorFilterState,
4051
+ type: ActionType$6.UpdateActionErrorFilterState,
4065
4052
  actionErrorFilterState,
4066
4053
  });
4067
4054
  }, ariaLabel: "only show error logs", selected: actionErrorFilterState.type === LogType$1.Error, noMarginOnRight: true })),
@@ -4073,7 +4060,7 @@ const LogReviewer = (props) => {
4073
4060
  return (React__default["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) => {
4074
4061
  actionErrorFilterState.action[action] = checked;
4075
4062
  dispatch({
4076
- type: ActionType$5.UpdateActionErrorFilterState,
4063
+ type: ActionType$6.UpdateActionErrorFilterState,
4077
4064
  actionErrorFilterState,
4078
4065
  });
4079
4066
  } }));
@@ -4084,7 +4071,7 @@ const LogReviewer = (props) => {
4084
4071
  return (React__default["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) => {
4085
4072
  actionErrorFilterState.target[target] = checked;
4086
4073
  dispatch({
4087
- type: ActionType$5.UpdateActionErrorFilterState,
4074
+ type: ActionType$6.UpdateActionErrorFilterState,
4088
4075
  actionErrorFilterState,
4089
4076
  });
4090
4077
  } }));
@@ -4096,7 +4083,7 @@ const LogReviewer = (props) => {
4096
4083
  React__default["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) => {
4097
4084
  actionErrorFilterState.errorMessage = e.target.value;
4098
4085
  dispatch({
4099
- type: ActionType$5.UpdateActionErrorFilterState,
4086
+ type: ActionType$6.UpdateActionErrorFilterState,
4100
4087
  actionErrorFilterState,
4101
4088
  });
4102
4089
  } })),
@@ -4107,7 +4094,7 @@ const LogReviewer = (props) => {
4107
4094
  .trim()
4108
4095
  .toUpperCase());
4109
4096
  dispatch({
4110
- type: ActionType$5.UpdateActionErrorFilterState,
4097
+ type: ActionType$6.UpdateActionErrorFilterState,
4111
4098
  actionErrorFilterState,
4112
4099
  });
4113
4100
  } }))))));
@@ -4121,7 +4108,7 @@ const LogReviewer = (props) => {
4121
4108
  React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user first name", value: advancedFilterState.userFirstName, placeholder: "e.g. Divardo", onChange: (e) => {
4122
4109
  advancedFilterState.userFirstName = e.target.value;
4123
4110
  dispatch({
4124
- type: ActionType$5.UpdateAdvancedFilterState,
4111
+ type: ActionType$6.UpdateAdvancedFilterState,
4125
4112
  advancedFilterState,
4126
4113
  });
4127
4114
  } })),
@@ -4130,7 +4117,7 @@ const LogReviewer = (props) => {
4130
4117
  React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user last name", value: advancedFilterState.userLastName, placeholder: "e.g. Calicci", onChange: (e) => {
4131
4118
  advancedFilterState.userLastName = e.target.value;
4132
4119
  dispatch({
4133
- type: ActionType$5.UpdateAdvancedFilterState,
4120
+ type: ActionType$6.UpdateAdvancedFilterState,
4134
4121
  advancedFilterState,
4135
4122
  });
4136
4123
  } })),
@@ -4140,7 +4127,7 @@ const LogReviewer = (props) => {
4140
4127
  advancedFilterState.userEmail = ((e.target.value)
4141
4128
  .trim());
4142
4129
  dispatch({
4143
- type: ActionType$5.UpdateAdvancedFilterState,
4130
+ type: ActionType$6.UpdateAdvancedFilterState,
4144
4131
  advancedFilterState,
4145
4132
  });
4146
4133
  } })),
@@ -4154,7 +4141,7 @@ const LogReviewer = (props) => {
4154
4141
  .trim());
4155
4142
  }
4156
4143
  dispatch({
4157
- type: ActionType$5.UpdateAdvancedFilterState,
4144
+ type: ActionType$6.UpdateAdvancedFilterState,
4158
4145
  advancedFilterState,
4159
4146
  });
4160
4147
  } })),
@@ -4162,21 +4149,21 @@ const LogReviewer = (props) => {
4162
4149
  React__default["default"].createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
4163
4150
  advancedFilterState.includeLearners = checked;
4164
4151
  dispatch({
4165
- type: ActionType$5.UpdateAdvancedFilterState,
4152
+ type: ActionType$6.UpdateAdvancedFilterState,
4166
4153
  advancedFilterState,
4167
4154
  });
4168
4155
  }, checked: advancedFilterState.includeLearners, ariaLabel: "show logs from students" }),
4169
4156
  React__default["default"].createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
4170
4157
  advancedFilterState.includeTTMs = checked;
4171
4158
  dispatch({
4172
- type: ActionType$5.UpdateAdvancedFilterState,
4159
+ type: ActionType$6.UpdateAdvancedFilterState,
4173
4160
  advancedFilterState,
4174
4161
  });
4175
4162
  }, checked: advancedFilterState.includeTTMs, ariaLabel: "show logs from teaching team members" }),
4176
4163
  React__default["default"].createElement(CheckboxButton, { text: "Admins", onChanged: (checked) => {
4177
4164
  advancedFilterState.includeAdmins = checked;
4178
4165
  dispatch({
4179
- type: ActionType$5.UpdateAdvancedFilterState,
4166
+ type: ActionType$6.UpdateAdvancedFilterState,
4180
4167
  advancedFilterState,
4181
4168
  });
4182
4169
  }, checked: advancedFilterState.includeAdmins, ariaLabel: "show logs from admins" }))),
@@ -4186,7 +4173,7 @@ const LogReviewer = (props) => {
4186
4173
  React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for course name", value: advancedFilterState.courseName, placeholder: "e.g. GLC 200", onChange: (e) => {
4187
4174
  advancedFilterState.courseName = e.target.value;
4188
4175
  dispatch({
4189
- type: ActionType$5.UpdateAdvancedFilterState,
4176
+ type: ActionType$6.UpdateAdvancedFilterState,
4190
4177
  advancedFilterState,
4191
4178
  });
4192
4179
  } })),
@@ -4200,7 +4187,7 @@ const LogReviewer = (props) => {
4200
4187
  .trim());
4201
4188
  }
4202
4189
  dispatch({
4203
- type: ActionType$5.UpdateAdvancedFilterState,
4190
+ type: ActionType$6.UpdateAdvancedFilterState,
4204
4191
  advancedFilterState,
4205
4192
  });
4206
4193
  } }))),
@@ -4209,21 +4196,21 @@ const LogReviewer = (props) => {
4209
4196
  React__default["default"].createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: advancedFilterState.isMobile === undefined, onSelected: () => {
4210
4197
  advancedFilterState.isMobile = undefined;
4211
4198
  dispatch({
4212
- type: ActionType$5.UpdateAdvancedFilterState,
4199
+ type: ActionType$6.UpdateAdvancedFilterState,
4213
4200
  advancedFilterState,
4214
4201
  });
4215
4202
  } }),
4216
4203
  React__default["default"].createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: advancedFilterState.isMobile === true, onSelected: () => {
4217
4204
  advancedFilterState.isMobile = true;
4218
4205
  dispatch({
4219
- type: ActionType$5.UpdateAdvancedFilterState,
4206
+ type: ActionType$6.UpdateAdvancedFilterState,
4220
4207
  advancedFilterState,
4221
4208
  });
4222
4209
  } }),
4223
4210
  React__default["default"].createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: advancedFilterState.isMobile === false, onSelected: () => {
4224
4211
  advancedFilterState.isMobile = false;
4225
4212
  dispatch({
4226
- type: ActionType$5.UpdateAdvancedFilterState,
4213
+ type: ActionType$6.UpdateAdvancedFilterState,
4227
4214
  advancedFilterState,
4228
4215
  });
4229
4216
  }, noMarginOnRight: true }))),
@@ -4232,21 +4219,21 @@ const LogReviewer = (props) => {
4232
4219
  React__default["default"].createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: advancedFilterState.source === undefined, onSelected: () => {
4233
4220
  advancedFilterState.source = undefined;
4234
4221
  dispatch({
4235
- type: ActionType$5.UpdateAdvancedFilterState,
4222
+ type: ActionType$6.UpdateAdvancedFilterState,
4236
4223
  advancedFilterState,
4237
4224
  });
4238
4225
  } }),
4239
4226
  React__default["default"].createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: advancedFilterState.source === LogSource$1.Client, onSelected: () => {
4240
4227
  advancedFilterState.source = LogSource$1.Client;
4241
4228
  dispatch({
4242
- type: ActionType$5.UpdateAdvancedFilterState,
4229
+ type: ActionType$6.UpdateAdvancedFilterState,
4243
4230
  advancedFilterState,
4244
4231
  });
4245
4232
  } }),
4246
4233
  React__default["default"].createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: advancedFilterState.source === LogSource$1.Server, onSelected: () => {
4247
4234
  advancedFilterState.source = LogSource$1.Server;
4248
4235
  dispatch({
4249
- type: ActionType$5.UpdateAdvancedFilterState,
4236
+ type: ActionType$6.UpdateAdvancedFilterState,
4250
4237
  advancedFilterState,
4251
4238
  });
4252
4239
  }, noMarginOnRight: true })),
@@ -4257,7 +4244,7 @@ const LogReviewer = (props) => {
4257
4244
  advancedFilterState.courseName = ((e.target.value)
4258
4245
  .trim());
4259
4246
  dispatch({
4260
- type: ActionType$5.UpdateAdvancedFilterState,
4247
+ type: ActionType$6.UpdateAdvancedFilterState,
4261
4248
  advancedFilterState,
4262
4249
  });
4263
4250
  } })),
@@ -4267,7 +4254,7 @@ const LogReviewer = (props) => {
4267
4254
  advancedFilterState.courseName = ((e.target.value)
4268
4255
  .trim());
4269
4256
  dispatch({
4270
- type: ActionType$5.UpdateAdvancedFilterState,
4257
+ type: ActionType$6.UpdateAdvancedFilterState,
4271
4258
  advancedFilterState,
4272
4259
  });
4273
4260
  } })))))));
@@ -12087,11 +12074,11 @@ var CreatableSelect$1 = CreatableSelect;
12087
12074
  */
12088
12075
  /* ------------- Actions ------------ */
12089
12076
  // Types of actions
12090
- var ActionType$4;
12077
+ var ActionType$5;
12091
12078
  (function (ActionType) {
12092
12079
  // Update the input value
12093
12080
  ActionType["SetInputValue"] = "SetInputValue";
12094
- })(ActionType$4 || (ActionType$4 = {}));
12081
+ })(ActionType$5 || (ActionType$5 = {}));
12095
12082
  /**
12096
12083
  * Reducer that executes actions
12097
12084
  * @author Yuen Ler Chow
@@ -12099,9 +12086,9 @@ var ActionType$4;
12099
12086
  * @param action action to execute
12100
12087
  * @returns updated state
12101
12088
  */
12102
- const reducer$5 = (state, action) => {
12089
+ const reducer$6 = (state, action) => {
12103
12090
  switch (action.type) {
12104
- case ActionType$4.SetInputValue: {
12091
+ case ActionType$5.SetInputValue: {
12105
12092
  return Object.assign(Object.assign({}, state), { inputValue: action.value });
12106
12093
  }
12107
12094
  default: {
@@ -12121,7 +12108,7 @@ const CreatableMultiselect = (props) => {
12121
12108
  inputValue: '',
12122
12109
  };
12123
12110
  // Initialize state
12124
- const [state, dispatch] = React.useReducer(reducer$5, initialState);
12111
+ const [state, dispatch] = React.useReducer(reducer$6, initialState);
12125
12112
  // Destructure common state
12126
12113
  const { inputValue } = state;
12127
12114
  /*------------------------------------------------------------------------*/
@@ -12198,7 +12185,7 @@ const CreatableMultiselect = (props) => {
12198
12185
  }
12199
12186
  // Reset text field to empty because the values have been added
12200
12187
  dispatch({
12201
- type: ActionType$4.SetInputValue,
12188
+ type: ActionType$5.SetInputValue,
12202
12189
  value: '',
12203
12190
  });
12204
12191
  };
@@ -12237,7 +12224,7 @@ const CreatableMultiselect = (props) => {
12237
12224
  else {
12238
12225
  // simply update the input value to the new input value
12239
12226
  dispatch({
12240
- type: ActionType$4.SetInputValue,
12227
+ type: ActionType$5.SetInputValue,
12241
12228
  value: newValue,
12242
12229
  });
12243
12230
  }
@@ -12289,13 +12276,13 @@ const style$1 = `
12289
12276
  `;
12290
12277
  /* ------------- Actions ------------ */
12291
12278
  // Types of actions
12292
- var ActionType$3;
12279
+ var ActionType$4;
12293
12280
  (function (ActionType) {
12294
12281
  // Update the DBEntry
12295
12282
  ActionType["UpdateDBEntry"] = "UpdateDBEntry";
12296
12283
  // Start the save spinner
12297
12284
  ActionType["StartSave"] = "StartSave";
12298
- })(ActionType$3 || (ActionType$3 = {}));
12285
+ })(ActionType$4 || (ActionType$4 = {}));
12299
12286
  /**
12300
12287
  * Reducer that executes actions
12301
12288
  * @author Yuen Ler Chow
@@ -12303,12 +12290,12 @@ var ActionType$3;
12303
12290
  * @param action action to execute
12304
12291
  * @returns updated state
12305
12292
  */
12306
- const reducer$4 = (state, action) => {
12293
+ const reducer$5 = (state, action) => {
12307
12294
  switch (action.type) {
12308
- case ActionType$3.UpdateDBEntry: {
12295
+ case ActionType$4.UpdateDBEntry: {
12309
12296
  return Object.assign(Object.assign({}, state), { entry: action.dbEntry });
12310
12297
  }
12311
- case ActionType$3.StartSave: {
12298
+ case ActionType$4.StartSave: {
12312
12299
  return Object.assign(Object.assign({}, state), { saving: true });
12313
12300
  }
12314
12301
  default: {
@@ -12333,7 +12320,7 @@ const AddOrEditDBEntry = (props) => {
12333
12320
  saving: false,
12334
12321
  };
12335
12322
  // Initialize state
12336
- const [state, dispatch] = React.useReducer(reducer$4, initialState);
12323
+ const [state, dispatch] = React.useReducer(reducer$5, initialState);
12337
12324
  // Destructure common state
12338
12325
  const { entry, saving, } = state;
12339
12326
  /*------------------------------------------------------------------------*/
@@ -12345,7 +12332,7 @@ const AddOrEditDBEntry = (props) => {
12345
12332
  */
12346
12333
  const save = () => __awaiter(void 0, void 0, void 0, function* () {
12347
12334
  // Start the save loading indicator
12348
- dispatch({ type: ActionType$3.StartSave });
12335
+ dispatch({ type: ActionType$4.StartSave });
12349
12336
  // add all default values to the entry
12350
12337
  entryFields.forEach((field) => {
12351
12338
  if (field.defaultValue && !entry[field.objectKey]) {
@@ -12528,7 +12515,7 @@ const AddOrEditDBEntry = (props) => {
12528
12515
  return (React__default["default"].createElement(RadioButton, { key: choice.value, text: choice.title, selected: entry[field.objectKey] === choice.value, onSelected: () => {
12529
12516
  entry[field.objectKey] = choice.value;
12530
12517
  dispatch({
12531
- type: ActionType$3.UpdateDBEntry,
12518
+ type: ActionType$4.UpdateDBEntry,
12532
12519
  dbEntry: entry,
12533
12520
  });
12534
12521
  }, ariaLabel: choice.title }));
@@ -12540,7 +12527,7 @@ const AddOrEditDBEntry = (props) => {
12540
12527
  React__default["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) => {
12541
12528
  entry[field.objectKey] = (e.target.value);
12542
12529
  dispatch({
12543
- type: ActionType$3.UpdateDBEntry,
12530
+ type: ActionType$4.UpdateDBEntry,
12544
12531
  dbEntry: entry,
12545
12532
  });
12546
12533
  } }))));
@@ -12553,7 +12540,7 @@ const AddOrEditDBEntry = (props) => {
12553
12540
  entry[field.objectKey] = (e.target.value
12554
12541
  .replace(/[^0-9]/g, ''));
12555
12542
  dispatch({
12556
- type: ActionType$3.UpdateDBEntry,
12543
+ type: ActionType$4.UpdateDBEntry,
12557
12544
  dbEntry: entry,
12558
12545
  });
12559
12546
  } }))));
@@ -12583,7 +12570,7 @@ const AddOrEditDBEntry = (props) => {
12583
12570
  }
12584
12571
  // Save
12585
12572
  dispatch({
12586
- type: ActionType$3.UpdateDBEntry,
12573
+ type: ActionType$4.UpdateDBEntry,
12587
12574
  dbEntry: entry,
12588
12575
  });
12589
12576
  }, ariaLabel: choice.title }));
@@ -12598,7 +12585,7 @@ const AddOrEditDBEntry = (props) => {
12598
12585
  // Update entry and save
12599
12586
  entry[field.objectKey] = values;
12600
12587
  dispatch({
12601
- type: ActionType$3.UpdateDBEntry,
12588
+ type: ActionType$4.UpdateDBEntry,
12602
12589
  dbEntry: entry,
12603
12590
  });
12604
12591
  } })))));
@@ -12611,7 +12598,7 @@ const AddOrEditDBEntry = (props) => {
12611
12598
  React__default["default"].createElement(CreatableMultiselect, { disabled: disabled, type: DBEntryFieldType$1.NumberArray, values: entry[field.objectKey] || [], onChange: (values) => {
12612
12599
  entry[field.objectKey] = values;
12613
12600
  dispatch({
12614
- type: ActionType$3.UpdateDBEntry,
12601
+ type: ActionType$4.UpdateDBEntry,
12615
12602
  dbEntry: entry,
12616
12603
  });
12617
12604
  } })))));
@@ -12685,7 +12672,7 @@ const generateEndpointPath = (collectionName, adminsOnly) => {
12685
12672
  */
12686
12673
  /* ------------- Actions ------------ */
12687
12674
  // Types of actions
12688
- var ActionType$2;
12675
+ var ActionType$3;
12689
12676
  (function (ActionType) {
12690
12677
  // Show adder
12691
12678
  ActionType["ShowAdder"] = "ShowAdder";
@@ -12699,7 +12686,7 @@ var ActionType$2;
12699
12686
  ActionType["StartDelete"] = "StartDelete";
12700
12687
  // Finish deletion process
12701
12688
  ActionType["FinishDelete"] = "FinishDelete";
12702
- })(ActionType$2 || (ActionType$2 = {}));
12689
+ })(ActionType$3 || (ActionType$3 = {}));
12703
12690
  /**
12704
12691
  * Reducer that executes actions
12705
12692
  * @author Yuen Ler Chow
@@ -12707,18 +12694,18 @@ var ActionType$2;
12707
12694
  * @param action action to execute
12708
12695
  * @returns updated state
12709
12696
  */
12710
- const reducer$3 = (state, action) => {
12697
+ const reducer$4 = (state, action) => {
12711
12698
  switch (action.type) {
12712
- case ActionType$2.FinishLoading: {
12699
+ case ActionType$3.FinishLoading: {
12713
12700
  return Object.assign(Object.assign({}, state), { loading: false, dbEntries: action.dbEntries });
12714
12701
  }
12715
- case ActionType$2.ShowAdder: {
12702
+ case ActionType$3.ShowAdder: {
12716
12703
  return Object.assign(Object.assign({}, state), { adding: true, dbEntryToEdit: undefined });
12717
12704
  }
12718
- case ActionType$2.ShowEditor: {
12705
+ case ActionType$3.ShowEditor: {
12719
12706
  return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: action.dbEntry });
12720
12707
  }
12721
- case ActionType$2.FinishAdd: {
12708
+ case ActionType$3.FinishAdd: {
12722
12709
  // Handle cancel
12723
12710
  const finishedEntry = action.dbEntry;
12724
12711
  if (!finishedEntry) {
@@ -12742,10 +12729,10 @@ const reducer$3 = (state, action) => {
12742
12729
  // Update the state
12743
12730
  return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: undefined, dbEntries: updatedDbEntries });
12744
12731
  }
12745
- case ActionType$2.StartDelete: {
12732
+ case ActionType$3.StartDelete: {
12746
12733
  return Object.assign(Object.assign({}, state), { loading: true });
12747
12734
  }
12748
- case ActionType$2.FinishDelete: {
12735
+ case ActionType$3.FinishDelete: {
12749
12736
  return Object.assign(Object.assign({}, state), { loading: false,
12750
12737
  // Remove the deleted entry from the list
12751
12738
  dbEntries: state.dbEntries.filter((entry) => {
@@ -12771,7 +12758,7 @@ const DBEntryManagerPanel = (props) => {
12771
12758
  loading: true,
12772
12759
  };
12773
12760
  // Initialize state
12774
- const [state, dispatch] = React.useReducer(reducer$3, initialState);
12761
+ const [state, dispatch] = React.useReducer(reducer$4, initialState);
12775
12762
  // Destructure common state
12776
12763
  const { adding, dbEntryToEdit, dbEntries, loading, } = state;
12777
12764
  /*------------------------------------------------------------------------*/
@@ -12797,7 +12784,7 @@ const DBEntryManagerPanel = (props) => {
12797
12784
  try {
12798
12785
  // Start loader
12799
12786
  dispatch({
12800
- type: ActionType$2.StartDelete,
12787
+ type: ActionType$3.StartDelete,
12801
12788
  });
12802
12789
  // Perform deletion
12803
12790
  yield visitServerEndpoint({
@@ -12806,7 +12793,7 @@ const DBEntryManagerPanel = (props) => {
12806
12793
  });
12807
12794
  // Finish loader
12808
12795
  dispatch({
12809
- type: ActionType$2.FinishDelete,
12796
+ type: ActionType$3.FinishDelete,
12810
12797
  dbEntry: entry,
12811
12798
  idPropName,
12812
12799
  });
@@ -12835,7 +12822,7 @@ const DBEntryManagerPanel = (props) => {
12835
12822
  });
12836
12823
  // Save loaded data
12837
12824
  dispatch({
12838
- type: ActionType$2.FinishLoading,
12825
+ type: ActionType$3.FinishLoading,
12839
12826
  dbEntries: data,
12840
12827
  });
12841
12828
  }
@@ -12878,7 +12865,7 @@ const DBEntryManagerPanel = (props) => {
12878
12865
  React__default["default"].createElement("span", { className: "d-none d-md-inline ms-1" }, "Remove")),
12879
12866
  !disableEdit && (React__default["default"].createElement("button", { type: "button", id: `DBEntryManagerPanel-edit-with-id-${entry[idPropName]}`, className: "btn btn-primary", "aria-label": `edit db entry: ${entry[titlePropName]}`, onClick: () => {
12880
12867
  dispatch({
12881
- type: ActionType$2.ShowEditor,
12868
+ type: ActionType$3.ShowEditor,
12882
12869
  dbEntry: entry,
12883
12870
  });
12884
12871
  } },
@@ -12888,7 +12875,7 @@ const DBEntryManagerPanel = (props) => {
12888
12875
  React__default["default"].createElement("div", { className: "d-grid" },
12889
12876
  React__default["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: () => {
12890
12877
  dispatch({
12891
- type: ActionType$2.ShowAdder,
12878
+ type: ActionType$3.ShowAdder,
12892
12879
  });
12893
12880
  } },
12894
12881
  React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faPlus, className: "me-2" }),
@@ -12900,7 +12887,7 @@ const DBEntryManagerPanel = (props) => {
12900
12887
  if (!loading && (adding || dbEntryToEdit)) {
12901
12888
  body = (React__default["default"].createElement(AddOrEditDBEntry, { saveEndpointPath: endpoint, validateEntry: validateEntry, modifyEntry: modifyEntry, entryFields: entryFields, dbEntryToEdit: dbEntryToEdit, idPropName: idPropName, entries: dbEntries, itemName: itemName, onFinished: (entry) => {
12902
12889
  dispatch({
12903
- type: ActionType$2.FinishAdd,
12890
+ type: ActionType$3.FinishAdd,
12904
12891
  dbEntry: entry,
12905
12892
  idPropName,
12906
12893
  });
@@ -13097,25 +13084,25 @@ const getItemIds = (items) => {
13097
13084
  };
13098
13085
  /* ------------- Actions ------------ */
13099
13086
  // Types of actions
13100
- var ActionType$1;
13087
+ var ActionType$2;
13101
13088
  (function (ActionType) {
13102
13089
  // Hide the "jump to bottom" button
13103
13090
  ActionType["HideJumpToBottomButton"] = "HideJumpToBottomButton";
13104
13091
  // Show the "jump to bottom" button
13105
13092
  ActionType["ShowJumpToBottomButton"] = "ShowJumpToBottomButton";
13106
- })(ActionType$1 || (ActionType$1 = {}));
13093
+ })(ActionType$2 || (ActionType$2 = {}));
13107
13094
  /**
13108
13095
  * Reducer that executes actions
13109
13096
  * @author Gabe Abrams
13110
13097
  * @param state current state
13111
13098
  * @param action action to execute
13112
13099
  */
13113
- const reducer$2 = (state, action) => {
13100
+ const reducer$3 = (state, action) => {
13114
13101
  switch (action.type) {
13115
- case ActionType$1.HideJumpToBottomButton: {
13102
+ case ActionType$2.HideJumpToBottomButton: {
13116
13103
  return Object.assign(Object.assign({}, state), { jumpToBottomButtonVisible: false });
13117
13104
  }
13118
- case ActionType$1.ShowJumpToBottomButton: {
13105
+ case ActionType$2.ShowJumpToBottomButton: {
13119
13106
  return Object.assign(Object.assign({}, state), { jumpToBottomButtonVisible: true });
13120
13107
  }
13121
13108
  default: {
@@ -13139,7 +13126,7 @@ const AutoscrollToBottomContainer = (props) => {
13139
13126
  jumpToBottomButtonVisible: false,
13140
13127
  };
13141
13128
  // Initialize state
13142
- const [state, dispatch] = React.useReducer(reducer$2, initialState);
13129
+ const [state, dispatch] = React.useReducer(reducer$3, initialState);
13143
13130
  // Destructure common state
13144
13131
  const { jumpToBottomButtonVisible, } = state;
13145
13132
  /* -------------- Refs -------------- */
@@ -13185,7 +13172,7 @@ const AutoscrollToBottomContainer = (props) => {
13185
13172
  }
13186
13173
  // Update state
13187
13174
  dispatch({
13188
- type: ActionType$1.HideJumpToBottomButton,
13175
+ type: ActionType$2.HideJumpToBottomButton,
13189
13176
  });
13190
13177
  // Scroll to bottom
13191
13178
  container.current.scrollTop = (container.current.scrollHeight
@@ -13209,7 +13196,7 @@ const AutoscrollToBottomContainer = (props) => {
13209
13196
  if (isScrolledToBottom()) {
13210
13197
  // Hide button
13211
13198
  dispatch({
13212
- type: ActionType$1.HideJumpToBottomButton,
13199
+ type: ActionType$2.HideJumpToBottomButton,
13213
13200
  });
13214
13201
  }
13215
13202
  };
@@ -13251,7 +13238,7 @@ const AutoscrollToBottomContainer = (props) => {
13251
13238
  else {
13252
13239
  // Not scrolled to bottom. Show "jump to bottom" button.
13253
13240
  dispatch({
13254
- type: ActionType$1.ShowJumpToBottomButton,
13241
+ type: ActionType$2.ShowJumpToBottomButton,
13255
13242
  });
13256
13243
  }
13257
13244
  }, [items]);
@@ -13321,25 +13308,25 @@ const combineClassNames = (classNames) => {
13321
13308
  */
13322
13309
  /* ------------- Actions ------------ */
13323
13310
  // Types of actions
13324
- var ActionType;
13311
+ var ActionType$1;
13325
13312
  (function (ActionType) {
13326
13313
  // Start hovering on an option
13327
13314
  ActionType["StartHover"] = "StartHover";
13328
13315
  // Stop hovering on an option
13329
13316
  ActionType["StopHover"] = "StopHover";
13330
- })(ActionType || (ActionType = {}));
13317
+ })(ActionType$1 || (ActionType$1 = {}));
13331
13318
  /**
13332
13319
  * Reducer that executes actions
13333
13320
  * @author Gabe Abrams
13334
13321
  * @param state current state
13335
13322
  * @param action action to execute
13336
13323
  */
13337
- const reducer$1 = (state, action) => {
13324
+ const reducer$2 = (state, action) => {
13338
13325
  switch (action.type) {
13339
- case ActionType.StartHover: {
13326
+ case ActionType$1.StartHover: {
13340
13327
  return Object.assign(Object.assign({}, state), { hoveredOptionId: action.hoveredOptionId });
13341
13328
  }
13342
- case ActionType.StopHover: {
13329
+ case ActionType$1.StopHover: {
13343
13330
  return Object.assign(Object.assign({}, state), { hoveredOptionId: undefined });
13344
13331
  }
13345
13332
  default: {
@@ -13363,7 +13350,7 @@ const MultiSwitch = (props) => {
13363
13350
  hoveredOptionId: undefined,
13364
13351
  };
13365
13352
  // Initialize state
13366
- const [state, dispatch] = React.useReducer(reducer$1, initialState);
13353
+ const [state, dispatch] = React.useReducer(reducer$2, initialState);
13367
13354
  // Destructure common state
13368
13355
  const { hoveredOptionId, } = state;
13369
13356
  /*------------------------------------------------------------------------*/
@@ -13375,7 +13362,7 @@ const MultiSwitch = (props) => {
13375
13362
  });
13376
13363
  // Constants
13377
13364
  const gutterRems = heightRem * 0.1;
13378
- const itemWidthRems = heightRem * 1.3;
13365
+ const itemWidthRems = heightRem * 2.2;
13379
13366
  const textFontSize = heightRem / 3.5;
13380
13367
  const iconFontSize = heightRem / 2;
13381
13368
  const borderWidthRems = 0.05;
@@ -13495,27 +13482,27 @@ const MultiSwitch = (props) => {
13495
13482
  : `click to select option "${option.label}"`), onClick: () => {
13496
13483
  // Remove hover
13497
13484
  dispatch({
13498
- type: ActionType.StopHover,
13485
+ type: ActionType$1.StopHover,
13499
13486
  });
13500
13487
  // Notify parent
13501
13488
  onChange(option.id);
13502
13489
  }, onMouseEnter: () => {
13503
13490
  dispatch({
13504
- type: ActionType.StartHover,
13491
+ type: ActionType$1.StartHover,
13505
13492
  hoveredOptionId: option.id,
13506
13493
  });
13507
13494
  }, onMouseLeave: () => {
13508
13495
  dispatch({
13509
- type: ActionType.StopHover,
13496
+ type: ActionType$1.StopHover,
13510
13497
  });
13511
13498
  }, onFocus: () => {
13512
13499
  dispatch({
13513
- type: ActionType.StartHover,
13500
+ type: ActionType$1.StartHover,
13514
13501
  hoveredOptionId: option.id,
13515
13502
  });
13516
13503
  }, onBlur: () => {
13517
13504
  dispatch({
13518
- type: ActionType.StopHover,
13505
+ type: ActionType$1.StopHover,
13519
13506
  });
13520
13507
  }, style: {
13521
13508
  pointerEvents: ((option.id === selectedOptionId)
@@ -13534,6 +13521,147 @@ const MultiSwitch = (props) => {
13534
13521
  React__default["default"].createElement("div", { className: "MultiSwitch-highlight-container" }, highlight)));
13535
13522
  };
13536
13523
 
13524
+ // Types of dropdown items
13525
+ var DropdownItemType;
13526
+ (function (DropdownItemType) {
13527
+ // Dropdown header
13528
+ DropdownItemType["Header"] = "Header";
13529
+ // Dropdown divider
13530
+ DropdownItemType["Divider"] = "Divider";
13531
+ // Dropdown item
13532
+ DropdownItemType["Item"] = "Item";
13533
+ })(DropdownItemType || (DropdownItemType = {}));
13534
+ var DropdownItemType$1 = DropdownItemType;
13535
+
13536
+ /**
13537
+ * A simple dropdown menu
13538
+ * @author Alessandra De Lucas
13539
+ * @author Yuen Ler Chow
13540
+ * @author Gabe Abrams
13541
+ */
13542
+ /* ------------- Actions ------------ */
13543
+ // Types of actions
13544
+ var ActionType;
13545
+ (function (ActionType) {
13546
+ // Toggle opening the dropdown menu
13547
+ ActionType["ToggleDropdown"] = "ToggleDropdown";
13548
+ // Close the dropdown menu
13549
+ ActionType["CloseDropdown"] = "CloseDropdown";
13550
+ })(ActionType || (ActionType = {}));
13551
+ /**
13552
+ * Reducer that executes actions
13553
+ * @author Alessandra De Lucas
13554
+ * @author Yuen Ler Chow
13555
+ * @param state current state
13556
+ * @param action action to execute
13557
+ */
13558
+ const reducer$1 = (state, action) => {
13559
+ switch (action.type) {
13560
+ case ActionType.ToggleDropdown: {
13561
+ return Object.assign(Object.assign({}, state), { isDropdownOpen: !state.isDropdownOpen });
13562
+ }
13563
+ case ActionType.CloseDropdown: {
13564
+ return Object.assign(Object.assign({}, state), { isDropdownOpen: false });
13565
+ }
13566
+ default: {
13567
+ return state;
13568
+ }
13569
+ }
13570
+ };
13571
+ /*------------------------------------------------------------------------*/
13572
+ /* ------------------------------ Component ----------------------------- */
13573
+ /*------------------------------------------------------------------------*/
13574
+ const Dropdown = (props) => {
13575
+ /*------------------------------------------------------------------------*/
13576
+ /* -------------------------------- Setup ------------------------------- */
13577
+ /*------------------------------------------------------------------------*/
13578
+ /* -------------- Props ------------- */
13579
+ // Destructure all props
13580
+ const { dropdownButton, items, } = props;
13581
+ /* -------------- State ------------- */
13582
+ // Initial state
13583
+ const initialState = {
13584
+ isDropdownOpen: false,
13585
+ };
13586
+ // Initialize state
13587
+ const [state, dispatch] = React.useReducer(reducer$1, initialState);
13588
+ // Destructure common state
13589
+ const { isDropdownOpen, } = state;
13590
+ /* -------------- Refs -------------- */
13591
+ // Initialize refs
13592
+ const dropdownRef = React.useRef(null);
13593
+ /*------------------------------------------------------------------------*/
13594
+ /* ------------------------- Component Functions ------------------------ */
13595
+ /*------------------------------------------------------------------------*/
13596
+ /**
13597
+ * Handle clicking outside of the dropdown menu to close it
13598
+ * @author Yuen Ler Chow
13599
+ * @param event the mouse event
13600
+ */
13601
+ const handleClickOutside = (event) => {
13602
+ if (
13603
+ // Dropdown has been rendered
13604
+ dropdownRef.current
13605
+ // Click occurred outside the dropdown
13606
+ && !dropdownRef.current.contains(event.target)) {
13607
+ dispatch({ type: ActionType.CloseDropdown });
13608
+ }
13609
+ };
13610
+ /*------------------------------------------------------------------------*/
13611
+ /* ------------------------- Lifecycle Functions ------------------------ */
13612
+ /*------------------------------------------------------------------------*/
13613
+ /**
13614
+ * Mount
13615
+ * @author Yuen Ler Chow
13616
+ */
13617
+ React.useEffect(() => {
13618
+ // Add event listener to close dropdown when clicking outside
13619
+ document.addEventListener('mousedown', handleClickOutside);
13620
+ // Cleanup
13621
+ return () => {
13622
+ document.removeEventListener('mousedown', handleClickOutside);
13623
+ };
13624
+ }, []);
13625
+ /*----------------------------------------*/
13626
+ /* --------------- Main UI -------------- */
13627
+ /*----------------------------------------*/
13628
+ return (React__default["default"].createElement("div", { className: "dropdown", ref: dropdownRef, "data-bs-theme": isDarkModeOn() ? 'dark' : undefined },
13629
+ React__default["default"].createElement("button", { className: combineClassNames([
13630
+ 'btn dropdown-toggle border',
13631
+ isDropdownOpen && 'show',
13632
+ `btn-${dropdownButton.variant}`,
13633
+ dropdownButton.variant === Variant$1.Light && 'text-dark',
13634
+ ]), type: "button", id: dropdownButton.id, "aria-expanded": isDropdownOpen, "aria-label": dropdownButton.ariaLabel, onClick: () => {
13635
+ dispatch({
13636
+ type: ActionType.ToggleDropdown,
13637
+ });
13638
+ } }, dropdownButton.content),
13639
+ React__default["default"].createElement("ul", { className: combineClassNames([
13640
+ 'dropdown-menu',
13641
+ isDarkModeOn() && 'dropdown-menu-dark',
13642
+ isDropdownOpen && 'show',
13643
+ ]) }, Object.values(items).map((item) => {
13644
+ if (item.type === DropdownItemType$1.Header) {
13645
+ return (
13646
+ // TODO: Implement header
13647
+ React__default["default"].createElement("span", null));
13648
+ }
13649
+ if (item.type === DropdownItemType$1.Divider) {
13650
+ return (
13651
+ // TODO: Implement divider
13652
+ React__default["default"].createElement("span", null));
13653
+ }
13654
+ return (React__default["default"].createElement("li", { key: item.id },
13655
+ React__default["default"].createElement("button", { type: "button", "aria-label": item.ariaLabel, className: "dropdown-item", onClick: (e) => {
13656
+ e.preventDefault();
13657
+ dispatch({
13658
+ type: ActionType.CloseDropdown,
13659
+ });
13660
+ item.onClick();
13661
+ } }, item.content)));
13662
+ }))));
13663
+ };
13664
+
13537
13665
  /**
13538
13666
  * One minute in ms
13539
13667
  * @author Gabe Abrams
@@ -15843,6 +15971,180 @@ const shuffleArray = (arr) => {
15843
15971
  return newArr;
15844
15972
  };
15845
15973
 
15974
+ /**
15975
+ * Sends and retries an http request
15976
+ * @author Gabriel Abrams
15977
+ * @param opts object containing all arguments
15978
+ * @param opts.path path to send request to
15979
+ * @param [opts.host] host to send request to
15980
+ * @param [opts.method=GET] http method to use
15981
+ * @param [opts.params] body/data to include in the request
15982
+ * @param [opts.headers] headers to include in the request
15983
+ * @param [opts.sendCrossDomainCredentials=true if in development mode] if true,
15984
+ * send cross-domain credentials even if not in dev mode
15985
+ * @param [opts.responseType=JSON] expected response type
15986
+ * @returns { body, status, headers } on success
15987
+ */
15988
+ const sendServerToServerRequest = (opts) => __awaiter(void 0, void 0, void 0, function* () {
15989
+ var _a;
15990
+ // Process method
15991
+ const method = (opts.method || 'GET');
15992
+ // Encode objects within params
15993
+ let params;
15994
+ if (opts.params) {
15995
+ params = {};
15996
+ Object.entries(opts.params).forEach(([key, val]) => {
15997
+ if (typeof val === 'object' && !Array.isArray(val)) {
15998
+ params[key] = JSON.stringify(val);
15999
+ }
16000
+ else {
16001
+ params[key] = val;
16002
+ }
16003
+ });
16004
+ }
16005
+ // Stringify parameters
16006
+ const stringifiedParams = qs__default["default"].stringify(params || {}, {
16007
+ encodeValuesOnly: true,
16008
+ arrayFormat: 'brackets',
16009
+ });
16010
+ // Create url (include query if GET)
16011
+ const query = (method === 'GET' ? `?${stringifiedParams}` : '');
16012
+ let url;
16013
+ if (!opts.host) {
16014
+ // No host included at all. Just send to a path
16015
+ url = `${opts.path}${query}`;
16016
+ }
16017
+ else {
16018
+ url = `https://${opts.host}${opts.path}${query}`;
16019
+ }
16020
+ // Update headers
16021
+ const headers = opts.headers || {};
16022
+ let data = null;
16023
+ if (!headers['Content-Type']) {
16024
+ // Form encoded
16025
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
16026
+ // Add data if applicable
16027
+ data = (method !== 'GET' ? stringifiedParams : null);
16028
+ }
16029
+ else {
16030
+ // JSON encode
16031
+ data = params;
16032
+ }
16033
+ // Encode data
16034
+ let encodedData;
16035
+ if (data) {
16036
+ if (headers['Content-Type'] === 'application/x-www-form-urlencoded') {
16037
+ encodedData = new URLSearchParams(params);
16038
+ }
16039
+ else {
16040
+ encodedData = JSON.stringify(data);
16041
+ }
16042
+ }
16043
+ // Send request
16044
+ try {
16045
+ const response = yield fetch(url, {
16046
+ method,
16047
+ mode: 'cors',
16048
+ headers: headers !== null && headers !== void 0 ? headers : {},
16049
+ body: ((method !== 'GET' && encodedData)
16050
+ ? encodedData
16051
+ : undefined),
16052
+ redirect: 'follow',
16053
+ });
16054
+ // Get headers map
16055
+ const responseHeaders = {};
16056
+ response.headers.forEach((value, key) => {
16057
+ responseHeaders[key] = value;
16058
+ });
16059
+ // Process response based on responseType
16060
+ try {
16061
+ // Parse response
16062
+ let responseBody;
16063
+ if (opts.responseType
16064
+ && opts.responseType === 'Text') {
16065
+ // Response type is text
16066
+ responseBody = yield response.text();
16067
+ }
16068
+ else {
16069
+ // Response type is JSON
16070
+ responseBody = yield response.json();
16071
+ }
16072
+ // Return response
16073
+ return {
16074
+ body: responseBody,
16075
+ status: response.status,
16076
+ headers: responseHeaders,
16077
+ };
16078
+ }
16079
+ catch (err) {
16080
+ throw new ErrorWithCode(`Failed to parse response as ${opts.responseType}: ${err === null || err === void 0 ? void 0 : err.message}`, ReactKitErrorCode$1.ResponseParseError);
16081
+ }
16082
+ }
16083
+ catch (err) {
16084
+ // Self-signed certificate error:
16085
+ if ((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes('self signed certificate')) {
16086
+ throw new ErrorWithCode('We refused to send a request because the receiver has self-signed certificates.', ReactKitErrorCode$1.SelfSigned);
16087
+ }
16088
+ // No tries left
16089
+ 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);
16090
+ }
16091
+ });
16092
+
16093
+ /**
16094
+ * Send a server-to-server request from this sever to another server that uses
16095
+ * dce-reactkit [for server only]
16096
+ * @author Gabe Abrams
16097
+ * @param opts object containing all arguments
16098
+ * @param opts.path - the path of the other server's endpoint
16099
+ * @param [opts.method=GET] - the method of the endpoint
16100
+ * @param [opts.params] - query/body parameters to include
16101
+ * @param [opts.headers] - headers to include
16102
+ * @returns response from server
16103
+ */
16104
+ const visitEndpointOnAnotherServer = (opts) => __awaiter(void 0, void 0, void 0, function* () {
16105
+ var _a;
16106
+ // Remove properties with undefined values
16107
+ let params;
16108
+ if (opts.params) {
16109
+ params = Object.fromEntries(Object
16110
+ .entries(opts.params)
16111
+ .filter(([, value]) => {
16112
+ return value !== undefined;
16113
+ }));
16114
+ }
16115
+ // Automatically JSONify arrays and objects
16116
+ if (params) {
16117
+ params = Object.fromEntries(Object
16118
+ .entries(params)
16119
+ .map(([key, value]) => {
16120
+ if (Array.isArray(value) || typeof value === 'object') {
16121
+ return [key, JSON.stringify(value)];
16122
+ }
16123
+ return [key, value];
16124
+ }));
16125
+ }
16126
+ // Send the request
16127
+ const response = yield sendServerToServerRequest({
16128
+ path: opts.path,
16129
+ method: (_a = opts.method) !== null && _a !== void 0 ? _a : 'GET',
16130
+ params,
16131
+ });
16132
+ // Check for failure
16133
+ if (!response || !response.body) {
16134
+ throw new ErrorWithCode('We didn\'t get a response from the server. Please check your internet connection.', ReactKitErrorCode$1.NoResponse);
16135
+ }
16136
+ if (!response.body.success) {
16137
+ // Other errors
16138
+ throw new ErrorWithCode((response.body.message
16139
+ || 'An unknown error occurred. Please contact an admin.'), (response.body.code
16140
+ || ReactKitErrorCode$1.NoCode));
16141
+ }
16142
+ // Success! Extract the body
16143
+ const { body } = response.body;
16144
+ // Return
16145
+ return body;
16146
+ });
16147
+
15846
16148
  /**
15847
16149
  * Days of the week
15848
16150
  * @author Gabe Abrams
@@ -15870,6 +16172,8 @@ exports.DBEntryFieldType = DBEntryFieldType$1;
15870
16172
  exports.DBEntryManagerPanel = DBEntryManagerPanel;
15871
16173
  exports.DayOfWeek = DayOfWeek$1;
15872
16174
  exports.Drawer = Drawer;
16175
+ exports.Dropdown = Dropdown;
16176
+ exports.DropdownItemType = DropdownItemType$1;
15873
16177
  exports.DynamicWord = DynamicWord;
15874
16178
  exports.ErrorBox = ErrorBox;
15875
16179
  exports.ErrorWithCode = ErrorWithCode;
@@ -15954,6 +16258,7 @@ exports.useForceRender = useForceRender;
15954
16258
  exports.validateEmail = validateEmail;
15955
16259
  exports.validatePhoneNumber = validatePhoneNumber;
15956
16260
  exports.validateString = validateString;
16261
+ exports.visitEndpointOnAnotherServer = visitEndpointOnAnotherServer;
15957
16262
  exports.visitServerEndpoint = visitServerEndpoint;
15958
16263
  exports.waitMs = waitMs;
15959
16264
  //# sourceMappingURL=index.js.map