dce-expresskit 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Log reviewer page size
3
+ * @author Yuen Ler Chow
4
+ */
5
+ declare const LOG_REVIEW_PAGE_SIZE = 100;
6
+ export default LOG_REVIEW_PAGE_SIZE;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Log reviewer page size
5
+ * @author Yuen Ler Chow
6
+ */
7
+ var LOG_REVIEW_PAGE_SIZE = 100;
8
+ exports.default = LOG_REVIEW_PAGE_SIZE;
9
+ //# sourceMappingURL=LOG_REVIEW_PAGE_SIZE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_REVIEW_PAGE_SIZE.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_PAGE_SIZE.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,IAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,kBAAe,oBAAoB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { Collection } from 'dce-mango';
2
+ import { Log, LogReviewerFilterState } from 'dce-reactkit';
3
+ /**
4
+ * Get logs for the log reviewer interface
5
+ * @author Yuen Ler Chow
6
+ * @param opts object containing all arguments
7
+ * @param opts.pageNumber the page number to retrieve (1-indexed)
8
+ * @param opts.filters filter criteria for logs
9
+ * @param opts.countDocuments if true, count number of documents matching
10
+ * filters and return num pages (not always required because if changing pages,
11
+ * we don't need to recount documents)
12
+ * @param opts.logCollection MongoDB collection containing logs
13
+ * @returns object with logs for the requested page and optionally total number of pages
14
+ */
15
+ declare const getLogReviewerLogs: (opts: {
16
+ pageNumber: number;
17
+ filters: LogReviewerFilterState;
18
+ countDocuments: boolean;
19
+ logCollection: Collection<Log>;
20
+ }) => Promise<import("dce-mango/lib/types/PaginatedResponse").default<Log> | {
21
+ numPages: number;
22
+ items: Log[];
23
+ currentPageNumber: number;
24
+ perPage: number;
25
+ hasAnotherPage: boolean;
26
+ }>;
27
+ export default getLogReviewerLogs;
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ // Import dce-reactkit
54
+ var dce_reactkit_1 = require("dce-reactkit");
55
+ // Import shared types
56
+ var LOG_REVIEW_PAGE_SIZE_1 = __importDefault(require("../constants/LOG_REVIEW_PAGE_SIZE"));
57
+ /**
58
+ * Get logs for the log reviewer interface
59
+ * @author Yuen Ler Chow
60
+ * @param opts object containing all arguments
61
+ * @param opts.pageNumber the page number to retrieve (1-indexed)
62
+ * @param opts.filters filter criteria for logs
63
+ * @param opts.countDocuments if true, count number of documents matching
64
+ * filters and return num pages (not always required because if changing pages,
65
+ * we don't need to recount documents)
66
+ * @param opts.logCollection MongoDB collection containing logs
67
+ * @returns object with logs for the requested page and optionally total number of pages
68
+ */
69
+ var getLogReviewerLogs = function (opts) { return __awaiter(void 0, void 0, void 0, function () {
70
+ var pageNumber, filters, countDocuments, logCollection, _a, dateFilterState, contextFilterState, tagFilterState, actionErrorFilterState, advancedFilterState, query, startDate, endDate, startTimestamp, endTimestamp, contextConditions, selectedTags, selectedTargets, selectedActions, roles, response, numPages, _b, _c;
71
+ return __generator(this, function (_d) {
72
+ switch (_d.label) {
73
+ case 0:
74
+ pageNumber = opts.pageNumber, filters = opts.filters, countDocuments = opts.countDocuments, logCollection = opts.logCollection;
75
+ _a = filters, dateFilterState = _a.dateFilterState, contextFilterState = _a.contextFilterState, tagFilterState = _a.tagFilterState, actionErrorFilterState = _a.actionErrorFilterState, advancedFilterState = _a.advancedFilterState;
76
+ query = {};
77
+ startDate = dateFilterState.startDate, endDate = dateFilterState.endDate;
78
+ startTimestamp = new Date("".concat(startDate.month, "/").concat(startDate.day, "/").concat(startDate.year)).getTime();
79
+ endTimestamp = ((new Date("".concat(endDate.month, "/").concat(endDate.day, "/").concat(endDate.year))).getTime()
80
+ + dce_reactkit_1.DAY_IN_MS);
81
+ // Add a date range condition to the query
82
+ query.timestamp = {
83
+ $gte: startTimestamp,
84
+ $lt: endTimestamp,
85
+ };
86
+ contextConditions = [];
87
+ Object.keys(contextFilterState).forEach(function (context) {
88
+ var value = contextFilterState[context];
89
+ if (typeof value === 'boolean') {
90
+ if (value) {
91
+ // The entire context is selected
92
+ contextConditions.push({ context: context });
93
+ }
94
+ }
95
+ else {
96
+ // The context has subcontexts
97
+ var subcontexts = Object.keys(value).filter(function (subcontext) {
98
+ return value[subcontext];
99
+ });
100
+ if (subcontexts.length > 0) {
101
+ contextConditions.push({
102
+ context: context,
103
+ subcontext: { $in: subcontexts },
104
+ });
105
+ }
106
+ }
107
+ });
108
+ if (contextConditions.length > 0) {
109
+ query.$or = contextConditions;
110
+ }
111
+ selectedTags = Object.keys(tagFilterState).filter(function (tag) { return tagFilterState[tag]; });
112
+ if (selectedTags.length > 0) {
113
+ query.tags = { $in: selectedTags };
114
+ }
115
+ /* --------- Action/Error Filter ---------- */
116
+ if (actionErrorFilterState.type) {
117
+ query.type = actionErrorFilterState.type;
118
+ }
119
+ if (actionErrorFilterState.type === dce_reactkit_1.LogType.Error) {
120
+ if (actionErrorFilterState.errorMessage) {
121
+ // Add error message to the query.
122
+ // $i is used for case-insensitive search, and $regex is used for partial matching
123
+ query.errorMessage = {
124
+ $regex: actionErrorFilterState.errorMessage,
125
+ $options: 'i',
126
+ };
127
+ }
128
+ if (actionErrorFilterState.errorCode) {
129
+ query.errorCode = {
130
+ $regex: actionErrorFilterState.errorCode,
131
+ $options: 'i',
132
+ };
133
+ }
134
+ }
135
+ if (actionErrorFilterState.type === dce_reactkit_1.LogType.Action) {
136
+ selectedTargets = (Object.keys(actionErrorFilterState.target)
137
+ .filter(function (target) {
138
+ return actionErrorFilterState.target[target];
139
+ }));
140
+ selectedActions = (Object.keys(actionErrorFilterState.action)
141
+ .filter(function (action) {
142
+ return actionErrorFilterState.action[action];
143
+ }));
144
+ if (selectedTargets.length > 0) {
145
+ query.target = { $in: selectedTargets };
146
+ }
147
+ if (selectedActions.length > 0) {
148
+ query.action = { $in: selectedActions };
149
+ }
150
+ }
151
+ /* ------------ Advanced Filter ----------- */
152
+ if (advancedFilterState.userFirstName) {
153
+ query.userFirstName = {
154
+ $regex: advancedFilterState.userFirstName,
155
+ $options: 'i',
156
+ };
157
+ }
158
+ if (advancedFilterState.userLastName) {
159
+ query.userLastName = {
160
+ $regex: advancedFilterState.userLastName,
161
+ $options: 'i',
162
+ };
163
+ }
164
+ if (advancedFilterState.userEmail) {
165
+ query.userEmail = {
166
+ $regex: advancedFilterState.userEmail,
167
+ $options: 'i',
168
+ };
169
+ }
170
+ if (advancedFilterState.userId) {
171
+ query.userId = Number.parseInt(advancedFilterState.userId, 10);
172
+ }
173
+ roles = [];
174
+ if (advancedFilterState.includeLearners) {
175
+ roles.push({ isLearner: true });
176
+ }
177
+ if (advancedFilterState.includeTTMs) {
178
+ roles.push({ isTTM: true });
179
+ }
180
+ if (advancedFilterState.includeAdmins) {
181
+ roles.push({ isAdmin: true });
182
+ }
183
+ // If any roles are selected, add them to the query
184
+ if (roles.length > 0) {
185
+ // The $or operator is used to match any of the roles
186
+ // The $and operator is to ensure that other conditions in the query are met
187
+ query.$and = [{ $or: roles }];
188
+ }
189
+ if (advancedFilterState.courseId) {
190
+ query.courseId = Number.parseInt(advancedFilterState.courseId, 10);
191
+ }
192
+ if (advancedFilterState.courseName) {
193
+ query.courseName = {
194
+ $regex: advancedFilterState.courseName,
195
+ $options: 'i',
196
+ };
197
+ }
198
+ if (advancedFilterState.isMobile !== undefined) {
199
+ query['device.isMobile'] = Boolean(advancedFilterState.isMobile);
200
+ }
201
+ if (advancedFilterState.source) {
202
+ query.source = advancedFilterState.source;
203
+ }
204
+ if (advancedFilterState.routePath) {
205
+ query.routePath = {
206
+ $regex: advancedFilterState.routePath,
207
+ $options: 'i',
208
+ };
209
+ }
210
+ if (advancedFilterState.routeTemplate) {
211
+ query.routeTemplate = {
212
+ $regex: advancedFilterState.routeTemplate,
213
+ $options: 'i',
214
+ };
215
+ }
216
+ return [4 /*yield*/, logCollection.findPaged({
217
+ query: query,
218
+ perPage: LOG_REVIEW_PAGE_SIZE_1.default,
219
+ pageNumber: pageNumber,
220
+ sortDescending: true,
221
+ })];
222
+ case 1:
223
+ response = _d.sent();
224
+ if (!countDocuments) return [3 /*break*/, 3];
225
+ _c = (_b = Math).ceil;
226
+ return [4 /*yield*/, logCollection.count(query)];
227
+ case 2:
228
+ numPages = _c.apply(_b, [(_d.sent())
229
+ / LOG_REVIEW_PAGE_SIZE_1.default]);
230
+ return [2 /*return*/, __assign(__assign({}, response), { numPages: numPages })];
231
+ case 3:
232
+ // Return response
233
+ return [2 /*return*/, response];
234
+ }
235
+ });
236
+ }); };
237
+ exports.default = getLogReviewerLogs;
238
+ //# sourceMappingURL=getLogReviewerLogs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLogReviewerLogs.js","sourceRoot":"","sources":["../../src/helpers/getLogReviewerLogs.ts"],"names":[],"mappings":"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"}
@@ -55,6 +55,7 @@ exports.internalGetCrossServerCredentialCollection = exports.internalGetLogColle
55
55
  var dce_reactkit_1 = require("dce-reactkit");
56
56
  // Import shared helpers
57
57
  var genRouteHandler_1 = __importDefault(require("./genRouteHandler"));
58
+ var getLogReviewerLogs_1 = __importDefault(require("./getLogReviewerLogs"));
58
59
  // Import shared types
59
60
  var ExpressKitErrorCode_1 = __importDefault(require("../types/ExpressKitErrorCode"));
60
61
  // Stored copy of dce-mango log collection
@@ -247,38 +248,36 @@ var initServer = function (opts) {
247
248
  }); },
248
249
  }));
249
250
  /**
250
- * Get all logs for a certain month
251
- * @author Gabe Abrams
252
- * @param {number} year the year to query (e.g. 2022)
253
- * @param {number} month the month to query (e.g. 1 = January)
254
- * @returns {Log[]} list of logs from the given month
251
+ * Get filtered logs based on provided filters
252
+ * @author Gabe Abrams, Yuen Ler Chow
253
+ * @param pageNumber the page number to get
254
+ * @param filters the filters to apply to the logs
255
+ * @returns {Log[]} list of logs that match the filters
255
256
  */
256
- opts.app.get("".concat(dce_reactkit_1.LOG_REVIEW_ROUTE_PATH_PREFIX, "/years/:year/months/:month"), (0, genRouteHandler_1.default)({
257
+ opts.app.get(dce_reactkit_1.LOG_REVIEW_GET_LOGS_ROUTE, (0, genRouteHandler_1.default)({
257
258
  paramTypes: {
258
- year: dce_reactkit_1.ParamType.Int,
259
- month: dce_reactkit_1.ParamType.Int,
260
259
  pageNumber: dce_reactkit_1.ParamType.Int,
260
+ filters: dce_reactkit_1.ParamType.JSON,
261
+ countDocuments: dce_reactkit_1.ParamType.Boolean,
261
262
  },
262
263
  handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
263
- var year, month, pageNumber, userId, isAdmin, canReview, response;
264
+ var pageNumber, userId, isAdmin, filters, countDocuments, canReview, response;
264
265
  var params = _b.params;
265
266
  return __generator(this, function (_c) {
266
267
  switch (_c.label) {
267
268
  case 0:
268
- year = params.year, month = params.month, pageNumber = params.pageNumber, userId = params.userId, isAdmin = params.isAdmin;
269
+ pageNumber = params.pageNumber, userId = params.userId, isAdmin = params.isAdmin, filters = params.filters, countDocuments = params.countDocuments;
269
270
  return [4 /*yield*/, canReviewLogs(userId, isAdmin)];
270
271
  case 1:
271
272
  canReview = _c.sent();
272
273
  if (!canReview) {
273
274
  throw new dce_reactkit_1.ErrorWithCode('You cannot access this resource because you do not have the appropriate permissions.', ExpressKitErrorCode_1.default.NotAllowedToReviewLogs);
274
275
  }
275
- return [4 /*yield*/, _logCollection.findPaged({
276
- query: {
277
- year: year,
278
- month: month,
279
- },
280
- perPage: 1000,
276
+ return [4 /*yield*/, (0, getLogReviewerLogs_1.default)({
281
277
  pageNumber: pageNumber,
278
+ filters: filters,
279
+ countDocuments: countDocuments,
280
+ logCollection: _logCollection,
282
281
  })];
283
282
  case 2:
284
283
  response = _c.sent();
@@ -1 +1 @@
1
- {"version":3,"file":"initServer.js","sourceRoot":"","sources":["../../src/helpers/initServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"initServer.js","sourceRoot":"","sources":["../../src/helpers/initServer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-expresskit",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "Shared functions, helpers, and tools for Harvard DCE Express-based servers",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "@fortawesome/free-solid-svg-icons": "^6.7.2",
26
26
  "@fortawesome/react-fontawesome": "^0.2.2",
27
27
  "bootstrap": "^5.3.3",
28
- "dce-reactkit": "^4.0.0-beta.2",
28
+ "dce-reactkit": "4.0.0-beta-logreviewer.1",
29
29
  "react": "^19.0.0"
30
30
  },
31
31
  "peerDependencies": {
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Log reviewer page size
3
+ * @author Yuen Ler Chow
4
+ */
5
+ const LOG_REVIEW_PAGE_SIZE = 100;
6
+
7
+ export default LOG_REVIEW_PAGE_SIZE;
@@ -0,0 +1,260 @@
1
+ // Import dce-mango
2
+ import { Collection } from 'dce-mango';
3
+
4
+ // Import dce-reactkit
5
+ import {
6
+ DAY_IN_MS,
7
+ Log,
8
+ LogReviewerFilterState,
9
+ LogType
10
+ } from 'dce-reactkit';
11
+
12
+ // Import shared types
13
+ import LOG_REVIEW_PAGE_SIZE from '../constants/LOG_REVIEW_PAGE_SIZE';
14
+
15
+ /**
16
+ * Get logs for the log reviewer interface
17
+ * @author Yuen Ler Chow
18
+ * @param opts object containing all arguments
19
+ * @param opts.pageNumber the page number to retrieve (1-indexed)
20
+ * @param opts.filters filter criteria for logs
21
+ * @param opts.countDocuments if true, count number of documents matching
22
+ * filters and return num pages (not always required because if changing pages,
23
+ * we don't need to recount documents)
24
+ * @param opts.logCollection MongoDB collection containing logs
25
+ * @returns object with logs for the requested page and optionally total number of pages
26
+ */
27
+ const getLogReviewerLogs = async (
28
+ opts: {
29
+ pageNumber: number,
30
+ filters: LogReviewerFilterState,
31
+ countDocuments: boolean,
32
+ logCollection: Collection<Log>,
33
+ },
34
+ ) => {
35
+ // Destructure opts
36
+ const {
37
+ pageNumber,
38
+ filters,
39
+ countDocuments,
40
+ logCollection,
41
+ } = opts;
42
+
43
+
44
+ // Destructure filters
45
+ const {
46
+ dateFilterState,
47
+ contextFilterState,
48
+ tagFilterState,
49
+ actionErrorFilterState,
50
+ advancedFilterState,
51
+ } = filters as LogReviewerFilterState;
52
+
53
+ // Build MongoDB query based on filters
54
+ const query: { [k: string]: any } = {};
55
+
56
+ /* -------------- Date Filter ------------- */
57
+
58
+ // Convert start and end dates from the dateFilterState into timestamps
59
+ const { startDate, endDate } = dateFilterState;
60
+ const startTimestamp = new Date(
61
+ `${startDate.month}/${startDate.day}/${startDate.year}`,
62
+ ).getTime();
63
+ const endTimestamp = (
64
+ (new Date(`${endDate.month}/${endDate.day}/${endDate.year}`)).getTime()
65
+ + DAY_IN_MS
66
+ );
67
+
68
+ // Add a date range condition to the query
69
+ query.timestamp = {
70
+ $gte: startTimestamp,
71
+ $lt: endTimestamp,
72
+ };
73
+
74
+ /* ------------ Context Filter ------------ */
75
+
76
+ // Process context filters to include selected contexts and subcontexts
77
+ const contextConditions: { [k: string]: any }[] = [];
78
+ Object.keys(contextFilterState).forEach((context) => {
79
+ const value = contextFilterState[context];
80
+ if (typeof value === 'boolean') {
81
+ if (value) {
82
+ // The entire context is selected
83
+ contextConditions.push({ context });
84
+ }
85
+ } else {
86
+ // The context has subcontexts
87
+ const subcontexts = Object.keys(value).filter((subcontext) => {
88
+ return value[subcontext];
89
+ });
90
+
91
+ if (subcontexts.length > 0) {
92
+ contextConditions.push({
93
+ context,
94
+ subcontext: { $in: subcontexts },
95
+ });
96
+ }
97
+ }
98
+ });
99
+ if (contextConditions.length > 0) {
100
+ query.$or = contextConditions;
101
+ }
102
+
103
+ /* -------------- Tag Filter -------------- */
104
+
105
+ const selectedTags = Object.keys(tagFilterState).filter((tag) => { return tagFilterState[tag]; });
106
+ if (selectedTags.length > 0) {
107
+ query.tags = { $in: selectedTags };
108
+ }
109
+
110
+ /* --------- Action/Error Filter ---------- */
111
+
112
+ if (actionErrorFilterState.type) {
113
+ query.type = actionErrorFilterState.type;
114
+ }
115
+
116
+ if (actionErrorFilterState.type === LogType.Error) {
117
+ if (actionErrorFilterState.errorMessage) {
118
+ // Add error message to the query.
119
+ // $i is used for case-insensitive search, and $regex is used for partial matching
120
+ query.errorMessage = {
121
+ $regex: actionErrorFilterState.errorMessage,
122
+ $options: 'i',
123
+ };
124
+ }
125
+
126
+ if (actionErrorFilterState.errorCode) {
127
+ query.errorCode = {
128
+ $regex: actionErrorFilterState.errorCode,
129
+ $options: 'i',
130
+ };
131
+ }
132
+ }
133
+
134
+ if (actionErrorFilterState.type === LogType.Action) {
135
+ const selectedTargets = (
136
+ Object.keys(actionErrorFilterState.target)
137
+ .filter((target) => {
138
+ return actionErrorFilterState.target[target];
139
+ })
140
+ );
141
+ const selectedActions = (
142
+ Object.keys(actionErrorFilterState.action)
143
+ .filter((action) => {
144
+ return actionErrorFilterState.action[action];
145
+ })
146
+ );
147
+ if (selectedTargets.length > 0) {
148
+ query.target = { $in: selectedTargets };
149
+ }
150
+ if (selectedActions.length > 0) {
151
+ query.action = { $in: selectedActions };
152
+ }
153
+ }
154
+
155
+ /* ------------ Advanced Filter ----------- */
156
+
157
+ if (advancedFilterState.userFirstName) {
158
+ query.userFirstName = {
159
+ $regex: advancedFilterState.userFirstName,
160
+ $options: 'i',
161
+ };
162
+ }
163
+
164
+ if (advancedFilterState.userLastName) {
165
+ query.userLastName = {
166
+ $regex: advancedFilterState.userLastName,
167
+ $options: 'i',
168
+ };
169
+ }
170
+
171
+ if (advancedFilterState.userEmail) {
172
+ query.userEmail = {
173
+ $regex: advancedFilterState.userEmail,
174
+ $options: 'i',
175
+ };
176
+ }
177
+
178
+ if (advancedFilterState.userId) {
179
+ query.userId = Number.parseInt(advancedFilterState.userId, 10);
180
+ }
181
+
182
+ const roles: {
183
+ isLearner?: boolean,
184
+ isTTM?: boolean,
185
+ isAdmin?: boolean,
186
+ }[] = [];
187
+ if (advancedFilterState.includeLearners) {
188
+ roles.push({ isLearner: true });
189
+ }
190
+ if (advancedFilterState.includeTTMs) {
191
+ roles.push({ isTTM: true });
192
+ }
193
+ if (advancedFilterState.includeAdmins) {
194
+ roles.push({ isAdmin: true });
195
+ }
196
+ // If any roles are selected, add them to the query
197
+ if (roles.length > 0) {
198
+ // The $or operator is used to match any of the roles
199
+ // The $and operator is to ensure that other conditions in the query are met
200
+ query.$and = [{ $or: roles }];
201
+ }
202
+
203
+ if (advancedFilterState.courseId) {
204
+ query.courseId = Number.parseInt(advancedFilterState.courseId, 10);
205
+ }
206
+
207
+ if (advancedFilterState.courseName) {
208
+ query.courseName = {
209
+ $regex: advancedFilterState.courseName,
210
+ $options: 'i',
211
+ };
212
+ }
213
+
214
+ if (advancedFilterState.isMobile !== undefined) {
215
+ query['device.isMobile'] = Boolean(advancedFilterState.isMobile);
216
+ }
217
+
218
+ if (advancedFilterState.source) {
219
+ query.source = advancedFilterState.source;
220
+ }
221
+
222
+ if (advancedFilterState.routePath) {
223
+ query.routePath = {
224
+ $regex: advancedFilterState.routePath,
225
+ $options: 'i',
226
+ };
227
+ }
228
+
229
+ if (advancedFilterState.routeTemplate) {
230
+ query.routeTemplate = {
231
+ $regex: advancedFilterState.routeTemplate,
232
+ $options: 'i',
233
+ };
234
+ }
235
+
236
+ // Query for logs
237
+ const response = await logCollection.findPaged({
238
+ query,
239
+ perPage: LOG_REVIEW_PAGE_SIZE,
240
+ pageNumber,
241
+ sortDescending: true,
242
+ });
243
+
244
+ // Count documents if requested
245
+ if (countDocuments) {
246
+ const numPages = Math.ceil(
247
+ await logCollection.count(query)
248
+ / LOG_REVIEW_PAGE_SIZE
249
+ );
250
+ return {
251
+ ...response,
252
+ numPages,
253
+ };
254
+ }
255
+
256
+ // Return response
257
+ return response;
258
+ };
259
+
260
+ export default getLogReviewerLogs;
@@ -6,17 +6,18 @@ import { Collection } from 'dce-mango';
6
6
 
7
7
  // Import dce-reactkit
8
8
  import {
9
- ErrorWithCode,
10
9
  ParamType,
11
10
  LogFunction,
12
- LOG_REVIEW_ROUTE_PATH_PREFIX,
13
11
  LOG_ROUTE_PATH,
14
12
  LOG_REVIEW_STATUS_ROUTE,
15
13
  Log,
14
+ LOG_REVIEW_GET_LOGS_ROUTE,
15
+ ErrorWithCode,
16
16
  } from 'dce-reactkit';
17
17
 
18
18
  // Import shared helpers
19
19
  import genRouteHandler from './genRouteHandler';
20
+ import getLogReviewerLogs from './getLogReviewerLogs';
20
21
 
21
22
  // Import shared types
22
23
  import ExpressKitErrorCode from '../types/ExpressKitErrorCode';
@@ -231,28 +232,28 @@ const initServer = (
231
232
  );
232
233
 
233
234
  /**
234
- * Get all logs for a certain month
235
- * @author Gabe Abrams
236
- * @param {number} year the year to query (e.g. 2022)
237
- * @param {number} month the month to query (e.g. 1 = January)
238
- * @returns {Log[]} list of logs from the given month
235
+ * Get filtered logs based on provided filters
236
+ * @author Gabe Abrams, Yuen Ler Chow
237
+ * @param pageNumber the page number to get
238
+ * @param filters the filters to apply to the logs
239
+ * @returns {Log[]} list of logs that match the filters
239
240
  */
240
241
  opts.app.get(
241
- `${LOG_REVIEW_ROUTE_PATH_PREFIX}/years/:year/months/:month`,
242
+ LOG_REVIEW_GET_LOGS_ROUTE,
242
243
  genRouteHandler({
243
244
  paramTypes: {
244
- year: ParamType.Int,
245
- month: ParamType.Int,
246
245
  pageNumber: ParamType.Int,
246
+ filters: ParamType.JSON,
247
+ countDocuments: ParamType.Boolean,
247
248
  },
248
249
  handler: async ({ params }) => {
249
- // Get user info
250
+ // Destructure params
250
251
  const {
251
- year,
252
- month,
253
252
  pageNumber,
254
253
  userId,
255
254
  isAdmin,
255
+ filters,
256
+ countDocuments,
256
257
  } = params;
257
258
 
258
259
  // Validate user
@@ -264,14 +265,12 @@ const initServer = (
264
265
  );
265
266
  }
266
267
 
267
- // Query for logs
268
- const response = await _logCollection.findPaged({
269
- query: {
270
- year,
271
- month,
272
- },
273
- perPage: 1000,
268
+ // Get logs
269
+ const response = await getLogReviewerLogs({
274
270
  pageNumber,
271
+ filters,
272
+ countDocuments,
273
+ logCollection: _logCollection,
275
274
  });
276
275
 
277
276
  // Return response