Skip to content

Commit d4d2f23

Browse files
refactored grouped logic into util file
1 parent 729ec90 commit d4d2f23

File tree

5 files changed

+76
-150
lines changed

5 files changed

+76
-150
lines changed

frontend/alert/components/AutoComplete.tsx

+19-32
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useOnClickOutside } from "pcx-shared-components/src/useOnClickOutside";
99
import { Input } from "./Input";
1010
import { Section } from "../types";
1111
import GroupSuggestion from "./GroupSuggestion";
12+
import { groupByProperty } from "../util";
1213

1314
/* A function that takes in a search term and returns a promise with both the search term and
1415
the search results.
@@ -137,18 +138,17 @@ interface TSuggestion {
137138
}
138139

139140
interface AutoCompleteProps {
140-
defaultValue: string,
141-
setTimeline: React.Dispatch<React.SetStateAction<string | null>>,
142-
selectedCourses: Set<Section>,
143-
setSelectedCourses: React.Dispatch<React.SetStateAction<Set<Section>>>,
144-
value: string,
145-
setValue: React.Dispatch<React.SetStateAction<string>>,
146-
inputRef: React.RefObject<HTMLInputElement>,
147-
clearSelections: () => void,
148-
clearInputValue: () => void,
141+
defaultValue: string;
142+
setTimeline: React.Dispatch<React.SetStateAction<string | null>>;
143+
selectedCourses: Set<Section>;
144+
setSelectedCourses: React.Dispatch<React.SetStateAction<Set<Section>>>;
145+
value: string;
146+
setValue: React.Dispatch<React.SetStateAction<string>>;
147+
inputRef: React.RefObject<HTMLInputElement>;
148+
clearSelections: () => void;
149+
clearInputValue: () => void;
149150
}
150151

151-
152152
const AutoComplete = ({
153153
defaultValue = "",
154154
setTimeline,
@@ -187,13 +187,11 @@ const AutoComplete = ({
187187
inputRef.current.value = generateCoursesValue();
188188
} else if (selectedCourses.size === 1) {
189189
// display the one selected section
190-
setValue(
191-
selectedCourses.values().next().value.section_id
192-
);
190+
setValue(selectedCourses.values().next().value.section_id);
193191
inputRef.current.value = selectedCourses
194192
.values()
195193
.next().value.section_id;
196-
}
194+
}
197195
}
198196
}, [selectedCourses]);
199197

@@ -247,24 +245,13 @@ const AutoComplete = ({
247245
* Returns suggested suggestion grouped by course
248246
* @return suggestions
249247
*/
250-
const groupedSuggestions = suggestions
251-
.sort((a, b) => a.section_id.localeCompare(b.section_id))
252-
.reduce((res, obj) => {
253-
const [courseName, midNum, endNum] = obj.section_id.split("-");
254-
const { activity } = obj;
255-
256-
if (res[`${courseName}-${midNum}`]) {
257-
if (res[`${courseName}-${midNum}`][activity]) {
258-
res[`${courseName}-${midNum}`][activity].push(obj);
259-
} else {
260-
res[`${courseName}-${midNum}`][activity] = [obj];
261-
}
262-
} else {
263-
res[`${courseName}-${midNum}`] = { [activity]: [obj] };
264-
}
265-
266-
return res;
267-
}, {});
248+
const groupedSuggestions = groupByProperty(
249+
suggestions,
250+
(a, b) => a.section_id.localeCompare(b.section_id),
251+
"-",
252+
(obj) => obj.section_id,
253+
(obj) => obj.activity
254+
);
268255

269256
return (
270257
<Container

frontend/alert/components/managealert/AlertHeader.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@ const GridSubtitle = styled.div`
1616

1717
// Component for an alert entry (renders as a row in CSS grid)
1818
interface AlertHeaderProps {
19-
course: string;
20-
rownum: number;
19+
courseCode: string;
20+
rowNum: number;
2121
}
22-
export const AlertHeader = ({ course, rownum }: AlertHeaderProps) => {
22+
export const AlertHeader = ({ courseCode, rowNum }: AlertHeaderProps) => {
2323
return (
2424
<>
2525
<GridCourseTitle column={1} valign border>
26-
<GridSubtitle>{course.toUpperCase()}</GridSubtitle>
26+
<GridSubtitle>{courseCode.toUpperCase()}</GridSubtitle>
2727
</GridCourseTitle>
2828
{/* used to make sure grid line goes to end */}
2929
{Array.from({ length: 7 }, (_, index) => (
3030
<GridItem
3131
column={index + 2}
32-
row={rownum}
32+
row={rowNum}
3333
border
3434
halign
3535
valign

frontend/alert/components/managealert/AlertItem.tsx

+10-10
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ interface AlertItemProps {
3939
status: SectionStatus;
4040
actions: AlertAction;
4141
closed: AlertAction;
42-
rownum: number;
42+
rowNum: number;
4343
checked: boolean;
4444
toggleAlert: () => void;
4545
alertHandler: () => void;
@@ -52,7 +52,7 @@ export const AlertItem = ({
5252
status,
5353
actions,
5454
closed,
55-
rownum,
55+
rowNum,
5656
checked,
5757
toggleAlert,
5858
alertHandler,
@@ -76,14 +76,14 @@ export const AlertItem = ({
7676

7777
return (
7878
<>
79-
<GridItem column={1} row={rownum} border halign valign>
79+
<GridItem column={1} row={rowNum} border halign valign>
8080
<input
8181
type="checkbox"
8282
checked={checked}
8383
onChange={toggleAlert}
8484
/>
8585
</GridItem>
86-
<GridItem column={2} row={rownum} border halign valign talign>
86+
<GridItem column={2} row={rowNum} border halign valign talign>
8787
{alertLastSent ? (
8888
<P size="0.7rem">{alertLastSent}</P>
8989
) : (
@@ -92,21 +92,21 @@ export const AlertItem = ({
9292
</P>
9393
)}
9494
</GridItem>
95-
<GridItem column={3} row={rownum} border halign valign talign>
95+
<GridItem column={3} row={rowNum} border halign valign talign>
9696
<P size="0.7rem">{course}</P>
9797
</GridItem>
98-
<StatusGridItem column={4} row={rownum} border halign valign>
98+
<StatusGridItem column={4} row={rowNum} border halign valign>
9999
<StatusInd background={statuscolor} />
100100
<P size="0.7rem">{statustext}</P>
101101
</StatusGridItem>
102-
<GridItem border column={5} row={rownum} halign valign></GridItem>
103-
<GridItem border column={6} row={rownum} halign valign>
102+
<GridItem border column={5} row={rowNum} halign valign></GridItem>
103+
<GridItem border column={6} row={rowNum} halign valign>
104104
<ToggleSwitch type={actions} handleChange={alertHandler} />
105105
</GridItem>
106-
<GridItem border column={7} row={rownum} halign valign>
106+
<GridItem border column={7} row={rowNum} halign valign>
107107
<ToggleSwitch type={closed} handleChange={closedHandler} />
108108
</GridItem>
109-
<GridItem border column={8} row={rownum} halign valign>
109+
<GridItem border column={8} row={rowNum} halign valign>
110110
<TrashImg
111111
src="/svg/trash.svg"
112112
width="1.15rem"

frontend/alert/components/managealert/ManageAlertUI.tsx

+10-103
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { AlertItem } from "./AlertItem";
77
import { maxWidth, PHONE } from "../../constants";
88
import { Alert, AlertAction, SectionStatus, TAlertSel } from "../../types";
99
import { AlertHeader } from "./AlertHeader";
10+
import { groupByProperty } from "../../util";
1011

1112
const Container = styled.div`
1213
background: #ffffff;
@@ -91,90 +92,7 @@ export const ManageAlert = ({
9192
const [searchTimeout, setSearchTimeout] = useState<number>();
9293
const [numSelected, setNumSelected] = useState(0);
9394

94-
// Alerts for testing
95-
var alert1: Alert = {
96-
id: 1,
97-
originalCreatedAt: "2023-09-11T12:00:00Z",
98-
section: "cis-1100-001",
99-
alertLastSent: "2023-09-11T12:00:00Z",
100-
status: SectionStatus.OPEN,
101-
actions: AlertAction.ONALERT,
102-
closedNotif: AlertAction.ONCLOSED,
103-
};
104-
var alert2: Alert = {
105-
id: 2,
106-
originalCreatedAt: "2023-09-11T12:00:00Z",
107-
section: "cis-1100-002",
108-
alertLastSent: "2023-09-11T12:00:00Z",
109-
status: SectionStatus.OPEN,
110-
actions: AlertAction.ONALERT,
111-
closedNotif: AlertAction.ONCLOSED,
112-
};
113-
var alert3: Alert = {
114-
id: 3,
115-
originalCreatedAt: "2023-09-11T12:00:00Z",
116-
section: "cis-1200-001",
117-
alertLastSent: "2023-09-11T12:00:00Z",
118-
status: SectionStatus.OPEN,
119-
actions: AlertAction.ONALERT,
120-
closedNotif: AlertAction.ONCLOSED,
121-
};
122-
var alert4: Alert = {
123-
id: 4,
124-
originalCreatedAt: "2023-09-11T12:00:00Z",
125-
section: "stat-4300-002",
126-
alertLastSent: "2023-09-11T12:00:00Z",
127-
status: SectionStatus.OPEN,
128-
actions: AlertAction.ONALERT,
129-
closedNotif: AlertAction.ONCLOSED,
130-
};
131-
var alert5: Alert = {
132-
id: 5,
133-
originalCreatedAt: "2023-09-11T12:00:00Z",
134-
section: "stat-4300-001",
135-
alertLastSent: "2023-09-11T12:00:00Z",
136-
status: SectionStatus.OPEN,
137-
actions: AlertAction.ONALERT,
138-
closedNotif: AlertAction.ONCLOSED,
139-
};
140-
var alert6: Alert = {
141-
id: 6,
142-
originalCreatedAt: "2023-09-11T12:00:00Z",
143-
section: "math-1400-001",
144-
alertLastSent: "2023-09-11T12:00:00Z",
145-
status: SectionStatus.OPEN,
146-
actions: AlertAction.ONALERT,
147-
closedNotif: AlertAction.ONCLOSED,
148-
};
149-
var alert7: Alert = {
150-
id: 7,
151-
originalCreatedAt: "2023-09-11T12:00:00Z",
152-
section: "math-1410-002",
153-
alertLastSent: "2023-09-11T12:00:00Z",
154-
status: SectionStatus.OPEN,
155-
actions: AlertAction.ONALERT,
156-
closedNotif: AlertAction.ONCLOSED,
157-
};
158-
var alert8: Alert = {
159-
id: 8,
160-
originalCreatedAt: "2023-09-11T12:00:00Z",
161-
section: "stat-4100-001",
162-
alertLastSent: "2023-09-11T12:00:00Z",
163-
status: SectionStatus.OPEN,
164-
actions: AlertAction.ONALERT,
165-
closedNotif: AlertAction.ONCLOSED,
166-
};
167-
var testAlerts: Alert[];
168-
testAlerts = [
169-
alert1,
170-
alert2,
171-
alert3,
172-
alert4,
173-
alert5,
174-
alert6,
175-
alert7,
176-
alert8,
177-
];
95+
let rowNum = 0;
17896

17997
useEffect(() => {
18098
setNumSelected(
@@ -195,24 +113,16 @@ export const ManageAlert = ({
195113
);
196114
};
197115

198-
let rowNum = 0;
199-
200116
/**
201117
* Returns alerts grouped by course
202118
* @return grouped alerts
203119
*/
204-
const groupedAlerts = testAlerts
205-
.sort((a, b) => a.section.localeCompare(b.section))
206-
.reduce((res, obj) => {
207-
const [courseName, midNum, endNum] = obj.section.split("-");
208-
if (res[`${courseName}-${midNum}`]) {
209-
res[`${courseName}-${midNum}`].push(obj);
210-
} else {
211-
res[`${courseName}-${midNum}`] = [obj];
212-
}
213-
214-
return res;
215-
}, {});
120+
const groupedAlerts = groupByProperty(
121+
alerts,
122+
(a, b) => a.section.localeCompare(b.section),
123+
"-",
124+
(obj) => obj.section
125+
);
216126

217127
return (
218128
<Container>
@@ -229,18 +139,15 @@ export const ManageAlert = ({
229139
/>
230140
<AlertGrid>
231141
{Object.keys(groupedAlerts).map((key) => {
232-
rowNum++;
233142
return (
234143
<>
235-
<AlertHeader course={key} rownum={rowNum} />
144+
<AlertHeader courseCode={key} rowNum={++rowNum} />
236145
{groupedAlerts[key]?.map?.((alert) => {
237-
console.log(alert);
238-
rowNum++;
239146
return (
240147
<AlertItem
241148
key={alert.id}
242149
checked={alertSel[alert.id]}
243-
rownum={rowNum}
150+
rowNum={++rowNum}
244151
alertLastSent={alert.alertLastSent}
245152
course={alert.section}
246153
status={alert.status}

frontend/alert/util.ts

+32
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,35 @@ export const mapActivityToString = (activity) => {
1515

1616
return activity in activityStringMap ? activityStringMap[activity] : "";
1717
};
18+
19+
export function groupByProperty(
20+
array,
21+
sortingFn,
22+
splitPattern,
23+
keyExtractor,
24+
activityExtractor = (obj) => undefined
25+
) {
26+
return array.sort(sortingFn).reduce((res, obj) => {
27+
const key = keyExtractor(obj);
28+
const activity = activityExtractor(obj);
29+
const [courseName, midNum, endNum] = key.split(splitPattern);
30+
if (activity) {
31+
if (res[`${courseName}-${midNum}`]) {
32+
if (res[`${courseName}-${midNum}`][activity]) {
33+
res[`${courseName}-${midNum}`][activity].push(obj);
34+
} else {
35+
res[`${courseName}-${midNum}`][activity] = [obj];
36+
}
37+
} else {
38+
res[`${courseName}-${midNum}`] = { [activity]: [obj] };
39+
}
40+
} else {
41+
if (res[`${courseName}-${midNum}`]) {
42+
res[`${courseName}-${midNum}`].push(obj);
43+
} else {
44+
res[`${courseName}-${midNum}`] = [obj];
45+
}
46+
}
47+
return res;
48+
}, {});
49+
}

0 commit comments

Comments
 (0)