dce-reactkit 3.9.0-beta-loading-modal.1 → 3.9.0-beta-loading-modal.3
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/cjs/index.js +784 -202
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/client/initClient.d.ts +16 -2
- package/dist/cjs/types/components/AppWrapper.d.ts +32 -0
- package/dist/cjs/types/components/CheckboxButton.d.ts +1 -0
- package/dist/cjs/types/components/Dropdown.d.ts +32 -0
- package/dist/cjs/types/components/RadioButton.d.ts +2 -0
- package/dist/cjs/types/helpers/genRouteHandler.d.ts +8 -0
- package/dist/cjs/types/helpers/validators/ChicagoTitleCase.d.ts +9 -0
- package/dist/cjs/types/helpers/validators/validURL.d.ts +8 -0
- package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/index.d.ts +24 -0
- package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +33 -0
- package/dist/cjs/types/index.d.ts +5 -2
- package/dist/cjs/types/types/DropdownItemType.d.ts +6 -0
- package/dist/cjs/types/types/ModalType.d.ts +1 -0
- package/dist/cjs/types/types/ReactKitErrorCode.d.ts +6 -1
- package/dist/esm/index.js +780 -203
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/client/initClient.d.ts +16 -2
- package/dist/esm/types/components/AppWrapper.d.ts +32 -0
- package/dist/esm/types/components/CheckboxButton.d.ts +1 -0
- package/dist/esm/types/components/Dropdown.d.ts +32 -0
- package/dist/esm/types/components/RadioButton.d.ts +2 -0
- package/dist/esm/types/helpers/genRouteHandler.d.ts +8 -0
- package/dist/esm/types/helpers/validators/ChicagoTitleCase.d.ts +9 -0
- package/dist/esm/types/helpers/validators/validURL.d.ts +8 -0
- package/dist/esm/types/helpers/visitEndpointOnAnotherServer/index.d.ts +24 -0
- package/dist/esm/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +33 -0
- package/dist/esm/types/index.d.ts +5 -2
- package/dist/esm/types/types/DropdownItemType.d.ts +6 -0
- package/dist/esm/types/types/ModalType.d.ts +1 -0
- package/dist/esm/types/types/ReactKitErrorCode.d.ts +6 -1
- package/dist/index.d.ts +163 -46
- package/package.json +2 -1
- package/src/client/initClient.tsx +49 -11
- package/src/components/AppWrapper.tsx +258 -2
- package/src/components/CheckboxButton.tsx +24 -6
- package/src/components/Dropdown.tsx +317 -0
- package/src/components/IntelliTable.tsx +1 -1
- package/src/components/ItemPicker/NestableItemList.tsx +1 -0
- package/src/components/LogReviewer.tsx +17 -4
- package/src/components/Modal/index.tsx +5 -2
- package/src/components/MultiSwitch.tsx +1 -1
- package/src/components/RadioButton.tsx +33 -6
- package/src/components/SimpleDateChooser.tsx +8 -2
- package/src/helpers/genRouteHandler.ts +116 -17
- package/src/helpers/logClientEvent.tsx +8 -0
- package/src/helpers/validators/ChicagoTitleCase.test.ts +85 -0
- package/src/helpers/validators/ChicagoTitleCase.ts +32 -0
- package/src/helpers/validators/findURL.test.ts +83 -0
- package/src/helpers/validators/findURL.ts +43 -0
- package/src/helpers/validators/validURL.test.ts +90 -0
- package/src/helpers/validators/validURL.ts +18 -0
- package/src/helpers/visitEndpointOnAnotherServer/index.ts +93 -0
- package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +164 -0
- package/src/helpers/visitServerEndpoint.tsx +1 -0
- package/src/index.ts +8 -0
- package/src/server/initLogCollection.ts +5 -0
- package/src/server/initServer.ts +11 -5
- package/src/types/DropdownItemType.ts +11 -0
- package/src/types/ModalType.tsx +1 -0
- package/src/types/ReactKitErrorCode.tsx +8 -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 =
|
|
62
|
+
// Highest error code = DRK18
|
|
61
63
|
/**
|
|
62
64
|
* List of error codes built into the react kit
|
|
63
65
|
* @author Gabe Abrams
|
|
@@ -69,6 +71,8 @@ var ReactKitErrorCode;
|
|
|
69
71
|
ReactKitErrorCode["SessionExpired"] = "DRK3";
|
|
70
72
|
ReactKitErrorCode["MissingParameter"] = "DRK4";
|
|
71
73
|
ReactKitErrorCode["InvalidParameter"] = "DRK5";
|
|
74
|
+
ReactKitErrorCode["HostNotAllowed"] = "DRK17";
|
|
75
|
+
ReactKitErrorCode["HostBanned"] = "DRK18";
|
|
72
76
|
ReactKitErrorCode["WrongCourse"] = "DRK6";
|
|
73
77
|
ReactKitErrorCode["NoCACCLSendRequestFunction"] = "DRK7";
|
|
74
78
|
ReactKitErrorCode["NoCACCLGetLaunchInfoFunction"] = "DRK8";
|
|
@@ -77,6 +81,10 @@ var ReactKitErrorCode;
|
|
|
77
81
|
ReactKitErrorCode["NotAllowedToReviewLogs"] = "DRK11";
|
|
78
82
|
ReactKitErrorCode["ThemeCheckedBeforeReactKitReady"] = "DRK12";
|
|
79
83
|
ReactKitErrorCode["SessionExpiredMessageGottenBeforeReactKitReady"] = "DRK13";
|
|
84
|
+
// Server-to-server requests
|
|
85
|
+
ReactKitErrorCode["NotConnected"] = "DRK14";
|
|
86
|
+
ReactKitErrorCode["SelfSigned"] = "DRK15";
|
|
87
|
+
ReactKitErrorCode["ResponseParseError"] = "DRK16";
|
|
80
88
|
})(ReactKitErrorCode || (ReactKitErrorCode = {}));
|
|
81
89
|
var ReactKitErrorCode$1 = ReactKitErrorCode;
|
|
82
90
|
|
|
@@ -178,6 +186,7 @@ var ModalButtonType$1 = ModalButtonType;
|
|
|
178
186
|
var ModalType;
|
|
179
187
|
(function (ModalType) {
|
|
180
188
|
ModalType["Okay"] = "okay";
|
|
189
|
+
ModalType["Cancel"] = "cancel";
|
|
181
190
|
ModalType["OkayCancel"] = "okay-cancel";
|
|
182
191
|
ModalType["YesNo"] = "yes-no";
|
|
183
192
|
ModalType["YesNoCancel"] = "yes-no-cancel";
|
|
@@ -400,11 +409,23 @@ const isDarkModeOn = () => {
|
|
|
400
409
|
* @param opts object containing all arguments
|
|
401
410
|
* @param opts.sendRequest caccl send request functions
|
|
402
411
|
* @param [opts.sessionExpiredMessage] a custom session expired message
|
|
412
|
+
* @param [opts.darkModeOn] if true, dark mode is enabled
|
|
413
|
+
* @param [opts.noServer] if true, there is no server for this app
|
|
403
414
|
*/
|
|
404
415
|
const initClient = (opts) => {
|
|
405
|
-
//
|
|
406
|
-
|
|
407
|
-
|
|
416
|
+
// Handle separately if there is no server
|
|
417
|
+
if (opts.noServer) {
|
|
418
|
+
// Store values
|
|
419
|
+
storedSendRequest = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
420
|
+
throw new Error('Cannot send requests because there is no server');
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
// Store values
|
|
425
|
+
storedSendRequest = opts.sendRequest;
|
|
426
|
+
sessionExpiredMessage = opts.sessionExpiredMessage;
|
|
427
|
+
}
|
|
428
|
+
// Handle universal parts
|
|
408
429
|
darkModeOn = !!opts.darkModeOn;
|
|
409
430
|
// Mark as initialized
|
|
410
431
|
onInitialized(null);
|
|
@@ -425,6 +446,9 @@ const modalTypeToModalButtonTypes = {
|
|
|
425
446
|
[ModalType$1.Okay]: [
|
|
426
447
|
ModalButtonType$1.Okay,
|
|
427
448
|
],
|
|
449
|
+
[ModalType$1.Cancel]: [
|
|
450
|
+
ModalButtonType$1.Cancel,
|
|
451
|
+
],
|
|
428
452
|
[ModalType$1.OkayCancel]: [
|
|
429
453
|
ModalButtonType$1.Okay,
|
|
430
454
|
ModalButtonType$1.Cancel,
|
|
@@ -743,7 +767,7 @@ const Modal = (props) => {
|
|
|
743
767
|
zIndex: baseZIndex + 2,
|
|
744
768
|
// Override sizes for even larger for XL
|
|
745
769
|
width: (size === ModalSize$1.ExtraLarge
|
|
746
|
-
? 'calc(100vw -
|
|
770
|
+
? 'calc(100vw - 1rem)'
|
|
747
771
|
: undefined),
|
|
748
772
|
maxWidth: (size === ModalSize$1.ExtraLarge
|
|
749
773
|
? '80rem'
|
|
@@ -786,7 +810,7 @@ const Modal = (props) => {
|
|
|
786
810
|
backgroundColor: (isDarkModeOn()
|
|
787
811
|
? '#444'
|
|
788
812
|
: undefined),
|
|
789
|
-
} }, isLoading
|
|
813
|
+
} }, isLoading ? (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
790
814
|
React__default["default"].createElement(LoadingSpinner, null),
|
|
791
815
|
React__default["default"].createElement("span", { className: "sr-only" }, "Content loading"))) : (children)),
|
|
792
816
|
footer && (React__default["default"].createElement("div", { className: "modal-footer pt-1 pb-1", style: {
|
|
@@ -880,6 +904,7 @@ const _setStubResponse = (opts) => {
|
|
|
880
904
|
*/
|
|
881
905
|
const visitServerEndpoint = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
882
906
|
var _a, _b, _c;
|
|
907
|
+
// Set default method
|
|
883
908
|
const method = ((_a = opts.method) !== null && _a !== void 0 ? _a : 'GET');
|
|
884
909
|
// Handle stubs
|
|
885
910
|
const stubResponse = (_b = stubResponses[method]) === null || _b === void 0 ? void 0 : _b[opts.path];
|
|
@@ -1179,6 +1204,92 @@ const confirm = (title, text, opts) => __awaiter(void 0, void 0, void 0, functio
|
|
|
1179
1204
|
});
|
|
1180
1205
|
});
|
|
1181
1206
|
/*----------------------------------------*/
|
|
1207
|
+
/* --------------- Prompt -------------- */
|
|
1208
|
+
/*----------------------------------------*/
|
|
1209
|
+
// Stored copies of setters
|
|
1210
|
+
let setPromptInfo;
|
|
1211
|
+
// Function to call when prompt is closed
|
|
1212
|
+
let onPromptClosed;
|
|
1213
|
+
/**
|
|
1214
|
+
* Show a prompt modal asking the user for input
|
|
1215
|
+
* @author Yuen Ler Chow
|
|
1216
|
+
* @param title the title text to display at the top of the prompt
|
|
1217
|
+
* @param [opts={}] additional options for the prompt dialog
|
|
1218
|
+
* @param [opts.textAboveInputField] the text to display in the prompt
|
|
1219
|
+
* @param [opts.defaultText] the default text for the input field
|
|
1220
|
+
* @param [opts.placeholder] the placeholder text for the input field
|
|
1221
|
+
* @param [opts.confirmButtonText=Okay] the text of the confirm button
|
|
1222
|
+
* @param [opts.confirmButtonVariant=Variant.Dark] the variant of the confirm button
|
|
1223
|
+
* @param [opts.cancelButtonText=Cancel] the text of the cancel button
|
|
1224
|
+
* @param [opts.cancelButtonVariant=Variant.Secondary] the variant of the cancel button
|
|
1225
|
+
* @param [opts.minNumChars] the minimum number of characters required for
|
|
1226
|
+
* the input to be valid
|
|
1227
|
+
* @param [opts.findValidationError] a function that takes the input text and
|
|
1228
|
+
* returns an error message if the input is invalid, returns undefined if the
|
|
1229
|
+
* input is valid
|
|
1230
|
+
* @param [opts.ariaLabel] the aria label for the input field
|
|
1231
|
+
* @returns Promise that resolves with the input string or null if canceled
|
|
1232
|
+
*/
|
|
1233
|
+
const prompt = (title, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1234
|
+
var _a, _b;
|
|
1235
|
+
// Wait for helper to exist
|
|
1236
|
+
yield waitForHelper(() => {
|
|
1237
|
+
return !!setPromptInfo;
|
|
1238
|
+
});
|
|
1239
|
+
// Fallback if prompt is not available
|
|
1240
|
+
if (!setPromptInfo) {
|
|
1241
|
+
const resultPassesValidation = false;
|
|
1242
|
+
while (!resultPassesValidation) {
|
|
1243
|
+
// eslint-disable-next-line no-alert
|
|
1244
|
+
const result = window.prompt(`${title}\n\n${(_a = opts === null || opts === void 0 ? void 0 : opts.textAboveInputField) !== null && _a !== void 0 ? _a : ''}`, (_b = opts === null || opts === void 0 ? void 0 : opts.defaultText) !== null && _b !== void 0 ? _b : '');
|
|
1245
|
+
// Exit loop if user cancels
|
|
1246
|
+
if (result === null) {
|
|
1247
|
+
return null;
|
|
1248
|
+
}
|
|
1249
|
+
// Validate min num chars
|
|
1250
|
+
const minNumCharsValidationError = (((opts === null || opts === void 0 ? void 0 : opts.minNumChars) && result.length < opts.minNumChars)
|
|
1251
|
+
? `Please enter at least ${opts.minNumChars} characters.`
|
|
1252
|
+
: undefined);
|
|
1253
|
+
// Run custom validation
|
|
1254
|
+
const customValidationError = ((opts === null || opts === void 0 ? void 0 : opts.findValidationError)
|
|
1255
|
+
&& opts.findValidationError(result));
|
|
1256
|
+
// Show validation issue
|
|
1257
|
+
if (minNumCharsValidationError || customValidationError) {
|
|
1258
|
+
// Create error message
|
|
1259
|
+
const errorMessage = ([
|
|
1260
|
+
minNumCharsValidationError,
|
|
1261
|
+
customValidationError,
|
|
1262
|
+
]
|
|
1263
|
+
// Filter out undefined messages
|
|
1264
|
+
.filter((msg) => {
|
|
1265
|
+
return !!msg;
|
|
1266
|
+
})
|
|
1267
|
+
// Join messages with newlines
|
|
1268
|
+
.join('\n'));
|
|
1269
|
+
// Show alert
|
|
1270
|
+
alert('Invalid Input', errorMessage);
|
|
1271
|
+
}
|
|
1272
|
+
else {
|
|
1273
|
+
return result;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
// Return promise that resolves with result of prompt
|
|
1278
|
+
return new Promise((resolve) => {
|
|
1279
|
+
var _a;
|
|
1280
|
+
// Setup handler
|
|
1281
|
+
onPromptClosed = (result) => {
|
|
1282
|
+
resolve(result);
|
|
1283
|
+
};
|
|
1284
|
+
// Show the prompt
|
|
1285
|
+
setPromptInfo({
|
|
1286
|
+
title,
|
|
1287
|
+
currentInputFieldText: ((_a = opts === null || opts === void 0 ? void 0 : opts.defaultText) !== null && _a !== void 0 ? _a : ''),
|
|
1288
|
+
opts: (opts !== null && opts !== void 0 ? opts : {}),
|
|
1289
|
+
});
|
|
1290
|
+
});
|
|
1291
|
+
});
|
|
1292
|
+
/*----------------------------------------*/
|
|
1182
1293
|
/* ------------- Fatal Error ------------ */
|
|
1183
1294
|
/*----------------------------------------*/
|
|
1184
1295
|
// Stored copies of setters
|
|
@@ -1194,14 +1305,14 @@ const fatalErrorHandlers = [];
|
|
|
1194
1305
|
* @param [errorTitle] title of the error box
|
|
1195
1306
|
*/
|
|
1196
1307
|
const showFatalError = (error, errorTitle = 'An Error Occurred') => __awaiter(void 0, void 0, void 0, function* () {
|
|
1197
|
-
var
|
|
1308
|
+
var _c, _d;
|
|
1198
1309
|
// Determine message and code
|
|
1199
1310
|
const message = (typeof error === 'string'
|
|
1200
1311
|
? error.trim()
|
|
1201
|
-
: String((
|
|
1312
|
+
: String((_c = error.message) !== null && _c !== void 0 ? _c : 'An unknown error occurred.'));
|
|
1202
1313
|
const code = (typeof error === 'string'
|
|
1203
1314
|
? ReactKitErrorCode$1.NoCode
|
|
1204
|
-
: String((
|
|
1315
|
+
: String((_d = error.code) !== null && _d !== void 0 ? _d : ReactKitErrorCode$1.NoCode));
|
|
1205
1316
|
// Call all fatal error listeners
|
|
1206
1317
|
try {
|
|
1207
1318
|
fatalErrorHandlers.forEach((handler) => {
|
|
@@ -1328,6 +1439,9 @@ const AppWrapper = (props) => {
|
|
|
1328
1439
|
// Confirm
|
|
1329
1440
|
const [confirmInfo, setConfirmInfoInner,] = React.useState(undefined);
|
|
1330
1441
|
setConfirmInfo = setConfirmInfoInner;
|
|
1442
|
+
// Prompt
|
|
1443
|
+
const [promptInfo, setPromptInfoInner] = React.useState(undefined);
|
|
1444
|
+
setPromptInfo = setPromptInfoInner;
|
|
1331
1445
|
// Session expired
|
|
1332
1446
|
const [sessionHasExpired, setSessionHasExpiredInner,] = React.useState(false);
|
|
1333
1447
|
setSessionHasExpired = setSessionHasExpiredInner;
|
|
@@ -1358,6 +1472,42 @@ const AppWrapper = (props) => {
|
|
|
1358
1472
|
}
|
|
1359
1473
|
}, onTopOfOtherModals: true, dontAllowBackdropExit: true }, confirmInfo.text));
|
|
1360
1474
|
}
|
|
1475
|
+
/* ------------- Prompt ------------ */
|
|
1476
|
+
if (promptInfo) {
|
|
1477
|
+
// Run min char validation
|
|
1478
|
+
const minNumCharsValidationError = ((promptInfo.opts.minNumChars
|
|
1479
|
+
&& promptInfo.currentInputFieldText.length < promptInfo.opts.minNumChars)
|
|
1480
|
+
? `Please enter at least ${promptInfo.opts.minNumChars} characters.`
|
|
1481
|
+
: undefined);
|
|
1482
|
+
// Run custom validation
|
|
1483
|
+
const customValidationError = (promptInfo.opts.findValidationError
|
|
1484
|
+
&& promptInfo.opts.findValidationError(promptInfo.currentInputFieldText));
|
|
1485
|
+
modal = (React__default["default"].createElement(Modal, { key: `prompt-${promptInfo.title}`, title: promptInfo.title,
|
|
1486
|
+
// Don't show ok button if there is a validation error
|
|
1487
|
+
type: ((customValidationError || minNumCharsValidationError)
|
|
1488
|
+
? ModalType$1.Cancel
|
|
1489
|
+
: ModalType$1.OkayCancel), okayLabel: promptInfo.opts.confirmButtonText, okayVariant: promptInfo.opts.confirmButtonVariant, cancelLabel: promptInfo.opts.cancelButtonText, cancelVariant: promptInfo.opts.cancelButtonVariant, onClose: (buttonType) => {
|
|
1490
|
+
// Get result
|
|
1491
|
+
const result = (buttonType === ModalButtonType$1.Okay
|
|
1492
|
+
? promptInfo.currentInputFieldText
|
|
1493
|
+
: null);
|
|
1494
|
+
// Close prompt
|
|
1495
|
+
setPromptInfo(undefined);
|
|
1496
|
+
// Call handler
|
|
1497
|
+
if (onPromptClosed) {
|
|
1498
|
+
onPromptClosed(result);
|
|
1499
|
+
}
|
|
1500
|
+
}, onTopOfOtherModals: true, dontAllowBackdropExit: true },
|
|
1501
|
+
React__default["default"].createElement("div", null,
|
|
1502
|
+
promptInfo.opts.textAboveInputField && (React__default["default"].createElement("div", null, promptInfo.opts.textAboveInputField)),
|
|
1503
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": promptInfo.opts.ariaLabel, placeholder: promptInfo.opts.placeholder, value: promptInfo.currentInputFieldText, onChange: (e) => {
|
|
1504
|
+
return setPromptInfo(Object.assign(Object.assign({}, promptInfo), { currentInputFieldText: e.target.value }));
|
|
1505
|
+
},
|
|
1506
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
1507
|
+
autoFocus: true }),
|
|
1508
|
+
minNumCharsValidationError && (React__default["default"].createElement("div", { className: "text-danger fw-bold mt-2" }, minNumCharsValidationError)),
|
|
1509
|
+
customValidationError && (React__default["default"].createElement("div", { className: "text-danger fw-bold mt-2" }, customValidationError)))));
|
|
1510
|
+
}
|
|
1361
1511
|
/* ------ Custom Modal Portals ------ */
|
|
1362
1512
|
// Custom modal portals
|
|
1363
1513
|
const customModalPortals = [];
|
|
@@ -1427,7 +1577,7 @@ const AppWrapper = (props) => {
|
|
|
1427
1577
|
? `
|
|
1428
1578
|
.tooltip-inner {
|
|
1429
1579
|
background-color: white;
|
|
1430
|
-
color: black;
|
|
1580
|
+
color: black !important;
|
|
1431
1581
|
border: 0.1rem solid black;
|
|
1432
1582
|
pointer-events: none;
|
|
1433
1583
|
}
|
|
@@ -1440,7 +1590,7 @@ const AppWrapper = (props) => {
|
|
|
1440
1590
|
: `
|
|
1441
1591
|
.tooltip-inner {
|
|
1442
1592
|
background-color: black;
|
|
1443
|
-
color: white;
|
|
1593
|
+
color: white !important;
|
|
1444
1594
|
border: 0.1rem solid white;
|
|
1445
1595
|
pointer-events: none;
|
|
1446
1596
|
}
|
|
@@ -1567,24 +1717,31 @@ const RadioButton = (props) => {
|
|
|
1567
1717
|
/* -------------------------------- Setup ------------------------------- */
|
|
1568
1718
|
/*------------------------------------------------------------------------*/
|
|
1569
1719
|
/* -------------- Props ------------- */
|
|
1570
|
-
const { text, onSelected, ariaLabel, title, selected, id, noMarginOnRight, selectedVariant = (isDarkModeOn()
|
|
1720
|
+
const { text, onSelected, ariaLabel, title, selected, id, className, noMarginOnRight, selectedVariant = (isDarkModeOn()
|
|
1571
1721
|
? Variant$1.Light
|
|
1572
1722
|
: Variant$1.Secondary), unselectedVariant = (isDarkModeOn()
|
|
1573
1723
|
? Variant$1.Secondary
|
|
1574
|
-
: Variant$1.Light), small, } = props;
|
|
1724
|
+
: Variant$1.Light), small, useComplexFormatting, } = props;
|
|
1575
1725
|
/*------------------------------------------------------------------------*/
|
|
1576
1726
|
/* ------------------------------- Render ------------------------------- */
|
|
1577
1727
|
/*------------------------------------------------------------------------*/
|
|
1578
1728
|
/*----------------------------------------*/
|
|
1579
1729
|
/* --------------- Main UI -------------- */
|
|
1580
1730
|
/*----------------------------------------*/
|
|
1581
|
-
return (React__default["default"].createElement("button", { type: "button", id: id, title: title, className: `btn btn-${selected ? selectedVariant : unselectedVariant}${selected ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' me-1'}`, "aria-label": `${ariaLabel}${selected ? ': currently selected' : ''}`, onClick: () => {
|
|
1731
|
+
return (React__default["default"].createElement("button", { type: "button", id: id, title: title, className: `btn btn-${selected ? selectedVariant : unselectedVariant}${selected ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' me-1'} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": `${ariaLabel}${selected ? ': currently selected' : ''}`, onClick: () => {
|
|
1582
1732
|
if (!selected) {
|
|
1583
1733
|
onSelected();
|
|
1584
1734
|
}
|
|
1585
1735
|
} },
|
|
1586
|
-
React__default["default"].createElement(
|
|
1587
|
-
|
|
1736
|
+
React__default["default"].createElement("div", { className: "d-flex flex-row align-items-center" },
|
|
1737
|
+
React__default["default"].createElement("div", { className: "me-1" },
|
|
1738
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: selected ? freeSolidSvgIcons.faDotCircle : freeRegularSvgIcons.faCircle })),
|
|
1739
|
+
useComplexFormatting
|
|
1740
|
+
? (React__default["default"].createElement("pre", { className: "ps-1 text-start text-break m-0", style: {
|
|
1741
|
+
whiteSpace: 'pre-wrap',
|
|
1742
|
+
tabSize: 2,
|
|
1743
|
+
} }, text))
|
|
1744
|
+
: (React__default["default"].createElement("div", { className: "flex-grow-1 text-start text-break" }, text)))));
|
|
1588
1745
|
};
|
|
1589
1746
|
|
|
1590
1747
|
/**
|
|
@@ -1603,7 +1760,7 @@ const CheckboxButton = (props) => {
|
|
|
1603
1760
|
? Variant$1.Light
|
|
1604
1761
|
: Variant$1.Secondary), uncheckedVariant = (isDarkModeOn()
|
|
1605
1762
|
? Variant$1.Secondary
|
|
1606
|
-
: Variant$1.Light), small, dashed, } = props;
|
|
1763
|
+
: Variant$1.Light), small, dashed, useComplexFormatting, } = props;
|
|
1607
1764
|
/*------------------------------------------------------------------------*/
|
|
1608
1765
|
/* ------------------------------- Render ------------------------------- */
|
|
1609
1766
|
/*------------------------------------------------------------------------*/
|
|
@@ -1624,10 +1781,15 @@ const CheckboxButton = (props) => {
|
|
|
1624
1781
|
return (React__default["default"].createElement("button", { type: "button", id: id, title: title, className: `CheckboxButton-status-${checked ? 'checked' : 'unchecked'} ${dashed ? 'CheckboxButton-dashed ' : ''}btn btn-${checked ? checkedVariant : uncheckedVariant}${checked ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' me-1'} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": `${ariaLabel}${checked ? ': currently checked' : ''}`, onClick: () => {
|
|
1625
1782
|
onChanged(!checked);
|
|
1626
1783
|
} },
|
|
1627
|
-
React__default["default"].createElement("div", { className: "d-flex" },
|
|
1628
|
-
React__default["default"].createElement("div", { className: "
|
|
1629
|
-
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: icon
|
|
1630
|
-
|
|
1784
|
+
React__default["default"].createElement("div", { className: "d-flex align-items-center" },
|
|
1785
|
+
React__default["default"].createElement("div", { className: "me-1" },
|
|
1786
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: icon })),
|
|
1787
|
+
useComplexFormatting
|
|
1788
|
+
? (React__default["default"].createElement("pre", { className: "ps-1 text-start text-break m-0", style: {
|
|
1789
|
+
whiteSpace: 'pre-wrap',
|
|
1790
|
+
tabSize: 2,
|
|
1791
|
+
} }, text))
|
|
1792
|
+
: (React__default["default"].createElement("div", { className: "flex-grow-1 text-start text-break" }, text)))));
|
|
1631
1793
|
};
|
|
1632
1794
|
|
|
1633
1795
|
/**
|
|
@@ -1808,7 +1970,13 @@ const SimpleDateChooser = (props) => {
|
|
|
1808
1970
|
}
|
|
1809
1971
|
const monthName = getMonthName(month).full;
|
|
1810
1972
|
// Year is start year +1 for each 12 months
|
|
1811
|
-
|
|
1973
|
+
let yearsToAdd = 0;
|
|
1974
|
+
let monthsOfYearsToAdd = unmoddedMonth;
|
|
1975
|
+
while (monthsOfYearsToAdd > 12) {
|
|
1976
|
+
monthsOfYearsToAdd -= 12;
|
|
1977
|
+
yearsToAdd += 1;
|
|
1978
|
+
}
|
|
1979
|
+
const year = startYear + yearsToAdd;
|
|
1812
1980
|
// Figure out which days are allowed
|
|
1813
1981
|
const days = [];
|
|
1814
1982
|
const numDaysInMonth = (new Date(year, month, 0)).getDate();
|
|
@@ -1859,7 +2027,7 @@ const SimpleDateChooser = (props) => {
|
|
|
1859
2027
|
});
|
|
1860
2028
|
}
|
|
1861
2029
|
});
|
|
1862
|
-
return (React__default["default"].createElement("div", { className: "SimpleDateChooser d-inline-block", "aria-label": `date chooser with selected date: ${month}
|
|
2030
|
+
return (React__default["default"].createElement("div", { className: "SimpleDateChooser d-inline-block", "aria-label": `date chooser with selected date: ${month}/${day}/${year}` },
|
|
1863
2031
|
React__default["default"].createElement("select", { "aria-label": `month for ${ariaLabel}`, className: "custom-select d-inline-block mr-1", style: { width: 'auto' }, id: `SimpleDateChooser-${name}-month`, value: `${month}-${year}`, onChange: (e) => {
|
|
1864
2032
|
const choice = choices[e.target.selectedIndex];
|
|
1865
2033
|
// Change day, month, and year
|
|
@@ -2252,27 +2420,27 @@ const PopPendingMark = (props) => {
|
|
|
2252
2420
|
*/
|
|
2253
2421
|
/* ------------- Actions ------------ */
|
|
2254
2422
|
// Types of actions
|
|
2255
|
-
var ActionType$
|
|
2423
|
+
var ActionType$9;
|
|
2256
2424
|
(function (ActionType) {
|
|
2257
2425
|
// Indicate that the text was recently copied
|
|
2258
2426
|
ActionType["IndicateRecentlyCopied"] = "indicate-recently-copied";
|
|
2259
2427
|
// Clear the status
|
|
2260
2428
|
ActionType["ClearRecentlyCopiedStatus"] = "clear-recently-copied-status";
|
|
2261
|
-
})(ActionType$
|
|
2429
|
+
})(ActionType$9 || (ActionType$9 = {}));
|
|
2262
2430
|
/**
|
|
2263
2431
|
* Reducer that executes actions
|
|
2264
2432
|
* @author Gabe Abrams
|
|
2265
2433
|
* @param state current state
|
|
2266
2434
|
* @param action action to execute
|
|
2267
2435
|
*/
|
|
2268
|
-
const reducer$
|
|
2436
|
+
const reducer$a = (state, action) => {
|
|
2269
2437
|
switch (action.type) {
|
|
2270
|
-
case ActionType$
|
|
2438
|
+
case ActionType$9.IndicateRecentlyCopied: {
|
|
2271
2439
|
return {
|
|
2272
2440
|
recentlyCopied: true,
|
|
2273
2441
|
};
|
|
2274
2442
|
}
|
|
2275
|
-
case ActionType$
|
|
2443
|
+
case ActionType$9.ClearRecentlyCopiedStatus: {
|
|
2276
2444
|
return {
|
|
2277
2445
|
recentlyCopied: false,
|
|
2278
2446
|
};
|
|
@@ -2298,7 +2466,7 @@ const CopiableBox = (props) => {
|
|
|
2298
2466
|
recentlyCopied: false,
|
|
2299
2467
|
};
|
|
2300
2468
|
// Initialize state
|
|
2301
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
2469
|
+
const [state, dispatch] = React.useReducer(reducer$a, initialState);
|
|
2302
2470
|
// Destructure common state
|
|
2303
2471
|
const { recentlyCopied, } = state;
|
|
2304
2472
|
/*------------------------------------------------------------------------*/
|
|
@@ -2318,13 +2486,13 @@ const CopiableBox = (props) => {
|
|
|
2318
2486
|
}
|
|
2319
2487
|
// Show copied notice
|
|
2320
2488
|
dispatch({
|
|
2321
|
-
type: ActionType$
|
|
2489
|
+
type: ActionType$9.IndicateRecentlyCopied,
|
|
2322
2490
|
});
|
|
2323
2491
|
// Wait a moment
|
|
2324
2492
|
yield waitMs(4000);
|
|
2325
2493
|
// Hide copied notice
|
|
2326
2494
|
dispatch({
|
|
2327
|
-
type: ActionType$
|
|
2495
|
+
type: ActionType$9.ClearRecentlyCopiedStatus,
|
|
2328
2496
|
});
|
|
2329
2497
|
});
|
|
2330
2498
|
/*------------------------------------------------------------------------*/
|
|
@@ -2380,20 +2548,20 @@ const CopiableBox = (props) => {
|
|
|
2380
2548
|
*/
|
|
2381
2549
|
/* ------------- Actions ------------ */
|
|
2382
2550
|
// Types of actions
|
|
2383
|
-
var ActionType$
|
|
2551
|
+
var ActionType$8;
|
|
2384
2552
|
(function (ActionType) {
|
|
2385
2553
|
// Toggle whether a child are being shown
|
|
2386
2554
|
ActionType["ToggleChild"] = "toggle-child";
|
|
2387
|
-
})(ActionType$
|
|
2555
|
+
})(ActionType$8 || (ActionType$8 = {}));
|
|
2388
2556
|
/**
|
|
2389
2557
|
* Reducer that executes actions
|
|
2390
2558
|
* @author Gabe Abrams
|
|
2391
2559
|
* @param state current state
|
|
2392
2560
|
* @param action action to execute
|
|
2393
2561
|
*/
|
|
2394
|
-
const reducer$
|
|
2562
|
+
const reducer$9 = (state, action) => {
|
|
2395
2563
|
switch (action.type) {
|
|
2396
|
-
case ActionType$
|
|
2564
|
+
case ActionType$8.ToggleChild: {
|
|
2397
2565
|
return Object.assign(Object.assign({}, state), { childExpanded: Object.assign(Object.assign({}, state.childExpanded), { [String(action.id)]: !state.childExpanded[String(action.id)] }) });
|
|
2398
2566
|
}
|
|
2399
2567
|
default: {
|
|
@@ -2422,7 +2590,7 @@ const NestableItemList = (props) => {
|
|
|
2422
2590
|
childExpanded: initChildExpanded,
|
|
2423
2591
|
};
|
|
2424
2592
|
// Initialize state
|
|
2425
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
2593
|
+
const [state, dispatch] = React.useReducer(reducer$9, initialState);
|
|
2426
2594
|
// Destructure common state
|
|
2427
2595
|
const { childExpanded, } = state;
|
|
2428
2596
|
/*------------------------------------------------------------------------*/
|
|
@@ -2512,14 +2680,14 @@ const NestableItemList = (props) => {
|
|
|
2512
2680
|
backgroundColor: 'transparent',
|
|
2513
2681
|
}, type: "button", onClick: () => {
|
|
2514
2682
|
dispatch({
|
|
2515
|
-
type: ActionType$
|
|
2683
|
+
type: ActionType$8.ToggleChild,
|
|
2516
2684
|
id: item.id,
|
|
2517
2685
|
});
|
|
2518
2686
|
}, "aria-label": `${childExpanded[item.id] ? 'Hide' : 'Show'} items in ${item.name}` },
|
|
2519
2687
|
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: childExpanded[item.id] ? freeSolidSvgIcons.faChevronDown : freeSolidSvgIcons.faChevronRight })))),
|
|
2520
2688
|
React__default["default"].createElement(CheckboxButton, { className: `NestableItemList-CheckboxButton-${item.id}`, text: item.name, checked: item.isGroup ? allChecked(item.children) : item.checked, dashed: item.isGroup ? !noneChecked(item.children) : false, onChanged: (checked) => {
|
|
2521
2689
|
onChanged(changeChecked(item.id, checked, items));
|
|
2522
|
-
}, ariaLabel: `Select ${item.name}`, checkedVariant: Variant$1.Light }),
|
|
2690
|
+
}, ariaLabel: `Select ${item.name}`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }),
|
|
2523
2691
|
(item.isGroup && childExpanded[item.id]) && (React__default["default"].createElement("div", { className: "NestableItemList-children-container", style: {
|
|
2524
2692
|
paddingLeft: '2.2rem',
|
|
2525
2693
|
} },
|
|
@@ -2796,7 +2964,7 @@ var SortType;
|
|
|
2796
2964
|
})(SortType || (SortType = {}));
|
|
2797
2965
|
/* ------------- Actions ------------ */
|
|
2798
2966
|
// Types of actions
|
|
2799
|
-
var ActionType$
|
|
2967
|
+
var ActionType$7;
|
|
2800
2968
|
(function (ActionType) {
|
|
2801
2969
|
// Toggle sort column param
|
|
2802
2970
|
ActionType["ToggleSortColumn"] = "toggle-sort-column";
|
|
@@ -2808,16 +2976,16 @@ var ActionType$6;
|
|
|
2808
2976
|
ActionType["ShowAllColumns"] = "show-all-columns";
|
|
2809
2977
|
// Hide all columns
|
|
2810
2978
|
ActionType["HideAllColumns"] = "hide-all-columns";
|
|
2811
|
-
})(ActionType$
|
|
2979
|
+
})(ActionType$7 || (ActionType$7 = {}));
|
|
2812
2980
|
/**
|
|
2813
2981
|
* Reducer that executes actions
|
|
2814
2982
|
* @author Gabe Abrams
|
|
2815
2983
|
* @param state current state
|
|
2816
2984
|
* @param action action to execute
|
|
2817
2985
|
*/
|
|
2818
|
-
const reducer$
|
|
2986
|
+
const reducer$8 = (state, action) => {
|
|
2819
2987
|
switch (action.type) {
|
|
2820
|
-
case ActionType$
|
|
2988
|
+
case ActionType$7.ToggleSortColumn: {
|
|
2821
2989
|
if (action.param !== state.sortColumnParam) {
|
|
2822
2990
|
// Different column param
|
|
2823
2991
|
return Object.assign(Object.assign({}, state), { sortColumnParam: action.param, sortType: SortType.Ascending });
|
|
@@ -2829,22 +2997,22 @@ const reducer$7 = (state, action) => {
|
|
|
2829
2997
|
// Stop sorting by column
|
|
2830
2998
|
return Object.assign(Object.assign({}, state), { sortColumnParam: undefined, sortType: SortType.Ascending });
|
|
2831
2999
|
}
|
|
2832
|
-
case ActionType$
|
|
3000
|
+
case ActionType$7.UpdateColumnVisibility: {
|
|
2833
3001
|
const { columnVisibilityMap } = state;
|
|
2834
3002
|
columnVisibilityMap[action.param] = action.visible;
|
|
2835
3003
|
return Object.assign(Object.assign({}, state), { columnVisibilityMap });
|
|
2836
3004
|
}
|
|
2837
|
-
case ActionType$
|
|
3005
|
+
case ActionType$7.ToggleColVisCusModalVisibility: {
|
|
2838
3006
|
return Object.assign(Object.assign({}, state), { columnVisibilityCustomizationModalVisible: !state.columnVisibilityCustomizationModalVisible });
|
|
2839
3007
|
}
|
|
2840
|
-
case ActionType$
|
|
3008
|
+
case ActionType$7.ShowAllColumns: {
|
|
2841
3009
|
const { columnVisibilityMap } = state;
|
|
2842
3010
|
Object.keys(columnVisibilityMap).forEach((param) => {
|
|
2843
3011
|
columnVisibilityMap[param] = true;
|
|
2844
3012
|
});
|
|
2845
3013
|
return Object.assign(Object.assign({}, state), { columnVisibilityMap });
|
|
2846
3014
|
}
|
|
2847
|
-
case ActionType$
|
|
3015
|
+
case ActionType$7.HideAllColumns: {
|
|
2848
3016
|
const { columnVisibilityMap } = state;
|
|
2849
3017
|
Object.keys(columnVisibilityMap).forEach((param) => {
|
|
2850
3018
|
columnVisibilityMap[param] = false;
|
|
@@ -2891,7 +3059,7 @@ const IntelliTable = (props) => {
|
|
|
2891
3059
|
columnVisibilityCustomizationModalVisible: false,
|
|
2892
3060
|
};
|
|
2893
3061
|
// Initialize state
|
|
2894
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
3062
|
+
const [state, dispatch] = React.useReducer(reducer$8, initialState);
|
|
2895
3063
|
// Destructure common state
|
|
2896
3064
|
const { sortColumnParam, sortType, columnVisibilityMap, columnVisibilityCustomizationModalVisible, } = state;
|
|
2897
3065
|
/*------------------------------------------------------------------------*/
|
|
@@ -2914,27 +3082,27 @@ const IntelliTable = (props) => {
|
|
|
2914
3082
|
return alert('Choose at least one column', 'To continue, you have to choose at least one column to show');
|
|
2915
3083
|
}
|
|
2916
3084
|
dispatch({
|
|
2917
|
-
type: ActionType$
|
|
3085
|
+
type: ActionType$7.ToggleColVisCusModalVisibility,
|
|
2918
3086
|
});
|
|
2919
3087
|
}, okayVariant: Variant$1.Light },
|
|
2920
3088
|
columns.map((column) => {
|
|
2921
3089
|
return (React__default["default"].createElement(CheckboxButton, { key: column.param, id: `IntelliTable-${id}-toggle-visibility-${column.param}`, className: "mb-2", text: column.title, onChanged: (checked) => {
|
|
2922
3090
|
dispatch({
|
|
2923
|
-
type: ActionType$
|
|
3091
|
+
type: ActionType$7.UpdateColumnVisibility,
|
|
2924
3092
|
param: column.param,
|
|
2925
3093
|
visible: checked,
|
|
2926
3094
|
});
|
|
2927
|
-
}, checked: columnVisibilityMap[column.param], ariaLabel: `show "${column.title}" column in the ${title} table`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.
|
|
3095
|
+
}, checked: columnVisibilityMap[column.param], ariaLabel: `show "${column.title}" column in the ${title} table`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
2928
3096
|
}),
|
|
2929
3097
|
React__default["default"].createElement("div", { className: "mt-3" }, "Or you can:"),
|
|
2930
3098
|
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: () => {
|
|
2931
3099
|
dispatch({
|
|
2932
|
-
type: ActionType$
|
|
3100
|
+
type: ActionType$7.ShowAllColumns,
|
|
2933
3101
|
});
|
|
2934
3102
|
} }, "Select All"),
|
|
2935
3103
|
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: () => {
|
|
2936
3104
|
dispatch({
|
|
2937
|
-
type: ActionType$
|
|
3105
|
+
type: ActionType$7.HideAllColumns,
|
|
2938
3106
|
});
|
|
2939
3107
|
} }, "Deselect All")));
|
|
2940
3108
|
}
|
|
@@ -2985,7 +3153,7 @@ const IntelliTable = (props) => {
|
|
|
2985
3153
|
React__default["default"].createElement("div", null,
|
|
2986
3154
|
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: () => {
|
|
2987
3155
|
dispatch({
|
|
2988
|
-
type: ActionType$
|
|
3156
|
+
type: ActionType$7.ToggleSortColumn,
|
|
2989
3157
|
param: column.param,
|
|
2990
3158
|
});
|
|
2991
3159
|
} },
|
|
@@ -3174,7 +3342,7 @@ const IntelliTable = (props) => {
|
|
|
3174
3342
|
React__default["default"].createElement(CSVDownloadButton, { "aria-label": `download data as csv for ${title}`, id: `IntelliTable-${id}-download-as-csv`, filename: filename, csv: csv }),
|
|
3175
3343
|
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: () => {
|
|
3176
3344
|
dispatch({
|
|
3177
|
-
type: ActionType$
|
|
3345
|
+
type: ActionType$7.ToggleColVisCusModalVisibility,
|
|
3178
3346
|
});
|
|
3179
3347
|
} },
|
|
3180
3348
|
"Show/Hide Cols",
|
|
@@ -3540,7 +3708,7 @@ const genHumanReadableName = (machineReadableName) => {
|
|
|
3540
3708
|
};
|
|
3541
3709
|
/* ------------- Actions ------------ */
|
|
3542
3710
|
// Types of actions
|
|
3543
|
-
var ActionType$
|
|
3711
|
+
var ActionType$6;
|
|
3544
3712
|
(function (ActionType) {
|
|
3545
3713
|
// Show the loading bar
|
|
3546
3714
|
ActionType["StartLoading"] = "start-loading";
|
|
@@ -3562,45 +3730,45 @@ var ActionType$5;
|
|
|
3562
3730
|
ActionType["UpdateActionErrorFilterState"] = "update-action-error-filter-state";
|
|
3563
3731
|
// Update the advanced filter state
|
|
3564
3732
|
ActionType["UpdateAdvancedFilterState"] = "update-advanced-filter-state";
|
|
3565
|
-
})(ActionType$
|
|
3733
|
+
})(ActionType$6 || (ActionType$6 = {}));
|
|
3566
3734
|
/**
|
|
3567
3735
|
* Reducer that executes actions
|
|
3568
3736
|
* @author Gabe Abrams
|
|
3569
3737
|
* @param state current state
|
|
3570
3738
|
* @param action action to execute
|
|
3571
3739
|
*/
|
|
3572
|
-
const reducer$
|
|
3740
|
+
const reducer$7 = (state, action) => {
|
|
3573
3741
|
switch (action.type) {
|
|
3574
|
-
case ActionType$
|
|
3742
|
+
case ActionType$6.StartLoading: {
|
|
3575
3743
|
return Object.assign(Object.assign({}, state), { loading: true });
|
|
3576
3744
|
}
|
|
3577
|
-
case ActionType$
|
|
3745
|
+
case ActionType$6.FinishLoading: {
|
|
3578
3746
|
return Object.assign(Object.assign({}, state), { loading: false, logMap: action.logMap });
|
|
3579
3747
|
}
|
|
3580
|
-
case ActionType$
|
|
3748
|
+
case ActionType$6.ToggleFilterDrawer: {
|
|
3581
3749
|
return Object.assign(Object.assign({}, state), { expandedFilterDrawer: (state.expandedFilterDrawer === action.filterDrawer
|
|
3582
3750
|
? undefined // hide
|
|
3583
3751
|
: action.filterDrawer) });
|
|
3584
3752
|
}
|
|
3585
|
-
case ActionType$
|
|
3753
|
+
case ActionType$6.HideFilterDrawer: {
|
|
3586
3754
|
return Object.assign(Object.assign({}, state), { expandedFilterDrawer: undefined });
|
|
3587
3755
|
}
|
|
3588
|
-
case ActionType$
|
|
3756
|
+
case ActionType$6.ResetFilters: {
|
|
3589
3757
|
return Object.assign(Object.assign({}, state), { dateFilterState: action.initDateFilterState, contextFilterState: action.initContextFilterState, tagFilterState: action.initTagFilterState, actionErrorFilterState: action.initActionErrorFilterState, advancedFilterState: action.initAdvancedFilterState });
|
|
3590
3758
|
}
|
|
3591
|
-
case ActionType$
|
|
3759
|
+
case ActionType$6.UpdateDateFilterState: {
|
|
3592
3760
|
return Object.assign(Object.assign({}, state), { dateFilterState: action.dateFilterState });
|
|
3593
3761
|
}
|
|
3594
|
-
case ActionType$
|
|
3762
|
+
case ActionType$6.UpdateContextFilterState: {
|
|
3595
3763
|
return Object.assign(Object.assign({}, state), { contextFilterState: action.contextFilterState });
|
|
3596
3764
|
}
|
|
3597
|
-
case ActionType$
|
|
3765
|
+
case ActionType$6.UpdateTagFilterState: {
|
|
3598
3766
|
return Object.assign(Object.assign({}, state), { tagFilterState: action.tagFilterState });
|
|
3599
3767
|
}
|
|
3600
|
-
case ActionType$
|
|
3768
|
+
case ActionType$6.UpdateActionErrorFilterState: {
|
|
3601
3769
|
return Object.assign(Object.assign({}, state), { actionErrorFilterState: action.actionErrorFilterState });
|
|
3602
3770
|
}
|
|
3603
|
-
case ActionType$
|
|
3771
|
+
case ActionType$6.UpdateAdvancedFilterState: {
|
|
3604
3772
|
return Object.assign(Object.assign({}, state), { advancedFilterState: action.advancedFilterState });
|
|
3605
3773
|
}
|
|
3606
3774
|
default: {
|
|
@@ -3729,7 +3897,7 @@ const LogReviewer = (props) => {
|
|
|
3729
3897
|
advancedFilterState: initAdvancedFilterState,
|
|
3730
3898
|
};
|
|
3731
3899
|
// Initialize state
|
|
3732
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
3900
|
+
const [state, dispatch] = React.useReducer(reducer$7, initialState);
|
|
3733
3901
|
// Destructure common state
|
|
3734
3902
|
const { loading, logMap, expandedFilterDrawer, dateFilterState, contextFilterState, tagFilterState, actionErrorFilterState, advancedFilterState, } = state;
|
|
3735
3903
|
/*------------------------------------------------------------------------*/
|
|
@@ -3779,7 +3947,7 @@ const LogReviewer = (props) => {
|
|
|
3779
3947
|
const handleDateRangeUpdated = (newDateFilterState) => __awaiter(void 0, void 0, void 0, function* () {
|
|
3780
3948
|
// Update state
|
|
3781
3949
|
dispatch({
|
|
3782
|
-
type: ActionType$
|
|
3950
|
+
type: ActionType$6.UpdateDateFilterState,
|
|
3783
3951
|
dateFilterState: newDateFilterState,
|
|
3784
3952
|
});
|
|
3785
3953
|
// Check which year/month combos we need to load
|
|
@@ -3790,7 +3958,7 @@ const LogReviewer = (props) => {
|
|
|
3790
3958
|
}
|
|
3791
3959
|
// Start loading
|
|
3792
3960
|
dispatch({
|
|
3793
|
-
type: ActionType$
|
|
3961
|
+
type: ActionType$6.StartLoading,
|
|
3794
3962
|
});
|
|
3795
3963
|
// Load required months
|
|
3796
3964
|
try {
|
|
@@ -3798,10 +3966,21 @@ const LogReviewer = (props) => {
|
|
|
3798
3966
|
// Destructure
|
|
3799
3967
|
const { year, month } = toLoad[i];
|
|
3800
3968
|
// Load
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3969
|
+
let logs = [];
|
|
3970
|
+
let pageNumber = 1;
|
|
3971
|
+
let hasAnotherPage = true;
|
|
3972
|
+
while (hasAnotherPage) {
|
|
3973
|
+
const response = yield visitServerEndpoint({
|
|
3974
|
+
path: `${LOG_REVIEW_ROUTE_PATH_PREFIX}/years/${year}/months/${month}`,
|
|
3975
|
+
method: 'GET',
|
|
3976
|
+
params: {
|
|
3977
|
+
pageNumber,
|
|
3978
|
+
},
|
|
3979
|
+
});
|
|
3980
|
+
logs = logs.concat(response.items);
|
|
3981
|
+
hasAnotherPage = response.hasAnotherPage;
|
|
3982
|
+
pageNumber += 1;
|
|
3983
|
+
}
|
|
3805
3984
|
// Add to map
|
|
3806
3985
|
if (!logMap[year]) {
|
|
3807
3986
|
logMap[year] = {};
|
|
@@ -3814,7 +3993,7 @@ const LogReviewer = (props) => {
|
|
|
3814
3993
|
}
|
|
3815
3994
|
// Finish loading
|
|
3816
3995
|
dispatch({
|
|
3817
|
-
type: ActionType$
|
|
3996
|
+
type: ActionType$6.FinishLoading,
|
|
3818
3997
|
logMap,
|
|
3819
3998
|
});
|
|
3820
3999
|
});
|
|
@@ -3853,7 +4032,7 @@ const LogReviewer = (props) => {
|
|
|
3853
4032
|
React__default["default"].createElement("div", { className: "LogReviewer-filter-toggle-buttons alert alert-secondary p-2 m-0" },
|
|
3854
4033
|
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: () => {
|
|
3855
4034
|
dispatch({
|
|
3856
|
-
type: ActionType$
|
|
4035
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
3857
4036
|
filterDrawer: FilterDrawer.Date,
|
|
3858
4037
|
});
|
|
3859
4038
|
} },
|
|
@@ -3861,7 +4040,7 @@ const LogReviewer = (props) => {
|
|
|
3861
4040
|
"Date"),
|
|
3862
4041
|
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: () => {
|
|
3863
4042
|
dispatch({
|
|
3864
|
-
type: ActionType$
|
|
4043
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
3865
4044
|
filterDrawer: FilterDrawer.Context,
|
|
3866
4045
|
});
|
|
3867
4046
|
} },
|
|
@@ -3869,7 +4048,7 @@ const LogReviewer = (props) => {
|
|
|
3869
4048
|
"Context"),
|
|
3870
4049
|
(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: () => {
|
|
3871
4050
|
dispatch({
|
|
3872
|
-
type: ActionType$
|
|
4051
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
3873
4052
|
filterDrawer: FilterDrawer.Tag,
|
|
3874
4053
|
});
|
|
3875
4054
|
} },
|
|
@@ -3877,7 +4056,7 @@ const LogReviewer = (props) => {
|
|
|
3877
4056
|
"Tag")),
|
|
3878
4057
|
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: () => {
|
|
3879
4058
|
dispatch({
|
|
3880
|
-
type: ActionType$
|
|
4059
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
3881
4060
|
filterDrawer: FilterDrawer.Action,
|
|
3882
4061
|
});
|
|
3883
4062
|
} },
|
|
@@ -3885,7 +4064,7 @@ const LogReviewer = (props) => {
|
|
|
3885
4064
|
"Action"),
|
|
3886
4065
|
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: () => {
|
|
3887
4066
|
dispatch({
|
|
3888
|
-
type: ActionType$
|
|
4067
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
3889
4068
|
filterDrawer: FilterDrawer.Advanced,
|
|
3890
4069
|
});
|
|
3891
4070
|
} },
|
|
@@ -3893,7 +4072,7 @@ const LogReviewer = (props) => {
|
|
|
3893
4072
|
"Advanced"),
|
|
3894
4073
|
React__default["default"].createElement("button", { type: "button", id: "LogReviewer-reset-filters-button", className: "btn btn-light", "aria-label": "reset filters", onClick: () => {
|
|
3895
4074
|
dispatch({
|
|
3896
|
-
type: ActionType$
|
|
4075
|
+
type: ActionType$6.ResetFilters,
|
|
3897
4076
|
initActionErrorFilterState,
|
|
3898
4077
|
initAdvancedFilterState,
|
|
3899
4078
|
initContextFilterState,
|
|
@@ -4015,7 +4194,7 @@ const LogReviewer = (props) => {
|
|
|
4015
4194
|
}
|
|
4016
4195
|
});
|
|
4017
4196
|
dispatch({
|
|
4018
|
-
type: ActionType$
|
|
4197
|
+
type: ActionType$6.UpdateContextFilterState,
|
|
4019
4198
|
contextFilterState,
|
|
4020
4199
|
});
|
|
4021
4200
|
} }));
|
|
@@ -4030,7 +4209,7 @@ const LogReviewer = (props) => {
|
|
|
4030
4209
|
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) => {
|
|
4031
4210
|
tagFilterState[tag] = checked;
|
|
4032
4211
|
dispatch({
|
|
4033
|
-
type: ActionType$
|
|
4212
|
+
type: ActionType$6.UpdateTagFilterState,
|
|
4034
4213
|
tagFilterState,
|
|
4035
4214
|
});
|
|
4036
4215
|
} }));
|
|
@@ -4043,21 +4222,21 @@ const LogReviewer = (props) => {
|
|
|
4043
4222
|
React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
|
|
4044
4223
|
actionErrorFilterState.type = undefined;
|
|
4045
4224
|
dispatch({
|
|
4046
|
-
type: ActionType$
|
|
4225
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
4047
4226
|
actionErrorFilterState,
|
|
4048
4227
|
});
|
|
4049
4228
|
}, ariaLabel: "show logs of all types", selected: actionErrorFilterState.type === undefined }),
|
|
4050
4229
|
React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-action-only", text: "Action Logs Only", onSelected: () => {
|
|
4051
4230
|
actionErrorFilterState.type = LogType$1.Action;
|
|
4052
4231
|
dispatch({
|
|
4053
|
-
type: ActionType$
|
|
4232
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
4054
4233
|
actionErrorFilterState,
|
|
4055
4234
|
});
|
|
4056
4235
|
}, ariaLabel: "only show action logs", selected: actionErrorFilterState.type === LogType$1.Action }),
|
|
4057
4236
|
React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-error-only", text: "Action Error Only", onSelected: () => {
|
|
4058
4237
|
actionErrorFilterState.type = LogType$1.Error;
|
|
4059
4238
|
dispatch({
|
|
4060
|
-
type: ActionType$
|
|
4239
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
4061
4240
|
actionErrorFilterState,
|
|
4062
4241
|
});
|
|
4063
4242
|
}, ariaLabel: "only show error logs", selected: actionErrorFilterState.type === LogType$1.Error, noMarginOnRight: true })),
|
|
@@ -4069,7 +4248,7 @@ const LogReviewer = (props) => {
|
|
|
4069
4248
|
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) => {
|
|
4070
4249
|
actionErrorFilterState.action[action] = checked;
|
|
4071
4250
|
dispatch({
|
|
4072
|
-
type: ActionType$
|
|
4251
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
4073
4252
|
actionErrorFilterState,
|
|
4074
4253
|
});
|
|
4075
4254
|
} }));
|
|
@@ -4080,7 +4259,7 @@ const LogReviewer = (props) => {
|
|
|
4080
4259
|
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) => {
|
|
4081
4260
|
actionErrorFilterState.target[target] = checked;
|
|
4082
4261
|
dispatch({
|
|
4083
|
-
type: ActionType$
|
|
4262
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
4084
4263
|
actionErrorFilterState,
|
|
4085
4264
|
});
|
|
4086
4265
|
} }));
|
|
@@ -4092,7 +4271,7 @@ const LogReviewer = (props) => {
|
|
|
4092
4271
|
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) => {
|
|
4093
4272
|
actionErrorFilterState.errorMessage = e.target.value;
|
|
4094
4273
|
dispatch({
|
|
4095
|
-
type: ActionType$
|
|
4274
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
4096
4275
|
actionErrorFilterState,
|
|
4097
4276
|
});
|
|
4098
4277
|
} })),
|
|
@@ -4103,7 +4282,7 @@ const LogReviewer = (props) => {
|
|
|
4103
4282
|
.trim()
|
|
4104
4283
|
.toUpperCase());
|
|
4105
4284
|
dispatch({
|
|
4106
|
-
type: ActionType$
|
|
4285
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
4107
4286
|
actionErrorFilterState,
|
|
4108
4287
|
});
|
|
4109
4288
|
} }))))));
|
|
@@ -4117,7 +4296,7 @@ const LogReviewer = (props) => {
|
|
|
4117
4296
|
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) => {
|
|
4118
4297
|
advancedFilterState.userFirstName = e.target.value;
|
|
4119
4298
|
dispatch({
|
|
4120
|
-
type: ActionType$
|
|
4299
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4121
4300
|
advancedFilterState,
|
|
4122
4301
|
});
|
|
4123
4302
|
} })),
|
|
@@ -4126,7 +4305,7 @@ const LogReviewer = (props) => {
|
|
|
4126
4305
|
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) => {
|
|
4127
4306
|
advancedFilterState.userLastName = e.target.value;
|
|
4128
4307
|
dispatch({
|
|
4129
|
-
type: ActionType$
|
|
4308
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4130
4309
|
advancedFilterState,
|
|
4131
4310
|
});
|
|
4132
4311
|
} })),
|
|
@@ -4136,7 +4315,7 @@ const LogReviewer = (props) => {
|
|
|
4136
4315
|
advancedFilterState.userEmail = ((e.target.value)
|
|
4137
4316
|
.trim());
|
|
4138
4317
|
dispatch({
|
|
4139
|
-
type: ActionType$
|
|
4318
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4140
4319
|
advancedFilterState,
|
|
4141
4320
|
});
|
|
4142
4321
|
} })),
|
|
@@ -4150,7 +4329,7 @@ const LogReviewer = (props) => {
|
|
|
4150
4329
|
.trim());
|
|
4151
4330
|
}
|
|
4152
4331
|
dispatch({
|
|
4153
|
-
type: ActionType$
|
|
4332
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4154
4333
|
advancedFilterState,
|
|
4155
4334
|
});
|
|
4156
4335
|
} })),
|
|
@@ -4158,21 +4337,21 @@ const LogReviewer = (props) => {
|
|
|
4158
4337
|
React__default["default"].createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
|
|
4159
4338
|
advancedFilterState.includeLearners = checked;
|
|
4160
4339
|
dispatch({
|
|
4161
|
-
type: ActionType$
|
|
4340
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4162
4341
|
advancedFilterState,
|
|
4163
4342
|
});
|
|
4164
4343
|
}, checked: advancedFilterState.includeLearners, ariaLabel: "show logs from students" }),
|
|
4165
4344
|
React__default["default"].createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
|
|
4166
4345
|
advancedFilterState.includeTTMs = checked;
|
|
4167
4346
|
dispatch({
|
|
4168
|
-
type: ActionType$
|
|
4347
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4169
4348
|
advancedFilterState,
|
|
4170
4349
|
});
|
|
4171
4350
|
}, checked: advancedFilterState.includeTTMs, ariaLabel: "show logs from teaching team members" }),
|
|
4172
4351
|
React__default["default"].createElement(CheckboxButton, { text: "Admins", onChanged: (checked) => {
|
|
4173
4352
|
advancedFilterState.includeAdmins = checked;
|
|
4174
4353
|
dispatch({
|
|
4175
|
-
type: ActionType$
|
|
4354
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4176
4355
|
advancedFilterState,
|
|
4177
4356
|
});
|
|
4178
4357
|
}, checked: advancedFilterState.includeAdmins, ariaLabel: "show logs from admins" }))),
|
|
@@ -4182,7 +4361,7 @@ const LogReviewer = (props) => {
|
|
|
4182
4361
|
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) => {
|
|
4183
4362
|
advancedFilterState.courseName = e.target.value;
|
|
4184
4363
|
dispatch({
|
|
4185
|
-
type: ActionType$
|
|
4364
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4186
4365
|
advancedFilterState,
|
|
4187
4366
|
});
|
|
4188
4367
|
} })),
|
|
@@ -4196,7 +4375,7 @@ const LogReviewer = (props) => {
|
|
|
4196
4375
|
.trim());
|
|
4197
4376
|
}
|
|
4198
4377
|
dispatch({
|
|
4199
|
-
type: ActionType$
|
|
4378
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4200
4379
|
advancedFilterState,
|
|
4201
4380
|
});
|
|
4202
4381
|
} }))),
|
|
@@ -4205,21 +4384,21 @@ const LogReviewer = (props) => {
|
|
|
4205
4384
|
React__default["default"].createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: advancedFilterState.isMobile === undefined, onSelected: () => {
|
|
4206
4385
|
advancedFilterState.isMobile = undefined;
|
|
4207
4386
|
dispatch({
|
|
4208
|
-
type: ActionType$
|
|
4387
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4209
4388
|
advancedFilterState,
|
|
4210
4389
|
});
|
|
4211
4390
|
} }),
|
|
4212
4391
|
React__default["default"].createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: advancedFilterState.isMobile === true, onSelected: () => {
|
|
4213
4392
|
advancedFilterState.isMobile = true;
|
|
4214
4393
|
dispatch({
|
|
4215
|
-
type: ActionType$
|
|
4394
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4216
4395
|
advancedFilterState,
|
|
4217
4396
|
});
|
|
4218
4397
|
} }),
|
|
4219
4398
|
React__default["default"].createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: advancedFilterState.isMobile === false, onSelected: () => {
|
|
4220
4399
|
advancedFilterState.isMobile = false;
|
|
4221
4400
|
dispatch({
|
|
4222
|
-
type: ActionType$
|
|
4401
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4223
4402
|
advancedFilterState,
|
|
4224
4403
|
});
|
|
4225
4404
|
}, noMarginOnRight: true }))),
|
|
@@ -4228,21 +4407,21 @@ const LogReviewer = (props) => {
|
|
|
4228
4407
|
React__default["default"].createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: advancedFilterState.source === undefined, onSelected: () => {
|
|
4229
4408
|
advancedFilterState.source = undefined;
|
|
4230
4409
|
dispatch({
|
|
4231
|
-
type: ActionType$
|
|
4410
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4232
4411
|
advancedFilterState,
|
|
4233
4412
|
});
|
|
4234
4413
|
} }),
|
|
4235
4414
|
React__default["default"].createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: advancedFilterState.source === LogSource$1.Client, onSelected: () => {
|
|
4236
4415
|
advancedFilterState.source = LogSource$1.Client;
|
|
4237
4416
|
dispatch({
|
|
4238
|
-
type: ActionType$
|
|
4417
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4239
4418
|
advancedFilterState,
|
|
4240
4419
|
});
|
|
4241
4420
|
} }),
|
|
4242
4421
|
React__default["default"].createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: advancedFilterState.source === LogSource$1.Server, onSelected: () => {
|
|
4243
4422
|
advancedFilterState.source = LogSource$1.Server;
|
|
4244
4423
|
dispatch({
|
|
4245
|
-
type: ActionType$
|
|
4424
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4246
4425
|
advancedFilterState,
|
|
4247
4426
|
});
|
|
4248
4427
|
}, noMarginOnRight: true })),
|
|
@@ -4253,7 +4432,7 @@ const LogReviewer = (props) => {
|
|
|
4253
4432
|
advancedFilterState.courseName = ((e.target.value)
|
|
4254
4433
|
.trim());
|
|
4255
4434
|
dispatch({
|
|
4256
|
-
type: ActionType$
|
|
4435
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4257
4436
|
advancedFilterState,
|
|
4258
4437
|
});
|
|
4259
4438
|
} })),
|
|
@@ -4263,7 +4442,7 @@ const LogReviewer = (props) => {
|
|
|
4263
4442
|
advancedFilterState.courseName = ((e.target.value)
|
|
4264
4443
|
.trim());
|
|
4265
4444
|
dispatch({
|
|
4266
|
-
type: ActionType$
|
|
4445
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
4267
4446
|
advancedFilterState,
|
|
4268
4447
|
});
|
|
4269
4448
|
} })))))));
|
|
@@ -12083,11 +12262,11 @@ var CreatableSelect$1 = CreatableSelect;
|
|
|
12083
12262
|
*/
|
|
12084
12263
|
/* ------------- Actions ------------ */
|
|
12085
12264
|
// Types of actions
|
|
12086
|
-
var ActionType$
|
|
12265
|
+
var ActionType$5;
|
|
12087
12266
|
(function (ActionType) {
|
|
12088
12267
|
// Update the input value
|
|
12089
12268
|
ActionType["SetInputValue"] = "SetInputValue";
|
|
12090
|
-
})(ActionType$
|
|
12269
|
+
})(ActionType$5 || (ActionType$5 = {}));
|
|
12091
12270
|
/**
|
|
12092
12271
|
* Reducer that executes actions
|
|
12093
12272
|
* @author Yuen Ler Chow
|
|
@@ -12095,9 +12274,9 @@ var ActionType$4;
|
|
|
12095
12274
|
* @param action action to execute
|
|
12096
12275
|
* @returns updated state
|
|
12097
12276
|
*/
|
|
12098
|
-
const reducer$
|
|
12277
|
+
const reducer$6 = (state, action) => {
|
|
12099
12278
|
switch (action.type) {
|
|
12100
|
-
case ActionType$
|
|
12279
|
+
case ActionType$5.SetInputValue: {
|
|
12101
12280
|
return Object.assign(Object.assign({}, state), { inputValue: action.value });
|
|
12102
12281
|
}
|
|
12103
12282
|
default: {
|
|
@@ -12117,7 +12296,7 @@ const CreatableMultiselect = (props) => {
|
|
|
12117
12296
|
inputValue: '',
|
|
12118
12297
|
};
|
|
12119
12298
|
// Initialize state
|
|
12120
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
12299
|
+
const [state, dispatch] = React.useReducer(reducer$6, initialState);
|
|
12121
12300
|
// Destructure common state
|
|
12122
12301
|
const { inputValue } = state;
|
|
12123
12302
|
/*------------------------------------------------------------------------*/
|
|
@@ -12194,7 +12373,7 @@ const CreatableMultiselect = (props) => {
|
|
|
12194
12373
|
}
|
|
12195
12374
|
// Reset text field to empty because the values have been added
|
|
12196
12375
|
dispatch({
|
|
12197
|
-
type: ActionType$
|
|
12376
|
+
type: ActionType$5.SetInputValue,
|
|
12198
12377
|
value: '',
|
|
12199
12378
|
});
|
|
12200
12379
|
};
|
|
@@ -12233,7 +12412,7 @@ const CreatableMultiselect = (props) => {
|
|
|
12233
12412
|
else {
|
|
12234
12413
|
// simply update the input value to the new input value
|
|
12235
12414
|
dispatch({
|
|
12236
|
-
type: ActionType$
|
|
12415
|
+
type: ActionType$5.SetInputValue,
|
|
12237
12416
|
value: newValue,
|
|
12238
12417
|
});
|
|
12239
12418
|
}
|
|
@@ -12285,13 +12464,13 @@ const style$1 = `
|
|
|
12285
12464
|
`;
|
|
12286
12465
|
/* ------------- Actions ------------ */
|
|
12287
12466
|
// Types of actions
|
|
12288
|
-
var ActionType$
|
|
12467
|
+
var ActionType$4;
|
|
12289
12468
|
(function (ActionType) {
|
|
12290
12469
|
// Update the DBEntry
|
|
12291
12470
|
ActionType["UpdateDBEntry"] = "UpdateDBEntry";
|
|
12292
12471
|
// Start the save spinner
|
|
12293
12472
|
ActionType["StartSave"] = "StartSave";
|
|
12294
|
-
})(ActionType$
|
|
12473
|
+
})(ActionType$4 || (ActionType$4 = {}));
|
|
12295
12474
|
/**
|
|
12296
12475
|
* Reducer that executes actions
|
|
12297
12476
|
* @author Yuen Ler Chow
|
|
@@ -12299,12 +12478,12 @@ var ActionType$3;
|
|
|
12299
12478
|
* @param action action to execute
|
|
12300
12479
|
* @returns updated state
|
|
12301
12480
|
*/
|
|
12302
|
-
const reducer$
|
|
12481
|
+
const reducer$5 = (state, action) => {
|
|
12303
12482
|
switch (action.type) {
|
|
12304
|
-
case ActionType$
|
|
12483
|
+
case ActionType$4.UpdateDBEntry: {
|
|
12305
12484
|
return Object.assign(Object.assign({}, state), { entry: action.dbEntry });
|
|
12306
12485
|
}
|
|
12307
|
-
case ActionType$
|
|
12486
|
+
case ActionType$4.StartSave: {
|
|
12308
12487
|
return Object.assign(Object.assign({}, state), { saving: true });
|
|
12309
12488
|
}
|
|
12310
12489
|
default: {
|
|
@@ -12329,7 +12508,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12329
12508
|
saving: false,
|
|
12330
12509
|
};
|
|
12331
12510
|
// Initialize state
|
|
12332
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
12511
|
+
const [state, dispatch] = React.useReducer(reducer$5, initialState);
|
|
12333
12512
|
// Destructure common state
|
|
12334
12513
|
const { entry, saving, } = state;
|
|
12335
12514
|
/*------------------------------------------------------------------------*/
|
|
@@ -12341,7 +12520,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12341
12520
|
*/
|
|
12342
12521
|
const save = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
12343
12522
|
// Start the save loading indicator
|
|
12344
|
-
dispatch({ type: ActionType$
|
|
12523
|
+
dispatch({ type: ActionType$4.StartSave });
|
|
12345
12524
|
// add all default values to the entry
|
|
12346
12525
|
entryFields.forEach((field) => {
|
|
12347
12526
|
if (field.defaultValue && !entry[field.objectKey]) {
|
|
@@ -12524,7 +12703,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12524
12703
|
return (React__default["default"].createElement(RadioButton, { key: choice.value, text: choice.title, selected: entry[field.objectKey] === choice.value, onSelected: () => {
|
|
12525
12704
|
entry[field.objectKey] = choice.value;
|
|
12526
12705
|
dispatch({
|
|
12527
|
-
type: ActionType$
|
|
12706
|
+
type: ActionType$4.UpdateDBEntry,
|
|
12528
12707
|
dbEntry: entry,
|
|
12529
12708
|
});
|
|
12530
12709
|
}, ariaLabel: choice.title }));
|
|
@@ -12536,7 +12715,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12536
12715
|
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) => {
|
|
12537
12716
|
entry[field.objectKey] = (e.target.value);
|
|
12538
12717
|
dispatch({
|
|
12539
|
-
type: ActionType$
|
|
12718
|
+
type: ActionType$4.UpdateDBEntry,
|
|
12540
12719
|
dbEntry: entry,
|
|
12541
12720
|
});
|
|
12542
12721
|
} }))));
|
|
@@ -12549,7 +12728,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12549
12728
|
entry[field.objectKey] = (e.target.value
|
|
12550
12729
|
.replace(/[^0-9]/g, ''));
|
|
12551
12730
|
dispatch({
|
|
12552
|
-
type: ActionType$
|
|
12731
|
+
type: ActionType$4.UpdateDBEntry,
|
|
12553
12732
|
dbEntry: entry,
|
|
12554
12733
|
});
|
|
12555
12734
|
} }))));
|
|
@@ -12579,7 +12758,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12579
12758
|
}
|
|
12580
12759
|
// Save
|
|
12581
12760
|
dispatch({
|
|
12582
|
-
type: ActionType$
|
|
12761
|
+
type: ActionType$4.UpdateDBEntry,
|
|
12583
12762
|
dbEntry: entry,
|
|
12584
12763
|
});
|
|
12585
12764
|
}, ariaLabel: choice.title }));
|
|
@@ -12594,7 +12773,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12594
12773
|
// Update entry and save
|
|
12595
12774
|
entry[field.objectKey] = values;
|
|
12596
12775
|
dispatch({
|
|
12597
|
-
type: ActionType$
|
|
12776
|
+
type: ActionType$4.UpdateDBEntry,
|
|
12598
12777
|
dbEntry: entry,
|
|
12599
12778
|
});
|
|
12600
12779
|
} })))));
|
|
@@ -12607,7 +12786,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
12607
12786
|
React__default["default"].createElement(CreatableMultiselect, { disabled: disabled, type: DBEntryFieldType$1.NumberArray, values: entry[field.objectKey] || [], onChange: (values) => {
|
|
12608
12787
|
entry[field.objectKey] = values;
|
|
12609
12788
|
dispatch({
|
|
12610
|
-
type: ActionType$
|
|
12789
|
+
type: ActionType$4.UpdateDBEntry,
|
|
12611
12790
|
dbEntry: entry,
|
|
12612
12791
|
});
|
|
12613
12792
|
} })))));
|
|
@@ -12681,7 +12860,7 @@ const generateEndpointPath = (collectionName, adminsOnly) => {
|
|
|
12681
12860
|
*/
|
|
12682
12861
|
/* ------------- Actions ------------ */
|
|
12683
12862
|
// Types of actions
|
|
12684
|
-
var ActionType$
|
|
12863
|
+
var ActionType$3;
|
|
12685
12864
|
(function (ActionType) {
|
|
12686
12865
|
// Show adder
|
|
12687
12866
|
ActionType["ShowAdder"] = "ShowAdder";
|
|
@@ -12695,7 +12874,7 @@ var ActionType$2;
|
|
|
12695
12874
|
ActionType["StartDelete"] = "StartDelete";
|
|
12696
12875
|
// Finish deletion process
|
|
12697
12876
|
ActionType["FinishDelete"] = "FinishDelete";
|
|
12698
|
-
})(ActionType$
|
|
12877
|
+
})(ActionType$3 || (ActionType$3 = {}));
|
|
12699
12878
|
/**
|
|
12700
12879
|
* Reducer that executes actions
|
|
12701
12880
|
* @author Yuen Ler Chow
|
|
@@ -12703,18 +12882,18 @@ var ActionType$2;
|
|
|
12703
12882
|
* @param action action to execute
|
|
12704
12883
|
* @returns updated state
|
|
12705
12884
|
*/
|
|
12706
|
-
const reducer$
|
|
12885
|
+
const reducer$4 = (state, action) => {
|
|
12707
12886
|
switch (action.type) {
|
|
12708
|
-
case ActionType$
|
|
12887
|
+
case ActionType$3.FinishLoading: {
|
|
12709
12888
|
return Object.assign(Object.assign({}, state), { loading: false, dbEntries: action.dbEntries });
|
|
12710
12889
|
}
|
|
12711
|
-
case ActionType$
|
|
12890
|
+
case ActionType$3.ShowAdder: {
|
|
12712
12891
|
return Object.assign(Object.assign({}, state), { adding: true, dbEntryToEdit: undefined });
|
|
12713
12892
|
}
|
|
12714
|
-
case ActionType$
|
|
12893
|
+
case ActionType$3.ShowEditor: {
|
|
12715
12894
|
return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: action.dbEntry });
|
|
12716
12895
|
}
|
|
12717
|
-
case ActionType$
|
|
12896
|
+
case ActionType$3.FinishAdd: {
|
|
12718
12897
|
// Handle cancel
|
|
12719
12898
|
const finishedEntry = action.dbEntry;
|
|
12720
12899
|
if (!finishedEntry) {
|
|
@@ -12738,10 +12917,10 @@ const reducer$3 = (state, action) => {
|
|
|
12738
12917
|
// Update the state
|
|
12739
12918
|
return Object.assign(Object.assign({}, state), { adding: false, dbEntryToEdit: undefined, dbEntries: updatedDbEntries });
|
|
12740
12919
|
}
|
|
12741
|
-
case ActionType$
|
|
12920
|
+
case ActionType$3.StartDelete: {
|
|
12742
12921
|
return Object.assign(Object.assign({}, state), { loading: true });
|
|
12743
12922
|
}
|
|
12744
|
-
case ActionType$
|
|
12923
|
+
case ActionType$3.FinishDelete: {
|
|
12745
12924
|
return Object.assign(Object.assign({}, state), { loading: false,
|
|
12746
12925
|
// Remove the deleted entry from the list
|
|
12747
12926
|
dbEntries: state.dbEntries.filter((entry) => {
|
|
@@ -12767,7 +12946,7 @@ const DBEntryManagerPanel = (props) => {
|
|
|
12767
12946
|
loading: true,
|
|
12768
12947
|
};
|
|
12769
12948
|
// Initialize state
|
|
12770
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
12949
|
+
const [state, dispatch] = React.useReducer(reducer$4, initialState);
|
|
12771
12950
|
// Destructure common state
|
|
12772
12951
|
const { adding, dbEntryToEdit, dbEntries, loading, } = state;
|
|
12773
12952
|
/*------------------------------------------------------------------------*/
|
|
@@ -12793,7 +12972,7 @@ const DBEntryManagerPanel = (props) => {
|
|
|
12793
12972
|
try {
|
|
12794
12973
|
// Start loader
|
|
12795
12974
|
dispatch({
|
|
12796
|
-
type: ActionType$
|
|
12975
|
+
type: ActionType$3.StartDelete,
|
|
12797
12976
|
});
|
|
12798
12977
|
// Perform deletion
|
|
12799
12978
|
yield visitServerEndpoint({
|
|
@@ -12802,7 +12981,7 @@ const DBEntryManagerPanel = (props) => {
|
|
|
12802
12981
|
});
|
|
12803
12982
|
// Finish loader
|
|
12804
12983
|
dispatch({
|
|
12805
|
-
type: ActionType$
|
|
12984
|
+
type: ActionType$3.FinishDelete,
|
|
12806
12985
|
dbEntry: entry,
|
|
12807
12986
|
idPropName,
|
|
12808
12987
|
});
|
|
@@ -12831,7 +13010,7 @@ const DBEntryManagerPanel = (props) => {
|
|
|
12831
13010
|
});
|
|
12832
13011
|
// Save loaded data
|
|
12833
13012
|
dispatch({
|
|
12834
|
-
type: ActionType$
|
|
13013
|
+
type: ActionType$3.FinishLoading,
|
|
12835
13014
|
dbEntries: data,
|
|
12836
13015
|
});
|
|
12837
13016
|
}
|
|
@@ -12874,7 +13053,7 @@ const DBEntryManagerPanel = (props) => {
|
|
|
12874
13053
|
React__default["default"].createElement("span", { className: "d-none d-md-inline ms-1" }, "Remove")),
|
|
12875
13054
|
!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: () => {
|
|
12876
13055
|
dispatch({
|
|
12877
|
-
type: ActionType$
|
|
13056
|
+
type: ActionType$3.ShowEditor,
|
|
12878
13057
|
dbEntry: entry,
|
|
12879
13058
|
});
|
|
12880
13059
|
} },
|
|
@@ -12884,7 +13063,7 @@ const DBEntryManagerPanel = (props) => {
|
|
|
12884
13063
|
React__default["default"].createElement("div", { className: "d-grid" },
|
|
12885
13064
|
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: () => {
|
|
12886
13065
|
dispatch({
|
|
12887
|
-
type: ActionType$
|
|
13066
|
+
type: ActionType$3.ShowAdder,
|
|
12888
13067
|
});
|
|
12889
13068
|
} },
|
|
12890
13069
|
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faPlus, className: "me-2" }),
|
|
@@ -12896,7 +13075,7 @@ const DBEntryManagerPanel = (props) => {
|
|
|
12896
13075
|
if (!loading && (adding || dbEntryToEdit)) {
|
|
12897
13076
|
body = (React__default["default"].createElement(AddOrEditDBEntry, { saveEndpointPath: endpoint, validateEntry: validateEntry, modifyEntry: modifyEntry, entryFields: entryFields, dbEntryToEdit: dbEntryToEdit, idPropName: idPropName, entries: dbEntries, itemName: itemName, onFinished: (entry) => {
|
|
12898
13077
|
dispatch({
|
|
12899
|
-
type: ActionType$
|
|
13078
|
+
type: ActionType$3.FinishAdd,
|
|
12900
13079
|
dbEntry: entry,
|
|
12901
13080
|
idPropName,
|
|
12902
13081
|
});
|
|
@@ -13093,25 +13272,25 @@ const getItemIds = (items) => {
|
|
|
13093
13272
|
};
|
|
13094
13273
|
/* ------------- Actions ------------ */
|
|
13095
13274
|
// Types of actions
|
|
13096
|
-
var ActionType$
|
|
13275
|
+
var ActionType$2;
|
|
13097
13276
|
(function (ActionType) {
|
|
13098
13277
|
// Hide the "jump to bottom" button
|
|
13099
13278
|
ActionType["HideJumpToBottomButton"] = "HideJumpToBottomButton";
|
|
13100
13279
|
// Show the "jump to bottom" button
|
|
13101
13280
|
ActionType["ShowJumpToBottomButton"] = "ShowJumpToBottomButton";
|
|
13102
|
-
})(ActionType$
|
|
13281
|
+
})(ActionType$2 || (ActionType$2 = {}));
|
|
13103
13282
|
/**
|
|
13104
13283
|
* Reducer that executes actions
|
|
13105
13284
|
* @author Gabe Abrams
|
|
13106
13285
|
* @param state current state
|
|
13107
13286
|
* @param action action to execute
|
|
13108
13287
|
*/
|
|
13109
|
-
const reducer$
|
|
13288
|
+
const reducer$3 = (state, action) => {
|
|
13110
13289
|
switch (action.type) {
|
|
13111
|
-
case ActionType$
|
|
13290
|
+
case ActionType$2.HideJumpToBottomButton: {
|
|
13112
13291
|
return Object.assign(Object.assign({}, state), { jumpToBottomButtonVisible: false });
|
|
13113
13292
|
}
|
|
13114
|
-
case ActionType$
|
|
13293
|
+
case ActionType$2.ShowJumpToBottomButton: {
|
|
13115
13294
|
return Object.assign(Object.assign({}, state), { jumpToBottomButtonVisible: true });
|
|
13116
13295
|
}
|
|
13117
13296
|
default: {
|
|
@@ -13135,7 +13314,7 @@ const AutoscrollToBottomContainer = (props) => {
|
|
|
13135
13314
|
jumpToBottomButtonVisible: false,
|
|
13136
13315
|
};
|
|
13137
13316
|
// Initialize state
|
|
13138
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
13317
|
+
const [state, dispatch] = React.useReducer(reducer$3, initialState);
|
|
13139
13318
|
// Destructure common state
|
|
13140
13319
|
const { jumpToBottomButtonVisible, } = state;
|
|
13141
13320
|
/* -------------- Refs -------------- */
|
|
@@ -13181,7 +13360,7 @@ const AutoscrollToBottomContainer = (props) => {
|
|
|
13181
13360
|
}
|
|
13182
13361
|
// Update state
|
|
13183
13362
|
dispatch({
|
|
13184
|
-
type: ActionType$
|
|
13363
|
+
type: ActionType$2.HideJumpToBottomButton,
|
|
13185
13364
|
});
|
|
13186
13365
|
// Scroll to bottom
|
|
13187
13366
|
container.current.scrollTop = (container.current.scrollHeight
|
|
@@ -13205,7 +13384,7 @@ const AutoscrollToBottomContainer = (props) => {
|
|
|
13205
13384
|
if (isScrolledToBottom()) {
|
|
13206
13385
|
// Hide button
|
|
13207
13386
|
dispatch({
|
|
13208
|
-
type: ActionType$
|
|
13387
|
+
type: ActionType$2.HideJumpToBottomButton,
|
|
13209
13388
|
});
|
|
13210
13389
|
}
|
|
13211
13390
|
};
|
|
@@ -13247,7 +13426,7 @@ const AutoscrollToBottomContainer = (props) => {
|
|
|
13247
13426
|
else {
|
|
13248
13427
|
// Not scrolled to bottom. Show "jump to bottom" button.
|
|
13249
13428
|
dispatch({
|
|
13250
|
-
type: ActionType$
|
|
13429
|
+
type: ActionType$2.ShowJumpToBottomButton,
|
|
13251
13430
|
});
|
|
13252
13431
|
}
|
|
13253
13432
|
}, [items]);
|
|
@@ -13317,25 +13496,25 @@ const combineClassNames = (classNames) => {
|
|
|
13317
13496
|
*/
|
|
13318
13497
|
/* ------------- Actions ------------ */
|
|
13319
13498
|
// Types of actions
|
|
13320
|
-
var ActionType;
|
|
13499
|
+
var ActionType$1;
|
|
13321
13500
|
(function (ActionType) {
|
|
13322
13501
|
// Start hovering on an option
|
|
13323
13502
|
ActionType["StartHover"] = "StartHover";
|
|
13324
13503
|
// Stop hovering on an option
|
|
13325
13504
|
ActionType["StopHover"] = "StopHover";
|
|
13326
|
-
})(ActionType || (ActionType = {}));
|
|
13505
|
+
})(ActionType$1 || (ActionType$1 = {}));
|
|
13327
13506
|
/**
|
|
13328
13507
|
* Reducer that executes actions
|
|
13329
13508
|
* @author Gabe Abrams
|
|
13330
13509
|
* @param state current state
|
|
13331
13510
|
* @param action action to execute
|
|
13332
13511
|
*/
|
|
13333
|
-
const reducer$
|
|
13512
|
+
const reducer$2 = (state, action) => {
|
|
13334
13513
|
switch (action.type) {
|
|
13335
|
-
case ActionType.StartHover: {
|
|
13514
|
+
case ActionType$1.StartHover: {
|
|
13336
13515
|
return Object.assign(Object.assign({}, state), { hoveredOptionId: action.hoveredOptionId });
|
|
13337
13516
|
}
|
|
13338
|
-
case ActionType.StopHover: {
|
|
13517
|
+
case ActionType$1.StopHover: {
|
|
13339
13518
|
return Object.assign(Object.assign({}, state), { hoveredOptionId: undefined });
|
|
13340
13519
|
}
|
|
13341
13520
|
default: {
|
|
@@ -13359,7 +13538,7 @@ const MultiSwitch = (props) => {
|
|
|
13359
13538
|
hoveredOptionId: undefined,
|
|
13360
13539
|
};
|
|
13361
13540
|
// Initialize state
|
|
13362
|
-
const [state, dispatch] = React.useReducer(reducer$
|
|
13541
|
+
const [state, dispatch] = React.useReducer(reducer$2, initialState);
|
|
13363
13542
|
// Destructure common state
|
|
13364
13543
|
const { hoveredOptionId, } = state;
|
|
13365
13544
|
/*------------------------------------------------------------------------*/
|
|
@@ -13371,7 +13550,7 @@ const MultiSwitch = (props) => {
|
|
|
13371
13550
|
});
|
|
13372
13551
|
// Constants
|
|
13373
13552
|
const gutterRems = heightRem * 0.1;
|
|
13374
|
-
const itemWidthRems = heightRem *
|
|
13553
|
+
const itemWidthRems = heightRem * 2.2;
|
|
13375
13554
|
const textFontSize = heightRem / 3.5;
|
|
13376
13555
|
const iconFontSize = heightRem / 2;
|
|
13377
13556
|
const borderWidthRems = 0.05;
|
|
@@ -13491,27 +13670,27 @@ const MultiSwitch = (props) => {
|
|
|
13491
13670
|
: `click to select option "${option.label}"`), onClick: () => {
|
|
13492
13671
|
// Remove hover
|
|
13493
13672
|
dispatch({
|
|
13494
|
-
type: ActionType.StopHover,
|
|
13673
|
+
type: ActionType$1.StopHover,
|
|
13495
13674
|
});
|
|
13496
13675
|
// Notify parent
|
|
13497
13676
|
onChange(option.id);
|
|
13498
13677
|
}, onMouseEnter: () => {
|
|
13499
13678
|
dispatch({
|
|
13500
|
-
type: ActionType.StartHover,
|
|
13679
|
+
type: ActionType$1.StartHover,
|
|
13501
13680
|
hoveredOptionId: option.id,
|
|
13502
13681
|
});
|
|
13503
13682
|
}, onMouseLeave: () => {
|
|
13504
13683
|
dispatch({
|
|
13505
|
-
type: ActionType.StopHover,
|
|
13684
|
+
type: ActionType$1.StopHover,
|
|
13506
13685
|
});
|
|
13507
13686
|
}, onFocus: () => {
|
|
13508
13687
|
dispatch({
|
|
13509
|
-
type: ActionType.StartHover,
|
|
13688
|
+
type: ActionType$1.StartHover,
|
|
13510
13689
|
hoveredOptionId: option.id,
|
|
13511
13690
|
});
|
|
13512
13691
|
}, onBlur: () => {
|
|
13513
13692
|
dispatch({
|
|
13514
|
-
type: ActionType.StopHover,
|
|
13693
|
+
type: ActionType$1.StopHover,
|
|
13515
13694
|
});
|
|
13516
13695
|
}, style: {
|
|
13517
13696
|
pointerEvents: ((option.id === selectedOptionId)
|
|
@@ -13530,6 +13709,147 @@ const MultiSwitch = (props) => {
|
|
|
13530
13709
|
React__default["default"].createElement("div", { className: "MultiSwitch-highlight-container" }, highlight)));
|
|
13531
13710
|
};
|
|
13532
13711
|
|
|
13712
|
+
// Types of dropdown items
|
|
13713
|
+
var DropdownItemType;
|
|
13714
|
+
(function (DropdownItemType) {
|
|
13715
|
+
// Dropdown header
|
|
13716
|
+
DropdownItemType["Header"] = "Header";
|
|
13717
|
+
// Dropdown divider
|
|
13718
|
+
DropdownItemType["Divider"] = "Divider";
|
|
13719
|
+
// Dropdown item
|
|
13720
|
+
DropdownItemType["Item"] = "Item";
|
|
13721
|
+
})(DropdownItemType || (DropdownItemType = {}));
|
|
13722
|
+
var DropdownItemType$1 = DropdownItemType;
|
|
13723
|
+
|
|
13724
|
+
/**
|
|
13725
|
+
* A simple dropdown menu
|
|
13726
|
+
* @author Alessandra De Lucas
|
|
13727
|
+
* @author Yuen Ler Chow
|
|
13728
|
+
* @author Gabe Abrams
|
|
13729
|
+
*/
|
|
13730
|
+
/* ------------- Actions ------------ */
|
|
13731
|
+
// Types of actions
|
|
13732
|
+
var ActionType;
|
|
13733
|
+
(function (ActionType) {
|
|
13734
|
+
// Toggle opening the dropdown menu
|
|
13735
|
+
ActionType["ToggleDropdown"] = "ToggleDropdown";
|
|
13736
|
+
// Close the dropdown menu
|
|
13737
|
+
ActionType["CloseDropdown"] = "CloseDropdown";
|
|
13738
|
+
})(ActionType || (ActionType = {}));
|
|
13739
|
+
/**
|
|
13740
|
+
* Reducer that executes actions
|
|
13741
|
+
* @author Alessandra De Lucas
|
|
13742
|
+
* @author Yuen Ler Chow
|
|
13743
|
+
* @param state current state
|
|
13744
|
+
* @param action action to execute
|
|
13745
|
+
*/
|
|
13746
|
+
const reducer$1 = (state, action) => {
|
|
13747
|
+
switch (action.type) {
|
|
13748
|
+
case ActionType.ToggleDropdown: {
|
|
13749
|
+
return Object.assign(Object.assign({}, state), { isDropdownOpen: !state.isDropdownOpen });
|
|
13750
|
+
}
|
|
13751
|
+
case ActionType.CloseDropdown: {
|
|
13752
|
+
return Object.assign(Object.assign({}, state), { isDropdownOpen: false });
|
|
13753
|
+
}
|
|
13754
|
+
default: {
|
|
13755
|
+
return state;
|
|
13756
|
+
}
|
|
13757
|
+
}
|
|
13758
|
+
};
|
|
13759
|
+
/*------------------------------------------------------------------------*/
|
|
13760
|
+
/* ------------------------------ Component ----------------------------- */
|
|
13761
|
+
/*------------------------------------------------------------------------*/
|
|
13762
|
+
const Dropdown = (props) => {
|
|
13763
|
+
/*------------------------------------------------------------------------*/
|
|
13764
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
13765
|
+
/*------------------------------------------------------------------------*/
|
|
13766
|
+
/* -------------- Props ------------- */
|
|
13767
|
+
// Destructure all props
|
|
13768
|
+
const { dropdownButton, items, } = props;
|
|
13769
|
+
/* -------------- State ------------- */
|
|
13770
|
+
// Initial state
|
|
13771
|
+
const initialState = {
|
|
13772
|
+
isDropdownOpen: false,
|
|
13773
|
+
};
|
|
13774
|
+
// Initialize state
|
|
13775
|
+
const [state, dispatch] = React.useReducer(reducer$1, initialState);
|
|
13776
|
+
// Destructure common state
|
|
13777
|
+
const { isDropdownOpen, } = state;
|
|
13778
|
+
/* -------------- Refs -------------- */
|
|
13779
|
+
// Initialize refs
|
|
13780
|
+
const dropdownRef = React.useRef(null);
|
|
13781
|
+
/*------------------------------------------------------------------------*/
|
|
13782
|
+
/* ------------------------- Component Functions ------------------------ */
|
|
13783
|
+
/*------------------------------------------------------------------------*/
|
|
13784
|
+
/**
|
|
13785
|
+
* Handle clicking outside of the dropdown menu to close it
|
|
13786
|
+
* @author Yuen Ler Chow
|
|
13787
|
+
* @param event the mouse event
|
|
13788
|
+
*/
|
|
13789
|
+
const handleClickOutside = (event) => {
|
|
13790
|
+
if (
|
|
13791
|
+
// Dropdown has been rendered
|
|
13792
|
+
dropdownRef.current
|
|
13793
|
+
// Click occurred outside the dropdown
|
|
13794
|
+
&& !dropdownRef.current.contains(event.target)) {
|
|
13795
|
+
dispatch({ type: ActionType.CloseDropdown });
|
|
13796
|
+
}
|
|
13797
|
+
};
|
|
13798
|
+
/*------------------------------------------------------------------------*/
|
|
13799
|
+
/* ------------------------- Lifecycle Functions ------------------------ */
|
|
13800
|
+
/*------------------------------------------------------------------------*/
|
|
13801
|
+
/**
|
|
13802
|
+
* Mount
|
|
13803
|
+
* @author Yuen Ler Chow
|
|
13804
|
+
*/
|
|
13805
|
+
React.useEffect(() => {
|
|
13806
|
+
// Add event listener to close dropdown when clicking outside
|
|
13807
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
13808
|
+
// Cleanup
|
|
13809
|
+
return () => {
|
|
13810
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
13811
|
+
};
|
|
13812
|
+
}, []);
|
|
13813
|
+
/*----------------------------------------*/
|
|
13814
|
+
/* --------------- Main UI -------------- */
|
|
13815
|
+
/*----------------------------------------*/
|
|
13816
|
+
return (React__default["default"].createElement("div", { className: "dropdown", ref: dropdownRef, "data-bs-theme": isDarkModeOn() ? 'dark' : undefined },
|
|
13817
|
+
React__default["default"].createElement("button", { className: combineClassNames([
|
|
13818
|
+
'btn dropdown-toggle border',
|
|
13819
|
+
isDropdownOpen && 'show',
|
|
13820
|
+
`btn-${dropdownButton.variant}`,
|
|
13821
|
+
dropdownButton.variant === Variant$1.Light && 'text-dark',
|
|
13822
|
+
]), type: "button", id: dropdownButton.id, "aria-expanded": isDropdownOpen, "aria-label": dropdownButton.ariaLabel, onClick: () => {
|
|
13823
|
+
dispatch({
|
|
13824
|
+
type: ActionType.ToggleDropdown,
|
|
13825
|
+
});
|
|
13826
|
+
} }, dropdownButton.content),
|
|
13827
|
+
React__default["default"].createElement("ul", { className: combineClassNames([
|
|
13828
|
+
'dropdown-menu',
|
|
13829
|
+
isDarkModeOn() && 'dropdown-menu-dark',
|
|
13830
|
+
isDropdownOpen && 'show',
|
|
13831
|
+
]) }, Object.values(items).map((item) => {
|
|
13832
|
+
if (item.type === DropdownItemType$1.Header) {
|
|
13833
|
+
return (
|
|
13834
|
+
// TODO: Implement header
|
|
13835
|
+
React__default["default"].createElement("span", null));
|
|
13836
|
+
}
|
|
13837
|
+
if (item.type === DropdownItemType$1.Divider) {
|
|
13838
|
+
return (
|
|
13839
|
+
// TODO: Implement divider
|
|
13840
|
+
React__default["default"].createElement("span", null));
|
|
13841
|
+
}
|
|
13842
|
+
return (React__default["default"].createElement("li", { key: item.id },
|
|
13843
|
+
React__default["default"].createElement("button", { type: "button", "aria-label": item.ariaLabel, className: "dropdown-item", onClick: (e) => {
|
|
13844
|
+
e.preventDefault();
|
|
13845
|
+
dispatch({
|
|
13846
|
+
type: ActionType.CloseDropdown,
|
|
13847
|
+
});
|
|
13848
|
+
item.onClick();
|
|
13849
|
+
} }, item.content)));
|
|
13850
|
+
}))));
|
|
13851
|
+
};
|
|
13852
|
+
|
|
13533
13853
|
/**
|
|
13534
13854
|
* One minute in ms
|
|
13535
13855
|
* @author Gabe Abrams
|
|
@@ -13920,22 +14240,27 @@ const initServer = (opts) => {
|
|
|
13920
14240
|
paramTypes: {
|
|
13921
14241
|
year: ParamType$1.Int,
|
|
13922
14242
|
month: ParamType$1.Int,
|
|
14243
|
+
pageNumber: ParamType$1.Int,
|
|
13923
14244
|
},
|
|
13924
14245
|
handler: ({ params }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13925
14246
|
// Get user info
|
|
13926
|
-
const { year, month, userId, isAdmin, } = params;
|
|
14247
|
+
const { year, month, pageNumber, userId, isAdmin, } = params;
|
|
13927
14248
|
// Validate user
|
|
13928
14249
|
const canReview = yield canReviewLogs(userId, isAdmin);
|
|
13929
14250
|
if (!canReview) {
|
|
13930
14251
|
throw new ErrorWithCode('You cannot access this resource because you do not have the appropriate permissions.', ReactKitErrorCode$1.NotAllowedToReviewLogs);
|
|
13931
14252
|
}
|
|
13932
14253
|
// Query for logs
|
|
13933
|
-
const
|
|
13934
|
-
|
|
13935
|
-
|
|
14254
|
+
const response = yield _logCollection.findPaged({
|
|
14255
|
+
query: {
|
|
14256
|
+
year,
|
|
14257
|
+
month,
|
|
14258
|
+
},
|
|
14259
|
+
perPage: 1000,
|
|
14260
|
+
pageNumber,
|
|
13936
14261
|
});
|
|
13937
|
-
// Return
|
|
13938
|
-
return
|
|
14262
|
+
// Return response
|
|
14263
|
+
return response;
|
|
13939
14264
|
}),
|
|
13940
14265
|
}));
|
|
13941
14266
|
};
|
|
@@ -14337,6 +14662,12 @@ const parseUserAgent = (userAgent) => {
|
|
|
14337
14662
|
* @param opts.handler function that processes the request
|
|
14338
14663
|
* @param [opts.skipSessionCheck] if true, skip the session check (allow users
|
|
14339
14664
|
* to not be logged in and launched via LTI)
|
|
14665
|
+
* @param [opts.allowedHosts] if included, only allow requests from these hosts
|
|
14666
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
14667
|
+
* you can include just one string instead of an array
|
|
14668
|
+
* @param [opts.bannedHosts] if included, do not allow requests from these hosts
|
|
14669
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
14670
|
+
* you can include just one string instead of an array
|
|
14340
14671
|
* @param [opts.unhandledErrorMessagePrefix] if included, when an error that
|
|
14341
14672
|
* is not of type ErrorWithCode is thrown, the client will receive an error
|
|
14342
14673
|
* where the error message is prefixed with this string. For example,
|
|
@@ -14364,10 +14695,76 @@ const parseUserAgent = (userAgent) => {
|
|
|
14364
14695
|
const genRouteHandler = (opts) => {
|
|
14365
14696
|
// Return a route handler
|
|
14366
14697
|
return (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14367
|
-
var _a, _b, _c;
|
|
14698
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
14368
14699
|
// Output params
|
|
14369
14700
|
const output = {};
|
|
14370
14701
|
/*----------------------------------------*/
|
|
14702
|
+
/* ----------- Hostname Check ----------- */
|
|
14703
|
+
/*----------------------------------------*/
|
|
14704
|
+
// Get hostnames
|
|
14705
|
+
const originURL = String(req.get('origin')
|
|
14706
|
+
|| req.headers.origin
|
|
14707
|
+
|| req.headers.referer);
|
|
14708
|
+
const originHostname = (originURL
|
|
14709
|
+
// Remove protocol
|
|
14710
|
+
.replace(/(^\w+:|^)\/\//, '')
|
|
14711
|
+
// Remove port
|
|
14712
|
+
.replace(/:\d+$/, ''));
|
|
14713
|
+
const serverHostname = String(req.hostname);
|
|
14714
|
+
// Check allowed
|
|
14715
|
+
if (opts.allowedHosts) {
|
|
14716
|
+
// Only accept requests from allowed hosts
|
|
14717
|
+
const allowedArray = (Array.isArray(opts.allowedHosts)
|
|
14718
|
+
? opts.allowedHosts
|
|
14719
|
+
: [opts.allowedHosts]);
|
|
14720
|
+
// Check if server is localhost
|
|
14721
|
+
if (serverHostname === 'localhost') {
|
|
14722
|
+
// Allow localhost
|
|
14723
|
+
allowedArray.push('localhost');
|
|
14724
|
+
}
|
|
14725
|
+
// Check if current host is allowed
|
|
14726
|
+
const allowed = allowedArray.some((allowedHost) => {
|
|
14727
|
+
if (allowedHost.startsWith('*')) {
|
|
14728
|
+
// Check end of hostname
|
|
14729
|
+
return originHostname.endsWith(allowedHost.substring(1));
|
|
14730
|
+
}
|
|
14731
|
+
// Check full hostname
|
|
14732
|
+
return originHostname.toLowerCase() === allowedHost.toLowerCase();
|
|
14733
|
+
});
|
|
14734
|
+
// If not allowed, return error
|
|
14735
|
+
if (!allowed) {
|
|
14736
|
+
return handleError(res, {
|
|
14737
|
+
message: 'You are not allowed to access this endpoint.',
|
|
14738
|
+
code: ReactKitErrorCode$1.HostNotAllowed,
|
|
14739
|
+
status: 403,
|
|
14740
|
+
});
|
|
14741
|
+
}
|
|
14742
|
+
}
|
|
14743
|
+
// Check banned
|
|
14744
|
+
if (opts.bannedHosts) {
|
|
14745
|
+
// Do not allow requests from banned hosts
|
|
14746
|
+
const bannedArray = (Array.isArray(opts.bannedHosts)
|
|
14747
|
+
? opts.bannedHosts
|
|
14748
|
+
: [opts.bannedHosts]);
|
|
14749
|
+
// Check if current host is banned
|
|
14750
|
+
const banned = bannedArray.some((bannedHost) => {
|
|
14751
|
+
if (bannedHost.startsWith('*')) {
|
|
14752
|
+
// Check end of hostname
|
|
14753
|
+
return originHostname.endsWith(bannedHost.substring(1));
|
|
14754
|
+
}
|
|
14755
|
+
// Check full hostname
|
|
14756
|
+
return originHostname.toLowerCase() === bannedHost.toLowerCase();
|
|
14757
|
+
});
|
|
14758
|
+
// If banned, return error
|
|
14759
|
+
if (banned) {
|
|
14760
|
+
return handleError(res, {
|
|
14761
|
+
message: 'You are not allowed to access this endpoint.',
|
|
14762
|
+
code: ReactKitErrorCode$1.HostBanned,
|
|
14763
|
+
status: 403,
|
|
14764
|
+
});
|
|
14765
|
+
}
|
|
14766
|
+
}
|
|
14767
|
+
/*----------------------------------------*/
|
|
14371
14768
|
/* ------------ Parse Params ------------ */
|
|
14372
14769
|
/*----------------------------------------*/
|
|
14373
14770
|
// Process items one by one
|
|
@@ -14565,34 +14962,34 @@ const genRouteHandler = (opts) => {
|
|
|
14565
14962
|
// Add launch info to output
|
|
14566
14963
|
output.userId = (launchInfo
|
|
14567
14964
|
? launchInfo.userId
|
|
14568
|
-
: undefined);
|
|
14965
|
+
: ((_b = output.userId) !== null && _b !== void 0 ? _b : undefined));
|
|
14569
14966
|
output.userFirstName = (launchInfo
|
|
14570
14967
|
? launchInfo.userFirstName
|
|
14571
|
-
: undefined);
|
|
14968
|
+
: ((_c = output.userFirstName) !== null && _c !== void 0 ? _c : undefined));
|
|
14572
14969
|
output.userLastName = (launchInfo
|
|
14573
14970
|
? launchInfo.userLastName
|
|
14574
|
-
: undefined);
|
|
14971
|
+
: ((_d = output.userLastName) !== null && _d !== void 0 ? _d : undefined));
|
|
14575
14972
|
output.userEmail = (launchInfo
|
|
14576
14973
|
? launchInfo.userEmail
|
|
14577
|
-
: undefined);
|
|
14974
|
+
: ((_e = output.userEmail) !== null && _e !== void 0 ? _e : undefined));
|
|
14578
14975
|
output.userAvatarURL = (launchInfo
|
|
14579
|
-
? ((
|
|
14580
|
-
: undefined);
|
|
14976
|
+
? ((_f = launchInfo.userImage) !== null && _f !== void 0 ? _f : 'http://www.gravatar.com/avatar/?d=identicon')
|
|
14977
|
+
: ((_g = output.userAvatarURL) !== null && _g !== void 0 ? _g : undefined));
|
|
14581
14978
|
output.isLearner = (launchInfo
|
|
14582
14979
|
? !!launchInfo.isLearner
|
|
14583
|
-
: undefined);
|
|
14980
|
+
: ((_h = output.isLearner) !== null && _h !== void 0 ? _h : undefined));
|
|
14584
14981
|
output.isTTM = (launchInfo
|
|
14585
14982
|
? !!launchInfo.isTTM
|
|
14586
|
-
: undefined);
|
|
14983
|
+
: ((_j = output.isTTM) !== null && _j !== void 0 ? _j : undefined));
|
|
14587
14984
|
output.isAdmin = (launchInfo
|
|
14588
14985
|
? !!launchInfo.isAdmin
|
|
14589
|
-
: undefined);
|
|
14986
|
+
: ((_k = output.isAdmin) !== null && _k !== void 0 ? _k : undefined));
|
|
14590
14987
|
output.courseId = (launchInfo
|
|
14591
|
-
? ((
|
|
14592
|
-
: undefined);
|
|
14988
|
+
? ((_l = output.courseId) !== null && _l !== void 0 ? _l : launchInfo.courseId)
|
|
14989
|
+
: ((_m = output.courseId) !== null && _m !== void 0 ? _m : undefined));
|
|
14593
14990
|
output.courseName = (launchInfo
|
|
14594
14991
|
? launchInfo.contextLabel
|
|
14595
|
-
: undefined);
|
|
14992
|
+
: ((_o = output.courseName) !== null && _o !== void 0 ? _o : undefined));
|
|
14596
14993
|
// Add other session variables
|
|
14597
14994
|
Object.keys(req.session).forEach((propName) => {
|
|
14598
14995
|
// Skip if prop already in output
|
|
@@ -14666,7 +15063,7 @@ const genRouteHandler = (opts) => {
|
|
|
14666
15063
|
* @author Gabe Abrams
|
|
14667
15064
|
*/
|
|
14668
15065
|
const logServerEvent = (logOpts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14669
|
-
var
|
|
15066
|
+
var _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
|
|
14670
15067
|
// NOTE: internally, we slip through an opts.overrideAsClientEvent boolean
|
|
14671
15068
|
// that indicates that this is actually a client event, but we don't
|
|
14672
15069
|
// include that in the LogFunction type because this is internal and
|
|
@@ -14678,16 +15075,16 @@ const genRouteHandler = (opts) => {
|
|
|
14678
15075
|
const { timestamp, year, month, day, hour, minute, } = getTimeInfoInET();
|
|
14679
15076
|
// Main log info
|
|
14680
15077
|
const mainLogInfo = {
|
|
14681
|
-
id: `${launchInfo ? 'unknown'
|
|
14682
|
-
userFirstName: (launchInfo ? 'unknown'
|
|
14683
|
-
userLastName: (launchInfo ? 'unknown'
|
|
14684
|
-
userEmail: (launchInfo ? 'unknown'
|
|
14685
|
-
userId: (launchInfo ? 'unknown'
|
|
15078
|
+
id: `${launchInfo ? launchInfo.userId : 'unknown'}-${Date.now()}-${Math.floor(Math.random() * 100000)}-${Math.floor(Math.random() * 100000)}`,
|
|
15079
|
+
userFirstName: (launchInfo ? launchInfo.userFirstName : 'unknown'),
|
|
15080
|
+
userLastName: (launchInfo ? launchInfo.userLastName : 'unknown'),
|
|
15081
|
+
userEmail: (launchInfo ? launchInfo.userEmail : 'unknown'),
|
|
15082
|
+
userId: (launchInfo ? launchInfo.userId : 'unknown'),
|
|
14686
15083
|
isLearner: (launchInfo && !!launchInfo.isLearner),
|
|
14687
15084
|
isAdmin: (launchInfo && !!launchInfo.isAdmin),
|
|
14688
15085
|
isTTM: (launchInfo && !!launchInfo.isTTM),
|
|
14689
|
-
courseId: (launchInfo ? 'unknown'
|
|
14690
|
-
courseName: (launchInfo ? 'unknown'
|
|
15086
|
+
courseId: (launchInfo ? launchInfo.courseId : 'unknown'),
|
|
15087
|
+
courseName: (launchInfo ? launchInfo.contextLabel : 'unknown'),
|
|
14691
15088
|
browser,
|
|
14692
15089
|
device,
|
|
14693
15090
|
year,
|
|
@@ -14698,24 +15095,24 @@ const genRouteHandler = (opts) => {
|
|
|
14698
15095
|
timestamp,
|
|
14699
15096
|
context: (typeof logOpts.context === 'string'
|
|
14700
15097
|
? logOpts.context
|
|
14701
|
-
: ((
|
|
14702
|
-
subcontext: ((
|
|
14703
|
-
tags: ((
|
|
14704
|
-
level: ((
|
|
14705
|
-
metadata: ((
|
|
15098
|
+
: ((_q = ((_p = logOpts.context) !== null && _p !== void 0 ? _p : {})._) !== null && _q !== void 0 ? _q : LogBuiltInMetadata.Context.Uncategorized)),
|
|
15099
|
+
subcontext: ((_r = logOpts.subcontext) !== null && _r !== void 0 ? _r : LogBuiltInMetadata.Context.Uncategorized),
|
|
15100
|
+
tags: ((_s = logOpts.tags) !== null && _s !== void 0 ? _s : []),
|
|
15101
|
+
level: ((_t = logOpts.level) !== null && _t !== void 0 ? _t : LogLevel$1.Info),
|
|
15102
|
+
metadata: ((_u = logOpts.metadata) !== null && _u !== void 0 ? _u : {}),
|
|
14706
15103
|
};
|
|
14707
15104
|
// Type-specific info
|
|
14708
15105
|
const typeSpecificInfo = (('error' in opts && opts.error)
|
|
14709
15106
|
? {
|
|
14710
15107
|
type: LogType$1.Error,
|
|
14711
|
-
errorMessage: (
|
|
14712
|
-
errorCode: (
|
|
14713
|
-
errorStack: (
|
|
15108
|
+
errorMessage: (_v = logOpts.error.message) !== null && _v !== void 0 ? _v : 'Unknown message',
|
|
15109
|
+
errorCode: (_w = logOpts.error.code) !== null && _w !== void 0 ? _w : ReactKitErrorCode$1.NoCode,
|
|
15110
|
+
errorStack: (_x = logOpts.error.stack) !== null && _x !== void 0 ? _x : 'No stack',
|
|
14714
15111
|
}
|
|
14715
15112
|
: {
|
|
14716
15113
|
type: LogType$1.Action,
|
|
14717
|
-
target: ((
|
|
14718
|
-
action: ((
|
|
15114
|
+
target: ((_y = logOpts.target) !== null && _y !== void 0 ? _y : LogBuiltInMetadata.Target.NoTarget),
|
|
15115
|
+
action: ((_z = logOpts.action) !== null && _z !== void 0 ? _z : LogAction$1.Unknown),
|
|
14719
15116
|
});
|
|
14720
15117
|
// Source-specific info
|
|
14721
15118
|
const sourceSpecificInfo = (logOpts.overrideAsClientEvent
|
|
@@ -14750,7 +15147,7 @@ const genRouteHandler = (opts) => {
|
|
|
14750
15147
|
catch (err) {
|
|
14751
15148
|
// Print because we cannot store the error
|
|
14752
15149
|
// eslint-disable-next-line no-console
|
|
14753
|
-
console.error('Could not log the following:', logOpts, 'due to this error:', ((
|
|
15150
|
+
console.error('Could not log the following:', logOpts, 'due to this error:', ((_0 = err) !== null && _0 !== void 0 ? _0 : {}).message, ((_1 = err) !== null && _1 !== void 0 ? _1 : {}).stack);
|
|
14754
15151
|
// Create a dummy log to return
|
|
14755
15152
|
const dummyMainInfo = {
|
|
14756
15153
|
id: '-1',
|
|
@@ -15094,6 +15491,11 @@ const initLogCollection = (Collection) => {
|
|
|
15094
15491
|
'context',
|
|
15095
15492
|
'subcontext',
|
|
15096
15493
|
'tags',
|
|
15494
|
+
'year',
|
|
15495
|
+
'month',
|
|
15496
|
+
'day',
|
|
15497
|
+
'hour',
|
|
15498
|
+
'type',
|
|
15097
15499
|
],
|
|
15098
15500
|
});
|
|
15099
15501
|
};
|
|
@@ -15839,6 +16241,182 @@ const shuffleArray = (arr) => {
|
|
|
15839
16241
|
return newArr;
|
|
15840
16242
|
};
|
|
15841
16243
|
|
|
16244
|
+
/**
|
|
16245
|
+
* Sends and retries an http request
|
|
16246
|
+
* @author Gabriel Abrams
|
|
16247
|
+
* @param opts object containing all arguments
|
|
16248
|
+
* @param opts.path path to send request to
|
|
16249
|
+
* @param [opts.host] host to send request to
|
|
16250
|
+
* @param [opts.method=GET] http method to use
|
|
16251
|
+
* @param [opts.params] body/data to include in the request
|
|
16252
|
+
* @param [opts.headers] headers to include in the request
|
|
16253
|
+
* @param [opts.sendCrossDomainCredentials=true if in development mode] if true,
|
|
16254
|
+
* send cross-domain credentials even if not in dev mode
|
|
16255
|
+
* @param [opts.responseType=JSON] expected response type
|
|
16256
|
+
* @returns { body, status, headers } on success
|
|
16257
|
+
*/
|
|
16258
|
+
const sendServerToServerRequest = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16259
|
+
var _a;
|
|
16260
|
+
// Process method
|
|
16261
|
+
const method = (opts.method || 'GET');
|
|
16262
|
+
// Encode objects within params
|
|
16263
|
+
let params;
|
|
16264
|
+
if (opts.params) {
|
|
16265
|
+
params = {};
|
|
16266
|
+
Object.entries(opts.params).forEach(([key, val]) => {
|
|
16267
|
+
if (typeof val === 'object' && !Array.isArray(val)) {
|
|
16268
|
+
params[key] = JSON.stringify(val);
|
|
16269
|
+
}
|
|
16270
|
+
else {
|
|
16271
|
+
params[key] = val;
|
|
16272
|
+
}
|
|
16273
|
+
});
|
|
16274
|
+
}
|
|
16275
|
+
// Stringify parameters
|
|
16276
|
+
const stringifiedParams = qs__default["default"].stringify(params || {}, {
|
|
16277
|
+
encodeValuesOnly: true,
|
|
16278
|
+
arrayFormat: 'brackets',
|
|
16279
|
+
});
|
|
16280
|
+
// Create url (include query if GET)
|
|
16281
|
+
const query = (method === 'GET' ? `?${stringifiedParams}` : '');
|
|
16282
|
+
let url;
|
|
16283
|
+
if (!opts.host) {
|
|
16284
|
+
// No host included at all. Just send to a path
|
|
16285
|
+
url = `${opts.path}${query}`;
|
|
16286
|
+
}
|
|
16287
|
+
else {
|
|
16288
|
+
url = `https://${opts.host}${opts.path}${query}`;
|
|
16289
|
+
}
|
|
16290
|
+
// Update headers
|
|
16291
|
+
const headers = opts.headers || {};
|
|
16292
|
+
let data = null;
|
|
16293
|
+
if (!headers['Content-Type']) {
|
|
16294
|
+
// Form encoded
|
|
16295
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
16296
|
+
// Add data if applicable
|
|
16297
|
+
data = (method !== 'GET' ? stringifiedParams : null);
|
|
16298
|
+
}
|
|
16299
|
+
else {
|
|
16300
|
+
// JSON encode
|
|
16301
|
+
data = params;
|
|
16302
|
+
}
|
|
16303
|
+
// Encode data
|
|
16304
|
+
let encodedData;
|
|
16305
|
+
if (data) {
|
|
16306
|
+
if (headers['Content-Type'] === 'application/x-www-form-urlencoded') {
|
|
16307
|
+
encodedData = new URLSearchParams(params);
|
|
16308
|
+
}
|
|
16309
|
+
else {
|
|
16310
|
+
encodedData = JSON.stringify(data);
|
|
16311
|
+
}
|
|
16312
|
+
}
|
|
16313
|
+
// Send request
|
|
16314
|
+
try {
|
|
16315
|
+
const response = yield fetch(url, {
|
|
16316
|
+
method,
|
|
16317
|
+
mode: 'cors',
|
|
16318
|
+
headers: headers !== null && headers !== void 0 ? headers : {},
|
|
16319
|
+
body: ((method !== 'GET' && encodedData)
|
|
16320
|
+
? encodedData
|
|
16321
|
+
: undefined),
|
|
16322
|
+
redirect: 'follow',
|
|
16323
|
+
});
|
|
16324
|
+
// Get headers map
|
|
16325
|
+
const responseHeaders = {};
|
|
16326
|
+
response.headers.forEach((value, key) => {
|
|
16327
|
+
responseHeaders[key] = value;
|
|
16328
|
+
});
|
|
16329
|
+
// Process response based on responseType
|
|
16330
|
+
try {
|
|
16331
|
+
// Parse response
|
|
16332
|
+
let responseBody;
|
|
16333
|
+
if (opts.responseType
|
|
16334
|
+
&& opts.responseType === 'Text') {
|
|
16335
|
+
// Response type is text
|
|
16336
|
+
responseBody = yield response.text();
|
|
16337
|
+
}
|
|
16338
|
+
else {
|
|
16339
|
+
// Response type is JSON
|
|
16340
|
+
responseBody = yield response.json();
|
|
16341
|
+
}
|
|
16342
|
+
// Return response
|
|
16343
|
+
return {
|
|
16344
|
+
body: responseBody,
|
|
16345
|
+
status: response.status,
|
|
16346
|
+
headers: responseHeaders,
|
|
16347
|
+
};
|
|
16348
|
+
}
|
|
16349
|
+
catch (err) {
|
|
16350
|
+
throw new ErrorWithCode(`Failed to parse response as ${opts.responseType}: ${err === null || err === void 0 ? void 0 : err.message}`, ReactKitErrorCode$1.ResponseParseError);
|
|
16351
|
+
}
|
|
16352
|
+
}
|
|
16353
|
+
catch (err) {
|
|
16354
|
+
// Self-signed certificate error:
|
|
16355
|
+
if ((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes('self signed certificate')) {
|
|
16356
|
+
throw new ErrorWithCode('We refused to send a request because the receiver has self-signed certificates.', ReactKitErrorCode$1.SelfSigned);
|
|
16357
|
+
}
|
|
16358
|
+
// No tries left
|
|
16359
|
+
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);
|
|
16360
|
+
}
|
|
16361
|
+
});
|
|
16362
|
+
|
|
16363
|
+
/**
|
|
16364
|
+
* Send a server-to-server request from this sever to another server that uses
|
|
16365
|
+
* dce-reactkit [for server only]
|
|
16366
|
+
* @author Gabe Abrams
|
|
16367
|
+
* @param opts object containing all arguments
|
|
16368
|
+
* @param opts.host - the host of the other server
|
|
16369
|
+
* @param opts.path - the path of the other server's endpoint
|
|
16370
|
+
* @param [opts.method=GET] - the method of the endpoint
|
|
16371
|
+
* @param [opts.params] - query/body parameters to include
|
|
16372
|
+
* @param [opts.headers] - headers to include
|
|
16373
|
+
* @returns response from server
|
|
16374
|
+
*/
|
|
16375
|
+
const visitEndpointOnAnotherServer = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16376
|
+
var _a;
|
|
16377
|
+
// Remove properties with undefined values
|
|
16378
|
+
let params;
|
|
16379
|
+
if (opts.params) {
|
|
16380
|
+
params = Object.fromEntries(Object
|
|
16381
|
+
.entries(opts.params)
|
|
16382
|
+
.filter(([, value]) => {
|
|
16383
|
+
return value !== undefined;
|
|
16384
|
+
}));
|
|
16385
|
+
}
|
|
16386
|
+
// Automatically JSONify arrays and objects
|
|
16387
|
+
if (params) {
|
|
16388
|
+
params = Object.fromEntries(Object
|
|
16389
|
+
.entries(params)
|
|
16390
|
+
.map(([key, value]) => {
|
|
16391
|
+
if (Array.isArray(value) || typeof value === 'object') {
|
|
16392
|
+
return [key, JSON.stringify(value)];
|
|
16393
|
+
}
|
|
16394
|
+
return [key, value];
|
|
16395
|
+
}));
|
|
16396
|
+
}
|
|
16397
|
+
// Send the request
|
|
16398
|
+
const response = yield sendServerToServerRequest({
|
|
16399
|
+
host: opts.host,
|
|
16400
|
+
path: opts.path,
|
|
16401
|
+
method: (_a = opts.method) !== null && _a !== void 0 ? _a : 'GET',
|
|
16402
|
+
params,
|
|
16403
|
+
});
|
|
16404
|
+
// Check for failure
|
|
16405
|
+
if (!response || !response.body) {
|
|
16406
|
+
throw new ErrorWithCode('We didn\'t get a response from the server. Please check your internet connection.', ReactKitErrorCode$1.NoResponse);
|
|
16407
|
+
}
|
|
16408
|
+
if (!response.body.success) {
|
|
16409
|
+
// Other errors
|
|
16410
|
+
throw new ErrorWithCode((response.body.message
|
|
16411
|
+
|| 'An unknown error occurred. Please contact an admin.'), (response.body.code
|
|
16412
|
+
|| ReactKitErrorCode$1.NoCode));
|
|
16413
|
+
}
|
|
16414
|
+
// Success! Extract the body
|
|
16415
|
+
const { body } = response.body;
|
|
16416
|
+
// Return
|
|
16417
|
+
return body;
|
|
16418
|
+
});
|
|
16419
|
+
|
|
15842
16420
|
/**
|
|
15843
16421
|
* Days of the week
|
|
15844
16422
|
* @author Gabe Abrams
|
|
@@ -15866,6 +16444,8 @@ exports.DBEntryFieldType = DBEntryFieldType$1;
|
|
|
15866
16444
|
exports.DBEntryManagerPanel = DBEntryManagerPanel;
|
|
15867
16445
|
exports.DayOfWeek = DayOfWeek$1;
|
|
15868
16446
|
exports.Drawer = Drawer;
|
|
16447
|
+
exports.Dropdown = Dropdown;
|
|
16448
|
+
exports.DropdownItemType = DropdownItemType$1;
|
|
15869
16449
|
exports.DynamicWord = DynamicWord;
|
|
15870
16450
|
exports.ErrorBox = ErrorBox;
|
|
15871
16451
|
exports.ErrorWithCode = ErrorWithCode;
|
|
@@ -15937,6 +16517,7 @@ exports.padDecimalZeros = padDecimalZeros;
|
|
|
15937
16517
|
exports.padZerosLeft = padZerosLeft;
|
|
15938
16518
|
exports.parallelLimit = parallelLimit;
|
|
15939
16519
|
exports.prefixWithAOrAn = prefixWithAOrAn;
|
|
16520
|
+
exports.prompt = prompt;
|
|
15940
16521
|
exports.roundToNumDecimals = roundToNumDecimals;
|
|
15941
16522
|
exports.setClientEventMetadataPopulator = setClientEventMetadataPopulator;
|
|
15942
16523
|
exports.showFatalError = showFatalError;
|
|
@@ -15950,6 +16531,7 @@ exports.useForceRender = useForceRender;
|
|
|
15950
16531
|
exports.validateEmail = validateEmail;
|
|
15951
16532
|
exports.validatePhoneNumber = validatePhoneNumber;
|
|
15952
16533
|
exports.validateString = validateString;
|
|
16534
|
+
exports.visitEndpointOnAnotherServer = visitEndpointOnAnotherServer;
|
|
15953
16535
|
exports.visitServerEndpoint = visitServerEndpoint;
|
|
15954
16536
|
exports.waitMs = waitMs;
|
|
15955
16537
|
//# sourceMappingURL=index.js.map
|