dce-reactkit 3.2.2-beta.2 → 3.2.2-beta.20
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 +338 -186
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/ButtonInputGroup.d.ts +1 -0
- package/dist/cjs/types/components/ItemPicker/index.d.ts +1 -0
- package/dist/cjs/types/index.d.ts +2 -1
- package/dist/cjs/types/server/initServer.d.ts +1 -1
- package/dist/cjs/types/types/LogBuiltInMetadata.d.ts +1 -1
- package/dist/esm/index.js +338 -187
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/ButtonInputGroup.d.ts +1 -0
- package/dist/esm/types/components/ItemPicker/index.d.ts +1 -0
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/esm/types/server/initServer.d.ts +1 -1
- package/dist/esm/types/types/LogBuiltInMetadata.d.ts +1 -1
- package/dist/index.d.ts +12 -3
- package/package.json +1 -1
- package/src/components/ButtonInputGroup.tsx +4 -1
- package/src/components/IntelliTable.tsx +4 -4
- package/src/components/ItemPicker/index.tsx +4 -0
- package/src/components/LogReviewer.tsx +280 -130
- package/src/components/SimpleDateChooser.tsx +20 -7
- package/src/constants/LOG_REVIEW_STATUS_ROUTE.ts +1 -1
- package/src/helpers/genRouteHandler.ts +1 -1
- package/src/helpers/logClientEvent.tsx +6 -1
- package/src/index.ts +2 -0
- package/src/server/initServer.ts +93 -73
- package/src/types/LogBuiltInMetadata.ts +5 -5
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
// Import shared helpers
|
|
22
22
|
import visitServerEndpoint from '../helpers/visitServerEndpoint';
|
|
23
23
|
import getTimeInfoInET from '../helpers/getTimeInfoInET';
|
|
24
|
-
import { showFatalError } from './AppWrapper';
|
|
24
|
+
import { alert, showFatalError } from './AppWrapper';
|
|
25
25
|
|
|
26
26
|
// Import shared constants
|
|
27
27
|
import LOG_REVIEW_ROUTE_PATH_PREFIX from '../constants/LOG_REVIEW_ROUTE_PATH_PREFIX';
|
|
@@ -34,6 +34,7 @@ import LogType from '../types/LogType';
|
|
|
34
34
|
import LogAction from '../types/LogAction';
|
|
35
35
|
import ParamType from '../types/ParamType';
|
|
36
36
|
import IntelliTableColumn from '../types/IntelliTableColumn';
|
|
37
|
+
import LogBuiltInMetadata from '../types/LogBuiltInMetadata';
|
|
37
38
|
|
|
38
39
|
// Import shared components
|
|
39
40
|
import SimpleDateChooser from './SimpleDateChooser';
|
|
@@ -206,6 +207,11 @@ const style = `
|
|
|
206
207
|
border: 0.05rem solid black;
|
|
207
208
|
border-radius: 0.5rem;
|
|
208
209
|
overflow: hidden;
|
|
210
|
+
padding: 0.7rem;
|
|
211
|
+
|
|
212
|
+
/* Solid background */
|
|
213
|
+
background-color: white;
|
|
214
|
+
color: black;
|
|
209
215
|
|
|
210
216
|
/* Place contents in flex column */
|
|
211
217
|
flex-direction: column;
|
|
@@ -232,6 +238,27 @@ const style = `
|
|
|
232
238
|
/* Vertical scroll */
|
|
233
239
|
overflow-y: auto;
|
|
234
240
|
}
|
|
241
|
+
|
|
242
|
+
.LogReviewer-header-close-button {
|
|
243
|
+
border: 0 !important;
|
|
244
|
+
background-color: transparent !important;
|
|
245
|
+
padding-top: 0 !important;
|
|
246
|
+
padding-bottom: 0 !important;
|
|
247
|
+
padding-right: 1em !important;
|
|
248
|
+
margin: 0 !important;
|
|
249
|
+
color: #444 !important;
|
|
250
|
+
|
|
251
|
+
right: 0 !important;
|
|
252
|
+
position: absolute !important;
|
|
253
|
+
}
|
|
254
|
+
.LogReviewer-header-close-button:hover {
|
|
255
|
+
border: 0 !important;
|
|
256
|
+
background-color: transparent !important;
|
|
257
|
+
padding-top: 0 !important;
|
|
258
|
+
padding-bottom: 0 !important;
|
|
259
|
+
margin: 0 !important;
|
|
260
|
+
color: #000 !important;
|
|
261
|
+
}
|
|
235
262
|
`;
|
|
236
263
|
|
|
237
264
|
/*------------------------------------------------------------------------*/
|
|
@@ -254,7 +281,7 @@ const genHumanReadableName = (machineReadableName: string) => {
|
|
|
254
281
|
// Uppercase! Add a space before
|
|
255
282
|
humanReadableName += ' ';
|
|
256
283
|
}
|
|
257
|
-
humanReadableName +=
|
|
284
|
+
humanReadableName += char;
|
|
258
285
|
});
|
|
259
286
|
|
|
260
287
|
// Trim and return
|
|
@@ -437,9 +464,25 @@ const reducer = (state: State, action: Action): State => {
|
|
|
437
464
|
};
|
|
438
465
|
}
|
|
439
466
|
case ActionType.UpdateTagFilterState: {
|
|
467
|
+
const { tagFilterState } = action;
|
|
468
|
+
|
|
469
|
+
// Select all if every tag is deselected
|
|
470
|
+
const numTagsSelected = (
|
|
471
|
+
Object.values(tagFilterState)
|
|
472
|
+
.filter((isSelected) => {
|
|
473
|
+
return isSelected;
|
|
474
|
+
})
|
|
475
|
+
.length
|
|
476
|
+
);
|
|
477
|
+
if (numTagsSelected === 0) {
|
|
478
|
+
Object.keys(tagFilterState).forEach((tag) => {
|
|
479
|
+
tagFilterState[tag] = true;
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
|
|
440
483
|
return {
|
|
441
484
|
...state,
|
|
442
|
-
tagFilterState
|
|
485
|
+
tagFilterState,
|
|
443
486
|
};
|
|
444
487
|
}
|
|
445
488
|
case ActionType.UpdateActionErrorFilterState: {
|
|
@@ -477,6 +520,34 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
477
520
|
onClose,
|
|
478
521
|
} = props;
|
|
479
522
|
|
|
523
|
+
// Add built-in LogMetadata
|
|
524
|
+
// > Add "uncategorized" subcontext to each context
|
|
525
|
+
Object.keys(LogMetadata.Context ?? {}).forEach((context) => {
|
|
526
|
+
if (
|
|
527
|
+
LogMetadata.Context
|
|
528
|
+
// Context has children already
|
|
529
|
+
&& typeof LogMetadata.Context[context] !== 'string'
|
|
530
|
+
) {
|
|
531
|
+
(LogMetadata.Context as any)[context][LogBuiltInMetadata.Context.Uncategorized] = (
|
|
532
|
+
LogBuiltInMetadata.Context.Uncategorized
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
})
|
|
536
|
+
// > Add built-in contexts
|
|
537
|
+
LogMetadata.Context = (LogMetadata.Context ?? {});
|
|
538
|
+
Object.keys(LogBuiltInMetadata.Context).forEach((context) => {
|
|
539
|
+
if (LogMetadata.Context) {
|
|
540
|
+
LogMetadata.Context[context] = context;
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
// > Add built-in targets
|
|
544
|
+
LogMetadata.Target = (LogMetadata.Target ?? {});
|
|
545
|
+
Object.keys(LogBuiltInMetadata.Target).forEach((target) => {
|
|
546
|
+
if (LogMetadata.Target) {
|
|
547
|
+
LogMetadata.Target[target] = target;
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
|
|
480
551
|
/* -------------- State ------------- */
|
|
481
552
|
|
|
482
553
|
// Create initial date filter state
|
|
@@ -550,6 +621,10 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
550
621
|
Object.values(LogAction).forEach((action) => {
|
|
551
622
|
initActionErrorFilterState.action[action] = true;
|
|
552
623
|
});
|
|
624
|
+
// Add built-in targets
|
|
625
|
+
Object.values(LogBuiltInMetadata.Target).forEach((target) => {
|
|
626
|
+
initActionErrorFilterState.target[target] = true;
|
|
627
|
+
});
|
|
553
628
|
|
|
554
629
|
// Initial state
|
|
555
630
|
const initialState: State = {
|
|
@@ -600,18 +675,23 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
600
675
|
let month = newDateFilterState.startDate.month;
|
|
601
676
|
while (
|
|
602
677
|
// Earlier year
|
|
603
|
-
(year
|
|
678
|
+
(year < newDateFilterState.endDate.year)
|
|
604
679
|
// Current year but included month
|
|
605
680
|
|| (
|
|
606
681
|
year === newDateFilterState.endDate.year
|
|
607
682
|
&& month <= newDateFilterState.endDate.month
|
|
608
683
|
)
|
|
609
684
|
) {
|
|
610
|
-
// Add to list
|
|
611
|
-
|
|
612
|
-
year
|
|
613
|
-
month
|
|
614
|
-
|
|
685
|
+
// Add to list if not already loaded
|
|
686
|
+
if (
|
|
687
|
+
!logMap[year]
|
|
688
|
+
|| !logMap[year][month]
|
|
689
|
+
) {
|
|
690
|
+
toLoad.push({
|
|
691
|
+
year,
|
|
692
|
+
month,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
615
695
|
|
|
616
696
|
// Increment
|
|
617
697
|
month += 1;
|
|
@@ -641,6 +721,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
641
721
|
|
|
642
722
|
// Check which year/month combos we need to load
|
|
643
723
|
const toLoad = listMonthsToLoad(newDateFilterState);
|
|
724
|
+
console.log('Filter update:', newDateFilterState, toLoad, logMap);
|
|
644
725
|
|
|
645
726
|
// If nothing to load, finished
|
|
646
727
|
if (toLoad.length === 0) {
|
|
@@ -727,16 +808,16 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
727
808
|
|
|
728
809
|
// Filter toggle
|
|
729
810
|
const filterToggles = (
|
|
730
|
-
<div className="LogReviewer-filter-toggles
|
|
811
|
+
<div className="LogReviewer-filter-toggles">
|
|
731
812
|
<h3 className="m-0">
|
|
732
813
|
Filters:
|
|
733
814
|
</h3>
|
|
734
|
-
<div className="LogReviewer-filter-toggle-buttons">
|
|
815
|
+
<div className="LogReviewer-filter-toggle-buttons alert alert-secondary p-2 m-0">
|
|
735
816
|
{/* Date */}
|
|
736
817
|
<button
|
|
737
818
|
type="button"
|
|
738
819
|
id="LogReviewer-toggle-date-filter-drawer"
|
|
739
|
-
className={`btn btn-${FilterDrawer.Date === expandedFilterDrawer} me-2`}
|
|
820
|
+
className={`btn btn-${FilterDrawer.Date === expandedFilterDrawer ? 'warning' : 'light'} me-2`}
|
|
740
821
|
aria-label="toggle date filter drawer"
|
|
741
822
|
onClick={() => {
|
|
742
823
|
dispatch({
|
|
@@ -755,7 +836,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
755
836
|
<button
|
|
756
837
|
type="button"
|
|
757
838
|
id="LogReviewer-toggle-context-filter-drawer"
|
|
758
|
-
className={`btn btn-${FilterDrawer.Context === expandedFilterDrawer} me-2`}
|
|
839
|
+
className={`btn btn-${FilterDrawer.Context === expandedFilterDrawer ? 'warning' : 'light'} me-2`}
|
|
759
840
|
aria-label="toggle context filter drawer"
|
|
760
841
|
onClick={() => {
|
|
761
842
|
dispatch({
|
|
@@ -771,29 +852,32 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
771
852
|
Context
|
|
772
853
|
</button>
|
|
773
854
|
{/* Tag */}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
855
|
+
{/* Skip if no tags are used */}
|
|
856
|
+
{(LogMetadata.Tag && Object.keys(LogMetadata.Tag).length > 0) && (
|
|
857
|
+
<button
|
|
858
|
+
type="button"
|
|
859
|
+
id="LogReviewer-toggle-tag-filter-drawer"
|
|
860
|
+
className={`btn btn-${FilterDrawer.Tag === expandedFilterDrawer ? 'warning' : 'light'} me-2`}
|
|
861
|
+
aria-label="toggle tag filter drawer"
|
|
862
|
+
onClick={() => {
|
|
863
|
+
dispatch({
|
|
864
|
+
type: ActionType.ToggleFilterDrawer,
|
|
865
|
+
filterDrawer: FilterDrawer.Tag,
|
|
866
|
+
});
|
|
867
|
+
}}
|
|
868
|
+
>
|
|
869
|
+
<FontAwesomeIcon
|
|
870
|
+
icon={faTag}
|
|
871
|
+
className="me-2"
|
|
872
|
+
/>
|
|
873
|
+
Tag
|
|
874
|
+
</button>
|
|
875
|
+
)}
|
|
792
876
|
{/* Action */}
|
|
793
877
|
<button
|
|
794
878
|
type="button"
|
|
795
879
|
id="LogReviewer-toggle-action-filter-drawer"
|
|
796
|
-
className={`btn btn-${FilterDrawer.Action === expandedFilterDrawer} me-2`}
|
|
880
|
+
className={`btn btn-${FilterDrawer.Action === expandedFilterDrawer ? 'warning' : 'light'} me-2`}
|
|
797
881
|
aria-label="toggle action and error filter drawer"
|
|
798
882
|
onClick={() => {
|
|
799
883
|
dispatch({
|
|
@@ -812,7 +896,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
812
896
|
<button
|
|
813
897
|
type="button"
|
|
814
898
|
id="LogReviewer-toggle-advanced-filter-drawer"
|
|
815
|
-
className={`btn btn-${FilterDrawer.Advanced === expandedFilterDrawer}`}
|
|
899
|
+
className={`btn btn-${FilterDrawer.Advanced === expandedFilterDrawer ? 'warning' : 'light'}`}
|
|
816
900
|
aria-label="toggle advanced filter drawer"
|
|
817
901
|
onClick={() => {
|
|
818
902
|
dispatch({
|
|
@@ -843,14 +927,11 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
843
927
|
year={dateFilterState.startDate.year}
|
|
844
928
|
month={dateFilterState.startDate.month}
|
|
845
929
|
day={dateFilterState.startDate.day}
|
|
930
|
+
chooseFromPast
|
|
931
|
+
numMonthsToShow={12}
|
|
846
932
|
onChange={(month, day, year) => {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
dateFilterState: {
|
|
850
|
-
...dateFilterState,
|
|
851
|
-
startDate: { month, day, year },
|
|
852
|
-
},
|
|
853
|
-
});
|
|
933
|
+
dateFilterState.startDate = { month, day, year };
|
|
934
|
+
handleDateRangeUpdated(dateFilterState);
|
|
854
935
|
}}
|
|
855
936
|
/>
|
|
856
937
|
{' '}
|
|
@@ -862,14 +943,28 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
862
943
|
year={dateFilterState.endDate.year}
|
|
863
944
|
month={dateFilterState.endDate.month}
|
|
864
945
|
day={dateFilterState.endDate.day}
|
|
946
|
+
chooseFromPast
|
|
947
|
+
numMonthsToShow={12}
|
|
865
948
|
onChange={(month, day, year) => {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
949
|
+
if (
|
|
950
|
+
year < dateFilterState.startDate.year
|
|
951
|
+
|| (
|
|
952
|
+
year === dateFilterState.startDate.year
|
|
953
|
+
&& month < dateFilterState.startDate.month
|
|
954
|
+
)
|
|
955
|
+
|| (
|
|
956
|
+
year === dateFilterState.startDate.year
|
|
957
|
+
&& month === dateFilterState.startDate.month
|
|
958
|
+
&& day < dateFilterState.startDate.day
|
|
959
|
+
)
|
|
960
|
+
) {
|
|
961
|
+
return alert(
|
|
962
|
+
'Invalid Start Date',
|
|
963
|
+
'The start date cannot be before the end date.',
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
dateFilterState.endDate = { month, day, year };
|
|
967
|
+
handleDateRangeUpdated(dateFilterState);
|
|
873
968
|
}}
|
|
874
969
|
/>
|
|
875
970
|
</TabBox>
|
|
@@ -908,7 +1003,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
908
1003
|
);
|
|
909
1004
|
const item: PickableItem = {
|
|
910
1005
|
id: context,
|
|
911
|
-
name: context,
|
|
1006
|
+
name: genHumanReadableName(context),
|
|
912
1007
|
isGroup: true,
|
|
913
1008
|
children,
|
|
914
1009
|
};
|
|
@@ -922,6 +1017,8 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
922
1017
|
title="Context"
|
|
923
1018
|
items={pickableItems}
|
|
924
1019
|
onChanged={(updatedItems) => {
|
|
1020
|
+
console.log('Items before:', pickableItems);
|
|
1021
|
+
console.log('Updated Items:', updatedItems);
|
|
925
1022
|
// Update our state
|
|
926
1023
|
updatedItems.forEach((pickableItem) => {
|
|
927
1024
|
if (pickableItem.isGroup) {
|
|
@@ -1023,7 +1120,10 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1023
1120
|
) && (
|
|
1024
1121
|
<TabBox title="Action Log Details">
|
|
1025
1122
|
{/* Action */}
|
|
1026
|
-
<ButtonInputGroup
|
|
1123
|
+
<ButtonInputGroup
|
|
1124
|
+
label="Action"
|
|
1125
|
+
className="mb-2"
|
|
1126
|
+
>
|
|
1027
1127
|
{
|
|
1028
1128
|
Object.keys(LogAction)
|
|
1029
1129
|
.map((action, i) => {
|
|
@@ -1048,6 +1148,13 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1048
1148
|
</ButtonInputGroup>
|
|
1049
1149
|
{/* Target */}
|
|
1050
1150
|
<ButtonInputGroup label="Target">
|
|
1151
|
+
{/* Nothing here */}
|
|
1152
|
+
{(Object.keys(LogMetadata.Target ?? {}).length === 0) && (
|
|
1153
|
+
<div>
|
|
1154
|
+
This app does not have any targets yet.
|
|
1155
|
+
</div>
|
|
1156
|
+
)}
|
|
1157
|
+
{/* List of targets */}
|
|
1051
1158
|
{
|
|
1052
1159
|
Object.keys(LogMetadata.Target ?? {})
|
|
1053
1160
|
.map((target, i) => {
|
|
@@ -1394,53 +1501,58 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1394
1501
|
/>
|
|
1395
1502
|
</ButtonInputGroup>
|
|
1396
1503
|
|
|
1397
|
-
{/*
|
|
1398
|
-
|
|
1399
|
-
<
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1504
|
+
{/* Server filters */}
|
|
1505
|
+
{advancedFilterState.source !== LogSource.Client && (
|
|
1506
|
+
<div className="mt-2">
|
|
1507
|
+
{/* Route path */}
|
|
1508
|
+
<div className="input-group mb-2">
|
|
1509
|
+
<span className="input-group-text">
|
|
1510
|
+
Server Route Path
|
|
1511
|
+
</span>
|
|
1512
|
+
<input
|
|
1513
|
+
type="text"
|
|
1514
|
+
className="form-control"
|
|
1515
|
+
aria-label="query for server route path"
|
|
1516
|
+
placeholder="e.g. /api/ttm/courses/12345"
|
|
1517
|
+
value={advancedFilterState.routePath}
|
|
1518
|
+
onChange={(e) => {
|
|
1519
|
+
advancedFilterState.courseName = (
|
|
1520
|
+
(e.target.value)
|
|
1521
|
+
.trim()
|
|
1522
|
+
);
|
|
1523
|
+
dispatch({
|
|
1524
|
+
type: ActionType.UpdateAdvancedFilterState,
|
|
1525
|
+
advancedFilterState,
|
|
1526
|
+
});
|
|
1527
|
+
}}
|
|
1528
|
+
/>
|
|
1529
|
+
</div>
|
|
1420
1530
|
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1531
|
+
{/* Route template */}
|
|
1532
|
+
<div className="input-group mb-2">
|
|
1533
|
+
<span className="input-group-text">
|
|
1534
|
+
Server Route Template
|
|
1535
|
+
</span>
|
|
1536
|
+
<input
|
|
1537
|
+
type="text"
|
|
1538
|
+
className="form-control"
|
|
1539
|
+
aria-label="query for server route template"
|
|
1540
|
+
value={advancedFilterState.routeTemplate}
|
|
1541
|
+
placeholder="e.g. /api/ttm/courses/:courseId"
|
|
1542
|
+
onChange={(e) => {
|
|
1543
|
+
advancedFilterState.courseName = (
|
|
1544
|
+
(e.target.value)
|
|
1545
|
+
.trim()
|
|
1546
|
+
);
|
|
1547
|
+
dispatch({
|
|
1548
|
+
type: ActionType.UpdateAdvancedFilterState,
|
|
1549
|
+
advancedFilterState,
|
|
1550
|
+
});
|
|
1551
|
+
}}
|
|
1552
|
+
/>
|
|
1553
|
+
</div>
|
|
1554
|
+
</div>
|
|
1555
|
+
)}
|
|
1444
1556
|
</TabBox>
|
|
1445
1557
|
</>
|
|
1446
1558
|
);
|
|
@@ -1463,9 +1575,10 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1463
1575
|
// > Perform filters
|
|
1464
1576
|
const logs: Log[] = [];
|
|
1465
1577
|
Object.keys(logMap).forEach((year) => {
|
|
1466
|
-
Object.keys(logMap).forEach((month) => {
|
|
1578
|
+
Object.keys(logMap[year]).forEach((month) => {
|
|
1467
1579
|
logMap[year][month].forEach((log) => {
|
|
1468
1580
|
/* ----------- Date Filter ---------- */
|
|
1581
|
+
console.log('Log:', log);
|
|
1469
1582
|
|
|
1470
1583
|
// Before start date
|
|
1471
1584
|
if (
|
|
@@ -1483,6 +1596,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1483
1596
|
&& (log.day < dateFilterState.startDate.day)
|
|
1484
1597
|
)
|
|
1485
1598
|
) {
|
|
1599
|
+
console.log('RULED OUT: START');
|
|
1486
1600
|
return;
|
|
1487
1601
|
}
|
|
1488
1602
|
|
|
@@ -1502,6 +1616,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1502
1616
|
&& (log.day > dateFilterState.endDate.day)
|
|
1503
1617
|
)
|
|
1504
1618
|
) {
|
|
1619
|
+
console.log('RULED OUT: END');
|
|
1505
1620
|
return;
|
|
1506
1621
|
}
|
|
1507
1622
|
|
|
@@ -1519,13 +1634,16 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1519
1634
|
})
|
|
1520
1635
|
)
|
|
1521
1636
|
) {
|
|
1637
|
+
console.log('RULED OUT: CONTEXT');
|
|
1522
1638
|
return;
|
|
1523
1639
|
}
|
|
1524
1640
|
|
|
1525
1641
|
// Subcontext doesn't match
|
|
1526
1642
|
if (
|
|
1643
|
+
// Log context is not "uncategorized" (no point in further filters)
|
|
1644
|
+
log.context !== LogBuiltInMetadata.Context.Uncategorized
|
|
1527
1645
|
// Log has a subcontext
|
|
1528
|
-
log.subcontext
|
|
1646
|
+
&& log.subcontext
|
|
1529
1647
|
// Context has subcontexts
|
|
1530
1648
|
&& (
|
|
1531
1649
|
contextFilterState[log.context]
|
|
@@ -1535,6 +1653,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1535
1653
|
// Subcontext is not selected
|
|
1536
1654
|
&& !(contextFilterState as any)[log.context][log.subcontext]
|
|
1537
1655
|
) {
|
|
1656
|
+
console.log('RULED OUT: SUBCONTEXT');
|
|
1538
1657
|
return;
|
|
1539
1658
|
}
|
|
1540
1659
|
|
|
@@ -1542,15 +1661,11 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1542
1661
|
|
|
1543
1662
|
// No tags match
|
|
1544
1663
|
if (
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
&& (
|
|
1549
|
-
log.tags.every((tag) => {
|
|
1550
|
-
return !tagFilterState[tag];
|
|
1551
|
-
})
|
|
1552
|
-
)
|
|
1664
|
+
log.tags.every((tag) => {
|
|
1665
|
+
return !tagFilterState[tag];
|
|
1666
|
+
})
|
|
1553
1667
|
) {
|
|
1668
|
+
console.log('RULED OUT: TAGS');
|
|
1554
1669
|
return;
|
|
1555
1670
|
}
|
|
1556
1671
|
|
|
@@ -1563,6 +1678,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1563
1678
|
// Log type doesn't match
|
|
1564
1679
|
&& actionErrorFilterState.type !== log.type
|
|
1565
1680
|
) {
|
|
1681
|
+
console.log('RULED OUT: TYPE');
|
|
1566
1682
|
return;
|
|
1567
1683
|
}
|
|
1568
1684
|
|
|
@@ -1579,6 +1695,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1579
1695
|
actionErrorFilterState.errorMessage.trim().toLowerCase(),
|
|
1580
1696
|
)
|
|
1581
1697
|
) {
|
|
1698
|
+
console.log('RULED OUT: ERROR MESSAGE');
|
|
1582
1699
|
return;
|
|
1583
1700
|
}
|
|
1584
1701
|
|
|
@@ -1593,6 +1710,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1593
1710
|
actionErrorFilterState.errorCode.trim().toUpperCase(),
|
|
1594
1711
|
)
|
|
1595
1712
|
) {
|
|
1713
|
+
console.log('RULED OUT: ERROR CODE');
|
|
1596
1714
|
return;
|
|
1597
1715
|
}
|
|
1598
1716
|
}
|
|
@@ -1606,6 +1724,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1606
1724
|
// Target isn't selected
|
|
1607
1725
|
&& !actionErrorFilterState.target[log.target]
|
|
1608
1726
|
) {
|
|
1727
|
+
console.log('RULED OUT: TARGET');
|
|
1609
1728
|
return;
|
|
1610
1729
|
}
|
|
1611
1730
|
|
|
@@ -1616,6 +1735,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1616
1735
|
// Action isn't selected
|
|
1617
1736
|
&& !actionErrorFilterState.action[log.action]
|
|
1618
1737
|
) {
|
|
1738
|
+
console.log('RULED OUT: ACTION');
|
|
1619
1739
|
return;
|
|
1620
1740
|
}
|
|
1621
1741
|
}
|
|
@@ -1631,6 +1751,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1631
1751
|
advancedFilterState.userFirstName.toLowerCase().trim(),
|
|
1632
1752
|
)
|
|
1633
1753
|
) {
|
|
1754
|
+
console.log('RULED OUT: FIRST');
|
|
1634
1755
|
return;
|
|
1635
1756
|
}
|
|
1636
1757
|
|
|
@@ -1643,6 +1764,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1643
1764
|
advancedFilterState.userLastName.toLowerCase().trim(),
|
|
1644
1765
|
)
|
|
1645
1766
|
) {
|
|
1767
|
+
console.log('RULED OUT: LAST');
|
|
1646
1768
|
return;
|
|
1647
1769
|
}
|
|
1648
1770
|
|
|
@@ -1655,6 +1777,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1655
1777
|
advancedFilterState.userEmail.toLowerCase().trim(),
|
|
1656
1778
|
)
|
|
1657
1779
|
) {
|
|
1780
|
+
console.log('RULED OUT: EMAIL');
|
|
1658
1781
|
return;
|
|
1659
1782
|
}
|
|
1660
1783
|
|
|
@@ -1667,6 +1790,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1667
1790
|
advancedFilterState.userId.trim(),
|
|
1668
1791
|
)
|
|
1669
1792
|
) {
|
|
1793
|
+
console.log('RULED OUT: USER ID');
|
|
1670
1794
|
return;
|
|
1671
1795
|
}
|
|
1672
1796
|
|
|
@@ -1677,6 +1801,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1677
1801
|
// Learners aren't included
|
|
1678
1802
|
&& !advancedFilterState.includeLearners
|
|
1679
1803
|
) {
|
|
1804
|
+
console.log('RULED OUT: LEARNER');
|
|
1680
1805
|
return;
|
|
1681
1806
|
}
|
|
1682
1807
|
|
|
@@ -1687,6 +1812,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1687
1812
|
// TTMs aren't included
|
|
1688
1813
|
&& !advancedFilterState.includeTTMs
|
|
1689
1814
|
) {
|
|
1815
|
+
console.log('RULED OUT: TTM');
|
|
1690
1816
|
return;
|
|
1691
1817
|
}
|
|
1692
1818
|
|
|
@@ -1697,6 +1823,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1697
1823
|
// Admins aren't included
|
|
1698
1824
|
&& !advancedFilterState.includeAdmins
|
|
1699
1825
|
) {
|
|
1826
|
+
console.log('RULED OUT: ADMIN');
|
|
1700
1827
|
return;
|
|
1701
1828
|
}
|
|
1702
1829
|
|
|
@@ -1709,6 +1836,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1709
1836
|
advancedFilterState.courseId.trim(),
|
|
1710
1837
|
)
|
|
1711
1838
|
) {
|
|
1839
|
+
console.log('RULED OUT: COURSE ID');
|
|
1712
1840
|
return;
|
|
1713
1841
|
}
|
|
1714
1842
|
|
|
@@ -1721,6 +1849,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1721
1849
|
advancedFilterState.courseName.trim(),
|
|
1722
1850
|
)
|
|
1723
1851
|
) {
|
|
1852
|
+
console.log('RULED OUT: COURSE NAME');
|
|
1724
1853
|
return;
|
|
1725
1854
|
}
|
|
1726
1855
|
|
|
@@ -1733,6 +1862,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1733
1862
|
// Mobile filter doesn't match
|
|
1734
1863
|
&& (advancedFilterState.isMobile === log.device.isMobile)
|
|
1735
1864
|
) {
|
|
1865
|
+
console.log('RULED OUT: MOBILE');
|
|
1736
1866
|
return;
|
|
1737
1867
|
}
|
|
1738
1868
|
|
|
@@ -1745,6 +1875,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1745
1875
|
// Source filter doesn't match
|
|
1746
1876
|
&& (advancedFilterState.source !== log.source)
|
|
1747
1877
|
) {
|
|
1878
|
+
console.log('RULED OUT: SOURCE');
|
|
1748
1879
|
return;
|
|
1749
1880
|
}
|
|
1750
1881
|
|
|
@@ -1757,6 +1888,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1757
1888
|
// Route path doesn't match
|
|
1758
1889
|
&& !(log.routePath.includes(advancedFilterState.routePath.trim()))
|
|
1759
1890
|
) {
|
|
1891
|
+
console.log('RULED OUT: PATH');
|
|
1760
1892
|
return;
|
|
1761
1893
|
}
|
|
1762
1894
|
|
|
@@ -1769,6 +1901,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1769
1901
|
// Route template doesn't match
|
|
1770
1902
|
&& !(log.routeTemplate.includes(advancedFilterState.routeTemplate.trim()))
|
|
1771
1903
|
) {
|
|
1904
|
+
console.log('RULED OUT: TEMPLATE');
|
|
1772
1905
|
return;
|
|
1773
1906
|
}
|
|
1774
1907
|
|
|
@@ -1974,19 +2107,40 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1974
2107
|
|
|
1975
2108
|
// Create intelliTable
|
|
1976
2109
|
const dataTable = (
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
2110
|
+
logs.length === 0
|
|
2111
|
+
? (
|
|
2112
|
+
<>
|
|
2113
|
+
<h3 className="m-0">
|
|
2114
|
+
Matching Logs:
|
|
2115
|
+
</h3>
|
|
2116
|
+
<div className="alert alert-warning text-center">
|
|
2117
|
+
<h4 className="m-1">
|
|
2118
|
+
No Logs to Show
|
|
2119
|
+
</h4>
|
|
2120
|
+
<div>
|
|
2121
|
+
Either your filters are too strict or no matching logs have been
|
|
2122
|
+
created yet.
|
|
2123
|
+
</div>
|
|
2124
|
+
</div>
|
|
2125
|
+
</>
|
|
2126
|
+
)
|
|
2127
|
+
: (
|
|
2128
|
+
<IntelliTable
|
|
2129
|
+
title="Matching Logs:"
|
|
2130
|
+
id="logs"
|
|
2131
|
+
data={logs}
|
|
2132
|
+
columns={columns}
|
|
2133
|
+
/>
|
|
2134
|
+
)
|
|
1983
2135
|
);
|
|
1984
2136
|
|
|
1985
2137
|
// Main body
|
|
1986
2138
|
body = (
|
|
1987
2139
|
<>
|
|
1988
2140
|
{filters}
|
|
1989
|
-
|
|
2141
|
+
<div className="mt-2">
|
|
2142
|
+
{dataTable}
|
|
2143
|
+
</div>
|
|
1990
2144
|
</>
|
|
1991
2145
|
);
|
|
1992
2146
|
}
|
|
@@ -2001,26 +2155,22 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
2001
2155
|
<div className="LogReviewer-inner-container">
|
|
2002
2156
|
<div className="LogReviewer-header">
|
|
2003
2157
|
<div className="LogReviewer-header-title">
|
|
2004
|
-
<
|
|
2158
|
+
<h3 className="text-center m-0">
|
|
2005
2159
|
Log Review Dashboard
|
|
2006
|
-
</
|
|
2160
|
+
</h3>
|
|
2161
|
+
</div>
|
|
2162
|
+
<div style={{ width: 0 }}>
|
|
2163
|
+
<button
|
|
2164
|
+
type="button"
|
|
2165
|
+
className="LogReviewer-header-close-button btn btn-dark btn-lg pe-0"
|
|
2166
|
+
aria-label="close log reviewer panel"
|
|
2167
|
+
onClick={onClose}
|
|
2168
|
+
>
|
|
2169
|
+
<FontAwesomeIcon
|
|
2170
|
+
icon={faTimes}
|
|
2171
|
+
/>
|
|
2172
|
+
</button>
|
|
2007
2173
|
</div>
|
|
2008
|
-
<button
|
|
2009
|
-
type="button"
|
|
2010
|
-
className="LogReviewer-header-close-button btn btn-lg"
|
|
2011
|
-
aria-label="close log reviewer panel"
|
|
2012
|
-
onClick={onClose}
|
|
2013
|
-
style={{
|
|
2014
|
-
border: 0,
|
|
2015
|
-
backgroundColor: 'transparent',
|
|
2016
|
-
padding: 0,
|
|
2017
|
-
margin: 0,
|
|
2018
|
-
}}
|
|
2019
|
-
>
|
|
2020
|
-
<FontAwesomeIcon
|
|
2021
|
-
icon={faTimes}
|
|
2022
|
-
/>
|
|
2023
|
-
</button>
|
|
2024
2174
|
</div>
|
|
2025
2175
|
<div className="LogReviewer-contents">
|
|
2026
2176
|
{body}
|