dce-reactkit 4.0.2-beta-simple-date-chooser.1 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +662 -771
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/Pagination.d.ts +13 -0
- package/dist/cjs/types/constants/LOG_REVIEW_GET_LOGS_ROUTE.d.ts +6 -0
- package/dist/cjs/types/helpers/cloneDeep.d.ts +8 -0
- package/dist/cjs/types/index.d.ts +4 -1
- package/dist/cjs/types/types/LogReviewerFilterState/ActionErrorFilterState.d.ts +17 -0
- package/dist/cjs/types/types/LogReviewerFilterState/AdvancedFilterState.d.ts +21 -0
- package/dist/cjs/types/types/LogReviewerFilterState/ContextFilterState.d.ts +10 -0
- package/dist/cjs/types/types/LogReviewerFilterState/DateFilterState.d.ts +17 -0
- package/dist/cjs/types/types/LogReviewerFilterState/TagFilterState.d.ts +8 -0
- package/dist/cjs/types/types/LogReviewerFilterState/index.d.ts +17 -0
- package/dist/esm/index.js +661 -773
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/Pagination.d.ts +13 -0
- package/dist/esm/types/constants/LOG_REVIEW_GET_LOGS_ROUTE.d.ts +6 -0
- package/dist/esm/types/helpers/cloneDeep.d.ts +8 -0
- package/dist/esm/types/index.d.ts +4 -1
- package/dist/esm/types/types/LogReviewerFilterState/ActionErrorFilterState.d.ts +17 -0
- package/dist/esm/types/types/LogReviewerFilterState/AdvancedFilterState.d.ts +21 -0
- package/dist/esm/types/types/LogReviewerFilterState/ContextFilterState.d.ts +10 -0
- package/dist/esm/types/types/LogReviewerFilterState/DateFilterState.d.ts +17 -0
- package/dist/esm/types/types/LogReviewerFilterState/TagFilterState.d.ts +8 -0
- package/dist/esm/types/types/LogReviewerFilterState/index.d.ts +17 -0
- package/dist/index.d.ts +98 -1
- package/package.json +2 -1
- package/src/components/LogReviewer.tsx +1133 -1307
- package/src/components/Pagination.tsx +172 -0
- package/src/components/SimpleDateChooser.tsx +1 -1
- package/src/constants/LOG_REVIEW_GET_LOGS_ROUTE.ts +9 -0
- package/src/helpers/cloneDeep.ts +11 -0
- package/src/index.ts +6 -0
- package/src/types/LogReviewerFilterState/ActionErrorFilterState.ts +24 -0
- package/src/types/LogReviewerFilterState/AdvancedFilterState.ts +36 -0
- package/src/types/LogReviewerFilterState/ContextFilterState.ts +16 -0
- package/src/types/LogReviewerFilterState/DateFilterState.ts +26 -0
- package/src/types/LogReviewerFilterState/TagFilterState.ts +9 -0
- package/src/types/LogReviewerFilterState/index.ts +24 -0
package/dist/cjs/index.js
CHANGED
|
@@ -6,6 +6,7 @@ var React = require('react');
|
|
|
6
6
|
var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
|
|
7
7
|
var reactFontawesome = require('@fortawesome/react-fontawesome');
|
|
8
8
|
var freeRegularSvgIcons = require('@fortawesome/free-regular-svg-icons');
|
|
9
|
+
var clone = require('nanoclone');
|
|
9
10
|
|
|
10
11
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
12
|
|
|
@@ -29,6 +30,7 @@ function _interopNamespace(e) {
|
|
|
29
30
|
|
|
30
31
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
31
32
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
33
|
+
var clone__default = /*#__PURE__*/_interopDefaultLegacy(clone);
|
|
32
34
|
|
|
33
35
|
/*! *****************************************************************************
|
|
34
36
|
Copyright (c) Microsoft Corporation.
|
|
@@ -3793,10 +3795,10 @@ const getHumanReadableDate = (dateOrTimestamp) => {
|
|
|
3793
3795
|
};
|
|
3794
3796
|
|
|
3795
3797
|
/**
|
|
3796
|
-
* Path of the route for
|
|
3798
|
+
* Path of the route for getting logs for log review
|
|
3797
3799
|
* @author Gabe Abrams
|
|
3798
3800
|
*/
|
|
3799
|
-
const
|
|
3801
|
+
const LOG_REVIEW_GET_LOGS_ROUTE = `/admin${ROUTE_PATH_PREFIX}/logs`;
|
|
3800
3802
|
|
|
3801
3803
|
/**
|
|
3802
3804
|
* Source of a log event
|
|
@@ -4401,6 +4403,71 @@ const IntelliTable = (props) => {
|
|
|
4401
4403
|
} }, table)));
|
|
4402
4404
|
};
|
|
4403
4405
|
|
|
4406
|
+
// Import React
|
|
4407
|
+
/*------------------------------------------------------------------------*/
|
|
4408
|
+
/* ------------------------------ Component ----------------------------- */
|
|
4409
|
+
/*------------------------------------------------------------------------*/
|
|
4410
|
+
const Pagination = (props) => {
|
|
4411
|
+
/*------------------------------------------------------------------------*/
|
|
4412
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
4413
|
+
/*------------------------------------------------------------------------*/
|
|
4414
|
+
/* -------------- Props ------------- */
|
|
4415
|
+
// Destructure props
|
|
4416
|
+
const { currentPage, numPages, loading = false, onPageChanged, } = props;
|
|
4417
|
+
/*------------------------------------------------------------------------*/
|
|
4418
|
+
/* ------------------------------- Render ------------------------------- */
|
|
4419
|
+
/*------------------------------------------------------------------------*/
|
|
4420
|
+
// Compute pages to display
|
|
4421
|
+
const pages = [];
|
|
4422
|
+
const delta = 2; // how many pages to show on either side of current
|
|
4423
|
+
let start = Math.max(1, currentPage - delta);
|
|
4424
|
+
let end = Math.min(numPages, currentPage + delta);
|
|
4425
|
+
// If we are too close to the beginning or end, shift the window.
|
|
4426
|
+
if (currentPage - delta < 1) {
|
|
4427
|
+
end = Math.min(numPages, end + (1 - (currentPage - delta)));
|
|
4428
|
+
}
|
|
4429
|
+
if (currentPage + delta > numPages) {
|
|
4430
|
+
start = Math.max(1, start - ((currentPage + delta) - numPages));
|
|
4431
|
+
}
|
|
4432
|
+
for (let i = start; i <= end; i++) {
|
|
4433
|
+
pages.push(i);
|
|
4434
|
+
}
|
|
4435
|
+
// Render
|
|
4436
|
+
return (React__default["default"].createElement("nav", { "aria-label": "Page navigation for logs", className: "mt-3" },
|
|
4437
|
+
React__default["default"].createElement("ul", { className: "pagination justify-content-center" },
|
|
4438
|
+
React__default["default"].createElement("li", { className: `page-item ${(currentPage <= 1 || loading) ? 'disabled' : ''}` },
|
|
4439
|
+
React__default["default"].createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(currentPage - 1); }, disabled: currentPage <= 1 || loading, "aria-label": "Go to previous page" },
|
|
4440
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faArrowLeft }),
|
|
4441
|
+
' ',
|
|
4442
|
+
"Prev")),
|
|
4443
|
+
(currentPage > 3 && pages[0] !== 1) && (React__default["default"].createElement("li", { className: "page-item" },
|
|
4444
|
+
React__default["default"].createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(1); }, disabled: loading, "aria-label": "Go to page 1" }, "1"))),
|
|
4445
|
+
currentPage > 4 && (React__default["default"].createElement("li", { className: "page-item disabled" },
|
|
4446
|
+
React__default["default"].createElement("span", { className: "page-link" }, "..."))),
|
|
4447
|
+
pages.map((pageNum) => {
|
|
4448
|
+
return (React__default["default"].createElement("li", { key: pageNum, className: `page-item ${pageNum === currentPage ? 'active' : ''}` },
|
|
4449
|
+
React__default["default"].createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(pageNum); }, disabled: loading, "aria-label": `Go to page ${pageNum}` }, pageNum)));
|
|
4450
|
+
}),
|
|
4451
|
+
currentPage < numPages - 3 && (React__default["default"].createElement("li", { className: "page-item disabled" },
|
|
4452
|
+
React__default["default"].createElement("span", { className: "page-link" }, "..."))),
|
|
4453
|
+
(currentPage < numPages - 2
|
|
4454
|
+
&& pages[pages.length - 1] !== numPages) && (React__default["default"].createElement("li", { className: "page-item" },
|
|
4455
|
+
React__default["default"].createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(numPages); }, disabled: loading, "aria-label": "Go to last page" }, numPages))),
|
|
4456
|
+
React__default["default"].createElement("li", { className: `page-item ${(currentPage >= numPages || loading) ? 'disabled' : ''}` },
|
|
4457
|
+
React__default["default"].createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(currentPage + 1); }, disabled: currentPage >= numPages || loading, "aria-label": "Go to next page" },
|
|
4458
|
+
"Next",
|
|
4459
|
+
' ',
|
|
4460
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faArrowRight }))))));
|
|
4461
|
+
};
|
|
4462
|
+
|
|
4463
|
+
/**
|
|
4464
|
+
* Deeply clones an object
|
|
4465
|
+
* @author Yuen Ler Chow
|
|
4466
|
+
* @param obj the object to clone
|
|
4467
|
+
* @returns a deep clone of the object
|
|
4468
|
+
*/
|
|
4469
|
+
const cloneDeep = clone__default["default"];
|
|
4470
|
+
|
|
4404
4471
|
/**
|
|
4405
4472
|
* Log reviewer panel that allows users (must be approved admins) to
|
|
4406
4473
|
* review logs written by dce-reactkit
|
|
@@ -4756,7 +4823,7 @@ var ActionType$6;
|
|
|
4756
4823
|
(function (ActionType) {
|
|
4757
4824
|
// Show the loading bar
|
|
4758
4825
|
ActionType["StartLoading"] = "start-loading";
|
|
4759
|
-
// Finish loading
|
|
4826
|
+
// Finish loading logs
|
|
4760
4827
|
ActionType["FinishLoading"] = "finish-loading";
|
|
4761
4828
|
// Reset filters to initial values
|
|
4762
4829
|
ActionType["ResetFilters"] = "reset-filters";
|
|
@@ -4774,6 +4841,14 @@ var ActionType$6;
|
|
|
4774
4841
|
ActionType["UpdateActionErrorFilterState"] = "update-action-error-filter-state";
|
|
4775
4842
|
// Update the advanced filter state
|
|
4776
4843
|
ActionType["UpdateAdvancedFilterState"] = "update-advanced-filter-state";
|
|
4844
|
+
// Set has another page
|
|
4845
|
+
ActionType["SetHasAnotherPage"] = "set-has-another-page";
|
|
4846
|
+
// Set the number of pages
|
|
4847
|
+
ActionType["SetNumPages"] = "set-num-pages";
|
|
4848
|
+
// Set page number
|
|
4849
|
+
ActionType["SetPageNumber"] = "set-page-number";
|
|
4850
|
+
// Reset user made filter change indicator
|
|
4851
|
+
ActionType["ResetUserMadeFilterChange"] = "reset-user-made-filter-change";
|
|
4777
4852
|
})(ActionType$6 || (ActionType$6 = {}));
|
|
4778
4853
|
/**
|
|
4779
4854
|
* Reducer that executes actions
|
|
@@ -4787,7 +4862,7 @@ const reducer$7 = (state, action) => {
|
|
|
4787
4862
|
return Object.assign(Object.assign({}, state), { loading: true });
|
|
4788
4863
|
}
|
|
4789
4864
|
case ActionType$6.FinishLoading: {
|
|
4790
|
-
return Object.assign(Object.assign({}, state), { loading: false,
|
|
4865
|
+
return Object.assign(Object.assign({}, state), { loading: false, logs: action.logs });
|
|
4791
4866
|
}
|
|
4792
4867
|
case ActionType$6.ToggleFilterDrawer: {
|
|
4793
4868
|
return Object.assign(Object.assign({}, state), { expandedFilterDrawer: (state.expandedFilterDrawer === action.filterDrawer
|
|
@@ -4798,22 +4873,34 @@ const reducer$7 = (state, action) => {
|
|
|
4798
4873
|
return Object.assign(Object.assign({}, state), { expandedFilterDrawer: undefined });
|
|
4799
4874
|
}
|
|
4800
4875
|
case ActionType$6.ResetFilters: {
|
|
4801
|
-
return Object.assign(Object.assign({}, state), {
|
|
4876
|
+
return Object.assign(Object.assign({}, state), { pendingDateFilterState: action.initDateFilterState, pendingContextFilterState: action.initContextFilterState, pendingTagFilterState: action.initTagFilterState, pendingActionErrorFilterState: action.initActionErrorFilterState, pendingAdvancedFilterState: action.initAdvancedFilterState, pageNumber: 1 });
|
|
4802
4877
|
}
|
|
4803
4878
|
case ActionType$6.UpdateDateFilterState: {
|
|
4804
|
-
return Object.assign(Object.assign({}, state), {
|
|
4879
|
+
return Object.assign(Object.assign({}, state), { pendingDateFilterState: action.dateFilterState, userMadeFilterChange: true });
|
|
4805
4880
|
}
|
|
4806
4881
|
case ActionType$6.UpdateContextFilterState: {
|
|
4807
|
-
return Object.assign(Object.assign({}, state), {
|
|
4882
|
+
return Object.assign(Object.assign({}, state), { pendingContextFilterState: action.contextFilterState, userMadeFilterChange: true });
|
|
4808
4883
|
}
|
|
4809
4884
|
case ActionType$6.UpdateTagFilterState: {
|
|
4810
|
-
return Object.assign(Object.assign({}, state), {
|
|
4885
|
+
return Object.assign(Object.assign({}, state), { pendingTagFilterState: action.tagFilterState, userMadeFilterChange: true });
|
|
4811
4886
|
}
|
|
4812
4887
|
case ActionType$6.UpdateActionErrorFilterState: {
|
|
4813
|
-
return Object.assign(Object.assign({}, state), {
|
|
4888
|
+
return Object.assign(Object.assign({}, state), { pendingActionErrorFilterState: action.actionErrorFilterState, userMadeFilterChange: true });
|
|
4814
4889
|
}
|
|
4815
4890
|
case ActionType$6.UpdateAdvancedFilterState: {
|
|
4816
|
-
return Object.assign(Object.assign({}, state), {
|
|
4891
|
+
return Object.assign(Object.assign({}, state), { pendingAdvancedFilterState: action.advancedFilterState, userMadeFilterChange: true });
|
|
4892
|
+
}
|
|
4893
|
+
case ActionType$6.SetHasAnotherPage: {
|
|
4894
|
+
return Object.assign(Object.assign({}, state), { hasAnotherPage: action.hasAnotherPage });
|
|
4895
|
+
}
|
|
4896
|
+
case ActionType$6.SetNumPages: {
|
|
4897
|
+
return Object.assign(Object.assign({}, state), { numPages: action.numPages });
|
|
4898
|
+
}
|
|
4899
|
+
case ActionType$6.SetPageNumber: {
|
|
4900
|
+
return Object.assign(Object.assign({}, state), { pageNumber: action.pageNumber });
|
|
4901
|
+
}
|
|
4902
|
+
case ActionType$6.ResetUserMadeFilterChange: {
|
|
4903
|
+
return Object.assign(Object.assign({}, state), { userMadeFilterChange: false });
|
|
4817
4904
|
}
|
|
4818
4905
|
default: {
|
|
4819
4906
|
return state;
|
|
@@ -4884,7 +4971,7 @@ const LogReviewer = (props) => {
|
|
|
4884
4971
|
else {
|
|
4885
4972
|
// Case: subcontexts exist
|
|
4886
4973
|
initContextFilterState[context] = {};
|
|
4887
|
-
Object.
|
|
4974
|
+
Object.keys(contextMap[context]).forEach((subcontext) => {
|
|
4888
4975
|
// Skip self ("_")
|
|
4889
4976
|
if (subcontext === '_') {
|
|
4890
4977
|
return;
|
|
@@ -4932,125 +5019,105 @@ const LogReviewer = (props) => {
|
|
|
4932
5019
|
// Initial state
|
|
4933
5020
|
const initialState = {
|
|
4934
5021
|
loading: true,
|
|
4935
|
-
|
|
5022
|
+
logs: [],
|
|
4936
5023
|
expandedFilterDrawer: undefined,
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
5024
|
+
pendingDateFilterState: initDateFilterState,
|
|
5025
|
+
pendingContextFilterState: initContextFilterState,
|
|
5026
|
+
pendingTagFilterState: initTagFilterState,
|
|
5027
|
+
pendingActionErrorFilterState: initActionErrorFilterState,
|
|
5028
|
+
pendingAdvancedFilterState: initAdvancedFilterState,
|
|
5029
|
+
pageNumber: 1,
|
|
5030
|
+
hasAnotherPage: false,
|
|
5031
|
+
numPages: 1,
|
|
5032
|
+
userMadeFilterChange: false,
|
|
4942
5033
|
};
|
|
4943
5034
|
// Initialize state
|
|
4944
5035
|
const [state, dispatch] = React.useReducer(reducer$7, initialState);
|
|
4945
5036
|
// Destructure common state
|
|
4946
|
-
const { loading,
|
|
5037
|
+
const { loading, logs, expandedFilterDrawer, pendingDateFilterState, pendingContextFilterState, pendingTagFilterState, pendingActionErrorFilterState, pendingAdvancedFilterState, pageNumber, numPages, userMadeFilterChange, } = state;
|
|
5038
|
+
/* -------------- Refs -------------- */
|
|
5039
|
+
// Initialize refs
|
|
5040
|
+
const activeFiltersRef = React.useRef({
|
|
5041
|
+
dateFilterState: JSON.parse(JSON.stringify(pendingDateFilterState)),
|
|
5042
|
+
contextFilterState: JSON.parse(JSON.stringify(pendingContextFilterState)),
|
|
5043
|
+
tagFilterState: JSON.parse(JSON.stringify(pendingTagFilterState)),
|
|
5044
|
+
actionErrorFilterState: JSON.parse(JSON.stringify(pendingActionErrorFilterState)),
|
|
5045
|
+
advancedFilterState: JSON.parse(JSON.stringify(pendingAdvancedFilterState)),
|
|
5046
|
+
});
|
|
4947
5047
|
/*------------------------------------------------------------------------*/
|
|
4948
5048
|
/* ------------------------- Component Functions ------------------------ */
|
|
4949
5049
|
/*------------------------------------------------------------------------*/
|
|
4950
5050
|
/**
|
|
4951
|
-
*
|
|
4952
|
-
*
|
|
4953
|
-
* @
|
|
4954
|
-
* @param
|
|
4955
|
-
* @
|
|
4956
|
-
|
|
4957
|
-
const listMonthsToLoad = (newDateFilterState) => {
|
|
4958
|
-
// List of year/month combos that need to be loaded
|
|
4959
|
-
const toLoad = [];
|
|
4960
|
-
// Loop through dates
|
|
4961
|
-
let { year, month } = newDateFilterState.startDate;
|
|
4962
|
-
while (
|
|
4963
|
-
// Earlier year
|
|
4964
|
-
(year < newDateFilterState.endDate.year)
|
|
4965
|
-
// Current year but included month
|
|
4966
|
-
|| (year === newDateFilterState.endDate.year
|
|
4967
|
-
&& month <= newDateFilterState.endDate.month)) {
|
|
4968
|
-
// Add to list if not already loaded
|
|
4969
|
-
if (!logMap[year]
|
|
4970
|
-
|| !logMap[year][month]) {
|
|
4971
|
-
toLoad.push({
|
|
4972
|
-
year,
|
|
4973
|
-
month,
|
|
4974
|
-
});
|
|
4975
|
-
}
|
|
4976
|
-
// Increment
|
|
4977
|
-
month += 1;
|
|
4978
|
-
if (month > 12) {
|
|
4979
|
-
month -= 12;
|
|
4980
|
-
year += 1;
|
|
4981
|
-
}
|
|
4982
|
-
}
|
|
4983
|
-
// Return
|
|
4984
|
-
return toLoad;
|
|
4985
|
-
};
|
|
4986
|
-
/**
|
|
4987
|
-
* Handle updated start/end dates (updates state, loads if necessary)
|
|
4988
|
-
* @author Gabe Abrams
|
|
4989
|
-
* @param newDateFilterState the new date filter state
|
|
5051
|
+
* Fetch logs from the server based on current filters
|
|
5052
|
+
* @author Yuen Ler Chow
|
|
5053
|
+
* @param opts object containing all arguments
|
|
5054
|
+
* @param opts.filters the filters to apply
|
|
5055
|
+
* @param opts.pageNum the page number to fetch
|
|
5056
|
+
* @param opts.filtersChanged if true, the filters have changed
|
|
4990
5057
|
*/
|
|
4991
|
-
const
|
|
4992
|
-
|
|
4993
|
-
dispatch({
|
|
4994
|
-
type: ActionType$6.UpdateDateFilterState,
|
|
4995
|
-
dateFilterState: newDateFilterState,
|
|
4996
|
-
});
|
|
4997
|
-
// Check which year/month combos we need to load
|
|
4998
|
-
const toLoad = listMonthsToLoad(newDateFilterState);
|
|
4999
|
-
// If nothing to load, finished
|
|
5000
|
-
if (toLoad.length === 0) {
|
|
5001
|
-
return;
|
|
5002
|
-
}
|
|
5003
|
-
// Start loading
|
|
5058
|
+
const fetchLogs = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5059
|
+
const { filters, pageNum, filtersChanged, } = opts;
|
|
5004
5060
|
dispatch({
|
|
5005
5061
|
type: ActionType$6.StartLoading,
|
|
5006
5062
|
});
|
|
5007
|
-
// Load required months
|
|
5008
5063
|
try {
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
}
|
|
5032
|
-
logMap[year][month] = logs;
|
|
5064
|
+
// Send filters to the server
|
|
5065
|
+
let fetchedLogs = [];
|
|
5066
|
+
// Get logs from server
|
|
5067
|
+
const response = yield visitServerEndpoint({
|
|
5068
|
+
path: LOG_REVIEW_GET_LOGS_ROUTE,
|
|
5069
|
+
method: 'GET',
|
|
5070
|
+
params: {
|
|
5071
|
+
pageNumber: pageNum,
|
|
5072
|
+
filters,
|
|
5073
|
+
countDocuments: filtersChanged,
|
|
5074
|
+
},
|
|
5075
|
+
});
|
|
5076
|
+
fetchedLogs = fetchedLogs.concat(response.items);
|
|
5077
|
+
dispatch({
|
|
5078
|
+
type: ActionType$6.SetHasAnotherPage,
|
|
5079
|
+
hasAnotherPage: response.hasAnotherPage,
|
|
5080
|
+
});
|
|
5081
|
+
if (filtersChanged && response.numPages !== undefined) {
|
|
5082
|
+
dispatch({
|
|
5083
|
+
type: ActionType$6.SetNumPages,
|
|
5084
|
+
numPages: response.numPages,
|
|
5085
|
+
});
|
|
5033
5086
|
}
|
|
5087
|
+
// Update logs in state
|
|
5088
|
+
dispatch({
|
|
5089
|
+
type: ActionType$6.FinishLoading,
|
|
5090
|
+
logs: fetchedLogs,
|
|
5091
|
+
});
|
|
5092
|
+
// Update page number
|
|
5093
|
+
dispatch({
|
|
5094
|
+
type: ActionType$6.SetPageNumber,
|
|
5095
|
+
pageNumber: pageNum,
|
|
5096
|
+
});
|
|
5034
5097
|
}
|
|
5035
5098
|
catch (err) {
|
|
5036
5099
|
return showFatalError(err);
|
|
5037
5100
|
}
|
|
5038
|
-
// Finish loading
|
|
5039
|
-
dispatch({
|
|
5040
|
-
type: ActionType$6.FinishLoading,
|
|
5041
|
-
logMap,
|
|
5042
|
-
});
|
|
5043
5101
|
});
|
|
5044
5102
|
/*------------------------------------------------------------------------*/
|
|
5045
5103
|
/* ------------------------- Lifecycle Functions ------------------------ */
|
|
5046
5104
|
/*------------------------------------------------------------------------*/
|
|
5047
5105
|
/**
|
|
5048
|
-
*
|
|
5049
|
-
* @author
|
|
5106
|
+
* Fetch logs on mount
|
|
5107
|
+
* @author Yuen Ler Chow
|
|
5050
5108
|
*/
|
|
5051
5109
|
React.useEffect(() => {
|
|
5052
|
-
|
|
5053
|
-
|
|
5110
|
+
fetchLogs({
|
|
5111
|
+
filters: {
|
|
5112
|
+
dateFilterState: pendingDateFilterState,
|
|
5113
|
+
contextFilterState: pendingContextFilterState,
|
|
5114
|
+
tagFilterState: pendingTagFilterState,
|
|
5115
|
+
actionErrorFilterState: pendingActionErrorFilterState,
|
|
5116
|
+
advancedFilterState: pendingAdvancedFilterState,
|
|
5117
|
+
},
|
|
5118
|
+
pageNum: 1,
|
|
5119
|
+
filtersChanged: true,
|
|
5120
|
+
});
|
|
5054
5121
|
}, []);
|
|
5055
5122
|
/*------------------------------------------------------------------------*/
|
|
5056
5123
|
/* ------------------------------- Render ------------------------------- */
|
|
@@ -5058,718 +5125,534 @@ const LogReviewer = (props) => {
|
|
|
5058
5125
|
/*----------------------------------------*/
|
|
5059
5126
|
/* --------------- Main UI -------------- */
|
|
5060
5127
|
/*----------------------------------------*/
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5128
|
+
/*----------------------------------------*/
|
|
5129
|
+
/* ------------ Pagination -------------- */
|
|
5130
|
+
/*----------------------------------------*/
|
|
5131
|
+
const paginationControls = logs.length > 0 && (React__default["default"].createElement(Pagination, { currentPage: pageNumber, numPages: numPages, loading: loading, onPageChanged: (targetPage) => {
|
|
5132
|
+
const { current: activeFilters } = activeFiltersRef;
|
|
5133
|
+
fetchLogs({
|
|
5134
|
+
filters: {
|
|
5135
|
+
dateFilterState: activeFilters.dateFilterState,
|
|
5136
|
+
contextFilterState: activeFilters.contextFilterState,
|
|
5137
|
+
tagFilterState: activeFilters.tagFilterState,
|
|
5138
|
+
actionErrorFilterState: activeFilters.actionErrorFilterState,
|
|
5139
|
+
advancedFilterState: activeFilters.advancedFilterState,
|
|
5140
|
+
},
|
|
5141
|
+
pageNum: targetPage,
|
|
5142
|
+
filtersChanged: false,
|
|
5143
|
+
});
|
|
5144
|
+
} }));
|
|
5145
|
+
/*----------------------------------------*/
|
|
5146
|
+
/* --------------- Filters -------------- */
|
|
5147
|
+
/*----------------------------------------*/
|
|
5148
|
+
// Filter toggle
|
|
5149
|
+
const filterToggles = (React__default["default"].createElement("div", { className: "LogReviewer-filter-toggles" },
|
|
5150
|
+
React__default["default"].createElement("div", { className: "LogReviewer-filter-toggle-buttons alert alert-secondary p-2 m-0" },
|
|
5151
|
+
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: () => {
|
|
5152
|
+
dispatch({
|
|
5153
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5154
|
+
filterDrawer: FilterDrawer.Date,
|
|
5155
|
+
});
|
|
5156
|
+
} },
|
|
5157
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCalendar, className: "me-2" }),
|
|
5158
|
+
"Date"),
|
|
5159
|
+
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: () => {
|
|
5160
|
+
dispatch({
|
|
5161
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5162
|
+
filterDrawer: FilterDrawer.Context,
|
|
5163
|
+
});
|
|
5164
|
+
} },
|
|
5165
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "me-2" }),
|
|
5166
|
+
"Context"),
|
|
5167
|
+
(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: () => {
|
|
5168
|
+
dispatch({
|
|
5169
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5170
|
+
filterDrawer: FilterDrawer.Tag,
|
|
5171
|
+
});
|
|
5172
|
+
} },
|
|
5173
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faTag, className: "me-2" }),
|
|
5174
|
+
"Tag")),
|
|
5175
|
+
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: () => {
|
|
5176
|
+
dispatch({
|
|
5177
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5178
|
+
filterDrawer: FilterDrawer.Action,
|
|
5179
|
+
});
|
|
5180
|
+
} },
|
|
5181
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faHammer, className: "me-2" }),
|
|
5182
|
+
"Action"),
|
|
5183
|
+
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: () => {
|
|
5184
|
+
dispatch({
|
|
5185
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5186
|
+
filterDrawer: FilterDrawer.Advanced,
|
|
5187
|
+
});
|
|
5188
|
+
} },
|
|
5189
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faList, className: "me-2" }),
|
|
5190
|
+
"Advanced"),
|
|
5191
|
+
React__default["default"].createElement("button", { type: "button", id: "LogReviewer-reset-filters-button", className: "btn btn-light", "aria-label": "reset filters", onClick: () => {
|
|
5192
|
+
// Save active filters
|
|
5193
|
+
// Deep clone the initial filter states to avoid any reference issues
|
|
5194
|
+
// if the filter states are modified later
|
|
5195
|
+
activeFiltersRef.current = cloneDeep({
|
|
5196
|
+
dateFilterState: initDateFilterState,
|
|
5197
|
+
contextFilterState: initContextFilterState,
|
|
5198
|
+
tagFilterState: initTagFilterState,
|
|
5199
|
+
actionErrorFilterState: initActionErrorFilterState,
|
|
5200
|
+
advancedFilterState: initAdvancedFilterState,
|
|
5201
|
+
});
|
|
5202
|
+
fetchLogs({
|
|
5203
|
+
filters: {
|
|
5204
|
+
dateFilterState: initDateFilterState,
|
|
5205
|
+
contextFilterState: initContextFilterState,
|
|
5206
|
+
tagFilterState: initTagFilterState,
|
|
5207
|
+
actionErrorFilterState: initActionErrorFilterState,
|
|
5208
|
+
advancedFilterState: initAdvancedFilterState,
|
|
5209
|
+
},
|
|
5210
|
+
pageNum: 1,
|
|
5211
|
+
filtersChanged: true,
|
|
5212
|
+
});
|
|
5213
|
+
dispatch({
|
|
5214
|
+
type: ActionType$6.ResetFilters,
|
|
5215
|
+
initActionErrorFilterState,
|
|
5216
|
+
initAdvancedFilterState,
|
|
5217
|
+
initContextFilterState,
|
|
5218
|
+
initDateFilterState,
|
|
5219
|
+
initTagFilterState,
|
|
5220
|
+
});
|
|
5221
|
+
dispatch({
|
|
5222
|
+
type: ActionType$6.HideFilterDrawer,
|
|
5223
|
+
});
|
|
5224
|
+
} },
|
|
5225
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faTimes }),
|
|
5226
|
+
' ',
|
|
5227
|
+
"Reset"),
|
|
5228
|
+
userMadeFilterChange && (React__default["default"].createElement("button", { type: "button", id: "LogReviewer-submit-filters-button", className: "btn btn-primary ms-2", "aria-label": "submit filters", onClick: () => {
|
|
5229
|
+
dispatch({
|
|
5230
|
+
type: ActionType$6.HideFilterDrawer,
|
|
5231
|
+
});
|
|
5232
|
+
// Reset user made filter change indicator
|
|
5233
|
+
dispatch({
|
|
5234
|
+
type: ActionType$6.ResetUserMadeFilterChange,
|
|
5235
|
+
});
|
|
5236
|
+
// Save active filters
|
|
5237
|
+
// Deep clone the pending filter states to avoid any reference issues
|
|
5238
|
+
// if the filter states are modified later
|
|
5239
|
+
activeFiltersRef.current = cloneDeep({
|
|
5240
|
+
dateFilterState: pendingDateFilterState,
|
|
5241
|
+
contextFilterState: pendingContextFilterState,
|
|
5242
|
+
tagFilterState: pendingTagFilterState,
|
|
5243
|
+
actionErrorFilterState: pendingActionErrorFilterState,
|
|
5244
|
+
advancedFilterState: pendingAdvancedFilterState,
|
|
5245
|
+
});
|
|
5246
|
+
fetchLogs({
|
|
5247
|
+
filters: {
|
|
5248
|
+
dateFilterState: pendingDateFilterState,
|
|
5249
|
+
contextFilterState: pendingContextFilterState,
|
|
5250
|
+
tagFilterState: pendingTagFilterState,
|
|
5251
|
+
actionErrorFilterState: pendingActionErrorFilterState,
|
|
5252
|
+
advancedFilterState: pendingAdvancedFilterState,
|
|
5253
|
+
},
|
|
5254
|
+
pageNum: 1,
|
|
5255
|
+
filtersChanged: true,
|
|
5256
|
+
});
|
|
5257
|
+
} },
|
|
5258
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faSearch }),
|
|
5259
|
+
' ',
|
|
5260
|
+
"Apply Filters")))));
|
|
5261
|
+
// Filter drawer
|
|
5262
|
+
let filterDrawer;
|
|
5263
|
+
if (expandedFilterDrawer) {
|
|
5264
|
+
if (expandedFilterDrawer === FilterDrawer.Date) {
|
|
5265
|
+
filterDrawer = (React__default["default"].createElement(TabBox, { title: "Date" },
|
|
5266
|
+
React__default["default"].createElement(SimpleDateChooser, { ariaLabel: "filter start date", name: "filter-start-date", year: pendingDateFilterState.startDate.year, month: pendingDateFilterState.startDate.month, day: pendingDateFilterState.startDate.day, dontAllowFuture: true, numMonthsToShow: 36, onChange: (month, day, year) => {
|
|
5267
|
+
const newDateFilterState = Object.assign(Object.assign({}, pendingDateFilterState), { startDate: { month, day, year } });
|
|
5110
5268
|
dispatch({
|
|
5111
|
-
type: ActionType$6.
|
|
5112
|
-
|
|
5269
|
+
type: ActionType$6.UpdateDateFilterState,
|
|
5270
|
+
dateFilterState: newDateFilterState,
|
|
5113
5271
|
});
|
|
5114
|
-
} },
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5272
|
+
} }),
|
|
5273
|
+
' ',
|
|
5274
|
+
"to",
|
|
5275
|
+
' ',
|
|
5276
|
+
React__default["default"].createElement(SimpleDateChooser, { ariaLabel: "filter end date", name: "filter-end-date", year: pendingDateFilterState.endDate.year, month: pendingDateFilterState.endDate.month, day: pendingDateFilterState.endDate.day, dontAllowFuture: true, numMonthsToShow: 12, onChange: (month, day, year) => {
|
|
5277
|
+
if (year < pendingDateFilterState.startDate.year
|
|
5278
|
+
|| (year === pendingDateFilterState.startDate.year
|
|
5279
|
+
&& month < pendingDateFilterState.startDate.month)
|
|
5280
|
+
|| (year === pendingDateFilterState.startDate.year
|
|
5281
|
+
&& month === pendingDateFilterState.startDate.month
|
|
5282
|
+
&& day < pendingDateFilterState.startDate.day)) {
|
|
5283
|
+
return alert('Invalid End Date', 'The end date cannot be before the start date.');
|
|
5284
|
+
}
|
|
5285
|
+
const newDateFilterState = Object.assign(Object.assign({}, pendingDateFilterState), { endDate: { month, day, year } });
|
|
5118
5286
|
dispatch({
|
|
5119
|
-
type: ActionType$6.
|
|
5120
|
-
|
|
5121
|
-
initAdvancedFilterState,
|
|
5122
|
-
initContextFilterState,
|
|
5123
|
-
initDateFilterState,
|
|
5124
|
-
initTagFilterState,
|
|
5287
|
+
type: ActionType$6.UpdateDateFilterState,
|
|
5288
|
+
dateFilterState: newDateFilterState,
|
|
5125
5289
|
});
|
|
5126
|
-
} }
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
React__default["default"].createElement(SimpleDateChooser, { ariaLabel: "filter end date", name: "filter-end-date", year: dateFilterState.endDate.year, month: dateFilterState.endDate.month, day: dateFilterState.endDate.day, dontAllowFuture: true, numMonthsToShow: 12, onChange: (month, day, year) => {
|
|
5143
|
-
if (year < dateFilterState.startDate.year
|
|
5144
|
-
|| (year === dateFilterState.startDate.year
|
|
5145
|
-
&& month < dateFilterState.startDate.month)
|
|
5146
|
-
|| (year === dateFilterState.startDate.year
|
|
5147
|
-
&& month === dateFilterState.startDate.month
|
|
5148
|
-
&& day < dateFilterState.startDate.day)) {
|
|
5149
|
-
return alert('Invalid Start Date', 'The start date cannot be before the end date.');
|
|
5150
|
-
}
|
|
5151
|
-
dateFilterState.endDate = { month, day, year };
|
|
5152
|
-
handleDateRangeUpdated(dateFilterState);
|
|
5153
|
-
} })));
|
|
5154
|
-
}
|
|
5155
|
-
else if (expandedFilterDrawer === FilterDrawer.Context) {
|
|
5156
|
-
// Create item picker items
|
|
5157
|
-
const builtInPickableItem = {
|
|
5158
|
-
id: 'built-in-contexts',
|
|
5159
|
-
name: 'Auto-logged',
|
|
5160
|
-
isGroup: true,
|
|
5161
|
-
children: [],
|
|
5162
|
-
};
|
|
5163
|
-
const pickableItems = [];
|
|
5164
|
-
Object.keys(contextMap)
|
|
5165
|
-
.forEach((context) => {
|
|
5166
|
-
const value = contextMap[context];
|
|
5167
|
-
if (typeof value === 'string') {
|
|
5168
|
-
// No subcategories
|
|
5169
|
-
const item = {
|
|
5170
|
-
id: context,
|
|
5171
|
-
name: genHumanReadableName(context),
|
|
5172
|
-
isGroup: false,
|
|
5173
|
-
checked: !!contextFilterState[context],
|
|
5174
|
-
};
|
|
5175
|
-
// Add built-in items to its own folder
|
|
5176
|
-
const isBuiltIn = context in LogBuiltInMetadata.Context;
|
|
5177
|
-
if (isBuiltIn) {
|
|
5178
|
-
// Add to built-in pickable item
|
|
5179
|
-
builtInPickableItem.children.push(item);
|
|
5180
|
-
}
|
|
5181
|
-
else {
|
|
5182
|
-
// Add to pickable items list
|
|
5183
|
-
pickableItems.push(item);
|
|
5184
|
-
}
|
|
5185
|
-
return;
|
|
5186
|
-
}
|
|
5187
|
-
// Has subcategories
|
|
5188
|
-
const children = (Object.keys(value)
|
|
5189
|
-
// Remove parent name
|
|
5190
|
-
.filter((subcontext) => {
|
|
5191
|
-
return subcontext !== '_';
|
|
5192
|
-
})
|
|
5193
|
-
// Create child pickable items
|
|
5194
|
-
.map((subcontext) => {
|
|
5195
|
-
return {
|
|
5196
|
-
id: subcontext,
|
|
5197
|
-
name: genHumanReadableName(subcontext),
|
|
5198
|
-
isGroup: false,
|
|
5199
|
-
checked: contextFilterState[context][subcontext],
|
|
5200
|
-
};
|
|
5201
|
-
}));
|
|
5290
|
+
} })));
|
|
5291
|
+
}
|
|
5292
|
+
else if (expandedFilterDrawer === FilterDrawer.Context) {
|
|
5293
|
+
// Create item picker items
|
|
5294
|
+
const builtInPickableItem = {
|
|
5295
|
+
id: 'built-in-contexts',
|
|
5296
|
+
name: 'Auto-logged',
|
|
5297
|
+
isGroup: true,
|
|
5298
|
+
children: [],
|
|
5299
|
+
};
|
|
5300
|
+
const pickableItems = [];
|
|
5301
|
+
Object.keys(contextMap)
|
|
5302
|
+
.forEach((context) => {
|
|
5303
|
+
const value = contextMap[context];
|
|
5304
|
+
if (typeof value === 'string') {
|
|
5305
|
+
// No subcategories
|
|
5202
5306
|
const item = {
|
|
5203
5307
|
id: context,
|
|
5204
5308
|
name: genHumanReadableName(context),
|
|
5205
|
-
isGroup:
|
|
5206
|
-
|
|
5309
|
+
isGroup: false,
|
|
5310
|
+
checked: !!pendingContextFilterState[context],
|
|
5207
5311
|
};
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5312
|
+
// Add built-in items to its own folder
|
|
5313
|
+
const isBuiltIn = context in LogBuiltInMetadata.Context;
|
|
5314
|
+
if (isBuiltIn) {
|
|
5315
|
+
// Add to built-in pickable item
|
|
5316
|
+
builtInPickableItem.children.push(item);
|
|
5317
|
+
}
|
|
5318
|
+
else {
|
|
5319
|
+
// Add to pickable items list
|
|
5320
|
+
pickableItems.push(item);
|
|
5321
|
+
}
|
|
5322
|
+
return;
|
|
5323
|
+
}
|
|
5324
|
+
// Has subcategories
|
|
5325
|
+
const children = (Object.keys(value)
|
|
5326
|
+
// Remove parent name
|
|
5327
|
+
.filter((subcontext) => {
|
|
5328
|
+
return (subcontext !== '_');
|
|
5329
|
+
})
|
|
5330
|
+
// Create child pickable items
|
|
5331
|
+
.map((subcontext) => {
|
|
5332
|
+
return {
|
|
5333
|
+
id: subcontext,
|
|
5334
|
+
name: genHumanReadableName(subcontext),
|
|
5335
|
+
isGroup: false,
|
|
5336
|
+
checked: pendingContextFilterState[context][subcontext],
|
|
5337
|
+
};
|
|
5338
|
+
}));
|
|
5339
|
+
const item = {
|
|
5340
|
+
id: context,
|
|
5341
|
+
name: genHumanReadableName(context),
|
|
5342
|
+
isGroup: true,
|
|
5343
|
+
children,
|
|
5344
|
+
};
|
|
5345
|
+
pickableItems.push(item);
|
|
5346
|
+
});
|
|
5347
|
+
// Add built-in contexts to end of list
|
|
5348
|
+
pickableItems.push(builtInPickableItem);
|
|
5349
|
+
// Create filter UI
|
|
5350
|
+
filterDrawer = (React__default["default"].createElement(ItemPicker, { title: "Context", items: pickableItems, onChanged: (updatedItems) => {
|
|
5351
|
+
// Update our state
|
|
5352
|
+
const newContextFilterState = Object.assign({}, pendingContextFilterState);
|
|
5353
|
+
updatedItems.forEach((pickableItem) => {
|
|
5354
|
+
if (pickableItem.isGroup) {
|
|
5355
|
+
// Has subcontexts
|
|
5356
|
+
if (pickableItem.id === 'built-in-contexts') {
|
|
5357
|
+
// Built-in
|
|
5358
|
+
// Treat as if these were top-level contexts
|
|
5359
|
+
pickableItem.children.forEach((subcontextItem) => {
|
|
5360
|
+
newContextFilterState[subcontextItem.id] = ('checked' in subcontextItem
|
|
5361
|
+
&& subcontextItem.checked);
|
|
5362
|
+
});
|
|
5234
5363
|
}
|
|
5235
5364
|
else {
|
|
5236
|
-
//
|
|
5237
|
-
|
|
5365
|
+
// Not built-in
|
|
5366
|
+
pickableItem.children.forEach((subcontextItem) => {
|
|
5367
|
+
if (!subcontextItem.isGroup) {
|
|
5368
|
+
newContextFilterState[pickableItem.id][subcontextItem.id] = (subcontextItem.checked);
|
|
5369
|
+
}
|
|
5370
|
+
});
|
|
5238
5371
|
}
|
|
5239
|
-
}
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
}
|
|
5244
|
-
}
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5372
|
+
}
|
|
5373
|
+
else {
|
|
5374
|
+
// No subcontexts
|
|
5375
|
+
newContextFilterState[pickableItem.id] = (pickableItem.checked);
|
|
5376
|
+
}
|
|
5377
|
+
});
|
|
5378
|
+
// Update state
|
|
5379
|
+
dispatch({
|
|
5380
|
+
type: ActionType$6.UpdateContextFilterState,
|
|
5381
|
+
contextFilterState: newContextFilterState,
|
|
5382
|
+
});
|
|
5383
|
+
} }));
|
|
5384
|
+
}
|
|
5385
|
+
else if (expandedFilterDrawer === FilterDrawer.Tag) {
|
|
5386
|
+
// Create filter UI
|
|
5387
|
+
filterDrawer = (React__default["default"].createElement(TabBox, { title: "Tags" },
|
|
5388
|
+
React__default["default"].createElement("div", null, "If any tags are selected, logs must contain at least one (but not necessarily all) of the selected tags."),
|
|
5389
|
+
React__default["default"].createElement("div", { className: "d-flex gap-1 flex-wrap" }, Object.keys((_d = LogMetadata.Tag) !== null && _d !== void 0 ? _d : {})
|
|
5390
|
+
.map((tag) => {
|
|
5391
|
+
const description = genHumanReadableName(tag);
|
|
5392
|
+
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: pendingTagFilterState[tag], onChanged: (checked) => {
|
|
5393
|
+
const newTagFilterState = Object.assign(Object.assign({}, pendingTagFilterState), { [tag]: checked });
|
|
5394
|
+
dispatch({
|
|
5395
|
+
type: ActionType$6.UpdateTagFilterState,
|
|
5396
|
+
tagFilterState: newTagFilterState,
|
|
5397
|
+
});
|
|
5398
|
+
}, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
5399
|
+
}))));
|
|
5400
|
+
}
|
|
5401
|
+
else if (expandedFilterDrawer === FilterDrawer.Action) {
|
|
5402
|
+
// Create filter UI
|
|
5403
|
+
filterDrawer = (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5404
|
+
React__default["default"].createElement(TabBox, { title: "Log Type" },
|
|
5405
|
+
React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
|
|
5406
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { type: undefined });
|
|
5407
|
+
dispatch({
|
|
5408
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5409
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5410
|
+
});
|
|
5411
|
+
}, ariaLabel: "show logs of all types", selected: pendingActionErrorFilterState.type === undefined, unselectedVariant: Variant$1.Light }),
|
|
5412
|
+
React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-action-only", text: "Action Logs Only", onSelected: () => {
|
|
5413
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { type: LogType$1.Action });
|
|
5414
|
+
dispatch({
|
|
5415
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5416
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5417
|
+
});
|
|
5418
|
+
}, ariaLabel: "only show action logs", selected: pendingActionErrorFilterState.type === LogType$1.Action, unselectedVariant: Variant$1.Light }),
|
|
5419
|
+
React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-error-only", text: "Action Error Only", onSelected: () => {
|
|
5420
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { type: LogType$1.Error });
|
|
5421
|
+
dispatch({
|
|
5422
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5423
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5424
|
+
});
|
|
5425
|
+
}, ariaLabel: "only show error logs", selected: pendingActionErrorFilterState.type === LogType$1.Error, noMarginOnRight: true, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light })),
|
|
5426
|
+
(pendingActionErrorFilterState.type === undefined
|
|
5427
|
+
|| pendingActionErrorFilterState.type === LogType$1.Action) && (React__default["default"].createElement(TabBox, { title: "Action Log Details" },
|
|
5428
|
+
React__default["default"].createElement(ButtonInputGroup, { label: "Action", className: "mb-2", wrapButtonsAndAddGaps: true }, Object.keys(LogAction$1)
|
|
5429
|
+
.map((action) => {
|
|
5430
|
+
const description = genHumanReadableName(action);
|
|
5431
|
+
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: pendingActionErrorFilterState.action[action], onChanged: (checked) => {
|
|
5432
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { action: Object.assign(Object.assign({}, pendingActionErrorFilterState.action), { [action]: checked }) });
|
|
5255
5433
|
dispatch({
|
|
5256
|
-
type: ActionType$6.
|
|
5257
|
-
|
|
5434
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5435
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5258
5436
|
});
|
|
5259
|
-
} }));
|
|
5260
|
-
}))
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
React__default["default"].createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
|
|
5267
|
-
actionErrorFilterState.type = undefined;
|
|
5437
|
+
}, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
5438
|
+
})),
|
|
5439
|
+
React__default["default"].createElement(ButtonInputGroup, { label: "Target", wrapButtonsAndAddGaps: true }, Object.keys(targetMap)
|
|
5440
|
+
.map((target) => {
|
|
5441
|
+
const description = genHumanReadableName(target);
|
|
5442
|
+
return (React__default["default"].createElement(CheckboxButton, { key: target, id: `LogReviewer-target-${target}-checkbox`, text: description, ariaLabel: `include logs with target "${description}" in results`, checked: pendingActionErrorFilterState.target[target], noMarginOnRight: true, onChanged: (checked) => {
|
|
5443
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { target: Object.assign(Object.assign({}, pendingActionErrorFilterState.target), { [target]: checked }) });
|
|
5268
5444
|
dispatch({
|
|
5269
5445
|
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5270
|
-
actionErrorFilterState,
|
|
5446
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5271
5447
|
});
|
|
5272
|
-
},
|
|
5273
|
-
|
|
5274
|
-
|
|
5448
|
+
}, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
5449
|
+
})))),
|
|
5450
|
+
(pendingActionErrorFilterState.type === undefined
|
|
5451
|
+
|| pendingActionErrorFilterState.type === LogType$1.Error) && (React__default["default"].createElement(TabBox, { title: "Error Log Details" },
|
|
5452
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5453
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "Error Message"),
|
|
5454
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for error message", value: pendingActionErrorFilterState.errorMessage, placeholder: "e.g. undefined is not a function", onChange: (e) => {
|
|
5455
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { errorMessage: e.target.value });
|
|
5275
5456
|
dispatch({
|
|
5276
5457
|
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5277
|
-
actionErrorFilterState,
|
|
5458
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5278
5459
|
});
|
|
5279
|
-
}
|
|
5280
|
-
|
|
5281
|
-
|
|
5460
|
+
} })),
|
|
5461
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5462
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "Error Code"),
|
|
5463
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for error code", value: pendingActionErrorFilterState.errorCode, placeholder: "e.g. GC22", onChange: (e) => {
|
|
5464
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { errorCode: ((e.target.value)
|
|
5465
|
+
.trim()
|
|
5466
|
+
.toUpperCase()) });
|
|
5282
5467
|
dispatch({
|
|
5283
5468
|
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5284
|
-
actionErrorFilterState,
|
|
5469
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5285
5470
|
});
|
|
5286
|
-
}
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
React__default["default"].createElement("
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
dispatch({
|
|
5329
|
-
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5330
|
-
actionErrorFilterState,
|
|
5331
|
-
});
|
|
5332
|
-
} }))))));
|
|
5333
|
-
}
|
|
5334
|
-
else if (expandedFilterDrawer === FilterDrawer.Advanced) {
|
|
5335
|
-
// Create advanced filter ui
|
|
5336
|
-
filterDrawer = (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5337
|
-
React__default["default"].createElement(TabBox, { title: "User" },
|
|
5338
|
-
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5339
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "User First Name"),
|
|
5340
|
-
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) => {
|
|
5341
|
-
advancedFilterState.userFirstName = e.target.value;
|
|
5342
|
-
dispatch({
|
|
5343
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5344
|
-
advancedFilterState,
|
|
5345
|
-
});
|
|
5346
|
-
} })),
|
|
5347
|
-
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5348
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "User Last Name"),
|
|
5349
|
-
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) => {
|
|
5350
|
-
advancedFilterState.userLastName = e.target.value;
|
|
5351
|
-
dispatch({
|
|
5352
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5353
|
-
advancedFilterState,
|
|
5354
|
-
});
|
|
5355
|
-
} })),
|
|
5356
|
-
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5357
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "User Email"),
|
|
5358
|
-
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user email", value: advancedFilterState.userEmail, placeholder: "e.g. calicci@fas.harvard.edu", onChange: (e) => {
|
|
5359
|
-
advancedFilterState.userEmail = ((e.target.value)
|
|
5360
|
-
.trim());
|
|
5361
|
-
dispatch({
|
|
5362
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5363
|
-
advancedFilterState,
|
|
5364
|
-
});
|
|
5365
|
-
} })),
|
|
5366
|
-
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5367
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "User Canvas Id"),
|
|
5368
|
-
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user canvas id", value: advancedFilterState.userId, placeholder: "e.g. 104985", onChange: (e) => {
|
|
5369
|
-
const { value } = e.target;
|
|
5370
|
-
// Only update if value contains only numbers
|
|
5371
|
-
if (/^\d+$/.test(value)) {
|
|
5372
|
-
advancedFilterState.userId = ((e.target.value)
|
|
5373
|
-
.trim());
|
|
5374
|
-
}
|
|
5375
|
-
dispatch({
|
|
5376
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5377
|
-
advancedFilterState,
|
|
5378
|
-
});
|
|
5379
|
-
} })),
|
|
5380
|
-
React__default["default"].createElement(ButtonInputGroup, { label: "Role" },
|
|
5381
|
-
React__default["default"].createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
|
|
5382
|
-
advancedFilterState.includeLearners = checked;
|
|
5383
|
-
dispatch({
|
|
5384
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5385
|
-
advancedFilterState,
|
|
5386
|
-
});
|
|
5387
|
-
}, checked: advancedFilterState.includeLearners, ariaLabel: "show logs from students" }),
|
|
5388
|
-
React__default["default"].createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
|
|
5389
|
-
advancedFilterState.includeTTMs = checked;
|
|
5471
|
+
} }))))));
|
|
5472
|
+
}
|
|
5473
|
+
else if (expandedFilterDrawer === FilterDrawer.Advanced) {
|
|
5474
|
+
// Create advanced filter ui
|
|
5475
|
+
filterDrawer = (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5476
|
+
React__default["default"].createElement(TabBox, { title: "User" },
|
|
5477
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5478
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "User First Name"),
|
|
5479
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user first name", value: pendingAdvancedFilterState.userFirstName, placeholder: "e.g. Divardo", onChange: (e) => {
|
|
5480
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userFirstName: e.target.value });
|
|
5481
|
+
dispatch({
|
|
5482
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5483
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5484
|
+
});
|
|
5485
|
+
} })),
|
|
5486
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5487
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "User Last Name"),
|
|
5488
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user last name", value: pendingAdvancedFilterState.userLastName, placeholder: "e.g. Calicci", onChange: (e) => {
|
|
5489
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userLastName: e.target.value });
|
|
5490
|
+
dispatch({
|
|
5491
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5492
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5493
|
+
});
|
|
5494
|
+
} })),
|
|
5495
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5496
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "User Email"),
|
|
5497
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user email", value: pendingAdvancedFilterState.userEmail, placeholder: "e.g. calicci@fas.harvard.edu", onChange: (e) => {
|
|
5498
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userEmail: ((e.target.value)
|
|
5499
|
+
.trim()) });
|
|
5500
|
+
dispatch({
|
|
5501
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5502
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5503
|
+
});
|
|
5504
|
+
} })),
|
|
5505
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5506
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "User Canvas Id"),
|
|
5507
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for user canvas id", value: pendingAdvancedFilterState.userId, placeholder: "e.g. 104985", onChange: (e) => {
|
|
5508
|
+
const { value } = e.target;
|
|
5509
|
+
// Only update if value contains only numbers
|
|
5510
|
+
if (/^\d+$/.test(value) || value === '') {
|
|
5511
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userId: ((e.target.value)
|
|
5512
|
+
.trim()) });
|
|
5390
5513
|
dispatch({
|
|
5391
5514
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5392
|
-
advancedFilterState,
|
|
5515
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5393
5516
|
});
|
|
5394
|
-
}
|
|
5395
|
-
|
|
5396
|
-
|
|
5517
|
+
}
|
|
5518
|
+
} })),
|
|
5519
|
+
React__default["default"].createElement(ButtonInputGroup, { label: "Role" },
|
|
5520
|
+
React__default["default"].createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
|
|
5521
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { includeLearners: checked });
|
|
5522
|
+
dispatch({
|
|
5523
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5524
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5525
|
+
});
|
|
5526
|
+
}, checked: pendingAdvancedFilterState.includeLearners, ariaLabel: "show logs from students", checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }),
|
|
5527
|
+
React__default["default"].createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
|
|
5528
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { includeTTMs: checked });
|
|
5529
|
+
dispatch({
|
|
5530
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5531
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5532
|
+
});
|
|
5533
|
+
}, checked: pendingAdvancedFilterState.includeTTMs, ariaLabel: "show logs from teaching team members", checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }),
|
|
5534
|
+
React__default["default"].createElement(CheckboxButton, { text: "Admins", onChanged: (checked) => {
|
|
5535
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { includeAdmins: checked });
|
|
5536
|
+
dispatch({
|
|
5537
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5538
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5539
|
+
});
|
|
5540
|
+
}, checked: pendingAdvancedFilterState.includeAdmins, ariaLabel: "show logs from admins", checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }))),
|
|
5541
|
+
React__default["default"].createElement(TabBox, { title: "Course" },
|
|
5542
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5543
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "Course Name"),
|
|
5544
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for course name", value: pendingAdvancedFilterState.courseName, placeholder: "e.g. GLC 200", onChange: (e) => {
|
|
5545
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { courseName: e.target.value });
|
|
5546
|
+
dispatch({
|
|
5547
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5548
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5549
|
+
});
|
|
5550
|
+
} })),
|
|
5551
|
+
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5552
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "Course Canvas Id"),
|
|
5553
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for course canvas id", value: pendingAdvancedFilterState.courseId, placeholder: "e.g. 15948", onChange: (e) => {
|
|
5554
|
+
const { value } = e.target;
|
|
5555
|
+
// Only update if value contains only numbers
|
|
5556
|
+
if (/^\d+$/.test(value) || value === '') {
|
|
5557
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { courseId: ((e.target.value)
|
|
5558
|
+
.trim()) });
|
|
5397
5559
|
dispatch({
|
|
5398
5560
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5399
|
-
advancedFilterState,
|
|
5561
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5400
5562
|
});
|
|
5401
|
-
}
|
|
5402
|
-
|
|
5563
|
+
}
|
|
5564
|
+
} }))),
|
|
5565
|
+
React__default["default"].createElement(TabBox, { title: "Device" },
|
|
5566
|
+
React__default["default"].createElement(ButtonInputGroup, { label: "Device Type" },
|
|
5567
|
+
React__default["default"].createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: pendingAdvancedFilterState.isMobile === undefined, onSelected: () => {
|
|
5568
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { isMobile: undefined });
|
|
5569
|
+
dispatch({
|
|
5570
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5571
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5572
|
+
});
|
|
5573
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5574
|
+
React__default["default"].createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: pendingAdvancedFilterState.isMobile === true, onSelected: () => {
|
|
5575
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { isMobile: true });
|
|
5576
|
+
dispatch({
|
|
5577
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5578
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5579
|
+
});
|
|
5580
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5581
|
+
React__default["default"].createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: pendingAdvancedFilterState.isMobile === false, onSelected: () => {
|
|
5582
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { isMobile: false });
|
|
5583
|
+
dispatch({
|
|
5584
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5585
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5586
|
+
});
|
|
5587
|
+
}, noMarginOnRight: true, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }))),
|
|
5588
|
+
React__default["default"].createElement(TabBox, { title: "Source" },
|
|
5589
|
+
React__default["default"].createElement(ButtonInputGroup, { label: "Source Type" },
|
|
5590
|
+
React__default["default"].createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: pendingAdvancedFilterState.source === undefined, onSelected: () => {
|
|
5591
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { source: undefined });
|
|
5592
|
+
dispatch({
|
|
5593
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5594
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5595
|
+
});
|
|
5596
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5597
|
+
React__default["default"].createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: pendingAdvancedFilterState.source === LogSource$1.Client, onSelected: () => {
|
|
5598
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { source: LogSource$1.Client });
|
|
5599
|
+
dispatch({
|
|
5600
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5601
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5602
|
+
});
|
|
5603
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5604
|
+
React__default["default"].createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: pendingAdvancedFilterState.source === LogSource$1.Server, onSelected: () => {
|
|
5605
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { source: LogSource$1.Server });
|
|
5606
|
+
dispatch({
|
|
5607
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5608
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5609
|
+
});
|
|
5610
|
+
}, noMarginOnRight: true, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light })),
|
|
5611
|
+
pendingAdvancedFilterState.source !== LogSource$1.Client && (React__default["default"].createElement("div", { className: "mt-2" },
|
|
5403
5612
|
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5404
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "
|
|
5405
|
-
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for
|
|
5406
|
-
|
|
5613
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "Server Route Path"),
|
|
5614
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for server route path", value: pendingAdvancedFilterState.routePath, placeholder: "e.g. /api/ttm/courses/12345", onChange: (e) => {
|
|
5615
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { routePath: ((e.target.value)
|
|
5616
|
+
.trim()) });
|
|
5407
5617
|
dispatch({
|
|
5408
5618
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5409
|
-
advancedFilterState,
|
|
5619
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5410
5620
|
});
|
|
5411
5621
|
} })),
|
|
5412
5622
|
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5413
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "
|
|
5414
|
-
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for
|
|
5415
|
-
const
|
|
5416
|
-
|
|
5417
|
-
if (/^\d+$/.test(value)) {
|
|
5418
|
-
advancedFilterState.courseId = ((e.target.value)
|
|
5419
|
-
.trim());
|
|
5420
|
-
}
|
|
5421
|
-
dispatch({
|
|
5422
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5423
|
-
advancedFilterState,
|
|
5424
|
-
});
|
|
5425
|
-
} }))),
|
|
5426
|
-
React__default["default"].createElement(TabBox, { title: "Device" },
|
|
5427
|
-
React__default["default"].createElement(ButtonInputGroup, { label: "Device Type" },
|
|
5428
|
-
React__default["default"].createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: advancedFilterState.isMobile === undefined, onSelected: () => {
|
|
5429
|
-
advancedFilterState.isMobile = undefined;
|
|
5430
|
-
dispatch({
|
|
5431
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5432
|
-
advancedFilterState,
|
|
5433
|
-
});
|
|
5434
|
-
} }),
|
|
5435
|
-
React__default["default"].createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: advancedFilterState.isMobile === true, onSelected: () => {
|
|
5436
|
-
advancedFilterState.isMobile = true;
|
|
5437
|
-
dispatch({
|
|
5438
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5439
|
-
advancedFilterState,
|
|
5440
|
-
});
|
|
5441
|
-
} }),
|
|
5442
|
-
React__default["default"].createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: advancedFilterState.isMobile === false, onSelected: () => {
|
|
5443
|
-
advancedFilterState.isMobile = false;
|
|
5444
|
-
dispatch({
|
|
5445
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5446
|
-
advancedFilterState,
|
|
5447
|
-
});
|
|
5448
|
-
}, noMarginOnRight: true }))),
|
|
5449
|
-
React__default["default"].createElement(TabBox, { title: "Source" },
|
|
5450
|
-
React__default["default"].createElement(ButtonInputGroup, { label: "Source Type" },
|
|
5451
|
-
React__default["default"].createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: advancedFilterState.source === undefined, onSelected: () => {
|
|
5452
|
-
advancedFilterState.source = undefined;
|
|
5453
|
-
dispatch({
|
|
5454
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5455
|
-
advancedFilterState,
|
|
5456
|
-
});
|
|
5457
|
-
} }),
|
|
5458
|
-
React__default["default"].createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: advancedFilterState.source === LogSource$1.Client, onSelected: () => {
|
|
5459
|
-
advancedFilterState.source = LogSource$1.Client;
|
|
5460
|
-
dispatch({
|
|
5461
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5462
|
-
advancedFilterState,
|
|
5463
|
-
});
|
|
5464
|
-
} }),
|
|
5465
|
-
React__default["default"].createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: advancedFilterState.source === LogSource$1.Server, onSelected: () => {
|
|
5466
|
-
advancedFilterState.source = LogSource$1.Server;
|
|
5623
|
+
React__default["default"].createElement("span", { className: "input-group-text" }, "Server Route Template"),
|
|
5624
|
+
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for server route template", value: pendingAdvancedFilterState.routeTemplate, placeholder: "e.g. /api/ttm/courses/:courseId", onChange: (e) => {
|
|
5625
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { routeTemplate: ((e.target.value)
|
|
5626
|
+
.trim()) });
|
|
5467
5627
|
dispatch({
|
|
5468
5628
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5469
|
-
advancedFilterState,
|
|
5629
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5470
5630
|
});
|
|
5471
|
-
}
|
|
5472
|
-
advancedFilterState.source !== LogSource$1.Client && (React__default["default"].createElement("div", { className: "mt-2" },
|
|
5473
|
-
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5474
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "Server Route Path"),
|
|
5475
|
-
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for server route path", value: advancedFilterState.routePath, placeholder: "e.g. /api/ttm/courses/12345", onChange: (e) => {
|
|
5476
|
-
advancedFilterState.courseName = ((e.target.value)
|
|
5477
|
-
.trim());
|
|
5478
|
-
dispatch({
|
|
5479
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5480
|
-
advancedFilterState,
|
|
5481
|
-
});
|
|
5482
|
-
} })),
|
|
5483
|
-
React__default["default"].createElement("div", { className: "input-group mb-2" },
|
|
5484
|
-
React__default["default"].createElement("span", { className: "input-group-text" }, "Server Route Template"),
|
|
5485
|
-
React__default["default"].createElement("input", { type: "text", className: "form-control", "aria-label": "query for server route template", value: advancedFilterState.routeTemplate, placeholder: "e.g. /api/ttm/courses/:courseId", onChange: (e) => {
|
|
5486
|
-
advancedFilterState.courseName = ((e.target.value)
|
|
5487
|
-
.trim());
|
|
5488
|
-
dispatch({
|
|
5489
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5490
|
-
advancedFilterState,
|
|
5491
|
-
});
|
|
5492
|
-
} })))))));
|
|
5493
|
-
}
|
|
5631
|
+
} })))))));
|
|
5494
5632
|
}
|
|
5495
|
-
// Filters UI
|
|
5496
|
-
const filters = (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5497
|
-
filterToggles,
|
|
5498
|
-
filterDrawer && (React__default["default"].createElement(Drawer, { customBackgroundColor: "#eee" }, filterDrawer))));
|
|
5499
|
-
// Actually filter the logs
|
|
5500
|
-
// > Perform filters
|
|
5501
|
-
const logs = [];
|
|
5502
|
-
Object.keys(logMap).forEach((year) => {
|
|
5503
|
-
Object.keys(logMap[year]).forEach((month) => {
|
|
5504
|
-
logMap[year][month].forEach((log) => {
|
|
5505
|
-
/* ----------- Date Filter ---------- */
|
|
5506
|
-
var _a;
|
|
5507
|
-
// Before start date
|
|
5508
|
-
if (
|
|
5509
|
-
// Previous year
|
|
5510
|
-
log.year < dateFilterState.startDate.year
|
|
5511
|
-
// Same year, earlier month
|
|
5512
|
-
|| ((log.year === dateFilterState.startDate.year)
|
|
5513
|
-
&& (log.month < dateFilterState.startDate.month))
|
|
5514
|
-
// Same year, same month, earlier day
|
|
5515
|
-
|| ((log.year === dateFilterState.startDate.year)
|
|
5516
|
-
&& (log.month === dateFilterState.startDate.month)
|
|
5517
|
-
&& (log.day < dateFilterState.startDate.day))) {
|
|
5518
|
-
return;
|
|
5519
|
-
}
|
|
5520
|
-
// After end date
|
|
5521
|
-
if (
|
|
5522
|
-
// Later year
|
|
5523
|
-
log.year > dateFilterState.endDate.year
|
|
5524
|
-
// Same year, later month
|
|
5525
|
-
|| ((log.year === dateFilterState.endDate.year)
|
|
5526
|
-
&& (log.month > dateFilterState.endDate.month))
|
|
5527
|
-
// Same year, same month, later day
|
|
5528
|
-
|| ((log.year === dateFilterState.endDate.year)
|
|
5529
|
-
&& (log.month === dateFilterState.endDate.month)
|
|
5530
|
-
&& (log.day > dateFilterState.endDate.day))) {
|
|
5531
|
-
return;
|
|
5532
|
-
}
|
|
5533
|
-
/* --------- Context Filter --------- */
|
|
5534
|
-
// Context doesn't match
|
|
5535
|
-
if (
|
|
5536
|
-
// Whole context is deselected
|
|
5537
|
-
contextFilterState[log.context] === false
|
|
5538
|
-
// None of the subcontexts are selected
|
|
5539
|
-
|| (
|
|
5540
|
-
// Has subcontexts
|
|
5541
|
-
typeof contextFilterState[log.context] !== 'boolean'
|
|
5542
|
-
// None of the subcontexts are selected
|
|
5543
|
-
&& Object.values((_a = contextFilterState[log.context]) !== null && _a !== void 0 ? _a : {})
|
|
5544
|
-
.every((isSelected) => {
|
|
5545
|
-
return !isSelected;
|
|
5546
|
-
}))) {
|
|
5547
|
-
return;
|
|
5548
|
-
}
|
|
5549
|
-
// Subcontext doesn't match
|
|
5550
|
-
if (
|
|
5551
|
-
// Log context is not "uncategorized" (no point in further filters)
|
|
5552
|
-
log.context !== LogBuiltInMetadata.Context.Uncategorized
|
|
5553
|
-
// Log has a subcontext
|
|
5554
|
-
&& log.subcontext
|
|
5555
|
-
// Context has subcontexts
|
|
5556
|
-
&& (contextFilterState[log.context]
|
|
5557
|
-
&& contextFilterState[log.context] !== false
|
|
5558
|
-
&& contextFilterState[log.context] !== true)
|
|
5559
|
-
// Subcontext is not selected
|
|
5560
|
-
&& !contextFilterState[log.context][log.subcontext]) {
|
|
5561
|
-
return;
|
|
5562
|
-
}
|
|
5563
|
-
/* -------------- Tags -------------- */
|
|
5564
|
-
// No tags match
|
|
5565
|
-
if (
|
|
5566
|
-
// At least one tag is required
|
|
5567
|
-
Object.values(tagFilterState)
|
|
5568
|
-
.filter((isSelected) => {
|
|
5569
|
-
return isSelected;
|
|
5570
|
-
})
|
|
5571
|
-
.length > 0
|
|
5572
|
-
// No tags match
|
|
5573
|
-
&& log.tags.every((tag) => {
|
|
5574
|
-
return !tagFilterState[tag];
|
|
5575
|
-
})) {
|
|
5576
|
-
return;
|
|
5577
|
-
}
|
|
5578
|
-
/* ------- Actions and Errors ------- */
|
|
5579
|
-
// Log type doesn't match
|
|
5580
|
-
if (
|
|
5581
|
-
// Filter won't allow all types
|
|
5582
|
-
actionErrorFilterState.type !== undefined
|
|
5583
|
-
// Log type doesn't match
|
|
5584
|
-
&& actionErrorFilterState.type !== log.type) {
|
|
5585
|
-
return;
|
|
5586
|
-
}
|
|
5587
|
-
// Filter errors
|
|
5588
|
-
if (log.type === LogType$1.Error) {
|
|
5589
|
-
// Message doesn't match
|
|
5590
|
-
if (
|
|
5591
|
-
// Message exists
|
|
5592
|
-
log.errorMessage
|
|
5593
|
-
// Message filter exists
|
|
5594
|
-
&& actionErrorFilterState.errorMessage.trim().length > 0
|
|
5595
|
-
// Message doesn't match
|
|
5596
|
-
&& log.errorMessage.toLowerCase().includes(actionErrorFilterState.errorMessage.trim().toLowerCase())) {
|
|
5597
|
-
return;
|
|
5598
|
-
}
|
|
5599
|
-
// Code doesn't match
|
|
5600
|
-
if (
|
|
5601
|
-
// Code exists
|
|
5602
|
-
log.errorCode
|
|
5603
|
-
// Code filter exists
|
|
5604
|
-
&& actionErrorFilterState.errorCode.trim().length > 0
|
|
5605
|
-
// Code doesn't match
|
|
5606
|
-
&& log.errorCode.toUpperCase().includes(actionErrorFilterState.errorCode.trim().toUpperCase())) {
|
|
5607
|
-
return;
|
|
5608
|
-
}
|
|
5609
|
-
}
|
|
5610
|
-
// Filter actions
|
|
5611
|
-
if (log.type === LogType$1.Action) {
|
|
5612
|
-
// Target isn't selected
|
|
5613
|
-
if (
|
|
5614
|
-
// Target exists
|
|
5615
|
-
log.target
|
|
5616
|
-
// Target isn't selected
|
|
5617
|
-
&& !actionErrorFilterState.target[log.target]) {
|
|
5618
|
-
return;
|
|
5619
|
-
}
|
|
5620
|
-
// Action
|
|
5621
|
-
if (
|
|
5622
|
-
// Action exists
|
|
5623
|
-
log.action
|
|
5624
|
-
// Action isn't selected
|
|
5625
|
-
&& !actionErrorFilterState.action[log.action]) {
|
|
5626
|
-
return;
|
|
5627
|
-
}
|
|
5628
|
-
}
|
|
5629
|
-
/* --------- Advanced Filter -------- */
|
|
5630
|
-
// First name doesn't match
|
|
5631
|
-
if (
|
|
5632
|
-
// First name exists
|
|
5633
|
-
log.userFirstName
|
|
5634
|
-
// First name query doesn't match
|
|
5635
|
-
&& !log.userFirstName.toLowerCase().includes(advancedFilterState.userFirstName.toLowerCase().trim())) {
|
|
5636
|
-
return;
|
|
5637
|
-
}
|
|
5638
|
-
// Last name doesn't match
|
|
5639
|
-
if (
|
|
5640
|
-
// Last name exists
|
|
5641
|
-
log.userLastName
|
|
5642
|
-
// Last name query doesn't match
|
|
5643
|
-
&& !log.userLastName.toLowerCase().includes(advancedFilterState.userLastName.toLowerCase().trim())) {
|
|
5644
|
-
return;
|
|
5645
|
-
}
|
|
5646
|
-
// Email doesn't match
|
|
5647
|
-
if (
|
|
5648
|
-
// Email exists
|
|
5649
|
-
log.userEmail
|
|
5650
|
-
// Email query doesn't match
|
|
5651
|
-
&& !log.userEmail.toLowerCase().includes(advancedFilterState.userEmail.toLowerCase().trim())) {
|
|
5652
|
-
return;
|
|
5653
|
-
}
|
|
5654
|
-
// User id doesn't match
|
|
5655
|
-
if (
|
|
5656
|
-
// User id exists
|
|
5657
|
-
log.userId
|
|
5658
|
-
// User id doesn't match
|
|
5659
|
-
&& !String(log.userId).includes(advancedFilterState.userId.trim())) {
|
|
5660
|
-
return;
|
|
5661
|
-
}
|
|
5662
|
-
// Learner not allowed
|
|
5663
|
-
if (
|
|
5664
|
-
// User is a learner
|
|
5665
|
-
log.isLearner
|
|
5666
|
-
// Learners aren't included
|
|
5667
|
-
&& !advancedFilterState.includeLearners) {
|
|
5668
|
-
return;
|
|
5669
|
-
}
|
|
5670
|
-
// TTM not allowed
|
|
5671
|
-
if (
|
|
5672
|
-
// User is a ttm
|
|
5673
|
-
log.isTTM
|
|
5674
|
-
// TTMs aren't included
|
|
5675
|
-
&& !advancedFilterState.includeTTMs) {
|
|
5676
|
-
return;
|
|
5677
|
-
}
|
|
5678
|
-
// Admin not allowed
|
|
5679
|
-
if (
|
|
5680
|
-
// User is an admin
|
|
5681
|
-
log.isAdmin
|
|
5682
|
-
// Admins aren't included
|
|
5683
|
-
&& !advancedFilterState.includeAdmins) {
|
|
5684
|
-
return;
|
|
5685
|
-
}
|
|
5686
|
-
// Course Id doesn't match
|
|
5687
|
-
if (
|
|
5688
|
-
// Course Id exists
|
|
5689
|
-
log.courseId
|
|
5690
|
-
// Course Id doesn't match
|
|
5691
|
-
&& !String(log.courseId).includes(advancedFilterState.courseId.trim())) {
|
|
5692
|
-
return;
|
|
5693
|
-
}
|
|
5694
|
-
// Course name doesn't match
|
|
5695
|
-
if (
|
|
5696
|
-
// Course name exists
|
|
5697
|
-
log.courseName
|
|
5698
|
-
// Course name doesn't match
|
|
5699
|
-
&& !String(log.courseName).includes(advancedFilterState.courseName.trim())) {
|
|
5700
|
-
return;
|
|
5701
|
-
}
|
|
5702
|
-
// Mobile filter doesn't match
|
|
5703
|
-
if (
|
|
5704
|
-
// Mobile filter exists
|
|
5705
|
-
advancedFilterState.isMobile !== undefined
|
|
5706
|
-
// Device info exists
|
|
5707
|
-
&& log.device
|
|
5708
|
-
// Mobile filter doesn't match
|
|
5709
|
-
&& (advancedFilterState.isMobile !== log.device.isMobile)) {
|
|
5710
|
-
return;
|
|
5711
|
-
}
|
|
5712
|
-
// Log source doesn't match
|
|
5713
|
-
if (
|
|
5714
|
-
// Source filter exists
|
|
5715
|
-
advancedFilterState.source !== undefined
|
|
5716
|
-
// Source info exists
|
|
5717
|
-
&& log.source
|
|
5718
|
-
// Source filter doesn't match
|
|
5719
|
-
&& (advancedFilterState.source !== log.source)) {
|
|
5720
|
-
return;
|
|
5721
|
-
}
|
|
5722
|
-
// Route path doesn't match (Only for server source)
|
|
5723
|
-
if (
|
|
5724
|
-
// Source is server
|
|
5725
|
-
(log.source === LogSource$1.Server)
|
|
5726
|
-
// Route path is being filtered
|
|
5727
|
-
&& (advancedFilterState.routePath.trim().length)
|
|
5728
|
-
// Route path doesn't match
|
|
5729
|
-
&& !(log.routePath.includes(advancedFilterState.routePath.trim()))) {
|
|
5730
|
-
return;
|
|
5731
|
-
}
|
|
5732
|
-
// Route template doesn't match (Only for server source)
|
|
5733
|
-
if (
|
|
5734
|
-
// Source is server
|
|
5735
|
-
(log.source === LogSource$1.Server)
|
|
5736
|
-
// Route template is being filtered
|
|
5737
|
-
&& (advancedFilterState.routeTemplate.trim().length)
|
|
5738
|
-
// Route template doesn't match
|
|
5739
|
-
&& !(log.routeTemplate.includes(advancedFilterState.routeTemplate.trim()))) {
|
|
5740
|
-
return;
|
|
5741
|
-
}
|
|
5742
|
-
/* -------------- Done -------------- */
|
|
5743
|
-
// Made it past all filters. Add to the list
|
|
5744
|
-
logs.push(log);
|
|
5745
|
-
});
|
|
5746
|
-
});
|
|
5747
|
-
});
|
|
5748
|
-
/*----------------------------------------*/
|
|
5749
|
-
/* ---------------- Data ---------------- */
|
|
5750
|
-
/*----------------------------------------*/
|
|
5751
|
-
// Nothing to show notice
|
|
5752
|
-
const noLogsNotice = (logs.length === 0
|
|
5753
|
-
? (React__default["default"].createElement("div", { className: "alert alert-warning text-center mt-2" },
|
|
5754
|
-
React__default["default"].createElement("h4", { className: "m-1" }, "No Logs to Show"),
|
|
5755
|
-
React__default["default"].createElement("div", null, "Either your filters are too strict or no matching logs have been created yet.")))
|
|
5756
|
-
: undefined);
|
|
5757
|
-
// Create intelliTable
|
|
5758
|
-
const dataTable = (React__default["default"].createElement(IntelliTable, { title: "Matching Logs:", csvName: `Logs from ${getHumanReadableDate()}`, id: "logs", data: logs, columns: columns }));
|
|
5759
|
-
// Main body
|
|
5760
|
-
body = (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5761
|
-
filters,
|
|
5762
|
-
React__default["default"].createElement("div", { className: "mt-2" },
|
|
5763
|
-
dataTable,
|
|
5764
|
-
noLogsNotice)));
|
|
5765
5633
|
}
|
|
5634
|
+
// Filters UI
|
|
5635
|
+
const filters = (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5636
|
+
filterToggles,
|
|
5637
|
+
filterDrawer && (React__default["default"].createElement(Drawer, { customBackgroundColor: "#eee" }, filterDrawer))));
|
|
5638
|
+
// Body that will be filled with the contents of the panel
|
|
5639
|
+
const body = (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
5640
|
+
loading && (React__default["default"].createElement("div", { className: "text-center p-5" },
|
|
5641
|
+
React__default["default"].createElement(LoadingSpinner, null))),
|
|
5642
|
+
!loading && (React__default["default"].createElement("div", null, filters)),
|
|
5643
|
+
!loading && logs.length === 0 && (React__default["default"].createElement("div", { className: "alert alert-warning text-center mt-2" },
|
|
5644
|
+
React__default["default"].createElement("h4", { className: "m-1" }, "No Logs to Show"),
|
|
5645
|
+
React__default["default"].createElement("div", null, "Either your filters are too strict or no matching logs have been created yet."))),
|
|
5646
|
+
React__default["default"].createElement("div", { className: loading || logs.length === 0 ? 'd-none' : undefined },
|
|
5647
|
+
React__default["default"].createElement(IntelliTable, { title: "Matching Logs", csvName: `Logs from ${getHumanReadableDate()}`, id: "logs", data: logs, columns: columns })),
|
|
5648
|
+
!loading && logs.length > 0 && paginationControls));
|
|
5766
5649
|
/* ---------- Wrap in Modal --------- */
|
|
5767
5650
|
return (React__default["default"].createElement("div", { className: "LogReviewer-outer-container" },
|
|
5768
5651
|
React__default["default"].createElement("style", null, style$2),
|
|
5769
5652
|
React__default["default"].createElement("div", { className: "LogReviewer-inner-container" },
|
|
5770
5653
|
React__default["default"].createElement("div", { className: "LogReviewer-header" },
|
|
5771
5654
|
React__default["default"].createElement("div", { className: "LogReviewer-header-title" },
|
|
5772
|
-
React__default["default"].createElement("h3", { className: "text-center
|
|
5655
|
+
React__default["default"].createElement("h3", { className: "text-center" }, "Log Review Dashboard")),
|
|
5773
5656
|
React__default["default"].createElement("div", { style: { width: 0 } },
|
|
5774
5657
|
React__default["default"].createElement("button", { type: "button", className: "LogReviewer-header-close-button btn btn-dark btn-lg pe-0", "aria-label": "close log reviewer panel", onClick: onClose },
|
|
5775
5658
|
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faTimes })))),
|
|
@@ -15445,6 +15328,12 @@ const HOUR_IN_MS = 3600000;
|
|
|
15445
15328
|
*/
|
|
15446
15329
|
const DAY_IN_MS = 86400000;
|
|
15447
15330
|
|
|
15331
|
+
/**
|
|
15332
|
+
* Path of the route for storing client-side logs
|
|
15333
|
+
* @author Gabe Abrams
|
|
15334
|
+
*/
|
|
15335
|
+
const LOG_REVIEW_ROUTE_PATH_PREFIX = `/admin${ROUTE_PATH_PREFIX}/logs`;
|
|
15336
|
+
|
|
15448
15337
|
/**
|
|
15449
15338
|
* Route for checking the status of the current user's
|
|
15450
15339
|
* access to log review
|
|
@@ -16508,6 +16397,7 @@ exports.ErrorWithCode = ErrorWithCode;
|
|
|
16508
16397
|
exports.HOUR_IN_MS = HOUR_IN_MS;
|
|
16509
16398
|
exports.IntelliTable = IntelliTable;
|
|
16510
16399
|
exports.ItemPicker = ItemPicker;
|
|
16400
|
+
exports.LOG_REVIEW_GET_LOGS_ROUTE = LOG_REVIEW_GET_LOGS_ROUTE;
|
|
16511
16401
|
exports.LOG_REVIEW_ROUTE_PATH_PREFIX = LOG_REVIEW_ROUTE_PATH_PREFIX;
|
|
16512
16402
|
exports.LOG_REVIEW_STATUS_ROUTE = LOG_REVIEW_STATUS_ROUTE;
|
|
16513
16403
|
exports.LOG_ROUTE_PATH = LOG_ROUTE_PATH;
|
|
@@ -16543,6 +16433,7 @@ exports.avg = avg;
|
|
|
16543
16433
|
exports.canReviewLogs = canReviewLogs;
|
|
16544
16434
|
exports.capitalize = capitalize;
|
|
16545
16435
|
exports.ceilToNumDecimals = ceilToNumDecimals;
|
|
16436
|
+
exports.cloneDeep = cloneDeep;
|
|
16546
16437
|
exports.combineClassNames = combineClassNames;
|
|
16547
16438
|
exports.compareArraysByProp = compareArraysByProp;
|
|
16548
16439
|
exports.confirm = confirm;
|