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/esm/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { useState, useRef, useEffect, useReducer, forwardRef, useContext, useLayoutEffect, createContext, useMemo, useCallback, Component, Fragment } from 'react';
|
|
3
|
-
import { faExclamationTriangle, faCircle, faHourglassEnd, faDotCircle, faCheckSquare, faHourglass, faClipboard, faChevronDown, faChevronRight, faCloudDownloadAlt, faMinus, faCheckCircle, faXmarkCircle, faSort, faSortDown, faSortUp, faCalendar, faTag, faHammer, faList, faTimes, faSave, faTrash, faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
|
|
3
|
+
import { faExclamationTriangle, faCircle, faHourglassEnd, faDotCircle, faCheckSquare, faHourglass, faClipboard, faChevronDown, faChevronRight, faCloudDownloadAlt, faMinus, faCheckCircle, faXmarkCircle, faSort, faSortDown, faSortUp, faArrowLeft, faArrowRight, faCalendar, faTag, faHammer, faList, faTimes, faSearch, faSave, faTrash, faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
|
|
4
4
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
5
5
|
import { faCircle as faCircle$1, faSquareMinus, faSquare } from '@fortawesome/free-regular-svg-icons';
|
|
6
|
+
import clone from 'nanoclone';
|
|
6
7
|
|
|
7
8
|
/*! *****************************************************************************
|
|
8
9
|
Copyright (c) Microsoft Corporation.
|
|
@@ -3767,10 +3768,10 @@ const getHumanReadableDate = (dateOrTimestamp) => {
|
|
|
3767
3768
|
};
|
|
3768
3769
|
|
|
3769
3770
|
/**
|
|
3770
|
-
* Path of the route for
|
|
3771
|
+
* Path of the route for getting logs for log review
|
|
3771
3772
|
* @author Gabe Abrams
|
|
3772
3773
|
*/
|
|
3773
|
-
const
|
|
3774
|
+
const LOG_REVIEW_GET_LOGS_ROUTE = `/admin${ROUTE_PATH_PREFIX}/logs`;
|
|
3774
3775
|
|
|
3775
3776
|
/**
|
|
3776
3777
|
* Source of a log event
|
|
@@ -4375,6 +4376,71 @@ const IntelliTable = (props) => {
|
|
|
4375
4376
|
} }, table)));
|
|
4376
4377
|
};
|
|
4377
4378
|
|
|
4379
|
+
// Import React
|
|
4380
|
+
/*------------------------------------------------------------------------*/
|
|
4381
|
+
/* ------------------------------ Component ----------------------------- */
|
|
4382
|
+
/*------------------------------------------------------------------------*/
|
|
4383
|
+
const Pagination = (props) => {
|
|
4384
|
+
/*------------------------------------------------------------------------*/
|
|
4385
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
4386
|
+
/*------------------------------------------------------------------------*/
|
|
4387
|
+
/* -------------- Props ------------- */
|
|
4388
|
+
// Destructure props
|
|
4389
|
+
const { currentPage, numPages, loading = false, onPageChanged, } = props;
|
|
4390
|
+
/*------------------------------------------------------------------------*/
|
|
4391
|
+
/* ------------------------------- Render ------------------------------- */
|
|
4392
|
+
/*------------------------------------------------------------------------*/
|
|
4393
|
+
// Compute pages to display
|
|
4394
|
+
const pages = [];
|
|
4395
|
+
const delta = 2; // how many pages to show on either side of current
|
|
4396
|
+
let start = Math.max(1, currentPage - delta);
|
|
4397
|
+
let end = Math.min(numPages, currentPage + delta);
|
|
4398
|
+
// If we are too close to the beginning or end, shift the window.
|
|
4399
|
+
if (currentPage - delta < 1) {
|
|
4400
|
+
end = Math.min(numPages, end + (1 - (currentPage - delta)));
|
|
4401
|
+
}
|
|
4402
|
+
if (currentPage + delta > numPages) {
|
|
4403
|
+
start = Math.max(1, start - ((currentPage + delta) - numPages));
|
|
4404
|
+
}
|
|
4405
|
+
for (let i = start; i <= end; i++) {
|
|
4406
|
+
pages.push(i);
|
|
4407
|
+
}
|
|
4408
|
+
// Render
|
|
4409
|
+
return (React__default.createElement("nav", { "aria-label": "Page navigation for logs", className: "mt-3" },
|
|
4410
|
+
React__default.createElement("ul", { className: "pagination justify-content-center" },
|
|
4411
|
+
React__default.createElement("li", { className: `page-item ${(currentPage <= 1 || loading) ? 'disabled' : ''}` },
|
|
4412
|
+
React__default.createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(currentPage - 1); }, disabled: currentPage <= 1 || loading, "aria-label": "Go to previous page" },
|
|
4413
|
+
React__default.createElement(FontAwesomeIcon, { icon: faArrowLeft }),
|
|
4414
|
+
' ',
|
|
4415
|
+
"Prev")),
|
|
4416
|
+
(currentPage > 3 && pages[0] !== 1) && (React__default.createElement("li", { className: "page-item" },
|
|
4417
|
+
React__default.createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(1); }, disabled: loading, "aria-label": "Go to page 1" }, "1"))),
|
|
4418
|
+
currentPage > 4 && (React__default.createElement("li", { className: "page-item disabled" },
|
|
4419
|
+
React__default.createElement("span", { className: "page-link" }, "..."))),
|
|
4420
|
+
pages.map((pageNum) => {
|
|
4421
|
+
return (React__default.createElement("li", { key: pageNum, className: `page-item ${pageNum === currentPage ? 'active' : ''}` },
|
|
4422
|
+
React__default.createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(pageNum); }, disabled: loading, "aria-label": `Go to page ${pageNum}` }, pageNum)));
|
|
4423
|
+
}),
|
|
4424
|
+
currentPage < numPages - 3 && (React__default.createElement("li", { className: "page-item disabled" },
|
|
4425
|
+
React__default.createElement("span", { className: "page-link" }, "..."))),
|
|
4426
|
+
(currentPage < numPages - 2
|
|
4427
|
+
&& pages[pages.length - 1] !== numPages) && (React__default.createElement("li", { className: "page-item" },
|
|
4428
|
+
React__default.createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(numPages); }, disabled: loading, "aria-label": "Go to last page" }, numPages))),
|
|
4429
|
+
React__default.createElement("li", { className: `page-item ${(currentPage >= numPages || loading) ? 'disabled' : ''}` },
|
|
4430
|
+
React__default.createElement("button", { type: "button", className: "page-link", onClick: () => { return onPageChanged(currentPage + 1); }, disabled: currentPage >= numPages || loading, "aria-label": "Go to next page" },
|
|
4431
|
+
"Next",
|
|
4432
|
+
' ',
|
|
4433
|
+
React__default.createElement(FontAwesomeIcon, { icon: faArrowRight }))))));
|
|
4434
|
+
};
|
|
4435
|
+
|
|
4436
|
+
/**
|
|
4437
|
+
* Deeply clones an object
|
|
4438
|
+
* @author Yuen Ler Chow
|
|
4439
|
+
* @param obj the object to clone
|
|
4440
|
+
* @returns a deep clone of the object
|
|
4441
|
+
*/
|
|
4442
|
+
const cloneDeep = clone;
|
|
4443
|
+
|
|
4378
4444
|
/**
|
|
4379
4445
|
* Log reviewer panel that allows users (must be approved admins) to
|
|
4380
4446
|
* review logs written by dce-reactkit
|
|
@@ -4730,7 +4796,7 @@ var ActionType$6;
|
|
|
4730
4796
|
(function (ActionType) {
|
|
4731
4797
|
// Show the loading bar
|
|
4732
4798
|
ActionType["StartLoading"] = "start-loading";
|
|
4733
|
-
// Finish loading
|
|
4799
|
+
// Finish loading logs
|
|
4734
4800
|
ActionType["FinishLoading"] = "finish-loading";
|
|
4735
4801
|
// Reset filters to initial values
|
|
4736
4802
|
ActionType["ResetFilters"] = "reset-filters";
|
|
@@ -4748,6 +4814,14 @@ var ActionType$6;
|
|
|
4748
4814
|
ActionType["UpdateActionErrorFilterState"] = "update-action-error-filter-state";
|
|
4749
4815
|
// Update the advanced filter state
|
|
4750
4816
|
ActionType["UpdateAdvancedFilterState"] = "update-advanced-filter-state";
|
|
4817
|
+
// Set has another page
|
|
4818
|
+
ActionType["SetHasAnotherPage"] = "set-has-another-page";
|
|
4819
|
+
// Set the number of pages
|
|
4820
|
+
ActionType["SetNumPages"] = "set-num-pages";
|
|
4821
|
+
// Set page number
|
|
4822
|
+
ActionType["SetPageNumber"] = "set-page-number";
|
|
4823
|
+
// Reset user made filter change indicator
|
|
4824
|
+
ActionType["ResetUserMadeFilterChange"] = "reset-user-made-filter-change";
|
|
4751
4825
|
})(ActionType$6 || (ActionType$6 = {}));
|
|
4752
4826
|
/**
|
|
4753
4827
|
* Reducer that executes actions
|
|
@@ -4761,7 +4835,7 @@ const reducer$7 = (state, action) => {
|
|
|
4761
4835
|
return Object.assign(Object.assign({}, state), { loading: true });
|
|
4762
4836
|
}
|
|
4763
4837
|
case ActionType$6.FinishLoading: {
|
|
4764
|
-
return Object.assign(Object.assign({}, state), { loading: false,
|
|
4838
|
+
return Object.assign(Object.assign({}, state), { loading: false, logs: action.logs });
|
|
4765
4839
|
}
|
|
4766
4840
|
case ActionType$6.ToggleFilterDrawer: {
|
|
4767
4841
|
return Object.assign(Object.assign({}, state), { expandedFilterDrawer: (state.expandedFilterDrawer === action.filterDrawer
|
|
@@ -4772,22 +4846,34 @@ const reducer$7 = (state, action) => {
|
|
|
4772
4846
|
return Object.assign(Object.assign({}, state), { expandedFilterDrawer: undefined });
|
|
4773
4847
|
}
|
|
4774
4848
|
case ActionType$6.ResetFilters: {
|
|
4775
|
-
return Object.assign(Object.assign({}, state), {
|
|
4849
|
+
return Object.assign(Object.assign({}, state), { pendingDateFilterState: action.initDateFilterState, pendingContextFilterState: action.initContextFilterState, pendingTagFilterState: action.initTagFilterState, pendingActionErrorFilterState: action.initActionErrorFilterState, pendingAdvancedFilterState: action.initAdvancedFilterState, pageNumber: 1 });
|
|
4776
4850
|
}
|
|
4777
4851
|
case ActionType$6.UpdateDateFilterState: {
|
|
4778
|
-
return Object.assign(Object.assign({}, state), {
|
|
4852
|
+
return Object.assign(Object.assign({}, state), { pendingDateFilterState: action.dateFilterState, userMadeFilterChange: true });
|
|
4779
4853
|
}
|
|
4780
4854
|
case ActionType$6.UpdateContextFilterState: {
|
|
4781
|
-
return Object.assign(Object.assign({}, state), {
|
|
4855
|
+
return Object.assign(Object.assign({}, state), { pendingContextFilterState: action.contextFilterState, userMadeFilterChange: true });
|
|
4782
4856
|
}
|
|
4783
4857
|
case ActionType$6.UpdateTagFilterState: {
|
|
4784
|
-
return Object.assign(Object.assign({}, state), {
|
|
4858
|
+
return Object.assign(Object.assign({}, state), { pendingTagFilterState: action.tagFilterState, userMadeFilterChange: true });
|
|
4785
4859
|
}
|
|
4786
4860
|
case ActionType$6.UpdateActionErrorFilterState: {
|
|
4787
|
-
return Object.assign(Object.assign({}, state), {
|
|
4861
|
+
return Object.assign(Object.assign({}, state), { pendingActionErrorFilterState: action.actionErrorFilterState, userMadeFilterChange: true });
|
|
4788
4862
|
}
|
|
4789
4863
|
case ActionType$6.UpdateAdvancedFilterState: {
|
|
4790
|
-
return Object.assign(Object.assign({}, state), {
|
|
4864
|
+
return Object.assign(Object.assign({}, state), { pendingAdvancedFilterState: action.advancedFilterState, userMadeFilterChange: true });
|
|
4865
|
+
}
|
|
4866
|
+
case ActionType$6.SetHasAnotherPage: {
|
|
4867
|
+
return Object.assign(Object.assign({}, state), { hasAnotherPage: action.hasAnotherPage });
|
|
4868
|
+
}
|
|
4869
|
+
case ActionType$6.SetNumPages: {
|
|
4870
|
+
return Object.assign(Object.assign({}, state), { numPages: action.numPages });
|
|
4871
|
+
}
|
|
4872
|
+
case ActionType$6.SetPageNumber: {
|
|
4873
|
+
return Object.assign(Object.assign({}, state), { pageNumber: action.pageNumber });
|
|
4874
|
+
}
|
|
4875
|
+
case ActionType$6.ResetUserMadeFilterChange: {
|
|
4876
|
+
return Object.assign(Object.assign({}, state), { userMadeFilterChange: false });
|
|
4791
4877
|
}
|
|
4792
4878
|
default: {
|
|
4793
4879
|
return state;
|
|
@@ -4858,7 +4944,7 @@ const LogReviewer = (props) => {
|
|
|
4858
4944
|
else {
|
|
4859
4945
|
// Case: subcontexts exist
|
|
4860
4946
|
initContextFilterState[context] = {};
|
|
4861
|
-
Object.
|
|
4947
|
+
Object.keys(contextMap[context]).forEach((subcontext) => {
|
|
4862
4948
|
// Skip self ("_")
|
|
4863
4949
|
if (subcontext === '_') {
|
|
4864
4950
|
return;
|
|
@@ -4906,125 +4992,105 @@ const LogReviewer = (props) => {
|
|
|
4906
4992
|
// Initial state
|
|
4907
4993
|
const initialState = {
|
|
4908
4994
|
loading: true,
|
|
4909
|
-
|
|
4995
|
+
logs: [],
|
|
4910
4996
|
expandedFilterDrawer: undefined,
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4997
|
+
pendingDateFilterState: initDateFilterState,
|
|
4998
|
+
pendingContextFilterState: initContextFilterState,
|
|
4999
|
+
pendingTagFilterState: initTagFilterState,
|
|
5000
|
+
pendingActionErrorFilterState: initActionErrorFilterState,
|
|
5001
|
+
pendingAdvancedFilterState: initAdvancedFilterState,
|
|
5002
|
+
pageNumber: 1,
|
|
5003
|
+
hasAnotherPage: false,
|
|
5004
|
+
numPages: 1,
|
|
5005
|
+
userMadeFilterChange: false,
|
|
4916
5006
|
};
|
|
4917
5007
|
// Initialize state
|
|
4918
5008
|
const [state, dispatch] = useReducer(reducer$7, initialState);
|
|
4919
5009
|
// Destructure common state
|
|
4920
|
-
const { loading,
|
|
5010
|
+
const { loading, logs, expandedFilterDrawer, pendingDateFilterState, pendingContextFilterState, pendingTagFilterState, pendingActionErrorFilterState, pendingAdvancedFilterState, pageNumber, numPages, userMadeFilterChange, } = state;
|
|
5011
|
+
/* -------------- Refs -------------- */
|
|
5012
|
+
// Initialize refs
|
|
5013
|
+
const activeFiltersRef = useRef({
|
|
5014
|
+
dateFilterState: JSON.parse(JSON.stringify(pendingDateFilterState)),
|
|
5015
|
+
contextFilterState: JSON.parse(JSON.stringify(pendingContextFilterState)),
|
|
5016
|
+
tagFilterState: JSON.parse(JSON.stringify(pendingTagFilterState)),
|
|
5017
|
+
actionErrorFilterState: JSON.parse(JSON.stringify(pendingActionErrorFilterState)),
|
|
5018
|
+
advancedFilterState: JSON.parse(JSON.stringify(pendingAdvancedFilterState)),
|
|
5019
|
+
});
|
|
4921
5020
|
/*------------------------------------------------------------------------*/
|
|
4922
5021
|
/* ------------------------- Component Functions ------------------------ */
|
|
4923
5022
|
/*------------------------------------------------------------------------*/
|
|
4924
5023
|
/**
|
|
4925
|
-
*
|
|
4926
|
-
*
|
|
4927
|
-
* @
|
|
4928
|
-
* @param
|
|
4929
|
-
* @
|
|
4930
|
-
|
|
4931
|
-
const listMonthsToLoad = (newDateFilterState) => {
|
|
4932
|
-
// List of year/month combos that need to be loaded
|
|
4933
|
-
const toLoad = [];
|
|
4934
|
-
// Loop through dates
|
|
4935
|
-
let { year, month } = newDateFilterState.startDate;
|
|
4936
|
-
while (
|
|
4937
|
-
// Earlier year
|
|
4938
|
-
(year < newDateFilterState.endDate.year)
|
|
4939
|
-
// Current year but included month
|
|
4940
|
-
|| (year === newDateFilterState.endDate.year
|
|
4941
|
-
&& month <= newDateFilterState.endDate.month)) {
|
|
4942
|
-
// Add to list if not already loaded
|
|
4943
|
-
if (!logMap[year]
|
|
4944
|
-
|| !logMap[year][month]) {
|
|
4945
|
-
toLoad.push({
|
|
4946
|
-
year,
|
|
4947
|
-
month,
|
|
4948
|
-
});
|
|
4949
|
-
}
|
|
4950
|
-
// Increment
|
|
4951
|
-
month += 1;
|
|
4952
|
-
if (month > 12) {
|
|
4953
|
-
month -= 12;
|
|
4954
|
-
year += 1;
|
|
4955
|
-
}
|
|
4956
|
-
}
|
|
4957
|
-
// Return
|
|
4958
|
-
return toLoad;
|
|
4959
|
-
};
|
|
4960
|
-
/**
|
|
4961
|
-
* Handle updated start/end dates (updates state, loads if necessary)
|
|
4962
|
-
* @author Gabe Abrams
|
|
4963
|
-
* @param newDateFilterState the new date filter state
|
|
5024
|
+
* Fetch logs from the server based on current filters
|
|
5025
|
+
* @author Yuen Ler Chow
|
|
5026
|
+
* @param opts object containing all arguments
|
|
5027
|
+
* @param opts.filters the filters to apply
|
|
5028
|
+
* @param opts.pageNum the page number to fetch
|
|
5029
|
+
* @param opts.filtersChanged if true, the filters have changed
|
|
4964
5030
|
*/
|
|
4965
|
-
const
|
|
4966
|
-
|
|
4967
|
-
dispatch({
|
|
4968
|
-
type: ActionType$6.UpdateDateFilterState,
|
|
4969
|
-
dateFilterState: newDateFilterState,
|
|
4970
|
-
});
|
|
4971
|
-
// Check which year/month combos we need to load
|
|
4972
|
-
const toLoad = listMonthsToLoad(newDateFilterState);
|
|
4973
|
-
// If nothing to load, finished
|
|
4974
|
-
if (toLoad.length === 0) {
|
|
4975
|
-
return;
|
|
4976
|
-
}
|
|
4977
|
-
// Start loading
|
|
5031
|
+
const fetchLogs = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5032
|
+
const { filters, pageNum, filtersChanged, } = opts;
|
|
4978
5033
|
dispatch({
|
|
4979
5034
|
type: ActionType$6.StartLoading,
|
|
4980
5035
|
});
|
|
4981
|
-
// Load required months
|
|
4982
5036
|
try {
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
}
|
|
5006
|
-
logMap[year][month] = logs;
|
|
5037
|
+
// Send filters to the server
|
|
5038
|
+
let fetchedLogs = [];
|
|
5039
|
+
// Get logs from server
|
|
5040
|
+
const response = yield visitServerEndpoint({
|
|
5041
|
+
path: LOG_REVIEW_GET_LOGS_ROUTE,
|
|
5042
|
+
method: 'GET',
|
|
5043
|
+
params: {
|
|
5044
|
+
pageNumber: pageNum,
|
|
5045
|
+
filters,
|
|
5046
|
+
countDocuments: filtersChanged,
|
|
5047
|
+
},
|
|
5048
|
+
});
|
|
5049
|
+
fetchedLogs = fetchedLogs.concat(response.items);
|
|
5050
|
+
dispatch({
|
|
5051
|
+
type: ActionType$6.SetHasAnotherPage,
|
|
5052
|
+
hasAnotherPage: response.hasAnotherPage,
|
|
5053
|
+
});
|
|
5054
|
+
if (filtersChanged && response.numPages !== undefined) {
|
|
5055
|
+
dispatch({
|
|
5056
|
+
type: ActionType$6.SetNumPages,
|
|
5057
|
+
numPages: response.numPages,
|
|
5058
|
+
});
|
|
5007
5059
|
}
|
|
5060
|
+
// Update logs in state
|
|
5061
|
+
dispatch({
|
|
5062
|
+
type: ActionType$6.FinishLoading,
|
|
5063
|
+
logs: fetchedLogs,
|
|
5064
|
+
});
|
|
5065
|
+
// Update page number
|
|
5066
|
+
dispatch({
|
|
5067
|
+
type: ActionType$6.SetPageNumber,
|
|
5068
|
+
pageNumber: pageNum,
|
|
5069
|
+
});
|
|
5008
5070
|
}
|
|
5009
5071
|
catch (err) {
|
|
5010
5072
|
return showFatalError(err);
|
|
5011
5073
|
}
|
|
5012
|
-
// Finish loading
|
|
5013
|
-
dispatch({
|
|
5014
|
-
type: ActionType$6.FinishLoading,
|
|
5015
|
-
logMap,
|
|
5016
|
-
});
|
|
5017
5074
|
});
|
|
5018
5075
|
/*------------------------------------------------------------------------*/
|
|
5019
5076
|
/* ------------------------- Lifecycle Functions ------------------------ */
|
|
5020
5077
|
/*------------------------------------------------------------------------*/
|
|
5021
5078
|
/**
|
|
5022
|
-
*
|
|
5023
|
-
* @author
|
|
5079
|
+
* Fetch logs on mount
|
|
5080
|
+
* @author Yuen Ler Chow
|
|
5024
5081
|
*/
|
|
5025
5082
|
useEffect(() => {
|
|
5026
|
-
|
|
5027
|
-
|
|
5083
|
+
fetchLogs({
|
|
5084
|
+
filters: {
|
|
5085
|
+
dateFilterState: pendingDateFilterState,
|
|
5086
|
+
contextFilterState: pendingContextFilterState,
|
|
5087
|
+
tagFilterState: pendingTagFilterState,
|
|
5088
|
+
actionErrorFilterState: pendingActionErrorFilterState,
|
|
5089
|
+
advancedFilterState: pendingAdvancedFilterState,
|
|
5090
|
+
},
|
|
5091
|
+
pageNum: 1,
|
|
5092
|
+
filtersChanged: true,
|
|
5093
|
+
});
|
|
5028
5094
|
}, []);
|
|
5029
5095
|
/*------------------------------------------------------------------------*/
|
|
5030
5096
|
/* ------------------------------- Render ------------------------------- */
|
|
@@ -5032,718 +5098,534 @@ const LogReviewer = (props) => {
|
|
|
5032
5098
|
/*----------------------------------------*/
|
|
5033
5099
|
/* --------------- Main UI -------------- */
|
|
5034
5100
|
/*----------------------------------------*/
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5101
|
+
/*----------------------------------------*/
|
|
5102
|
+
/* ------------ Pagination -------------- */
|
|
5103
|
+
/*----------------------------------------*/
|
|
5104
|
+
const paginationControls = logs.length > 0 && (React__default.createElement(Pagination, { currentPage: pageNumber, numPages: numPages, loading: loading, onPageChanged: (targetPage) => {
|
|
5105
|
+
const { current: activeFilters } = activeFiltersRef;
|
|
5106
|
+
fetchLogs({
|
|
5107
|
+
filters: {
|
|
5108
|
+
dateFilterState: activeFilters.dateFilterState,
|
|
5109
|
+
contextFilterState: activeFilters.contextFilterState,
|
|
5110
|
+
tagFilterState: activeFilters.tagFilterState,
|
|
5111
|
+
actionErrorFilterState: activeFilters.actionErrorFilterState,
|
|
5112
|
+
advancedFilterState: activeFilters.advancedFilterState,
|
|
5113
|
+
},
|
|
5114
|
+
pageNum: targetPage,
|
|
5115
|
+
filtersChanged: false,
|
|
5116
|
+
});
|
|
5117
|
+
} }));
|
|
5118
|
+
/*----------------------------------------*/
|
|
5119
|
+
/* --------------- Filters -------------- */
|
|
5120
|
+
/*----------------------------------------*/
|
|
5121
|
+
// Filter toggle
|
|
5122
|
+
const filterToggles = (React__default.createElement("div", { className: "LogReviewer-filter-toggles" },
|
|
5123
|
+
React__default.createElement("div", { className: "LogReviewer-filter-toggle-buttons alert alert-secondary p-2 m-0" },
|
|
5124
|
+
React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-date-filter-drawer", className: `btn btn-${FilterDrawer.Date === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle date filter drawer", onClick: () => {
|
|
5125
|
+
dispatch({
|
|
5126
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5127
|
+
filterDrawer: FilterDrawer.Date,
|
|
5128
|
+
});
|
|
5129
|
+
} },
|
|
5130
|
+
React__default.createElement(FontAwesomeIcon, { icon: faCalendar, className: "me-2" }),
|
|
5131
|
+
"Date"),
|
|
5132
|
+
React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-context-filter-drawer", className: `btn btn-${FilterDrawer.Context === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle context filter drawer", onClick: () => {
|
|
5133
|
+
dispatch({
|
|
5134
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5135
|
+
filterDrawer: FilterDrawer.Context,
|
|
5136
|
+
});
|
|
5137
|
+
} },
|
|
5138
|
+
React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "me-2" }),
|
|
5139
|
+
"Context"),
|
|
5140
|
+
(LogMetadata.Tag && Object.keys(LogMetadata.Tag).length > 0) && (React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-tag-filter-drawer", className: `btn btn-${FilterDrawer.Tag === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle tag filter drawer", onClick: () => {
|
|
5141
|
+
dispatch({
|
|
5142
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5143
|
+
filterDrawer: FilterDrawer.Tag,
|
|
5144
|
+
});
|
|
5145
|
+
} },
|
|
5146
|
+
React__default.createElement(FontAwesomeIcon, { icon: faTag, className: "me-2" }),
|
|
5147
|
+
"Tag")),
|
|
5148
|
+
React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-action-filter-drawer", className: `btn btn-${FilterDrawer.Action === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle action and error filter drawer", onClick: () => {
|
|
5149
|
+
dispatch({
|
|
5150
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5151
|
+
filterDrawer: FilterDrawer.Action,
|
|
5152
|
+
});
|
|
5153
|
+
} },
|
|
5154
|
+
React__default.createElement(FontAwesomeIcon, { icon: faHammer, className: "me-2" }),
|
|
5155
|
+
"Action"),
|
|
5156
|
+
React__default.createElement("button", { type: "button", id: "LogReviewer-toggle-advanced-filter-drawer", className: `btn btn-${FilterDrawer.Advanced === expandedFilterDrawer ? 'warning' : 'light'} me-2`, "aria-label": "toggle advanced filter drawer", onClick: () => {
|
|
5157
|
+
dispatch({
|
|
5158
|
+
type: ActionType$6.ToggleFilterDrawer,
|
|
5159
|
+
filterDrawer: FilterDrawer.Advanced,
|
|
5160
|
+
});
|
|
5161
|
+
} },
|
|
5162
|
+
React__default.createElement(FontAwesomeIcon, { icon: faList, className: "me-2" }),
|
|
5163
|
+
"Advanced"),
|
|
5164
|
+
React__default.createElement("button", { type: "button", id: "LogReviewer-reset-filters-button", className: "btn btn-light", "aria-label": "reset filters", onClick: () => {
|
|
5165
|
+
// Save active filters
|
|
5166
|
+
// Deep clone the initial filter states to avoid any reference issues
|
|
5167
|
+
// if the filter states are modified later
|
|
5168
|
+
activeFiltersRef.current = cloneDeep({
|
|
5169
|
+
dateFilterState: initDateFilterState,
|
|
5170
|
+
contextFilterState: initContextFilterState,
|
|
5171
|
+
tagFilterState: initTagFilterState,
|
|
5172
|
+
actionErrorFilterState: initActionErrorFilterState,
|
|
5173
|
+
advancedFilterState: initAdvancedFilterState,
|
|
5174
|
+
});
|
|
5175
|
+
fetchLogs({
|
|
5176
|
+
filters: {
|
|
5177
|
+
dateFilterState: initDateFilterState,
|
|
5178
|
+
contextFilterState: initContextFilterState,
|
|
5179
|
+
tagFilterState: initTagFilterState,
|
|
5180
|
+
actionErrorFilterState: initActionErrorFilterState,
|
|
5181
|
+
advancedFilterState: initAdvancedFilterState,
|
|
5182
|
+
},
|
|
5183
|
+
pageNum: 1,
|
|
5184
|
+
filtersChanged: true,
|
|
5185
|
+
});
|
|
5186
|
+
dispatch({
|
|
5187
|
+
type: ActionType$6.ResetFilters,
|
|
5188
|
+
initActionErrorFilterState,
|
|
5189
|
+
initAdvancedFilterState,
|
|
5190
|
+
initContextFilterState,
|
|
5191
|
+
initDateFilterState,
|
|
5192
|
+
initTagFilterState,
|
|
5193
|
+
});
|
|
5194
|
+
dispatch({
|
|
5195
|
+
type: ActionType$6.HideFilterDrawer,
|
|
5196
|
+
});
|
|
5197
|
+
} },
|
|
5198
|
+
React__default.createElement(FontAwesomeIcon, { icon: faTimes }),
|
|
5199
|
+
' ',
|
|
5200
|
+
"Reset"),
|
|
5201
|
+
userMadeFilterChange && (React__default.createElement("button", { type: "button", id: "LogReviewer-submit-filters-button", className: "btn btn-primary ms-2", "aria-label": "submit filters", onClick: () => {
|
|
5202
|
+
dispatch({
|
|
5203
|
+
type: ActionType$6.HideFilterDrawer,
|
|
5204
|
+
});
|
|
5205
|
+
// Reset user made filter change indicator
|
|
5206
|
+
dispatch({
|
|
5207
|
+
type: ActionType$6.ResetUserMadeFilterChange,
|
|
5208
|
+
});
|
|
5209
|
+
// Save active filters
|
|
5210
|
+
// Deep clone the pending filter states to avoid any reference issues
|
|
5211
|
+
// if the filter states are modified later
|
|
5212
|
+
activeFiltersRef.current = cloneDeep({
|
|
5213
|
+
dateFilterState: pendingDateFilterState,
|
|
5214
|
+
contextFilterState: pendingContextFilterState,
|
|
5215
|
+
tagFilterState: pendingTagFilterState,
|
|
5216
|
+
actionErrorFilterState: pendingActionErrorFilterState,
|
|
5217
|
+
advancedFilterState: pendingAdvancedFilterState,
|
|
5218
|
+
});
|
|
5219
|
+
fetchLogs({
|
|
5220
|
+
filters: {
|
|
5221
|
+
dateFilterState: pendingDateFilterState,
|
|
5222
|
+
contextFilterState: pendingContextFilterState,
|
|
5223
|
+
tagFilterState: pendingTagFilterState,
|
|
5224
|
+
actionErrorFilterState: pendingActionErrorFilterState,
|
|
5225
|
+
advancedFilterState: pendingAdvancedFilterState,
|
|
5226
|
+
},
|
|
5227
|
+
pageNum: 1,
|
|
5228
|
+
filtersChanged: true,
|
|
5229
|
+
});
|
|
5230
|
+
} },
|
|
5231
|
+
React__default.createElement(FontAwesomeIcon, { icon: faSearch }),
|
|
5232
|
+
' ',
|
|
5233
|
+
"Apply Filters")))));
|
|
5234
|
+
// Filter drawer
|
|
5235
|
+
let filterDrawer;
|
|
5236
|
+
if (expandedFilterDrawer) {
|
|
5237
|
+
if (expandedFilterDrawer === FilterDrawer.Date) {
|
|
5238
|
+
filterDrawer = (React__default.createElement(TabBox, { title: "Date" },
|
|
5239
|
+
React__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) => {
|
|
5240
|
+
const newDateFilterState = Object.assign(Object.assign({}, pendingDateFilterState), { startDate: { month, day, year } });
|
|
5084
5241
|
dispatch({
|
|
5085
|
-
type: ActionType$6.
|
|
5086
|
-
|
|
5242
|
+
type: ActionType$6.UpdateDateFilterState,
|
|
5243
|
+
dateFilterState: newDateFilterState,
|
|
5087
5244
|
});
|
|
5088
|
-
} },
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5245
|
+
} }),
|
|
5246
|
+
' ',
|
|
5247
|
+
"to",
|
|
5248
|
+
' ',
|
|
5249
|
+
React__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) => {
|
|
5250
|
+
if (year < pendingDateFilterState.startDate.year
|
|
5251
|
+
|| (year === pendingDateFilterState.startDate.year
|
|
5252
|
+
&& month < pendingDateFilterState.startDate.month)
|
|
5253
|
+
|| (year === pendingDateFilterState.startDate.year
|
|
5254
|
+
&& month === pendingDateFilterState.startDate.month
|
|
5255
|
+
&& day < pendingDateFilterState.startDate.day)) {
|
|
5256
|
+
return alert('Invalid End Date', 'The end date cannot be before the start date.');
|
|
5257
|
+
}
|
|
5258
|
+
const newDateFilterState = Object.assign(Object.assign({}, pendingDateFilterState), { endDate: { month, day, year } });
|
|
5092
5259
|
dispatch({
|
|
5093
|
-
type: ActionType$6.
|
|
5094
|
-
|
|
5095
|
-
initAdvancedFilterState,
|
|
5096
|
-
initContextFilterState,
|
|
5097
|
-
initDateFilterState,
|
|
5098
|
-
initTagFilterState,
|
|
5260
|
+
type: ActionType$6.UpdateDateFilterState,
|
|
5261
|
+
dateFilterState: newDateFilterState,
|
|
5099
5262
|
});
|
|
5100
|
-
} }
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
React__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) => {
|
|
5117
|
-
if (year < dateFilterState.startDate.year
|
|
5118
|
-
|| (year === dateFilterState.startDate.year
|
|
5119
|
-
&& month < dateFilterState.startDate.month)
|
|
5120
|
-
|| (year === dateFilterState.startDate.year
|
|
5121
|
-
&& month === dateFilterState.startDate.month
|
|
5122
|
-
&& day < dateFilterState.startDate.day)) {
|
|
5123
|
-
return alert('Invalid Start Date', 'The start date cannot be before the end date.');
|
|
5124
|
-
}
|
|
5125
|
-
dateFilterState.endDate = { month, day, year };
|
|
5126
|
-
handleDateRangeUpdated(dateFilterState);
|
|
5127
|
-
} })));
|
|
5128
|
-
}
|
|
5129
|
-
else if (expandedFilterDrawer === FilterDrawer.Context) {
|
|
5130
|
-
// Create item picker items
|
|
5131
|
-
const builtInPickableItem = {
|
|
5132
|
-
id: 'built-in-contexts',
|
|
5133
|
-
name: 'Auto-logged',
|
|
5134
|
-
isGroup: true,
|
|
5135
|
-
children: [],
|
|
5136
|
-
};
|
|
5137
|
-
const pickableItems = [];
|
|
5138
|
-
Object.keys(contextMap)
|
|
5139
|
-
.forEach((context) => {
|
|
5140
|
-
const value = contextMap[context];
|
|
5141
|
-
if (typeof value === 'string') {
|
|
5142
|
-
// No subcategories
|
|
5143
|
-
const item = {
|
|
5144
|
-
id: context,
|
|
5145
|
-
name: genHumanReadableName(context),
|
|
5146
|
-
isGroup: false,
|
|
5147
|
-
checked: !!contextFilterState[context],
|
|
5148
|
-
};
|
|
5149
|
-
// Add built-in items to its own folder
|
|
5150
|
-
const isBuiltIn = context in LogBuiltInMetadata.Context;
|
|
5151
|
-
if (isBuiltIn) {
|
|
5152
|
-
// Add to built-in pickable item
|
|
5153
|
-
builtInPickableItem.children.push(item);
|
|
5154
|
-
}
|
|
5155
|
-
else {
|
|
5156
|
-
// Add to pickable items list
|
|
5157
|
-
pickableItems.push(item);
|
|
5158
|
-
}
|
|
5159
|
-
return;
|
|
5160
|
-
}
|
|
5161
|
-
// Has subcategories
|
|
5162
|
-
const children = (Object.keys(value)
|
|
5163
|
-
// Remove parent name
|
|
5164
|
-
.filter((subcontext) => {
|
|
5165
|
-
return subcontext !== '_';
|
|
5166
|
-
})
|
|
5167
|
-
// Create child pickable items
|
|
5168
|
-
.map((subcontext) => {
|
|
5169
|
-
return {
|
|
5170
|
-
id: subcontext,
|
|
5171
|
-
name: genHumanReadableName(subcontext),
|
|
5172
|
-
isGroup: false,
|
|
5173
|
-
checked: contextFilterState[context][subcontext],
|
|
5174
|
-
};
|
|
5175
|
-
}));
|
|
5263
|
+
} })));
|
|
5264
|
+
}
|
|
5265
|
+
else if (expandedFilterDrawer === FilterDrawer.Context) {
|
|
5266
|
+
// Create item picker items
|
|
5267
|
+
const builtInPickableItem = {
|
|
5268
|
+
id: 'built-in-contexts',
|
|
5269
|
+
name: 'Auto-logged',
|
|
5270
|
+
isGroup: true,
|
|
5271
|
+
children: [],
|
|
5272
|
+
};
|
|
5273
|
+
const pickableItems = [];
|
|
5274
|
+
Object.keys(contextMap)
|
|
5275
|
+
.forEach((context) => {
|
|
5276
|
+
const value = contextMap[context];
|
|
5277
|
+
if (typeof value === 'string') {
|
|
5278
|
+
// No subcategories
|
|
5176
5279
|
const item = {
|
|
5177
5280
|
id: context,
|
|
5178
5281
|
name: genHumanReadableName(context),
|
|
5179
|
-
isGroup:
|
|
5180
|
-
|
|
5282
|
+
isGroup: false,
|
|
5283
|
+
checked: !!pendingContextFilterState[context],
|
|
5181
5284
|
};
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5285
|
+
// Add built-in items to its own folder
|
|
5286
|
+
const isBuiltIn = context in LogBuiltInMetadata.Context;
|
|
5287
|
+
if (isBuiltIn) {
|
|
5288
|
+
// Add to built-in pickable item
|
|
5289
|
+
builtInPickableItem.children.push(item);
|
|
5290
|
+
}
|
|
5291
|
+
else {
|
|
5292
|
+
// Add to pickable items list
|
|
5293
|
+
pickableItems.push(item);
|
|
5294
|
+
}
|
|
5295
|
+
return;
|
|
5296
|
+
}
|
|
5297
|
+
// Has subcategories
|
|
5298
|
+
const children = (Object.keys(value)
|
|
5299
|
+
// Remove parent name
|
|
5300
|
+
.filter((subcontext) => {
|
|
5301
|
+
return (subcontext !== '_');
|
|
5302
|
+
})
|
|
5303
|
+
// Create child pickable items
|
|
5304
|
+
.map((subcontext) => {
|
|
5305
|
+
return {
|
|
5306
|
+
id: subcontext,
|
|
5307
|
+
name: genHumanReadableName(subcontext),
|
|
5308
|
+
isGroup: false,
|
|
5309
|
+
checked: pendingContextFilterState[context][subcontext],
|
|
5310
|
+
};
|
|
5311
|
+
}));
|
|
5312
|
+
const item = {
|
|
5313
|
+
id: context,
|
|
5314
|
+
name: genHumanReadableName(context),
|
|
5315
|
+
isGroup: true,
|
|
5316
|
+
children,
|
|
5317
|
+
};
|
|
5318
|
+
pickableItems.push(item);
|
|
5319
|
+
});
|
|
5320
|
+
// Add built-in contexts to end of list
|
|
5321
|
+
pickableItems.push(builtInPickableItem);
|
|
5322
|
+
// Create filter UI
|
|
5323
|
+
filterDrawer = (React__default.createElement(ItemPicker, { title: "Context", items: pickableItems, onChanged: (updatedItems) => {
|
|
5324
|
+
// Update our state
|
|
5325
|
+
const newContextFilterState = Object.assign({}, pendingContextFilterState);
|
|
5326
|
+
updatedItems.forEach((pickableItem) => {
|
|
5327
|
+
if (pickableItem.isGroup) {
|
|
5328
|
+
// Has subcontexts
|
|
5329
|
+
if (pickableItem.id === 'built-in-contexts') {
|
|
5330
|
+
// Built-in
|
|
5331
|
+
// Treat as if these were top-level contexts
|
|
5332
|
+
pickableItem.children.forEach((subcontextItem) => {
|
|
5333
|
+
newContextFilterState[subcontextItem.id] = ('checked' in subcontextItem
|
|
5334
|
+
&& subcontextItem.checked);
|
|
5335
|
+
});
|
|
5208
5336
|
}
|
|
5209
5337
|
else {
|
|
5210
|
-
//
|
|
5211
|
-
|
|
5338
|
+
// Not built-in
|
|
5339
|
+
pickableItem.children.forEach((subcontextItem) => {
|
|
5340
|
+
if (!subcontextItem.isGroup) {
|
|
5341
|
+
newContextFilterState[pickableItem.id][subcontextItem.id] = (subcontextItem.checked);
|
|
5342
|
+
}
|
|
5343
|
+
});
|
|
5212
5344
|
}
|
|
5213
|
-
}
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
}
|
|
5218
|
-
}
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5345
|
+
}
|
|
5346
|
+
else {
|
|
5347
|
+
// No subcontexts
|
|
5348
|
+
newContextFilterState[pickableItem.id] = (pickableItem.checked);
|
|
5349
|
+
}
|
|
5350
|
+
});
|
|
5351
|
+
// Update state
|
|
5352
|
+
dispatch({
|
|
5353
|
+
type: ActionType$6.UpdateContextFilterState,
|
|
5354
|
+
contextFilterState: newContextFilterState,
|
|
5355
|
+
});
|
|
5356
|
+
} }));
|
|
5357
|
+
}
|
|
5358
|
+
else if (expandedFilterDrawer === FilterDrawer.Tag) {
|
|
5359
|
+
// Create filter UI
|
|
5360
|
+
filterDrawer = (React__default.createElement(TabBox, { title: "Tags" },
|
|
5361
|
+
React__default.createElement("div", null, "If any tags are selected, logs must contain at least one (but not necessarily all) of the selected tags."),
|
|
5362
|
+
React__default.createElement("div", { className: "d-flex gap-1 flex-wrap" }, Object.keys((_d = LogMetadata.Tag) !== null && _d !== void 0 ? _d : {})
|
|
5363
|
+
.map((tag) => {
|
|
5364
|
+
const description = genHumanReadableName(tag);
|
|
5365
|
+
return (React__default.createElement(CheckboxButton, { key: tag, id: `LogReviewer-tag-${tag}-checkbox`, text: description, ariaLabel: `require that logs be tagged with "${description}" or any other selected tag`, checked: pendingTagFilterState[tag], onChanged: (checked) => {
|
|
5366
|
+
const newTagFilterState = Object.assign(Object.assign({}, pendingTagFilterState), { [tag]: checked });
|
|
5367
|
+
dispatch({
|
|
5368
|
+
type: ActionType$6.UpdateTagFilterState,
|
|
5369
|
+
tagFilterState: newTagFilterState,
|
|
5370
|
+
});
|
|
5371
|
+
}, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
5372
|
+
}))));
|
|
5373
|
+
}
|
|
5374
|
+
else if (expandedFilterDrawer === FilterDrawer.Action) {
|
|
5375
|
+
// Create filter UI
|
|
5376
|
+
filterDrawer = (React__default.createElement(React__default.Fragment, null,
|
|
5377
|
+
React__default.createElement(TabBox, { title: "Log Type" },
|
|
5378
|
+
React__default.createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
|
|
5379
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { type: undefined });
|
|
5380
|
+
dispatch({
|
|
5381
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5382
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5383
|
+
});
|
|
5384
|
+
}, ariaLabel: "show logs of all types", selected: pendingActionErrorFilterState.type === undefined, unselectedVariant: Variant$1.Light }),
|
|
5385
|
+
React__default.createElement(RadioButton, { id: "LogReviewer-type-action-only", text: "Action Logs Only", onSelected: () => {
|
|
5386
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { type: LogType$1.Action });
|
|
5387
|
+
dispatch({
|
|
5388
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5389
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5390
|
+
});
|
|
5391
|
+
}, ariaLabel: "only show action logs", selected: pendingActionErrorFilterState.type === LogType$1.Action, unselectedVariant: Variant$1.Light }),
|
|
5392
|
+
React__default.createElement(RadioButton, { id: "LogReviewer-type-error-only", text: "Action Error Only", onSelected: () => {
|
|
5393
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { type: LogType$1.Error });
|
|
5394
|
+
dispatch({
|
|
5395
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5396
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5397
|
+
});
|
|
5398
|
+
}, ariaLabel: "only show error logs", selected: pendingActionErrorFilterState.type === LogType$1.Error, noMarginOnRight: true, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light })),
|
|
5399
|
+
(pendingActionErrorFilterState.type === undefined
|
|
5400
|
+
|| pendingActionErrorFilterState.type === LogType$1.Action) && (React__default.createElement(TabBox, { title: "Action Log Details" },
|
|
5401
|
+
React__default.createElement(ButtonInputGroup, { label: "Action", className: "mb-2", wrapButtonsAndAddGaps: true }, Object.keys(LogAction$1)
|
|
5402
|
+
.map((action) => {
|
|
5403
|
+
const description = genHumanReadableName(action);
|
|
5404
|
+
return (React__default.createElement(CheckboxButton, { key: action, id: `LogReviewer-action-${action}-checkbox`, text: description, ariaLabel: `include logs with action type "${description}" in results`, noMarginOnRight: true, checked: pendingActionErrorFilterState.action[action], onChanged: (checked) => {
|
|
5405
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { action: Object.assign(Object.assign({}, pendingActionErrorFilterState.action), { [action]: checked }) });
|
|
5229
5406
|
dispatch({
|
|
5230
|
-
type: ActionType$6.
|
|
5231
|
-
|
|
5407
|
+
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5408
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5232
5409
|
});
|
|
5233
|
-
} }));
|
|
5234
|
-
}))
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
React__default.createElement(RadioButton, { id: "LogReviewer-type-all", text: "All Logs", onSelected: () => {
|
|
5241
|
-
actionErrorFilterState.type = undefined;
|
|
5410
|
+
}, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
5411
|
+
})),
|
|
5412
|
+
React__default.createElement(ButtonInputGroup, { label: "Target", wrapButtonsAndAddGaps: true }, Object.keys(targetMap)
|
|
5413
|
+
.map((target) => {
|
|
5414
|
+
const description = genHumanReadableName(target);
|
|
5415
|
+
return (React__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) => {
|
|
5416
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { target: Object.assign(Object.assign({}, pendingActionErrorFilterState.target), { [target]: checked }) });
|
|
5242
5417
|
dispatch({
|
|
5243
5418
|
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5244
|
-
actionErrorFilterState,
|
|
5419
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5245
5420
|
});
|
|
5246
|
-
},
|
|
5247
|
-
|
|
5248
|
-
|
|
5421
|
+
}, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
5422
|
+
})))),
|
|
5423
|
+
(pendingActionErrorFilterState.type === undefined
|
|
5424
|
+
|| pendingActionErrorFilterState.type === LogType$1.Error) && (React__default.createElement(TabBox, { title: "Error Log Details" },
|
|
5425
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5426
|
+
React__default.createElement("span", { className: "input-group-text" }, "Error Message"),
|
|
5427
|
+
React__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) => {
|
|
5428
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { errorMessage: e.target.value });
|
|
5249
5429
|
dispatch({
|
|
5250
5430
|
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5251
|
-
actionErrorFilterState,
|
|
5431
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5252
5432
|
});
|
|
5253
|
-
}
|
|
5254
|
-
|
|
5255
|
-
|
|
5433
|
+
} })),
|
|
5434
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5435
|
+
React__default.createElement("span", { className: "input-group-text" }, "Error Code"),
|
|
5436
|
+
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for error code", value: pendingActionErrorFilterState.errorCode, placeholder: "e.g. GC22", onChange: (e) => {
|
|
5437
|
+
const newActionErrorFilterState = Object.assign(Object.assign({}, pendingActionErrorFilterState), { errorCode: ((e.target.value)
|
|
5438
|
+
.trim()
|
|
5439
|
+
.toUpperCase()) });
|
|
5256
5440
|
dispatch({
|
|
5257
5441
|
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5258
|
-
actionErrorFilterState,
|
|
5442
|
+
actionErrorFilterState: newActionErrorFilterState,
|
|
5259
5443
|
});
|
|
5260
|
-
}
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
React__default.createElement("
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
dispatch({
|
|
5303
|
-
type: ActionType$6.UpdateActionErrorFilterState,
|
|
5304
|
-
actionErrorFilterState,
|
|
5305
|
-
});
|
|
5306
|
-
} }))))));
|
|
5307
|
-
}
|
|
5308
|
-
else if (expandedFilterDrawer === FilterDrawer.Advanced) {
|
|
5309
|
-
// Create advanced filter ui
|
|
5310
|
-
filterDrawer = (React__default.createElement(React__default.Fragment, null,
|
|
5311
|
-
React__default.createElement(TabBox, { title: "User" },
|
|
5312
|
-
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5313
|
-
React__default.createElement("span", { className: "input-group-text" }, "User First Name"),
|
|
5314
|
-
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user first name", value: advancedFilterState.userFirstName, placeholder: "e.g. Divardo", onChange: (e) => {
|
|
5315
|
-
advancedFilterState.userFirstName = e.target.value;
|
|
5316
|
-
dispatch({
|
|
5317
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5318
|
-
advancedFilterState,
|
|
5319
|
-
});
|
|
5320
|
-
} })),
|
|
5321
|
-
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5322
|
-
React__default.createElement("span", { className: "input-group-text" }, "User Last Name"),
|
|
5323
|
-
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user last name", value: advancedFilterState.userLastName, placeholder: "e.g. Calicci", onChange: (e) => {
|
|
5324
|
-
advancedFilterState.userLastName = e.target.value;
|
|
5325
|
-
dispatch({
|
|
5326
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5327
|
-
advancedFilterState,
|
|
5328
|
-
});
|
|
5329
|
-
} })),
|
|
5330
|
-
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5331
|
-
React__default.createElement("span", { className: "input-group-text" }, "User Email"),
|
|
5332
|
-
React__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) => {
|
|
5333
|
-
advancedFilterState.userEmail = ((e.target.value)
|
|
5334
|
-
.trim());
|
|
5335
|
-
dispatch({
|
|
5336
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5337
|
-
advancedFilterState,
|
|
5338
|
-
});
|
|
5339
|
-
} })),
|
|
5340
|
-
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5341
|
-
React__default.createElement("span", { className: "input-group-text" }, "User Canvas Id"),
|
|
5342
|
-
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user canvas id", value: advancedFilterState.userId, placeholder: "e.g. 104985", onChange: (e) => {
|
|
5343
|
-
const { value } = e.target;
|
|
5344
|
-
// Only update if value contains only numbers
|
|
5345
|
-
if (/^\d+$/.test(value)) {
|
|
5346
|
-
advancedFilterState.userId = ((e.target.value)
|
|
5347
|
-
.trim());
|
|
5348
|
-
}
|
|
5349
|
-
dispatch({
|
|
5350
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5351
|
-
advancedFilterState,
|
|
5352
|
-
});
|
|
5353
|
-
} })),
|
|
5354
|
-
React__default.createElement(ButtonInputGroup, { label: "Role" },
|
|
5355
|
-
React__default.createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
|
|
5356
|
-
advancedFilterState.includeLearners = checked;
|
|
5357
|
-
dispatch({
|
|
5358
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5359
|
-
advancedFilterState,
|
|
5360
|
-
});
|
|
5361
|
-
}, checked: advancedFilterState.includeLearners, ariaLabel: "show logs from students" }),
|
|
5362
|
-
React__default.createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
|
|
5363
|
-
advancedFilterState.includeTTMs = checked;
|
|
5444
|
+
} }))))));
|
|
5445
|
+
}
|
|
5446
|
+
else if (expandedFilterDrawer === FilterDrawer.Advanced) {
|
|
5447
|
+
// Create advanced filter ui
|
|
5448
|
+
filterDrawer = (React__default.createElement(React__default.Fragment, null,
|
|
5449
|
+
React__default.createElement(TabBox, { title: "User" },
|
|
5450
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5451
|
+
React__default.createElement("span", { className: "input-group-text" }, "User First Name"),
|
|
5452
|
+
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user first name", value: pendingAdvancedFilterState.userFirstName, placeholder: "e.g. Divardo", onChange: (e) => {
|
|
5453
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userFirstName: e.target.value });
|
|
5454
|
+
dispatch({
|
|
5455
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5456
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5457
|
+
});
|
|
5458
|
+
} })),
|
|
5459
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5460
|
+
React__default.createElement("span", { className: "input-group-text" }, "User Last Name"),
|
|
5461
|
+
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user last name", value: pendingAdvancedFilterState.userLastName, placeholder: "e.g. Calicci", onChange: (e) => {
|
|
5462
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userLastName: e.target.value });
|
|
5463
|
+
dispatch({
|
|
5464
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5465
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5466
|
+
});
|
|
5467
|
+
} })),
|
|
5468
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5469
|
+
React__default.createElement("span", { className: "input-group-text" }, "User Email"),
|
|
5470
|
+
React__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) => {
|
|
5471
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userEmail: ((e.target.value)
|
|
5472
|
+
.trim()) });
|
|
5473
|
+
dispatch({
|
|
5474
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5475
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5476
|
+
});
|
|
5477
|
+
} })),
|
|
5478
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5479
|
+
React__default.createElement("span", { className: "input-group-text" }, "User Canvas Id"),
|
|
5480
|
+
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for user canvas id", value: pendingAdvancedFilterState.userId, placeholder: "e.g. 104985", onChange: (e) => {
|
|
5481
|
+
const { value } = e.target;
|
|
5482
|
+
// Only update if value contains only numbers
|
|
5483
|
+
if (/^\d+$/.test(value) || value === '') {
|
|
5484
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { userId: ((e.target.value)
|
|
5485
|
+
.trim()) });
|
|
5364
5486
|
dispatch({
|
|
5365
5487
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5366
|
-
advancedFilterState,
|
|
5488
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5367
5489
|
});
|
|
5368
|
-
}
|
|
5369
|
-
|
|
5370
|
-
|
|
5490
|
+
}
|
|
5491
|
+
} })),
|
|
5492
|
+
React__default.createElement(ButtonInputGroup, { label: "Role" },
|
|
5493
|
+
React__default.createElement(CheckboxButton, { text: "Students", onChanged: (checked) => {
|
|
5494
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { includeLearners: checked });
|
|
5495
|
+
dispatch({
|
|
5496
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5497
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5498
|
+
});
|
|
5499
|
+
}, checked: pendingAdvancedFilterState.includeLearners, ariaLabel: "show logs from students", checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }),
|
|
5500
|
+
React__default.createElement(CheckboxButton, { text: "Teaching Team Members", onChanged: (checked) => {
|
|
5501
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { includeTTMs: checked });
|
|
5502
|
+
dispatch({
|
|
5503
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5504
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5505
|
+
});
|
|
5506
|
+
}, checked: pendingAdvancedFilterState.includeTTMs, ariaLabel: "show logs from teaching team members", checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }),
|
|
5507
|
+
React__default.createElement(CheckboxButton, { text: "Admins", onChanged: (checked) => {
|
|
5508
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { includeAdmins: checked });
|
|
5509
|
+
dispatch({
|
|
5510
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5511
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5512
|
+
});
|
|
5513
|
+
}, checked: pendingAdvancedFilterState.includeAdmins, ariaLabel: "show logs from admins", checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }))),
|
|
5514
|
+
React__default.createElement(TabBox, { title: "Course" },
|
|
5515
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5516
|
+
React__default.createElement("span", { className: "input-group-text" }, "Course Name"),
|
|
5517
|
+
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for course name", value: pendingAdvancedFilterState.courseName, placeholder: "e.g. GLC 200", onChange: (e) => {
|
|
5518
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { courseName: e.target.value });
|
|
5519
|
+
dispatch({
|
|
5520
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5521
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5522
|
+
});
|
|
5523
|
+
} })),
|
|
5524
|
+
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5525
|
+
React__default.createElement("span", { className: "input-group-text" }, "Course Canvas Id"),
|
|
5526
|
+
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for course canvas id", value: pendingAdvancedFilterState.courseId, placeholder: "e.g. 15948", onChange: (e) => {
|
|
5527
|
+
const { value } = e.target;
|
|
5528
|
+
// Only update if value contains only numbers
|
|
5529
|
+
if (/^\d+$/.test(value) || value === '') {
|
|
5530
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { courseId: ((e.target.value)
|
|
5531
|
+
.trim()) });
|
|
5371
5532
|
dispatch({
|
|
5372
5533
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5373
|
-
advancedFilterState,
|
|
5534
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5374
5535
|
});
|
|
5375
|
-
}
|
|
5376
|
-
|
|
5536
|
+
}
|
|
5537
|
+
} }))),
|
|
5538
|
+
React__default.createElement(TabBox, { title: "Device" },
|
|
5539
|
+
React__default.createElement(ButtonInputGroup, { label: "Device Type" },
|
|
5540
|
+
React__default.createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: pendingAdvancedFilterState.isMobile === undefined, onSelected: () => {
|
|
5541
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { isMobile: undefined });
|
|
5542
|
+
dispatch({
|
|
5543
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5544
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5545
|
+
});
|
|
5546
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5547
|
+
React__default.createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: pendingAdvancedFilterState.isMobile === true, onSelected: () => {
|
|
5548
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { isMobile: true });
|
|
5549
|
+
dispatch({
|
|
5550
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5551
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5552
|
+
});
|
|
5553
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5554
|
+
React__default.createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: pendingAdvancedFilterState.isMobile === false, onSelected: () => {
|
|
5555
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { isMobile: false });
|
|
5556
|
+
dispatch({
|
|
5557
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5558
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5559
|
+
});
|
|
5560
|
+
}, noMarginOnRight: true, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }))),
|
|
5561
|
+
React__default.createElement(TabBox, { title: "Source" },
|
|
5562
|
+
React__default.createElement(ButtonInputGroup, { label: "Source Type" },
|
|
5563
|
+
React__default.createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: pendingAdvancedFilterState.source === undefined, onSelected: () => {
|
|
5564
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { source: undefined });
|
|
5565
|
+
dispatch({
|
|
5566
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5567
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5568
|
+
});
|
|
5569
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5570
|
+
React__default.createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: pendingAdvancedFilterState.source === LogSource$1.Client, onSelected: () => {
|
|
5571
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { source: LogSource$1.Client });
|
|
5572
|
+
dispatch({
|
|
5573
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5574
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5575
|
+
});
|
|
5576
|
+
}, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light }),
|
|
5577
|
+
React__default.createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: pendingAdvancedFilterState.source === LogSource$1.Server, onSelected: () => {
|
|
5578
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { source: LogSource$1.Server });
|
|
5579
|
+
dispatch({
|
|
5580
|
+
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5581
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5582
|
+
});
|
|
5583
|
+
}, noMarginOnRight: true, selectedVariant: Variant$1.Light, unselectedVariant: Variant$1.Light })),
|
|
5584
|
+
pendingAdvancedFilterState.source !== LogSource$1.Client && (React__default.createElement("div", { className: "mt-2" },
|
|
5377
5585
|
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5378
|
-
React__default.createElement("span", { className: "input-group-text" }, "
|
|
5379
|
-
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for
|
|
5380
|
-
|
|
5586
|
+
React__default.createElement("span", { className: "input-group-text" }, "Server Route Path"),
|
|
5587
|
+
React__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) => {
|
|
5588
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { routePath: ((e.target.value)
|
|
5589
|
+
.trim()) });
|
|
5381
5590
|
dispatch({
|
|
5382
5591
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5383
|
-
advancedFilterState,
|
|
5592
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5384
5593
|
});
|
|
5385
5594
|
} })),
|
|
5386
5595
|
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5387
|
-
React__default.createElement("span", { className: "input-group-text" }, "
|
|
5388
|
-
React__default.createElement("input", { type: "text", className: "form-control", "aria-label": "query for
|
|
5389
|
-
const
|
|
5390
|
-
|
|
5391
|
-
if (/^\d+$/.test(value)) {
|
|
5392
|
-
advancedFilterState.courseId = ((e.target.value)
|
|
5393
|
-
.trim());
|
|
5394
|
-
}
|
|
5395
|
-
dispatch({
|
|
5396
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5397
|
-
advancedFilterState,
|
|
5398
|
-
});
|
|
5399
|
-
} }))),
|
|
5400
|
-
React__default.createElement(TabBox, { title: "Device" },
|
|
5401
|
-
React__default.createElement(ButtonInputGroup, { label: "Device Type" },
|
|
5402
|
-
React__default.createElement(RadioButton, { text: "All Devices", ariaLabel: "show logs from all devices", selected: advancedFilterState.isMobile === undefined, onSelected: () => {
|
|
5403
|
-
advancedFilterState.isMobile = undefined;
|
|
5404
|
-
dispatch({
|
|
5405
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5406
|
-
advancedFilterState,
|
|
5407
|
-
});
|
|
5408
|
-
} }),
|
|
5409
|
-
React__default.createElement(RadioButton, { text: "Mobile Only", ariaLabel: "show logs from mobile devices", selected: advancedFilterState.isMobile === true, onSelected: () => {
|
|
5410
|
-
advancedFilterState.isMobile = true;
|
|
5411
|
-
dispatch({
|
|
5412
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5413
|
-
advancedFilterState,
|
|
5414
|
-
});
|
|
5415
|
-
} }),
|
|
5416
|
-
React__default.createElement(RadioButton, { text: "Desktop Only", ariaLabel: "show logs from desktop devices", selected: advancedFilterState.isMobile === false, onSelected: () => {
|
|
5417
|
-
advancedFilterState.isMobile = false;
|
|
5418
|
-
dispatch({
|
|
5419
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5420
|
-
advancedFilterState,
|
|
5421
|
-
});
|
|
5422
|
-
}, noMarginOnRight: true }))),
|
|
5423
|
-
React__default.createElement(TabBox, { title: "Source" },
|
|
5424
|
-
React__default.createElement(ButtonInputGroup, { label: "Source Type" },
|
|
5425
|
-
React__default.createElement(RadioButton, { text: "Both", ariaLabel: "show logs from all sources", selected: advancedFilterState.source === undefined, onSelected: () => {
|
|
5426
|
-
advancedFilterState.source = undefined;
|
|
5427
|
-
dispatch({
|
|
5428
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5429
|
-
advancedFilterState,
|
|
5430
|
-
});
|
|
5431
|
-
} }),
|
|
5432
|
-
React__default.createElement(RadioButton, { text: "Client Only", ariaLabel: "show logs from client source", selected: advancedFilterState.source === LogSource$1.Client, onSelected: () => {
|
|
5433
|
-
advancedFilterState.source = LogSource$1.Client;
|
|
5434
|
-
dispatch({
|
|
5435
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5436
|
-
advancedFilterState,
|
|
5437
|
-
});
|
|
5438
|
-
} }),
|
|
5439
|
-
React__default.createElement(RadioButton, { text: "Server Only", ariaLabel: "show logs from server source", selected: advancedFilterState.source === LogSource$1.Server, onSelected: () => {
|
|
5440
|
-
advancedFilterState.source = LogSource$1.Server;
|
|
5596
|
+
React__default.createElement("span", { className: "input-group-text" }, "Server Route Template"),
|
|
5597
|
+
React__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) => {
|
|
5598
|
+
const newAdvancedFilterState = Object.assign(Object.assign({}, pendingAdvancedFilterState), { routeTemplate: ((e.target.value)
|
|
5599
|
+
.trim()) });
|
|
5441
5600
|
dispatch({
|
|
5442
5601
|
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5443
|
-
advancedFilterState,
|
|
5602
|
+
advancedFilterState: newAdvancedFilterState,
|
|
5444
5603
|
});
|
|
5445
|
-
}
|
|
5446
|
-
advancedFilterState.source !== LogSource$1.Client && (React__default.createElement("div", { className: "mt-2" },
|
|
5447
|
-
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5448
|
-
React__default.createElement("span", { className: "input-group-text" }, "Server Route Path"),
|
|
5449
|
-
React__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) => {
|
|
5450
|
-
advancedFilterState.courseName = ((e.target.value)
|
|
5451
|
-
.trim());
|
|
5452
|
-
dispatch({
|
|
5453
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5454
|
-
advancedFilterState,
|
|
5455
|
-
});
|
|
5456
|
-
} })),
|
|
5457
|
-
React__default.createElement("div", { className: "input-group mb-2" },
|
|
5458
|
-
React__default.createElement("span", { className: "input-group-text" }, "Server Route Template"),
|
|
5459
|
-
React__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) => {
|
|
5460
|
-
advancedFilterState.courseName = ((e.target.value)
|
|
5461
|
-
.trim());
|
|
5462
|
-
dispatch({
|
|
5463
|
-
type: ActionType$6.UpdateAdvancedFilterState,
|
|
5464
|
-
advancedFilterState,
|
|
5465
|
-
});
|
|
5466
|
-
} })))))));
|
|
5467
|
-
}
|
|
5604
|
+
} })))))));
|
|
5468
5605
|
}
|
|
5469
|
-
// Filters UI
|
|
5470
|
-
const filters = (React__default.createElement(React__default.Fragment, null,
|
|
5471
|
-
filterToggles,
|
|
5472
|
-
filterDrawer && (React__default.createElement(Drawer, { customBackgroundColor: "#eee" }, filterDrawer))));
|
|
5473
|
-
// Actually filter the logs
|
|
5474
|
-
// > Perform filters
|
|
5475
|
-
const logs = [];
|
|
5476
|
-
Object.keys(logMap).forEach((year) => {
|
|
5477
|
-
Object.keys(logMap[year]).forEach((month) => {
|
|
5478
|
-
logMap[year][month].forEach((log) => {
|
|
5479
|
-
/* ----------- Date Filter ---------- */
|
|
5480
|
-
var _a;
|
|
5481
|
-
// Before start date
|
|
5482
|
-
if (
|
|
5483
|
-
// Previous year
|
|
5484
|
-
log.year < dateFilterState.startDate.year
|
|
5485
|
-
// Same year, earlier month
|
|
5486
|
-
|| ((log.year === dateFilterState.startDate.year)
|
|
5487
|
-
&& (log.month < dateFilterState.startDate.month))
|
|
5488
|
-
// Same year, same month, earlier day
|
|
5489
|
-
|| ((log.year === dateFilterState.startDate.year)
|
|
5490
|
-
&& (log.month === dateFilterState.startDate.month)
|
|
5491
|
-
&& (log.day < dateFilterState.startDate.day))) {
|
|
5492
|
-
return;
|
|
5493
|
-
}
|
|
5494
|
-
// After end date
|
|
5495
|
-
if (
|
|
5496
|
-
// Later year
|
|
5497
|
-
log.year > dateFilterState.endDate.year
|
|
5498
|
-
// Same year, later month
|
|
5499
|
-
|| ((log.year === dateFilterState.endDate.year)
|
|
5500
|
-
&& (log.month > dateFilterState.endDate.month))
|
|
5501
|
-
// Same year, same month, later day
|
|
5502
|
-
|| ((log.year === dateFilterState.endDate.year)
|
|
5503
|
-
&& (log.month === dateFilterState.endDate.month)
|
|
5504
|
-
&& (log.day > dateFilterState.endDate.day))) {
|
|
5505
|
-
return;
|
|
5506
|
-
}
|
|
5507
|
-
/* --------- Context Filter --------- */
|
|
5508
|
-
// Context doesn't match
|
|
5509
|
-
if (
|
|
5510
|
-
// Whole context is deselected
|
|
5511
|
-
contextFilterState[log.context] === false
|
|
5512
|
-
// None of the subcontexts are selected
|
|
5513
|
-
|| (
|
|
5514
|
-
// Has subcontexts
|
|
5515
|
-
typeof contextFilterState[log.context] !== 'boolean'
|
|
5516
|
-
// None of the subcontexts are selected
|
|
5517
|
-
&& Object.values((_a = contextFilterState[log.context]) !== null && _a !== void 0 ? _a : {})
|
|
5518
|
-
.every((isSelected) => {
|
|
5519
|
-
return !isSelected;
|
|
5520
|
-
}))) {
|
|
5521
|
-
return;
|
|
5522
|
-
}
|
|
5523
|
-
// Subcontext doesn't match
|
|
5524
|
-
if (
|
|
5525
|
-
// Log context is not "uncategorized" (no point in further filters)
|
|
5526
|
-
log.context !== LogBuiltInMetadata.Context.Uncategorized
|
|
5527
|
-
// Log has a subcontext
|
|
5528
|
-
&& log.subcontext
|
|
5529
|
-
// Context has subcontexts
|
|
5530
|
-
&& (contextFilterState[log.context]
|
|
5531
|
-
&& contextFilterState[log.context] !== false
|
|
5532
|
-
&& contextFilterState[log.context] !== true)
|
|
5533
|
-
// Subcontext is not selected
|
|
5534
|
-
&& !contextFilterState[log.context][log.subcontext]) {
|
|
5535
|
-
return;
|
|
5536
|
-
}
|
|
5537
|
-
/* -------------- Tags -------------- */
|
|
5538
|
-
// No tags match
|
|
5539
|
-
if (
|
|
5540
|
-
// At least one tag is required
|
|
5541
|
-
Object.values(tagFilterState)
|
|
5542
|
-
.filter((isSelected) => {
|
|
5543
|
-
return isSelected;
|
|
5544
|
-
})
|
|
5545
|
-
.length > 0
|
|
5546
|
-
// No tags match
|
|
5547
|
-
&& log.tags.every((tag) => {
|
|
5548
|
-
return !tagFilterState[tag];
|
|
5549
|
-
})) {
|
|
5550
|
-
return;
|
|
5551
|
-
}
|
|
5552
|
-
/* ------- Actions and Errors ------- */
|
|
5553
|
-
// Log type doesn't match
|
|
5554
|
-
if (
|
|
5555
|
-
// Filter won't allow all types
|
|
5556
|
-
actionErrorFilterState.type !== undefined
|
|
5557
|
-
// Log type doesn't match
|
|
5558
|
-
&& actionErrorFilterState.type !== log.type) {
|
|
5559
|
-
return;
|
|
5560
|
-
}
|
|
5561
|
-
// Filter errors
|
|
5562
|
-
if (log.type === LogType$1.Error) {
|
|
5563
|
-
// Message doesn't match
|
|
5564
|
-
if (
|
|
5565
|
-
// Message exists
|
|
5566
|
-
log.errorMessage
|
|
5567
|
-
// Message filter exists
|
|
5568
|
-
&& actionErrorFilterState.errorMessage.trim().length > 0
|
|
5569
|
-
// Message doesn't match
|
|
5570
|
-
&& log.errorMessage.toLowerCase().includes(actionErrorFilterState.errorMessage.trim().toLowerCase())) {
|
|
5571
|
-
return;
|
|
5572
|
-
}
|
|
5573
|
-
// Code doesn't match
|
|
5574
|
-
if (
|
|
5575
|
-
// Code exists
|
|
5576
|
-
log.errorCode
|
|
5577
|
-
// Code filter exists
|
|
5578
|
-
&& actionErrorFilterState.errorCode.trim().length > 0
|
|
5579
|
-
// Code doesn't match
|
|
5580
|
-
&& log.errorCode.toUpperCase().includes(actionErrorFilterState.errorCode.trim().toUpperCase())) {
|
|
5581
|
-
return;
|
|
5582
|
-
}
|
|
5583
|
-
}
|
|
5584
|
-
// Filter actions
|
|
5585
|
-
if (log.type === LogType$1.Action) {
|
|
5586
|
-
// Target isn't selected
|
|
5587
|
-
if (
|
|
5588
|
-
// Target exists
|
|
5589
|
-
log.target
|
|
5590
|
-
// Target isn't selected
|
|
5591
|
-
&& !actionErrorFilterState.target[log.target]) {
|
|
5592
|
-
return;
|
|
5593
|
-
}
|
|
5594
|
-
// Action
|
|
5595
|
-
if (
|
|
5596
|
-
// Action exists
|
|
5597
|
-
log.action
|
|
5598
|
-
// Action isn't selected
|
|
5599
|
-
&& !actionErrorFilterState.action[log.action]) {
|
|
5600
|
-
return;
|
|
5601
|
-
}
|
|
5602
|
-
}
|
|
5603
|
-
/* --------- Advanced Filter -------- */
|
|
5604
|
-
// First name doesn't match
|
|
5605
|
-
if (
|
|
5606
|
-
// First name exists
|
|
5607
|
-
log.userFirstName
|
|
5608
|
-
// First name query doesn't match
|
|
5609
|
-
&& !log.userFirstName.toLowerCase().includes(advancedFilterState.userFirstName.toLowerCase().trim())) {
|
|
5610
|
-
return;
|
|
5611
|
-
}
|
|
5612
|
-
// Last name doesn't match
|
|
5613
|
-
if (
|
|
5614
|
-
// Last name exists
|
|
5615
|
-
log.userLastName
|
|
5616
|
-
// Last name query doesn't match
|
|
5617
|
-
&& !log.userLastName.toLowerCase().includes(advancedFilterState.userLastName.toLowerCase().trim())) {
|
|
5618
|
-
return;
|
|
5619
|
-
}
|
|
5620
|
-
// Email doesn't match
|
|
5621
|
-
if (
|
|
5622
|
-
// Email exists
|
|
5623
|
-
log.userEmail
|
|
5624
|
-
// Email query doesn't match
|
|
5625
|
-
&& !log.userEmail.toLowerCase().includes(advancedFilterState.userEmail.toLowerCase().trim())) {
|
|
5626
|
-
return;
|
|
5627
|
-
}
|
|
5628
|
-
// User id doesn't match
|
|
5629
|
-
if (
|
|
5630
|
-
// User id exists
|
|
5631
|
-
log.userId
|
|
5632
|
-
// User id doesn't match
|
|
5633
|
-
&& !String(log.userId).includes(advancedFilterState.userId.trim())) {
|
|
5634
|
-
return;
|
|
5635
|
-
}
|
|
5636
|
-
// Learner not allowed
|
|
5637
|
-
if (
|
|
5638
|
-
// User is a learner
|
|
5639
|
-
log.isLearner
|
|
5640
|
-
// Learners aren't included
|
|
5641
|
-
&& !advancedFilterState.includeLearners) {
|
|
5642
|
-
return;
|
|
5643
|
-
}
|
|
5644
|
-
// TTM not allowed
|
|
5645
|
-
if (
|
|
5646
|
-
// User is a ttm
|
|
5647
|
-
log.isTTM
|
|
5648
|
-
// TTMs aren't included
|
|
5649
|
-
&& !advancedFilterState.includeTTMs) {
|
|
5650
|
-
return;
|
|
5651
|
-
}
|
|
5652
|
-
// Admin not allowed
|
|
5653
|
-
if (
|
|
5654
|
-
// User is an admin
|
|
5655
|
-
log.isAdmin
|
|
5656
|
-
// Admins aren't included
|
|
5657
|
-
&& !advancedFilterState.includeAdmins) {
|
|
5658
|
-
return;
|
|
5659
|
-
}
|
|
5660
|
-
// Course Id doesn't match
|
|
5661
|
-
if (
|
|
5662
|
-
// Course Id exists
|
|
5663
|
-
log.courseId
|
|
5664
|
-
// Course Id doesn't match
|
|
5665
|
-
&& !String(log.courseId).includes(advancedFilterState.courseId.trim())) {
|
|
5666
|
-
return;
|
|
5667
|
-
}
|
|
5668
|
-
// Course name doesn't match
|
|
5669
|
-
if (
|
|
5670
|
-
// Course name exists
|
|
5671
|
-
log.courseName
|
|
5672
|
-
// Course name doesn't match
|
|
5673
|
-
&& !String(log.courseName).includes(advancedFilterState.courseName.trim())) {
|
|
5674
|
-
return;
|
|
5675
|
-
}
|
|
5676
|
-
// Mobile filter doesn't match
|
|
5677
|
-
if (
|
|
5678
|
-
// Mobile filter exists
|
|
5679
|
-
advancedFilterState.isMobile !== undefined
|
|
5680
|
-
// Device info exists
|
|
5681
|
-
&& log.device
|
|
5682
|
-
// Mobile filter doesn't match
|
|
5683
|
-
&& (advancedFilterState.isMobile !== log.device.isMobile)) {
|
|
5684
|
-
return;
|
|
5685
|
-
}
|
|
5686
|
-
// Log source doesn't match
|
|
5687
|
-
if (
|
|
5688
|
-
// Source filter exists
|
|
5689
|
-
advancedFilterState.source !== undefined
|
|
5690
|
-
// Source info exists
|
|
5691
|
-
&& log.source
|
|
5692
|
-
// Source filter doesn't match
|
|
5693
|
-
&& (advancedFilterState.source !== log.source)) {
|
|
5694
|
-
return;
|
|
5695
|
-
}
|
|
5696
|
-
// Route path doesn't match (Only for server source)
|
|
5697
|
-
if (
|
|
5698
|
-
// Source is server
|
|
5699
|
-
(log.source === LogSource$1.Server)
|
|
5700
|
-
// Route path is being filtered
|
|
5701
|
-
&& (advancedFilterState.routePath.trim().length)
|
|
5702
|
-
// Route path doesn't match
|
|
5703
|
-
&& !(log.routePath.includes(advancedFilterState.routePath.trim()))) {
|
|
5704
|
-
return;
|
|
5705
|
-
}
|
|
5706
|
-
// Route template doesn't match (Only for server source)
|
|
5707
|
-
if (
|
|
5708
|
-
// Source is server
|
|
5709
|
-
(log.source === LogSource$1.Server)
|
|
5710
|
-
// Route template is being filtered
|
|
5711
|
-
&& (advancedFilterState.routeTemplate.trim().length)
|
|
5712
|
-
// Route template doesn't match
|
|
5713
|
-
&& !(log.routeTemplate.includes(advancedFilterState.routeTemplate.trim()))) {
|
|
5714
|
-
return;
|
|
5715
|
-
}
|
|
5716
|
-
/* -------------- Done -------------- */
|
|
5717
|
-
// Made it past all filters. Add to the list
|
|
5718
|
-
logs.push(log);
|
|
5719
|
-
});
|
|
5720
|
-
});
|
|
5721
|
-
});
|
|
5722
|
-
/*----------------------------------------*/
|
|
5723
|
-
/* ---------------- Data ---------------- */
|
|
5724
|
-
/*----------------------------------------*/
|
|
5725
|
-
// Nothing to show notice
|
|
5726
|
-
const noLogsNotice = (logs.length === 0
|
|
5727
|
-
? (React__default.createElement("div", { className: "alert alert-warning text-center mt-2" },
|
|
5728
|
-
React__default.createElement("h4", { className: "m-1" }, "No Logs to Show"),
|
|
5729
|
-
React__default.createElement("div", null, "Either your filters are too strict or no matching logs have been created yet.")))
|
|
5730
|
-
: undefined);
|
|
5731
|
-
// Create intelliTable
|
|
5732
|
-
const dataTable = (React__default.createElement(IntelliTable, { title: "Matching Logs:", csvName: `Logs from ${getHumanReadableDate()}`, id: "logs", data: logs, columns: columns }));
|
|
5733
|
-
// Main body
|
|
5734
|
-
body = (React__default.createElement(React__default.Fragment, null,
|
|
5735
|
-
filters,
|
|
5736
|
-
React__default.createElement("div", { className: "mt-2" },
|
|
5737
|
-
dataTable,
|
|
5738
|
-
noLogsNotice)));
|
|
5739
5606
|
}
|
|
5607
|
+
// Filters UI
|
|
5608
|
+
const filters = (React__default.createElement(React__default.Fragment, null,
|
|
5609
|
+
filterToggles,
|
|
5610
|
+
filterDrawer && (React__default.createElement(Drawer, { customBackgroundColor: "#eee" }, filterDrawer))));
|
|
5611
|
+
// Body that will be filled with the contents of the panel
|
|
5612
|
+
const body = (React__default.createElement(React__default.Fragment, null,
|
|
5613
|
+
loading && (React__default.createElement("div", { className: "text-center p-5" },
|
|
5614
|
+
React__default.createElement(LoadingSpinner, null))),
|
|
5615
|
+
!loading && (React__default.createElement("div", null, filters)),
|
|
5616
|
+
!loading && logs.length === 0 && (React__default.createElement("div", { className: "alert alert-warning text-center mt-2" },
|
|
5617
|
+
React__default.createElement("h4", { className: "m-1" }, "No Logs to Show"),
|
|
5618
|
+
React__default.createElement("div", null, "Either your filters are too strict or no matching logs have been created yet."))),
|
|
5619
|
+
React__default.createElement("div", { className: loading || logs.length === 0 ? 'd-none' : undefined },
|
|
5620
|
+
React__default.createElement(IntelliTable, { title: "Matching Logs", csvName: `Logs from ${getHumanReadableDate()}`, id: "logs", data: logs, columns: columns })),
|
|
5621
|
+
!loading && logs.length > 0 && paginationControls));
|
|
5740
5622
|
/* ---------- Wrap in Modal --------- */
|
|
5741
5623
|
return (React__default.createElement("div", { className: "LogReviewer-outer-container" },
|
|
5742
5624
|
React__default.createElement("style", null, style$2),
|
|
5743
5625
|
React__default.createElement("div", { className: "LogReviewer-inner-container" },
|
|
5744
5626
|
React__default.createElement("div", { className: "LogReviewer-header" },
|
|
5745
5627
|
React__default.createElement("div", { className: "LogReviewer-header-title" },
|
|
5746
|
-
React__default.createElement("h3", { className: "text-center
|
|
5628
|
+
React__default.createElement("h3", { className: "text-center" }, "Log Review Dashboard")),
|
|
5747
5629
|
React__default.createElement("div", { style: { width: 0 } },
|
|
5748
5630
|
React__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 },
|
|
5749
5631
|
React__default.createElement(FontAwesomeIcon, { icon: faTimes })))),
|
|
@@ -15419,6 +15301,12 @@ const HOUR_IN_MS = 3600000;
|
|
|
15419
15301
|
*/
|
|
15420
15302
|
const DAY_IN_MS = 86400000;
|
|
15421
15303
|
|
|
15304
|
+
/**
|
|
15305
|
+
* Path of the route for storing client-side logs
|
|
15306
|
+
* @author Gabe Abrams
|
|
15307
|
+
*/
|
|
15308
|
+
const LOG_REVIEW_ROUTE_PATH_PREFIX = `/admin${ROUTE_PATH_PREFIX}/logs`;
|
|
15309
|
+
|
|
15422
15310
|
/**
|
|
15423
15311
|
* Route for checking the status of the current user's
|
|
15424
15312
|
* access to log review
|
|
@@ -16463,5 +16351,5 @@ var DayOfWeek;
|
|
|
16463
16351
|
})(DayOfWeek || (DayOfWeek = {}));
|
|
16464
16352
|
var DayOfWeek$1 = DayOfWeek;
|
|
16465
16353
|
|
|
16466
|
-
export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, Dropdown, DropdownItemType$1 as DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogLevel$1 as LogLevel, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, SimpleTimeChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, getWordCount, idify, initClient, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
|
|
16354
|
+
export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, Dropdown, DropdownItemType$1 as DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LOG_REVIEW_GET_LOGS_ROUTE, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogLevel$1 as LogLevel, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, SimpleTimeChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, cloneDeep, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, getWordCount, idify, initClient, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
|
|
16467
16355
|
//# sourceMappingURL=index.js.map
|