dce-reactkit 3.5.5 → 3.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -293,7 +293,7 @@ const ModalButtonTypeToLabelAndVariant = {
293
293
  /*------------------------------------------------------------------------*/
294
294
  /* Style */
295
295
  /*------------------------------------------------------------------------*/
296
- const style$9 = `
296
+ const style$a = `
297
297
  .Modal-backdrop {
298
298
  position: fixed;
299
299
  top: 0;
@@ -467,7 +467,7 @@ const Modal = (props) => {
467
467
  left: 0,
468
468
  right: 0,
469
469
  } },
470
- React__default.createElement("style", null, style$9),
470
+ React__default.createElement("style", null, style$a),
471
471
  React__default.createElement("div", { className: `Modal-backdrop ${backdropAnimationClass}`, style: {
472
472
  zIndex: 5000000003,
473
473
  }, onClick: () => __awaiter(void 0, void 0, void 0, function* () {
@@ -986,7 +986,7 @@ const AppWrapper = (props) => {
986
986
  /*------------------------------------------------------------------------*/
987
987
  /* Style */
988
988
  /*------------------------------------------------------------------------*/
989
- const style$8 = `
989
+ const style$9 = `
990
990
  /* Container fades in */
991
991
  .LoadingSpinner-container {
992
992
  animation-name: LoadingSpinner-container-fade-in;
@@ -1064,7 +1064,7 @@ const LoadingSpinner = () => {
1064
1064
  /*------------------------------------------------------------------------*/
1065
1065
  // Add all four blips to a container
1066
1066
  return (React__default.createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
1067
- React__default.createElement("style", null, style$8),
1067
+ React__default.createElement("style", null, style$9),
1068
1068
  React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-1 me-1" }),
1069
1069
  React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-2 me-1" }),
1070
1070
  React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-3 me-1" }),
@@ -1078,7 +1078,7 @@ const LoadingSpinner = () => {
1078
1078
  /*------------------------------------------------------------------------*/
1079
1079
  /* Style */
1080
1080
  /*------------------------------------------------------------------------*/
1081
- const style$7 = `
1081
+ const style$8 = `
1082
1082
  /* Tab Box */
1083
1083
  .TabBox-box {
1084
1084
  /* Light Border */
@@ -1158,7 +1158,7 @@ const TabBox = (props) => {
1158
1158
  /*----------------------------------------*/
1159
1159
  // Full UI
1160
1160
  return (React__default.createElement("div", { className: `TabBox-container ${noBottomMargin ? '' : 'mb-2'}` },
1161
- React__default.createElement("style", null, style$7),
1161
+ React__default.createElement("style", null, style$8),
1162
1162
  React__default.createElement("div", { className: "TabBox-title-container" },
1163
1163
  React__default.createElement("div", { className: "TabBox-title" }, title)),
1164
1164
  React__default.createElement("div", { className: `TabBox-box ps-2 pt-2 pe-2 ${noBottomPadding ? '' : 'pb-2'}` },
@@ -1480,7 +1480,7 @@ const SimpleDateChooser = (props) => {
1480
1480
  /*------------------------------------------------------------------------*/
1481
1481
  /* Style */
1482
1482
  /*------------------------------------------------------------------------*/
1483
- const style$6 = `
1483
+ const style$7 = `
1484
1484
  .Drawer-container {
1485
1485
  margin-left: 1rem;
1486
1486
  margin-right: 1rem;
@@ -1514,7 +1514,7 @@ const Drawer = (props) => {
1514
1514
  return (React__default.createElement("div", { className: "Drawer-container", style: {
1515
1515
  backgroundColor: (customBackgroundColor !== null && customBackgroundColor !== void 0 ? customBackgroundColor : undefined),
1516
1516
  } },
1517
- React__default.createElement("style", null, style$6),
1517
+ React__default.createElement("style", null, style$7),
1518
1518
  children));
1519
1519
  };
1520
1520
 
@@ -1525,7 +1525,7 @@ const Drawer = (props) => {
1525
1525
  /*------------------------------------------------------------------------*/
1526
1526
  /* Style */
1527
1527
  /*------------------------------------------------------------------------*/
1528
- const style$5 = `
1528
+ const style$6 = `
1529
1529
  .PopSuccessMark-outer-container {
1530
1530
  position: relative;
1531
1531
  display: inline-block;
@@ -1630,7 +1630,7 @@ const PopSuccessMark = (props) => {
1630
1630
  width: `${sizeRem}rem`,
1631
1631
  height: `${sizeRem}rem`,
1632
1632
  }, "aria-label": "checkmark indicating success" },
1633
- React__default.createElement("style", null, style$5),
1633
+ React__default.createElement("style", null, style$6),
1634
1634
  React__default.createElement("div", { className: `PopSuccessMark-check-stroke-1 bg-${checkVariant}`, style: {
1635
1635
  borderRadius: `${sizeRem / 5}rem`,
1636
1636
  } }),
@@ -1646,7 +1646,7 @@ const PopSuccessMark = (props) => {
1646
1646
  /*------------------------------------------------------------------------*/
1647
1647
  /* Style */
1648
1648
  /*------------------------------------------------------------------------*/
1649
- const style$4 = `
1649
+ const style$5 = `
1650
1650
  .PopFailureMark-outer-container {
1651
1651
  position: relative;
1652
1652
  display: inline-block;
@@ -1750,7 +1750,7 @@ const PopFailureMark = (props) => {
1750
1750
  width: `${sizeRem}rem`,
1751
1751
  height: `${sizeRem}rem`,
1752
1752
  }, "aria-label": "mark indicating failure" },
1753
- React__default.createElement("style", null, style$4),
1753
+ React__default.createElement("style", null, style$5),
1754
1754
  React__default.createElement("div", { className: `PopFailureMark-x-stroke-1 bg-${xVariant}`, style: {
1755
1755
  borderRadius: `${sizeRem / 5}rem`,
1756
1756
  } }),
@@ -1766,7 +1766,7 @@ const PopFailureMark = (props) => {
1766
1766
  /*------------------------------------------------------------------------*/
1767
1767
  /* Style */
1768
1768
  /*------------------------------------------------------------------------*/
1769
- const style$3 = `
1769
+ const style$4 = `
1770
1770
  .PopPendingMark-outer-container {
1771
1771
  position: relative;
1772
1772
  display: inline-block;
@@ -1839,7 +1839,7 @@ const PopPendingMark = (props) => {
1839
1839
  width: `${sizeRem}rem`,
1840
1840
  height: `${sizeRem}rem`,
1841
1841
  }, "aria-label": "mark indicating that the item is pending" },
1842
- React__default.createElement("style", null, style$3),
1842
+ React__default.createElement("style", null, style$4),
1843
1843
  React__default.createElement("div", null,
1844
1844
  React__default.createElement(FontAwesomeIcon, { icon: faHourglass, className: `PopPendingMark-hourglass text-${hourglassVariant}`, style: {
1845
1845
  fontSize: `${sizeRem * 0.6}rem`,
@@ -1852,27 +1852,27 @@ const PopPendingMark = (props) => {
1852
1852
  */
1853
1853
  /* ------------- Actions ------------ */
1854
1854
  // Types of actions
1855
- var ActionType$7;
1855
+ var ActionType$8;
1856
1856
  (function (ActionType) {
1857
1857
  // Indicate that the text was recently copied
1858
1858
  ActionType["IndicateRecentlyCopied"] = "indicate-recently-copied";
1859
1859
  // Clear the status
1860
1860
  ActionType["ClearRecentlyCopiedStatus"] = "clear-recently-copied-status";
1861
- })(ActionType$7 || (ActionType$7 = {}));
1861
+ })(ActionType$8 || (ActionType$8 = {}));
1862
1862
  /**
1863
1863
  * Reducer that executes actions
1864
1864
  * @author Gabe Abrams
1865
1865
  * @param state current state
1866
1866
  * @param action action to execute
1867
1867
  */
1868
- const reducer$7 = (state, action) => {
1868
+ const reducer$8 = (state, action) => {
1869
1869
  switch (action.type) {
1870
- case ActionType$7.IndicateRecentlyCopied: {
1870
+ case ActionType$8.IndicateRecentlyCopied: {
1871
1871
  return {
1872
1872
  recentlyCopied: true,
1873
1873
  };
1874
1874
  }
1875
- case ActionType$7.ClearRecentlyCopiedStatus: {
1875
+ case ActionType$8.ClearRecentlyCopiedStatus: {
1876
1876
  return {
1877
1877
  recentlyCopied: false,
1878
1878
  };
@@ -1898,7 +1898,7 @@ const CopiableBox = (props) => {
1898
1898
  recentlyCopied: false,
1899
1899
  };
1900
1900
  // Initialize state
1901
- const [state, dispatch] = useReducer(reducer$7, initialState);
1901
+ const [state, dispatch] = useReducer(reducer$8, initialState);
1902
1902
  // Destructure common state
1903
1903
  const { recentlyCopied, } = state;
1904
1904
  /*------------------------------------------------------------------------*/
@@ -1918,13 +1918,13 @@ const CopiableBox = (props) => {
1918
1918
  }
1919
1919
  // Show copied notice
1920
1920
  dispatch({
1921
- type: ActionType$7.IndicateRecentlyCopied,
1921
+ type: ActionType$8.IndicateRecentlyCopied,
1922
1922
  });
1923
1923
  // Wait a moment
1924
1924
  yield waitMs(4000);
1925
1925
  // Hide copied notice
1926
1926
  dispatch({
1927
- type: ActionType$7.ClearRecentlyCopiedStatus,
1927
+ type: ActionType$8.ClearRecentlyCopiedStatus,
1928
1928
  });
1929
1929
  });
1930
1930
  /*------------------------------------------------------------------------*/
@@ -1980,20 +1980,20 @@ const CopiableBox = (props) => {
1980
1980
  */
1981
1981
  /* ------------- Actions ------------ */
1982
1982
  // Types of actions
1983
- var ActionType$6;
1983
+ var ActionType$7;
1984
1984
  (function (ActionType) {
1985
1985
  // Toggle whether a child are being shown
1986
1986
  ActionType["ToggleChild"] = "toggle-child";
1987
- })(ActionType$6 || (ActionType$6 = {}));
1987
+ })(ActionType$7 || (ActionType$7 = {}));
1988
1988
  /**
1989
1989
  * Reducer that executes actions
1990
1990
  * @author Gabe Abrams
1991
1991
  * @param state current state
1992
1992
  * @param action action to execute
1993
1993
  */
1994
- const reducer$6 = (state, action) => {
1994
+ const reducer$7 = (state, action) => {
1995
1995
  switch (action.type) {
1996
- case ActionType$6.ToggleChild: {
1996
+ case ActionType$7.ToggleChild: {
1997
1997
  return Object.assign(Object.assign({}, state), { childExpanded: Object.assign(Object.assign({}, state.childExpanded), { [String(action.id)]: !state.childExpanded[String(action.id)] }) });
1998
1998
  }
1999
1999
  default: {
@@ -2022,7 +2022,7 @@ const NestableItemList = (props) => {
2022
2022
  childExpanded: initChildExpanded,
2023
2023
  };
2024
2024
  // Initialize state
2025
- const [state, dispatch] = useReducer(reducer$6, initialState);
2025
+ const [state, dispatch] = useReducer(reducer$7, initialState);
2026
2026
  // Destructure common state
2027
2027
  const { childExpanded, } = state;
2028
2028
  /*------------------------------------------------------------------------*/
@@ -2112,7 +2112,7 @@ const NestableItemList = (props) => {
2112
2112
  backgroundColor: 'transparent',
2113
2113
  }, type: "button", onClick: () => {
2114
2114
  dispatch({
2115
- type: ActionType$6.ToggleChild,
2115
+ type: ActionType$7.ToggleChild,
2116
2116
  id: item.id,
2117
2117
  });
2118
2118
  }, "aria-label": `${childExpanded[item.id] ? 'Hide' : 'Show'} items in ${item.name}` },
@@ -2388,7 +2388,7 @@ var SortType;
2388
2388
  })(SortType || (SortType = {}));
2389
2389
  /* ------------- Actions ------------ */
2390
2390
  // Types of actions
2391
- var ActionType$5;
2391
+ var ActionType$6;
2392
2392
  (function (ActionType) {
2393
2393
  // Toggle sort column param
2394
2394
  ActionType["ToggleSortColumn"] = "toggle-sort-column";
@@ -2400,16 +2400,16 @@ var ActionType$5;
2400
2400
  ActionType["ShowAllColumns"] = "show-all-columns";
2401
2401
  // Hide all columns
2402
2402
  ActionType["HideAllColumns"] = "hide-all-columns";
2403
- })(ActionType$5 || (ActionType$5 = {}));
2403
+ })(ActionType$6 || (ActionType$6 = {}));
2404
2404
  /**
2405
2405
  * Reducer that executes actions
2406
2406
  * @author Gabe Abrams
2407
2407
  * @param state current state
2408
2408
  * @param action action to execute
2409
2409
  */
2410
- const reducer$5 = (state, action) => {
2410
+ const reducer$6 = (state, action) => {
2411
2411
  switch (action.type) {
2412
- case ActionType$5.ToggleSortColumn: {
2412
+ case ActionType$6.ToggleSortColumn: {
2413
2413
  if (action.param !== state.sortColumnParam) {
2414
2414
  // Different column param
2415
2415
  return Object.assign(Object.assign({}, state), { sortColumnParam: action.param, sortType: SortType.Ascending });
@@ -2421,22 +2421,22 @@ const reducer$5 = (state, action) => {
2421
2421
  // Stop sorting by column
2422
2422
  return Object.assign(Object.assign({}, state), { sortColumnParam: undefined, sortType: SortType.Ascending });
2423
2423
  }
2424
- case ActionType$5.UpdateColumnVisibility: {
2424
+ case ActionType$6.UpdateColumnVisibility: {
2425
2425
  const { columnVisibilityMap } = state;
2426
2426
  columnVisibilityMap[action.param] = action.visible;
2427
2427
  return Object.assign(Object.assign({}, state), { columnVisibilityMap });
2428
2428
  }
2429
- case ActionType$5.ToggleColVisCusModalVisibility: {
2429
+ case ActionType$6.ToggleColVisCusModalVisibility: {
2430
2430
  return Object.assign(Object.assign({}, state), { columnVisibilityCustomizationModalVisible: !state.columnVisibilityCustomizationModalVisible });
2431
2431
  }
2432
- case ActionType$5.ShowAllColumns: {
2432
+ case ActionType$6.ShowAllColumns: {
2433
2433
  const { columnVisibilityMap } = state;
2434
2434
  Object.keys(columnVisibilityMap).forEach((param) => {
2435
2435
  columnVisibilityMap[param] = true;
2436
2436
  });
2437
2437
  return Object.assign(Object.assign({}, state), { columnVisibilityMap });
2438
2438
  }
2439
- case ActionType$5.HideAllColumns: {
2439
+ case ActionType$6.HideAllColumns: {
2440
2440
  const { columnVisibilityMap } = state;
2441
2441
  Object.keys(columnVisibilityMap).forEach((param) => {
2442
2442
  columnVisibilityMap[param] = false;
@@ -2483,7 +2483,7 @@ const IntelliTable = (props) => {
2483
2483
  columnVisibilityCustomizationModalVisible: false,
2484
2484
  };
2485
2485
  // Initialize state
2486
- const [state, dispatch] = useReducer(reducer$5, initialState);
2486
+ const [state, dispatch] = useReducer(reducer$6, initialState);
2487
2487
  // Destructure common state
2488
2488
  const { sortColumnParam, sortType, columnVisibilityMap, columnVisibilityCustomizationModalVisible, } = state;
2489
2489
  /*------------------------------------------------------------------------*/
@@ -2506,13 +2506,13 @@ const IntelliTable = (props) => {
2506
2506
  return alert$1('Choose at least one column', 'To continue, you have to choose at least one column to show');
2507
2507
  }
2508
2508
  dispatch({
2509
- type: ActionType$5.ToggleColVisCusModalVisibility,
2509
+ type: ActionType$6.ToggleColVisCusModalVisibility,
2510
2510
  });
2511
2511
  }, okayVariant: Variant$1.Light },
2512
2512
  columns.map((column) => {
2513
2513
  return (React__default.createElement(CheckboxButton, { key: column.param, id: `IntelliTable-${id}-toggle-visibility-${column.param}`, className: "mb-2", text: column.title, onChanged: (checked) => {
2514
2514
  dispatch({
2515
- type: ActionType$5.UpdateColumnVisibility,
2515
+ type: ActionType$6.UpdateColumnVisibility,
2516
2516
  param: column.param,
2517
2517
  visible: checked,
2518
2518
  });
@@ -2521,12 +2521,12 @@ const IntelliTable = (props) => {
2521
2521
  React__default.createElement("div", { className: "mt-3" }, "Or you can:"),
2522
2522
  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: () => {
2523
2523
  dispatch({
2524
- type: ActionType$5.ShowAllColumns,
2524
+ type: ActionType$6.ShowAllColumns,
2525
2525
  });
2526
2526
  } }, "Select All"),
2527
2527
  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: () => {
2528
2528
  dispatch({
2529
- type: ActionType$5.HideAllColumns,
2529
+ type: ActionType$6.HideAllColumns,
2530
2530
  });
2531
2531
  } }, "Deselect All")));
2532
2532
  }
@@ -2577,7 +2577,7 @@ const IntelliTable = (props) => {
2577
2577
  React__default.createElement("div", null,
2578
2578
  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: () => {
2579
2579
  dispatch({
2580
- type: ActionType$5.ToggleSortColumn,
2580
+ type: ActionType$6.ToggleSortColumn,
2581
2581
  param: column.param,
2582
2582
  });
2583
2583
  } },
@@ -2766,7 +2766,7 @@ const IntelliTable = (props) => {
2766
2766
  React__default.createElement(CSVDownloadButton, { "aria-label": `download data as csv for ${title}`, id: `IntelliTable-${id}-download-as-csv`, filename: filename, csv: csv }),
2767
2767
  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: () => {
2768
2768
  dispatch({
2769
- type: ActionType$5.ToggleColVisCusModalVisibility,
2769
+ type: ActionType$6.ToggleColVisCusModalVisibility,
2770
2770
  });
2771
2771
  } },
2772
2772
  "Show/Hide Cols",
@@ -2798,7 +2798,7 @@ var FilterDrawer;
2798
2798
  /*------------------------------------------------------------------------*/
2799
2799
  /* Style */
2800
2800
  /*------------------------------------------------------------------------*/
2801
- const style$2 = `
2801
+ const style$3 = `
2802
2802
  .LogReviewer-outer-container {
2803
2803
  /* Full Screen */
2804
2804
  display: inline-block;
@@ -3132,7 +3132,7 @@ const genHumanReadableName = (machineReadableName) => {
3132
3132
  };
3133
3133
  /* ------------- Actions ------------ */
3134
3134
  // Types of actions
3135
- var ActionType$4;
3135
+ var ActionType$5;
3136
3136
  (function (ActionType) {
3137
3137
  // Show the loading bar
3138
3138
  ActionType["StartLoading"] = "start-loading";
@@ -3154,45 +3154,45 @@ var ActionType$4;
3154
3154
  ActionType["UpdateActionErrorFilterState"] = "update-action-error-filter-state";
3155
3155
  // Update the advanced filter state
3156
3156
  ActionType["UpdateAdvancedFilterState"] = "update-advanced-filter-state";
3157
- })(ActionType$4 || (ActionType$4 = {}));
3157
+ })(ActionType$5 || (ActionType$5 = {}));
3158
3158
  /**
3159
3159
  * Reducer that executes actions
3160
3160
  * @author Gabe Abrams
3161
3161
  * @param state current state
3162
3162
  * @param action action to execute
3163
3163
  */
3164
- const reducer$4 = (state, action) => {
3164
+ const reducer$5 = (state, action) => {
3165
3165
  switch (action.type) {
3166
- case ActionType$4.StartLoading: {
3166
+ case ActionType$5.StartLoading: {
3167
3167
  return Object.assign(Object.assign({}, state), { loading: true });
3168
3168
  }
3169
- case ActionType$4.FinishLoading: {
3169
+ case ActionType$5.FinishLoading: {
3170
3170
  return Object.assign(Object.assign({}, state), { loading: false, logMap: action.logMap });
3171
3171
  }
3172
- case ActionType$4.ToggleFilterDrawer: {
3172
+ case ActionType$5.ToggleFilterDrawer: {
3173
3173
  return Object.assign(Object.assign({}, state), { expandedFilterDrawer: (state.expandedFilterDrawer === action.filterDrawer
3174
3174
  ? undefined // hide
3175
3175
  : action.filterDrawer) });
3176
3176
  }
3177
- case ActionType$4.HideFilterDrawer: {
3177
+ case ActionType$5.HideFilterDrawer: {
3178
3178
  return Object.assign(Object.assign({}, state), { expandedFilterDrawer: undefined });
3179
3179
  }
3180
- case ActionType$4.ResetFilters: {
3180
+ case ActionType$5.ResetFilters: {
3181
3181
  return Object.assign(Object.assign({}, state), { dateFilterState: action.initDateFilterState, contextFilterState: action.initContextFilterState, tagFilterState: action.initTagFilterState, actionErrorFilterState: action.initActionErrorFilterState, advancedFilterState: action.initAdvancedFilterState });
3182
3182
  }
3183
- case ActionType$4.UpdateDateFilterState: {
3183
+ case ActionType$5.UpdateDateFilterState: {
3184
3184
  return Object.assign(Object.assign({}, state), { dateFilterState: action.dateFilterState });
3185
3185
  }
3186
- case ActionType$4.UpdateContextFilterState: {
3186
+ case ActionType$5.UpdateContextFilterState: {
3187
3187
  return Object.assign(Object.assign({}, state), { contextFilterState: action.contextFilterState });
3188
3188
  }
3189
- case ActionType$4.UpdateTagFilterState: {
3189
+ case ActionType$5.UpdateTagFilterState: {
3190
3190
  return Object.assign(Object.assign({}, state), { tagFilterState: action.tagFilterState });
3191
3191
  }
3192
- case ActionType$4.UpdateActionErrorFilterState: {
3192
+ case ActionType$5.UpdateActionErrorFilterState: {
3193
3193
  return Object.assign(Object.assign({}, state), { actionErrorFilterState: action.actionErrorFilterState });
3194
3194
  }
3195
- case ActionType$4.UpdateAdvancedFilterState: {
3195
+ case ActionType$5.UpdateAdvancedFilterState: {
3196
3196
  return Object.assign(Object.assign({}, state), { advancedFilterState: action.advancedFilterState });
3197
3197
  }
3198
3198
  default: {
@@ -3321,7 +3321,7 @@ const LogReviewer = (props) => {
3321
3321
  advancedFilterState: initAdvancedFilterState,
3322
3322
  };
3323
3323
  // Initialize state
3324
- const [state, dispatch] = useReducer(reducer$4, initialState);
3324
+ const [state, dispatch] = useReducer(reducer$5, initialState);
3325
3325
  // Destructure common state
3326
3326
  const { loading, logMap, expandedFilterDrawer, dateFilterState, contextFilterState, tagFilterState, actionErrorFilterState, advancedFilterState, } = state;
3327
3327
  /*------------------------------------------------------------------------*/
@@ -3372,7 +3372,7 @@ const LogReviewer = (props) => {
3372
3372
  const handleDateRangeUpdated = (newDateFilterState) => __awaiter(void 0, void 0, void 0, function* () {
3373
3373
  // Update state
3374
3374
  dispatch({
3375
- type: ActionType$4.UpdateDateFilterState,
3375
+ type: ActionType$5.UpdateDateFilterState,
3376
3376
  dateFilterState: newDateFilterState,
3377
3377
  });
3378
3378
  // Check which year/month combos we need to load
@@ -3383,7 +3383,7 @@ const LogReviewer = (props) => {
3383
3383
  }
3384
3384
  // Start loading
3385
3385
  dispatch({
3386
- type: ActionType$4.StartLoading,
3386
+ type: ActionType$5.StartLoading,
3387
3387
  });
3388
3388
  // Load required months
3389
3389
  try {
@@ -3407,7 +3407,7 @@ const LogReviewer = (props) => {
3407
3407
  }
3408
3408
  // Finish loading
3409
3409
  dispatch({
3410
- type: ActionType$4.FinishLoading,
3410
+ type: ActionType$5.FinishLoading,
3411
3411
  logMap,
3412
3412
  });
3413
3413
  });
@@ -3446,7 +3446,7 @@ const LogReviewer = (props) => {
3446
3446
  React__default.createElement("div", { className: "LogReviewer-filter-toggle-buttons alert alert-secondary p-2 m-0" },
3447
3447
  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: () => {
3448
3448
  dispatch({
3449
- type: ActionType$4.ToggleFilterDrawer,
3449
+ type: ActionType$5.ToggleFilterDrawer,
3450
3450
  filterDrawer: FilterDrawer.Date,
3451
3451
  });
3452
3452
  } },
@@ -3454,7 +3454,7 @@ const LogReviewer = (props) => {
3454
3454
  "Date"),
3455
3455
  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: () => {
3456
3456
  dispatch({
3457
- type: ActionType$4.ToggleFilterDrawer,
3457
+ type: ActionType$5.ToggleFilterDrawer,
3458
3458
  filterDrawer: FilterDrawer.Context,
3459
3459
  });
3460
3460
  } },
@@ -3462,7 +3462,7 @@ const LogReviewer = (props) => {
3462
3462
  "Context"),
3463
3463
  (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: () => {
3464
3464
  dispatch({
3465
- type: ActionType$4.ToggleFilterDrawer,
3465
+ type: ActionType$5.ToggleFilterDrawer,
3466
3466
  filterDrawer: FilterDrawer.Tag,
3467
3467
  });
3468
3468
  } },
@@ -3470,7 +3470,7 @@ const LogReviewer = (props) => {
3470
3470
  "Tag")),
3471
3471
  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: () => {
3472
3472
  dispatch({
3473
- type: ActionType$4.ToggleFilterDrawer,
3473
+ type: ActionType$5.ToggleFilterDrawer,
3474
3474
  filterDrawer: FilterDrawer.Action,
3475
3475
  });
3476
3476
  } },
@@ -3478,7 +3478,7 @@ const LogReviewer = (props) => {
3478
3478
  "Action"),
3479
3479
  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: () => {
3480
3480
  dispatch({
3481
- type: ActionType$4.ToggleFilterDrawer,
3481
+ type: ActionType$5.ToggleFilterDrawer,
3482
3482
  filterDrawer: FilterDrawer.Advanced,
3483
3483
  });
3484
3484
  } },
@@ -3486,7 +3486,7 @@ const LogReviewer = (props) => {
3486
3486
  "Advanced"),
3487
3487
  React__default.createElement("button", { type: "button", id: "LogReviewer-reset-filters-button", className: "btn btn-light", "aria-label": "reset filters", onClick: () => {
3488
3488
  dispatch({
3489
- type: ActionType$4.ResetFilters,
3489
+ type: ActionType$5.ResetFilters,
3490
3490
  initActionErrorFilterState,
3491
3491
  initAdvancedFilterState,
3492
3492
  initContextFilterState,
@@ -3608,7 +3608,7 @@ const LogReviewer = (props) => {
3608
3608
  }
3609
3609
  });
3610
3610
  dispatch({
3611
- type: ActionType$4.UpdateContextFilterState,
3611
+ type: ActionType$5.UpdateContextFilterState,
3612
3612
  contextFilterState,
3613
3613
  });
3614
3614
  } }));
@@ -3623,7 +3623,7 @@ const LogReviewer = (props) => {
3623
3623
  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) => {
3624
3624
  tagFilterState[tag] = checked;
3625
3625
  dispatch({
3626
- type: ActionType$4.UpdateTagFilterState,
3626
+ type: ActionType$5.UpdateTagFilterState,
3627
3627
  tagFilterState,
3628
3628
  });
3629
3629
  } }));
@@ -3636,21 +3636,21 @@ const LogReviewer = (props) => {
3636
3636
  React__default.createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
3637
3637
  actionErrorFilterState.type = undefined;
3638
3638
  dispatch({
3639
- type: ActionType$4.UpdateActionErrorFilterState,
3639
+ type: ActionType$5.UpdateActionErrorFilterState,
3640
3640
  actionErrorFilterState,
3641
3641
  });
3642
3642
  }, ariaLabel: "show logs of all types", selected: actionErrorFilterState.type === undefined }),
3643
3643
  React__default.createElement(RadioButton, { id: "LogReviewer-type-action-only", text: "Action Logs Only", onSelected: () => {
3644
3644
  actionErrorFilterState.type = LogType$1.Action;
3645
3645
  dispatch({
3646
- type: ActionType$4.UpdateActionErrorFilterState,
3646
+ type: ActionType$5.UpdateActionErrorFilterState,
3647
3647
  actionErrorFilterState,
3648
3648
  });
3649
3649
  }, ariaLabel: "only show action logs", selected: actionErrorFilterState.type === LogType$1.Action }),
3650
3650
  React__default.createElement(RadioButton, { id: "LogReviewer-type-error-only", text: "Action Error Only", onSelected: () => {
3651
3651
  actionErrorFilterState.type = LogType$1.Error;
3652
3652
  dispatch({
3653
- type: ActionType$4.UpdateActionErrorFilterState,
3653
+ type: ActionType$5.UpdateActionErrorFilterState,
3654
3654
  actionErrorFilterState,
3655
3655
  });
3656
3656
  }, ariaLabel: "only show error logs", selected: actionErrorFilterState.type === LogType$1.Error, noMarginOnRight: true })),
@@ -3662,7 +3662,7 @@ const LogReviewer = (props) => {
3662
3662
  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) => {
3663
3663
  actionErrorFilterState.action[action] = checked;
3664
3664
  dispatch({
3665
- type: ActionType$4.UpdateActionErrorFilterState,
3665
+ type: ActionType$5.UpdateActionErrorFilterState,
3666
3666
  actionErrorFilterState,
3667
3667
  });
3668
3668
  } }));
@@ -3673,7 +3673,7 @@ const LogReviewer = (props) => {
3673
3673
  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) => {
3674
3674
  actionErrorFilterState.target[target] = checked;
3675
3675
  dispatch({
3676
- type: ActionType$4.UpdateActionErrorFilterState,
3676
+ type: ActionType$5.UpdateActionErrorFilterState,
3677
3677
  actionErrorFilterState,
3678
3678
  });
3679
3679
  } }));
@@ -3685,7 +3685,7 @@ const LogReviewer = (props) => {
3685
3685
  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) => {
3686
3686
  actionErrorFilterState.errorMessage = e.target.value;
3687
3687
  dispatch({
3688
- type: ActionType$4.UpdateActionErrorFilterState,
3688
+ type: ActionType$5.UpdateActionErrorFilterState,
3689
3689
  actionErrorFilterState,
3690
3690
  });
3691
3691
  } })),
@@ -3696,7 +3696,7 @@ const LogReviewer = (props) => {
3696
3696
  .trim()
3697
3697
  .toUpperCase());
3698
3698
  dispatch({
3699
- type: ActionType$4.UpdateActionErrorFilterState,
3699
+ type: ActionType$5.UpdateActionErrorFilterState,
3700
3700
  actionErrorFilterState,
3701
3701
  });
3702
3702
  } }))))));
@@ -3710,7 +3710,7 @@ const LogReviewer = (props) => {
3710
3710
  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) => {
3711
3711
  advancedFilterState.userFirstName = e.target.value;
3712
3712
  dispatch({
3713
- type: ActionType$4.UpdateAdvancedFilterState,
3713
+ type: ActionType$5.UpdateAdvancedFilterState,
3714
3714
  advancedFilterState,
3715
3715
  });
3716
3716
  } })),
@@ -3719,7 +3719,7 @@ const LogReviewer = (props) => {
3719
3719
  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) => {
3720
3720
  advancedFilterState.userLastName = e.target.value;
3721
3721
  dispatch({
3722
- type: ActionType$4.UpdateAdvancedFilterState,
3722
+ type: ActionType$5.UpdateAdvancedFilterState,
3723
3723
  advancedFilterState,
3724
3724
  });
3725
3725
  } })),
@@ -3729,7 +3729,7 @@ const LogReviewer = (props) => {
3729
3729
  advancedFilterState.userEmail = ((e.target.value)
3730
3730
  .trim());
3731
3731
  dispatch({
3732
- type: ActionType$4.UpdateAdvancedFilterState,
3732
+ type: ActionType$5.UpdateAdvancedFilterState,
3733
3733
  advancedFilterState,
3734
3734
  });
3735
3735
  } })),
@@ -3743,7 +3743,7 @@ const LogReviewer = (props) => {
3743
3743
  .trim());
3744
3744
  }
3745
3745
  dispatch({
3746
- type: ActionType$4.UpdateAdvancedFilterState,
3746
+ type: ActionType$5.UpdateAdvancedFilterState,
3747
3747
  advancedFilterState,
3748
3748
  });
3749
3749
  } })),
@@ -3751,21 +3751,21 @@ const LogReviewer = (props) => {
3751
3751
  React__default.createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
3752
3752
  advancedFilterState.includeLearners = checked;
3753
3753
  dispatch({
3754
- type: ActionType$4.UpdateAdvancedFilterState,
3754
+ type: ActionType$5.UpdateAdvancedFilterState,
3755
3755
  advancedFilterState,
3756
3756
  });
3757
3757
  }, checked: advancedFilterState.includeLearners, ariaLabel: "show logs from students" }),
3758
3758
  React__default.createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
3759
3759
  advancedFilterState.includeTTMs = checked;
3760
3760
  dispatch({
3761
- type: ActionType$4.UpdateAdvancedFilterState,
3761
+ type: ActionType$5.UpdateAdvancedFilterState,
3762
3762
  advancedFilterState,
3763
3763
  });
3764
3764
  }, checked: advancedFilterState.includeTTMs, ariaLabel: "show logs from teaching team members" }),
3765
3765
  React__default.createElement(CheckboxButton, { text: "Admins", onChanged: (checked) => {
3766
3766
  advancedFilterState.includeAdmins = checked;
3767
3767
  dispatch({
3768
- type: ActionType$4.UpdateAdvancedFilterState,
3768
+ type: ActionType$5.UpdateAdvancedFilterState,
3769
3769
  advancedFilterState,
3770
3770
  });
3771
3771
  }, checked: advancedFilterState.includeAdmins, ariaLabel: "show logs from admins" }))),
@@ -3775,7 +3775,7 @@ const LogReviewer = (props) => {
3775
3775
  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) => {
3776
3776
  advancedFilterState.courseName = e.target.value;
3777
3777
  dispatch({
3778
- type: ActionType$4.UpdateAdvancedFilterState,
3778
+ type: ActionType$5.UpdateAdvancedFilterState,
3779
3779
  advancedFilterState,
3780
3780
  });
3781
3781
  } })),
@@ -3789,7 +3789,7 @@ const LogReviewer = (props) => {
3789
3789
  .trim());
3790
3790
  }
3791
3791
  dispatch({
3792
- type: ActionType$4.UpdateAdvancedFilterState,
3792
+ type: ActionType$5.UpdateAdvancedFilterState,
3793
3793
  advancedFilterState,
3794
3794
  });
3795
3795
  } }))),
@@ -3798,21 +3798,21 @@ const LogReviewer = (props) => {
3798
3798
  React__default.createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: advancedFilterState.isMobile === undefined, onSelected: () => {
3799
3799
  advancedFilterState.isMobile = undefined;
3800
3800
  dispatch({
3801
- type: ActionType$4.UpdateAdvancedFilterState,
3801
+ type: ActionType$5.UpdateAdvancedFilterState,
3802
3802
  advancedFilterState,
3803
3803
  });
3804
3804
  } }),
3805
3805
  React__default.createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: advancedFilterState.isMobile === true, onSelected: () => {
3806
3806
  advancedFilterState.isMobile = true;
3807
3807
  dispatch({
3808
- type: ActionType$4.UpdateAdvancedFilterState,
3808
+ type: ActionType$5.UpdateAdvancedFilterState,
3809
3809
  advancedFilterState,
3810
3810
  });
3811
3811
  } }),
3812
3812
  React__default.createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: advancedFilterState.isMobile === false, onSelected: () => {
3813
3813
  advancedFilterState.isMobile = false;
3814
3814
  dispatch({
3815
- type: ActionType$4.UpdateAdvancedFilterState,
3815
+ type: ActionType$5.UpdateAdvancedFilterState,
3816
3816
  advancedFilterState,
3817
3817
  });
3818
3818
  }, noMarginOnRight: true }))),
@@ -3821,21 +3821,21 @@ const LogReviewer = (props) => {
3821
3821
  React__default.createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: advancedFilterState.source === undefined, onSelected: () => {
3822
3822
  advancedFilterState.source = undefined;
3823
3823
  dispatch({
3824
- type: ActionType$4.UpdateAdvancedFilterState,
3824
+ type: ActionType$5.UpdateAdvancedFilterState,
3825
3825
  advancedFilterState,
3826
3826
  });
3827
3827
  } }),
3828
3828
  React__default.createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: advancedFilterState.source === LogSource$1.Client, onSelected: () => {
3829
3829
  advancedFilterState.source = LogSource$1.Client;
3830
3830
  dispatch({
3831
- type: ActionType$4.UpdateAdvancedFilterState,
3831
+ type: ActionType$5.UpdateAdvancedFilterState,
3832
3832
  advancedFilterState,
3833
3833
  });
3834
3834
  } }),
3835
3835
  React__default.createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: advancedFilterState.source === LogSource$1.Server, onSelected: () => {
3836
3836
  advancedFilterState.source = LogSource$1.Server;
3837
3837
  dispatch({
3838
- type: ActionType$4.UpdateAdvancedFilterState,
3838
+ type: ActionType$5.UpdateAdvancedFilterState,
3839
3839
  advancedFilterState,
3840
3840
  });
3841
3841
  }, noMarginOnRight: true })),
@@ -3846,7 +3846,7 @@ const LogReviewer = (props) => {
3846
3846
  advancedFilterState.courseName = ((e.target.value)
3847
3847
  .trim());
3848
3848
  dispatch({
3849
- type: ActionType$4.UpdateAdvancedFilterState,
3849
+ type: ActionType$5.UpdateAdvancedFilterState,
3850
3850
  advancedFilterState,
3851
3851
  });
3852
3852
  } })),
@@ -3856,7 +3856,7 @@ const LogReviewer = (props) => {
3856
3856
  advancedFilterState.courseName = ((e.target.value)
3857
3857
  .trim());
3858
3858
  dispatch({
3859
- type: ActionType$4.UpdateAdvancedFilterState,
3859
+ type: ActionType$5.UpdateAdvancedFilterState,
3860
3860
  advancedFilterState,
3861
3861
  });
3862
3862
  } })))))));
@@ -4135,7 +4135,7 @@ const LogReviewer = (props) => {
4135
4135
  }
4136
4136
  /* ---------- Wrap in Modal --------- */
4137
4137
  return (React__default.createElement("div", { className: "LogReviewer-outer-container" },
4138
- React__default.createElement("style", null, style$2),
4138
+ React__default.createElement("style", null, style$3),
4139
4139
  React__default.createElement("div", { className: "LogReviewer-inner-container" },
4140
4140
  React__default.createElement("div", { className: "LogReviewer-header" },
4141
4141
  React__default.createElement("div", { className: "LogReviewer-header-title" },
@@ -39461,11 +39461,11 @@ var CreatableSelect$1 = CreatableSelect;
39461
39461
  */
39462
39462
  /* ------------- Actions ------------ */
39463
39463
  // Types of actions
39464
- var ActionType$3;
39464
+ var ActionType$4;
39465
39465
  (function (ActionType) {
39466
39466
  // Update the input value
39467
39467
  ActionType["SetInputValue"] = "SetInputValue";
39468
- })(ActionType$3 || (ActionType$3 = {}));
39468
+ })(ActionType$4 || (ActionType$4 = {}));
39469
39469
  /**
39470
39470
  * Reducer that executes actions
39471
39471
  * @author Yuen Ler Chow
@@ -39473,9 +39473,9 @@ var ActionType$3;
39473
39473
  * @param action action to execute
39474
39474
  * @returns updated state
39475
39475
  */
39476
- const reducer$3 = (state, action) => {
39476
+ const reducer$4 = (state, action) => {
39477
39477
  switch (action.type) {
39478
- case ActionType$3.SetInputValue: {
39478
+ case ActionType$4.SetInputValue: {
39479
39479
  return Object.assign(Object.assign({}, state), { inputValue: action.value });
39480
39480
  }
39481
39481
  default: {
@@ -39495,7 +39495,7 @@ const CreatableMultiselect = (props) => {
39495
39495
  inputValue: '',
39496
39496
  };
39497
39497
  // Initialize state
39498
- const [state, dispatch] = useReducer(reducer$3, initialState);
39498
+ const [state, dispatch] = useReducer(reducer$4, initialState);
39499
39499
  // Destructure common state
39500
39500
  const { inputValue } = state;
39501
39501
  /*------------------------------------------------------------------------*/
@@ -39572,7 +39572,7 @@ const CreatableMultiselect = (props) => {
39572
39572
  }
39573
39573
  // Reset text field to empty because the values have been added
39574
39574
  dispatch({
39575
- type: ActionType$3.SetInputValue,
39575
+ type: ActionType$4.SetInputValue,
39576
39576
  value: '',
39577
39577
  });
39578
39578
  };
@@ -39611,7 +39611,7 @@ const CreatableMultiselect = (props) => {
39611
39611
  else {
39612
39612
  // simply update the input value to the new input value
39613
39613
  dispatch({
39614
- type: ActionType$3.SetInputValue,
39614
+ type: ActionType$4.SetInputValue,
39615
39615
  value: newValue,
39616
39616
  });
39617
39617
  }
@@ -39656,20 +39656,20 @@ const CreatableMultiselect = (props) => {
39656
39656
  /*------------------------------------------------------------------------*/
39657
39657
  /* -------------------------------- Style ------------------------------- */
39658
39658
  /*------------------------------------------------------------------------*/
39659
- const style$1 = `
39659
+ const style$2 = `
39660
39660
  .AddOrEditDBEntry-input-label {
39661
39661
  min-width: 7rem;
39662
39662
  }
39663
39663
  `;
39664
39664
  /* ------------- Actions ------------ */
39665
39665
  // Types of actions
39666
- var ActionType$2;
39666
+ var ActionType$3;
39667
39667
  (function (ActionType) {
39668
39668
  // Update the DBEntry
39669
39669
  ActionType["UpdateDBEntry"] = "UpdateDBEntry";
39670
39670
  // Start the save spinner
39671
39671
  ActionType["StartSave"] = "StartSave";
39672
- })(ActionType$2 || (ActionType$2 = {}));
39672
+ })(ActionType$3 || (ActionType$3 = {}));
39673
39673
  /**
39674
39674
  * Reducer that executes actions
39675
39675
  * @author Yuen Ler Chow
@@ -39677,12 +39677,12 @@ var ActionType$2;
39677
39677
  * @param action action to execute
39678
39678
  * @returns updated state
39679
39679
  */
39680
- const reducer$2 = (state, action) => {
39680
+ const reducer$3 = (state, action) => {
39681
39681
  switch (action.type) {
39682
- case ActionType$2.UpdateDBEntry: {
39682
+ case ActionType$3.UpdateDBEntry: {
39683
39683
  return Object.assign(Object.assign({}, state), { entry: action.dbEntry });
39684
39684
  }
39685
- case ActionType$2.StartSave: {
39685
+ case ActionType$3.StartSave: {
39686
39686
  return Object.assign(Object.assign({}, state), { saving: true });
39687
39687
  }
39688
39688
  default: {
@@ -39707,7 +39707,7 @@ const AddOrEditDBEntry = (props) => {
39707
39707
  saving: false,
39708
39708
  };
39709
39709
  // Initialize state
39710
- const [state, dispatch] = useReducer(reducer$2, initialState);
39710
+ const [state, dispatch] = useReducer(reducer$3, initialState);
39711
39711
  // Destructure common state
39712
39712
  const { entry, saving, } = state;
39713
39713
  /*------------------------------------------------------------------------*/
@@ -39719,7 +39719,7 @@ const AddOrEditDBEntry = (props) => {
39719
39719
  */
39720
39720
  const save = () => __awaiter(void 0, void 0, void 0, function* () {
39721
39721
  // Start the save loading indicator
39722
- dispatch({ type: ActionType$2.StartSave });
39722
+ dispatch({ type: ActionType$3.StartSave });
39723
39723
  // add all default values to the entry
39724
39724
  entryFields.forEach((field) => {
39725
39725
  if (field.defaultValue && !entry[field.objectKey]) {
@@ -39902,7 +39902,7 @@ const AddOrEditDBEntry = (props) => {
39902
39902
  return (React__default.createElement(RadioButton, { key: choice.value, text: choice.title, selected: entry[field.objectKey] === choice.value, onSelected: () => {
39903
39903
  entry[field.objectKey] = choice.value;
39904
39904
  dispatch({
39905
- type: ActionType$2.UpdateDBEntry,
39905
+ type: ActionType$3.UpdateDBEntry,
39906
39906
  dbEntry: entry,
39907
39907
  });
39908
39908
  }, ariaLabel: choice.title }));
@@ -39914,7 +39914,7 @@ const AddOrEditDBEntry = (props) => {
39914
39914
  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) => {
39915
39915
  entry[field.objectKey] = (e.target.value);
39916
39916
  dispatch({
39917
- type: ActionType$2.UpdateDBEntry,
39917
+ type: ActionType$3.UpdateDBEntry,
39918
39918
  dbEntry: entry,
39919
39919
  });
39920
39920
  } }))));
@@ -39927,7 +39927,7 @@ const AddOrEditDBEntry = (props) => {
39927
39927
  entry[field.objectKey] = (e.target.value
39928
39928
  .replace(/[^0-9]/g, ''));
39929
39929
  dispatch({
39930
- type: ActionType$2.UpdateDBEntry,
39930
+ type: ActionType$3.UpdateDBEntry,
39931
39931
  dbEntry: entry,
39932
39932
  });
39933
39933
  } }))));
@@ -39957,7 +39957,7 @@ const AddOrEditDBEntry = (props) => {
39957
39957
  }
39958
39958
  // Save
39959
39959
  dispatch({
39960
- type: ActionType$2.UpdateDBEntry,
39960
+ type: ActionType$3.UpdateDBEntry,
39961
39961
  dbEntry: entry,
39962
39962
  });
39963
39963
  }, ariaLabel: choice.title }));
@@ -39972,7 +39972,7 @@ const AddOrEditDBEntry = (props) => {
39972
39972
  // Update entry and save
39973
39973
  entry[field.objectKey] = values;
39974
39974
  dispatch({
39975
- type: ActionType$2.UpdateDBEntry,
39975
+ type: ActionType$3.UpdateDBEntry,
39976
39976
  dbEntry: entry,
39977
39977
  });
39978
39978
  } })))));
@@ -39985,7 +39985,7 @@ const AddOrEditDBEntry = (props) => {
39985
39985
  React__default.createElement(CreatableMultiselect, { disabled: disabled, type: DBEntryFieldType$1.NumberArray, values: entry[field.objectKey] || [], onChange: (values) => {
39986
39986
  entry[field.objectKey] = values;
39987
39987
  dispatch({
39988
- type: ActionType$2.UpdateDBEntry,
39988
+ type: ActionType$3.UpdateDBEntry,
39989
39989
  dbEntry: entry,
39990
39990
  });
39991
39991
  } })))));
@@ -40034,7 +40034,7 @@ const AddOrEditDBEntry = (props) => {
40034
40034
  /* --------------- Main UI -------------- */
40035
40035
  /*----------------------------------------*/
40036
40036
  return (React__default.createElement("div", { className: "alert alert-light text-black" },
40037
- React__default.createElement("style", null, style$1),
40037
+ React__default.createElement("style", null, style$2),
40038
40038
  body));
40039
40039
  };
40040
40040
 
@@ -40059,7 +40059,7 @@ const generateEndpointPath = (collectionName, adminsOnly) => {
40059
40059
  */
40060
40060
  /* ------------- Actions ------------ */
40061
40061
  // Types of actions
40062
- var ActionType$1;
40062
+ var ActionType$2;
40063
40063
  (function (ActionType) {
40064
40064
  // Show adder
40065
40065
  ActionType["ShowAdder"] = "ShowAdder";
@@ -40073,7 +40073,7 @@ var ActionType$1;
40073
40073
  ActionType["StartDelete"] = "StartDelete";
40074
40074
  // Finish deletion process
40075
40075
  ActionType["FinishDelete"] = "FinishDelete";
40076
- })(ActionType$1 || (ActionType$1 = {}));
40076
+ })(ActionType$2 || (ActionType$2 = {}));
40077
40077
  /**
40078
40078
  * Reducer that executes actions
40079
40079
  * @author Yuen Ler Chow
@@ -40081,18 +40081,18 @@ var ActionType$1;
40081
40081
  * @param action action to execute
40082
40082
  * @returns updated state
40083
40083
  */
40084
- const reducer$1 = (state, action) => {
40084
+ const reducer$2 = (state, action) => {
40085
40085
  switch (action.type) {
40086
- case ActionType$1.FinishLoading: {
40086
+ case ActionType$2.FinishLoading: {
40087
40087
  return Object.assign(Object.assign({}, state), { loading: false, dbEntries: action.dbEntries });
40088
40088
  }
40089
- case ActionType$1.ShowAdder: {
40089
+ case ActionType$2.ShowAdder: {
40090
40090
  return Object.assign(Object.assign({}, state), { adding: true, dbEntryToEdit: undefined });
40091
40091
  }
40092
- case ActionType$1.ShowEditor: {
40092
+ case ActionType$2.ShowEditor: {
40093
40093
  return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: action.dbEntry });
40094
40094
  }
40095
- case ActionType$1.FinishAdd: {
40095
+ case ActionType$2.FinishAdd: {
40096
40096
  // Handle cancel
40097
40097
  const finishedEntry = action.dbEntry;
40098
40098
  if (!finishedEntry) {
@@ -40116,10 +40116,10 @@ const reducer$1 = (state, action) => {
40116
40116
  // Update the state
40117
40117
  return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: undefined, dbEntries: updatedDbEntries });
40118
40118
  }
40119
- case ActionType$1.StartDelete: {
40119
+ case ActionType$2.StartDelete: {
40120
40120
  return Object.assign(Object.assign({}, state), { loading: true });
40121
40121
  }
40122
- case ActionType$1.FinishDelete: {
40122
+ case ActionType$2.FinishDelete: {
40123
40123
  return Object.assign(Object.assign({}, state), { loading: false,
40124
40124
  // Remove the deleted entry from the list
40125
40125
  dbEntries: state.dbEntries.filter((entry) => {
@@ -40145,7 +40145,7 @@ const DBEntryManagerPanel = (props) => {
40145
40145
  loading: true,
40146
40146
  };
40147
40147
  // Initialize state
40148
- const [state, dispatch] = useReducer(reducer$1, initialState);
40148
+ const [state, dispatch] = useReducer(reducer$2, initialState);
40149
40149
  // Destructure common state
40150
40150
  const { adding, dbEntryToEdit, dbEntries, loading, } = state;
40151
40151
  /*------------------------------------------------------------------------*/
@@ -40171,7 +40171,7 @@ const DBEntryManagerPanel = (props) => {
40171
40171
  try {
40172
40172
  // Start loader
40173
40173
  dispatch({
40174
- type: ActionType$1.StartDelete,
40174
+ type: ActionType$2.StartDelete,
40175
40175
  });
40176
40176
  // Perform deletion
40177
40177
  yield visitServerEndpoint({
@@ -40180,7 +40180,7 @@ const DBEntryManagerPanel = (props) => {
40180
40180
  });
40181
40181
  // Finish loader
40182
40182
  dispatch({
40183
- type: ActionType$1.FinishDelete,
40183
+ type: ActionType$2.FinishDelete,
40184
40184
  dbEntry: entry,
40185
40185
  idPropName,
40186
40186
  });
@@ -40209,7 +40209,7 @@ const DBEntryManagerPanel = (props) => {
40209
40209
  });
40210
40210
  // Save loaded data
40211
40211
  dispatch({
40212
- type: ActionType$1.FinishLoading,
40212
+ type: ActionType$2.FinishLoading,
40213
40213
  dbEntries: data,
40214
40214
  });
40215
40215
  }
@@ -40252,7 +40252,7 @@ const DBEntryManagerPanel = (props) => {
40252
40252
  React__default.createElement("span", { className: "d-none d-md-inline ms-1" }, "Remove")),
40253
40253
  !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: () => {
40254
40254
  dispatch({
40255
- type: ActionType$1.ShowEditor,
40255
+ type: ActionType$2.ShowEditor,
40256
40256
  dbEntry: entry,
40257
40257
  });
40258
40258
  } },
@@ -40262,7 +40262,7 @@ const DBEntryManagerPanel = (props) => {
40262
40262
  React__default.createElement("div", { className: "d-grid" },
40263
40263
  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: () => {
40264
40264
  dispatch({
40265
- type: ActionType$1.ShowAdder,
40265
+ type: ActionType$2.ShowAdder,
40266
40266
  });
40267
40267
  } },
40268
40268
  React__default.createElement(FontAwesomeIcon, { icon: faPlus, className: "me-2" }),
@@ -40274,7 +40274,7 @@ const DBEntryManagerPanel = (props) => {
40274
40274
  if (!loading && (adding || dbEntryToEdit)) {
40275
40275
  body = (React__default.createElement(AddOrEditDBEntry, { saveEndpointPath: endpoint, validateEntry: validateEntry, modifyEntry: modifyEntry, entryFields: entryFields, dbEntryToEdit: dbEntryToEdit, idPropName: idPropName, entries: dbEntries, itemName: itemName, onFinished: (entry) => {
40276
40276
  dispatch({
40277
- type: ActionType$1.FinishAdd,
40277
+ type: ActionType$2.FinishAdd,
40278
40278
  dbEntry: entry,
40279
40279
  idPropName,
40280
40280
  });
@@ -40302,7 +40302,7 @@ const TOOLTIP_BORDER_RADIUS_REM = 0.3;
40302
40302
  /*------------------------------------------------------------------------*/
40303
40303
  /* -------------------------------- Style ------------------------------- */
40304
40304
  /*------------------------------------------------------------------------*/
40305
- const style = `
40305
+ const style$1 = `
40306
40306
  /* Container for contents and tooltip */
40307
40307
  .Tooltip-outer-container {
40308
40308
  display: inline-block;
@@ -40472,7 +40472,7 @@ const style = `
40472
40472
  `;
40473
40473
  /* ------------- Actions ------------ */
40474
40474
  // Types of actions
40475
- var ActionType;
40475
+ var ActionType$1;
40476
40476
  (function (ActionType) {
40477
40477
  // Make the tooltip visible
40478
40478
  ActionType["Show"] = "Show";
@@ -40484,28 +40484,28 @@ var ActionType;
40484
40484
  ActionType["SetSquareBottomLeft"] = "SetSquareBottomLeft";
40485
40485
  // Set whether bottom right corner should be square
40486
40486
  ActionType["SetSquareBottomRight"] = "SetSquareBottomRight";
40487
- })(ActionType || (ActionType = {}));
40487
+ })(ActionType$1 || (ActionType$1 = {}));
40488
40488
  /**
40489
40489
  * Reducer that executes actions
40490
40490
  * @author Gabe Abrams
40491
40491
  * @param state current state
40492
40492
  * @param action action to execute
40493
40493
  */
40494
- const reducer = (state, action) => {
40494
+ const reducer$1 = (state, action) => {
40495
40495
  switch (action.type) {
40496
- case ActionType.Show: {
40496
+ case ActionType$1.Show: {
40497
40497
  return Object.assign(Object.assign({}, state), { isVisible: true });
40498
40498
  }
40499
- case ActionType.Hide: {
40499
+ case ActionType$1.Hide: {
40500
40500
  return Object.assign(Object.assign({}, state), { isVisible: false, nudgePx: 0 });
40501
40501
  }
40502
- case ActionType.SetNudgePx: {
40502
+ case ActionType$1.SetNudgePx: {
40503
40503
  return Object.assign(Object.assign({}, state), { nudgePx: action.nudgePx });
40504
40504
  }
40505
- case ActionType.SetSquareBottomLeft: {
40505
+ case ActionType$1.SetSquareBottomLeft: {
40506
40506
  return Object.assign(Object.assign({}, state), { squareBottomLeft: action.squareBottomLeft });
40507
40507
  }
40508
- case ActionType.SetSquareBottomRight: {
40508
+ case ActionType$1.SetSquareBottomRight: {
40509
40509
  return Object.assign(Object.assign({}, state), { squareBottomRight: action.squareBottomRight });
40510
40510
  }
40511
40511
  default: {
@@ -40530,7 +40530,7 @@ const Tooltip = (props) => {
40530
40530
  nudgePx: 0,
40531
40531
  };
40532
40532
  // Initialize state
40533
- const [state, dispatch] = useReducer(reducer, initialState);
40533
+ const [state, dispatch] = useReducer(reducer$1, initialState);
40534
40534
  // Destructure common state
40535
40535
  const { isVisible, nudgePx, squareBottomLeft, squareBottomRight, } = state;
40536
40536
  /* -------------- Refs -------------- */
@@ -40569,7 +40569,7 @@ const Tooltip = (props) => {
40569
40569
  }
40570
40570
  // Update state
40571
40571
  dispatch({
40572
- type: ActionType.SetNudgePx,
40572
+ type: ActionType$1.SetNudgePx,
40573
40573
  nudgePx: newNudgePx,
40574
40574
  });
40575
40575
  }
@@ -40583,12 +40583,12 @@ const Tooltip = (props) => {
40583
40583
  const remInPixels = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10);
40584
40584
  // Set bottom left corner rounding
40585
40585
  dispatch({
40586
- type: ActionType.SetSquareBottomLeft,
40586
+ type: ActionType$1.SetSquareBottomLeft,
40587
40587
  squareBottomLeft: (arrowRect.left < (TOOLTIP_BORDER_RADIUS_REM * remInPixels)),
40588
40588
  });
40589
40589
  // Set bottom right corner rounding
40590
40590
  dispatch({
40591
- type: ActionType.SetSquareBottomRight,
40591
+ type: ActionType$1.SetSquareBottomRight,
40592
40592
  squareBottomRight: (arrowRect.right
40593
40593
  > window.innerWidth - (TOOLTIP_BORDER_RADIUS_REM * remInPixels)),
40594
40594
  });
@@ -40611,22 +40611,22 @@ const Tooltip = (props) => {
40611
40611
  // Render
40612
40612
  return (React__default.createElement("div", { className: "Tooltip-outer-container", "aria-label": text, onMouseEnter: () => {
40613
40613
  dispatch({
40614
- type: ActionType.Show,
40614
+ type: ActionType$1.Show,
40615
40615
  });
40616
40616
  }, onMouseLeave: () => {
40617
40617
  dispatch({
40618
- type: ActionType.Hide,
40618
+ type: ActionType$1.Hide,
40619
40619
  });
40620
40620
  }, onFocus: () => {
40621
40621
  dispatch({
40622
- type: ActionType.Show,
40622
+ type: ActionType$1.Show,
40623
40623
  });
40624
40624
  }, onBlur: () => {
40625
40625
  dispatch({
40626
- type: ActionType.Hide,
40626
+ type: ActionType$1.Hide,
40627
40627
  });
40628
40628
  } },
40629
- React__default.createElement("style", null, style),
40629
+ React__default.createElement("style", null, style$1),
40630
40630
  children,
40631
40631
  React__default.createElement("div", { className: `Tooltip-arrow Tooltip-arrow-visible-${isVisible ? 'true' : 'false'}`, ref: arrowElement },
40632
40632
  React__default.createElement(FontAwesomeIcon, { icon: faCaretDown })),
@@ -40683,6 +40683,306 @@ const ToggleSwitch = (props) => {
40683
40683
  } })));
40684
40684
  };
40685
40685
 
40686
+ /**
40687
+ * Convert a string to hyphenated lowercase format with no space or
40688
+ * non-alphanumeric characters
40689
+ * @author Gabe Abrams
40690
+ * @param str the string to convert
40691
+ * @returns the idified string
40692
+ */
40693
+ const idify = (str) => {
40694
+ return (str
40695
+ // Trim whitespace
40696
+ .trim()
40697
+ // Convert to lowercase
40698
+ .toLowerCase()
40699
+ // Replace non-alphanumeric characters with hyphens
40700
+ .replace(/[^a-z0-9]+/g, '-')
40701
+ // Change multiple hyphens in a row for a single hyphen
40702
+ .replace(/-+/g, '-')
40703
+ // Remove hyphens at the beginning and end of the string
40704
+ .replace(/^-+|-+$/g, ''));
40705
+ };
40706
+
40707
+ /**
40708
+ * Container that automatically scrolls when new items are added,
40709
+ * lets the user scroll up to see old items, but resumes
40710
+ * autoscroll when the user scrolls back to the bottom.
40711
+ * Note: takes up full height of parent, so parent should
40712
+ * have a determined height for the scroll to work.
40713
+ * @author Gabe Abrams
40714
+ */
40715
+ /*------------------------------------------------------------------------*/
40716
+ /* -------------------------------- Style ------------------------------- */
40717
+ /*------------------------------------------------------------------------*/
40718
+ const style = `
40719
+ .AutoscrollToBottomContainer-outer-container {
40720
+ /* Take up all space */
40721
+ height: 100%;
40722
+ position: relative;
40723
+ }
40724
+
40725
+ .AutoscrollToBottomContainer-scrollable-container {
40726
+ /* Take up max 100% height, don't take it up if not needed */
40727
+ /* (so column-reverse layout doesn't start at the bottom) */
40728
+ max-height: 100%;
40729
+ overflow-y: auto;
40730
+
40731
+ /* Allow children to position */
40732
+ position: relative;
40733
+
40734
+ /* Reverse order of children so scroll starts at bottom */
40735
+ /* (but children will have to be rendered in reverse order) */
40736
+ display: flex;
40737
+ flex-direction: column-reverse;
40738
+ }
40739
+
40740
+ .AutoscrollToBottomContainer-jump-to-bottom-container {
40741
+ /* Don't take any space in parent */
40742
+ height: 0;
40743
+ overflow: visible;
40744
+
40745
+ /* On top of items */
40746
+ z-index: 2;
40747
+
40748
+ /* Position in center bottom */
40749
+ position: absolute;
40750
+ bottom: 2rem;
40751
+
40752
+ /* Center horizontally */
40753
+ width: 100%;
40754
+ text-align: center;
40755
+ }
40756
+
40757
+ .AutoscrollToBottomContainer-item-container {
40758
+ /* Normal Height */
40759
+ position: relative;
40760
+ z-index: 1;
40761
+ }
40762
+ `;
40763
+ /*------------------------------------------------------------------------*/
40764
+ /* ------------------------------ Constants ----------------------------- */
40765
+ /*------------------------------------------------------------------------*/
40766
+ // Scrolled to bottom threshold
40767
+ // (how close you have to be to the bottom for it to count as the bottom)
40768
+ const SCROLLED_TO_BOTTOM_THRESHOLD_REMS = 2;
40769
+ /*------------------------------------------------------------------------*/
40770
+ /* -------------------------- Static Functions -------------------------- */
40771
+ /*------------------------------------------------------------------------*/
40772
+ /**
40773
+ * Get ids of items
40774
+ * @author Gabe Abrams
40775
+ * @param items the items in the container
40776
+ * @returns ids of items
40777
+ */
40778
+ const getItemIds = (items) => {
40779
+ return Array.from(items).map((child) => {
40780
+ return child.id;
40781
+ });
40782
+ };
40783
+ /* ------------- Actions ------------ */
40784
+ // Types of actions
40785
+ var ActionType;
40786
+ (function (ActionType) {
40787
+ // Identify that the user is now scrolled to the bottom
40788
+ ActionType["NowScrolledToBottom"] = "NowScrolledToBottom";
40789
+ // Identify that the user scrolled away from the bottom
40790
+ ActionType["NowScrolledAwayFromBottom"] = "NowScrolledAwayFromBottom";
40791
+ // Identify that new content appeared at the bottom but is not visible
40792
+ ActionType["NewContentAtBottom"] = "NewContentAtBottom";
40793
+ })(ActionType || (ActionType = {}));
40794
+ /**
40795
+ * Reducer that executes actions
40796
+ * @author Gabe Abrams
40797
+ * @param state current state
40798
+ * @param action action to execute
40799
+ */
40800
+ const reducer = (state, action) => {
40801
+ switch (action.type) {
40802
+ case ActionType.NowScrolledToBottom: {
40803
+ return Object.assign(Object.assign({}, state), {
40804
+ // Store the event
40805
+ wasScrolledToBottom: true,
40806
+ // Hide the "jump to bottom" button
40807
+ jumpToBottomButtonVisible: false });
40808
+ }
40809
+ case ActionType.NowScrolledAwayFromBottom: {
40810
+ return Object.assign(Object.assign({}, state), {
40811
+ // Store the event
40812
+ wasScrolledToBottom: false });
40813
+ }
40814
+ case ActionType.NewContentAtBottom: {
40815
+ return Object.assign(Object.assign({}, state), {
40816
+ // Store the event
40817
+ wasScrolledToBottom: false,
40818
+ // Show the "jump to bottom" button
40819
+ jumpToBottomButtonVisible: true });
40820
+ }
40821
+ default: {
40822
+ return state;
40823
+ }
40824
+ }
40825
+ };
40826
+ /*------------------------------------------------------------------------*/
40827
+ /* ------------------------------ Component ----------------------------- */
40828
+ /*------------------------------------------------------------------------*/
40829
+ const AutoscrollToBottomContainer = (props) => {
40830
+ /*------------------------------------------------------------------------*/
40831
+ /* -------------------------------- Setup ------------------------------- */
40832
+ /*------------------------------------------------------------------------*/
40833
+ /* -------------- Props ------------- */
40834
+ // Destructure all props
40835
+ const { itemsName, items, jumpToBottomButtonVariant = Variant$1.Danger, } = props;
40836
+ /* -------------- State ------------- */
40837
+ // Initial state
40838
+ const initialState = {
40839
+ wasScrolledToBottom: true,
40840
+ jumpToBottomButtonVisible: false,
40841
+ };
40842
+ // Initialize state
40843
+ const [state, dispatch] = useReducer(reducer, initialState);
40844
+ // Destructure common state
40845
+ const { wasScrolledToBottom, jumpToBottomButtonVisible, } = state;
40846
+ /* -------------- Refs -------------- */
40847
+ // Initialize refs
40848
+ const lastItemIds = useRef([]);
40849
+ const container = useRef(null);
40850
+ /*------------------------------------------------------------------------*/
40851
+ /* ------------------------- Component Functions ------------------------ */
40852
+ /*------------------------------------------------------------------------*/
40853
+ /*----------------------------------------*/
40854
+ /* --------------- Scroll --------------- */
40855
+ /*----------------------------------------*/
40856
+ /**
40857
+ * Check if the user is scrolled to the bottom
40858
+ * @author Gabe Abrams
40859
+ * @returns true if scrolled to the bottom
40860
+ */
40861
+ const isScrolledToBottom = () => {
40862
+ // Skip if no container
40863
+ if (!container.current) {
40864
+ return true;
40865
+ }
40866
+ // Get info about container
40867
+ const { scrollTop, } = container.current;
40868
+ // Distance to bottom
40869
+ const rootFontSizePx = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10);
40870
+ const distanceToBottomRems = Math.abs(scrollTop / rootFontSizePx);
40871
+ // Figure out if we're scrolled to the bottom
40872
+ return (distanceToBottomRems < SCROLLED_TO_BOTTOM_THRESHOLD_REMS);
40873
+ };
40874
+ /**
40875
+ * Scroll the user to the bottom of the container
40876
+ * @author Gabe Abrams
40877
+ */
40878
+ const scrollToBottom = () => {
40879
+ // Skip if no container
40880
+ if (!container.current) {
40881
+ return;
40882
+ }
40883
+ // Update state
40884
+ dispatch({
40885
+ type: ActionType.NowScrolledToBottom,
40886
+ });
40887
+ // Scroll to bottom
40888
+ container.current.scrollTop = 0;
40889
+ };
40890
+ /*----------------------------------------*/
40891
+ /* -------------- Handlers -------------- */
40892
+ /*----------------------------------------*/
40893
+ /**
40894
+ * Handle scroll events on the container
40895
+ * @author Gabe Abrams
40896
+ */
40897
+ const handleScroll = () => {
40898
+ // Skip if no container
40899
+ if (!container.current) {
40900
+ return;
40901
+ }
40902
+ // Check if now scrolled to bottom
40903
+ const nowScrolledToBottom = isScrolledToBottom();
40904
+ // Remember if now no longer scrolled to bottom
40905
+ if (nowScrolledToBottom) {
40906
+ dispatch({
40907
+ type: ActionType.NowScrolledToBottom,
40908
+ });
40909
+ }
40910
+ else {
40911
+ dispatch({
40912
+ type: ActionType.NowScrolledAwayFromBottom,
40913
+ });
40914
+ }
40915
+ };
40916
+ /*------------------------------------------------------------------------*/
40917
+ /* ------------------------- Lifecycle Functions ------------------------ */
40918
+ /*------------------------------------------------------------------------*/
40919
+ /**
40920
+ * Mount
40921
+ * @author Gabe Abrams
40922
+ */
40923
+ useEffect(() => {
40924
+ // Scroll to the bottom
40925
+ scrollToBottom();
40926
+ }, []);
40927
+ /**
40928
+ * Update (also called on mount)
40929
+ * @author Gabe Abrams
40930
+ */
40931
+ useEffect(() => {
40932
+ // Check if new content appeared
40933
+ const currentItemIds = getItemIds(items);
40934
+ // Check if new content appeared at bottom
40935
+ const newContentAtBottom = (currentItemIds.length > 0
40936
+ && (currentItemIds[currentItemIds.length - 1]
40937
+ !== lastItemIds.current[lastItemIds.current.length - 1]));
40938
+ // Do nothing if no new content
40939
+ if (!newContentAtBottom) {
40940
+ return;
40941
+ }
40942
+ // Check if used to be scrolled to the bottom
40943
+ if (wasScrolledToBottom) {
40944
+ // Was scrolled to the bottom! Autoscroll.
40945
+ scrollToBottom();
40946
+ }
40947
+ else {
40948
+ // Not scrolled to bottom. Show "jump to bottom" button.
40949
+ dispatch({
40950
+ type: ActionType.NewContentAtBottom,
40951
+ });
40952
+ }
40953
+ // Update last item ids
40954
+ lastItemIds.current = currentItemIds;
40955
+ }, [items]);
40956
+ /*------------------------------------------------------------------------*/
40957
+ /* ------------------------------- Render ------------------------------- */
40958
+ /*------------------------------------------------------------------------*/
40959
+ /*----------------------------------------*/
40960
+ /* --------------- Main UI -------------- */
40961
+ /*----------------------------------------*/
40962
+ // Jump to Bottom button
40963
+ let jumpToBottomButton;
40964
+ if (jumpToBottomButtonVisible) {
40965
+ jumpToBottomButton = (React__default.createElement("div", { className: `AutoscrollToBottomContainer-jump-to-bottom-container AutoscrollToBottomContainer-for-${idify(itemsName !== null && itemsName !== void 0 ? itemsName : 'items')}` },
40966
+ React__default.createElement("button", { type: "button", className: `AutoscrollToBottomContainer-jump-to-bottom-button AutoscrollToBottomContainer-jump-to-bottom-button-for-${idify(itemsName !== null && itemsName !== void 0 ? itemsName : 'items')} btn btn-sm btn-${jumpToBottomButtonVariant} pt-0 pb-0`, onClick: scrollToBottom, "aria-label": "scroll back to bottom and show new content" },
40967
+ "New",
40968
+ ' ', itemsName !== null && itemsName !== void 0 ? itemsName : 'Content',
40969
+ React__default.createElement(FontAwesomeIcon, { icon: faChevronDown, className: "ms-1" }))));
40970
+ }
40971
+ // Main UI
40972
+ return (React__default.createElement("div", { className: "AutoscrollToBottomContainer-outer-container" },
40973
+ React__default.createElement("style", null, style),
40974
+ jumpToBottomButton,
40975
+ React__default.createElement("div", { className: "AutoscrollToBottomContainer-scrollable-container", onScroll: () => {
40976
+ handleScroll();
40977
+ }, ref: container }, items
40978
+ // Render each item with a key
40979
+ .map((item) => {
40980
+ return (React__default.createElement("div", { className: "AutoscrollToBottomContainer-item-container", key: item.id }, item.item));
40981
+ })
40982
+ // Reverse order because flex column is reverse
40983
+ .reverse())));
40984
+ };
40985
+
40686
40986
  /**
40687
40987
  * One minute in ms
40688
40988
  * @author Gabe Abrams
@@ -42562,5 +42862,5 @@ var DayOfWeek;
42562
42862
  })(DayOfWeek || (DayOfWeek = {}));
42563
42863
  var DayOfWeek$1 = DayOfWeek;
42564
42864
 
42565
- export { AppWrapper, 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, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert$1 as alert, avg, canReviewLogs, ceilToNumDecimals, compareArraysByProp, confirm, extractProp, floorToNumDecimals, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, initClient, initLogCollection, initServer, isMobileOrTablet, logClientEvent, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, roundToNumDecimals, showFatalError, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
42865
+ 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, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert$1 as alert, avg, canReviewLogs, ceilToNumDecimals, compareArraysByProp, confirm, extractProp, floorToNumDecimals, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, logClientEvent, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, roundToNumDecimals, showFatalError, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
42566
42866
  //# sourceMappingURL=index.js.map