Skip to content

Commit f9390e9

Browse files
committed
Refactor: Improve code formatting and consistency across leaderboard components
1 parent 5c29fbe commit f9390e9

File tree

12 files changed

+113
-55
lines changed

12 files changed

+113
-55
lines changed

src/commons/assessmentWorkspace/AssessmentWorkspace.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
237237
*/
238238
useEffect(() => {
239239
checkWorkspaceReset();
240-
if (assessment != undefined && question.type == "voting"){
240+
if (assessment != undefined && question.type == 'voting') {
241241
dispatch(LeaderboardActions.setWorkspaceInitialRun(votingId));
242242
}
243243
}, [dispatch, assessment]);

src/commons/sagas/LeaderboardSaga.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
getAllContests,
1010
getAllTotalXp,
1111
getContestPopularVoteLeaderboard,
12-
getContestScoreLeaderboard} from './RequestsSaga';
12+
getContestScoreLeaderboard
13+
} from './RequestsSaga';
1314

1415
const LeaderboardSaga = combineSagaHandlers(LeaderboardActions, {
1516
getAllUsersXp: function* () {
@@ -51,7 +52,7 @@ const LeaderboardSaga = combineSagaHandlers(LeaderboardActions, {
5152
if (contests) {
5253
yield put(actions.saveContests(contests));
5354
}
54-
},
55+
}
5556
});
5657

5758
export default LeaderboardSaga;

src/commons/sagas/RequestsSaga.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { call } from 'redux-saga/effects';
22
import { backendParamsToProgressStatus } from 'src/features/grading/GradingUtils';
3-
import { ContestLeaderboardRow, LeaderboardContestDetails, LeaderboardRow } from 'src/features/leaderboard/LeaderboardTypes';
3+
import {
4+
ContestLeaderboardRow,
5+
LeaderboardContestDetails,
6+
LeaderboardRow
7+
} from 'src/features/leaderboard/LeaderboardTypes';
48
import { OptionType } from 'src/pages/academy/teamFormation/subcomponents/TeamFormationForm';
59

610
import {
@@ -557,7 +561,9 @@ export const getContestPopularVoteLeaderboard = async (
557561
/**
558562
* GET /courses/{courseId}/all_contests
559563
*/
560-
export const getAllContests = async (tokens: Tokens): Promise<LeaderboardContestDetails[] | null> => {
564+
export const getAllContests = async (
565+
tokens: Tokens
566+
): Promise<LeaderboardContestDetails[] | null> => {
561567
const resp = await request(`${courseId()}/all_contests`, 'GET', {
562568
...tokens
563569
});

src/features/leaderboard/LeaderboardActions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { createActions } from 'src/commons/redux/utils';
22

3-
import { ContestLeaderboardRow, LeaderboardContestDetails, LeaderboardRow } from './LeaderboardTypes';
3+
import {
4+
ContestLeaderboardRow,
5+
LeaderboardContestDetails,
6+
LeaderboardRow
7+
} from './LeaderboardTypes';
48

59
const LeaderboardActions = createActions('leaderboard', {
610
getAllUsersXp: 0,

src/features/leaderboard/LeaderboardReducer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ export const LeaderboardReducer: Reducer<LeaderboardState, SourceActionType> = c
3232
})
3333
.addCase(LeaderboardActions.resetWorkspaceInitialRun, (state, action) => {
3434
state.initialRun[action.payload] = false;
35-
})
35+
});
3636
}
3737
);

src/features/leaderboard/LeaderboardTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type LeaderboardState = {
2424
contestPopularVote: ContestLeaderboardRow[];
2525
code: string;
2626
contests: LeaderboardContestDetails[];
27-
initialRun: {[id: number]: boolean};
27+
initialRun: { [id: number]: boolean };
2828
};
2929

3030
export type LeaderboardContestDetails = {

src/pages/academy/groundControl/configureControls/ExportVoteLeaderboardButton.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ const ExportVoteLeaderboardButton: React.FC<Props> = ({ assessmentId }) => {
1414

1515
// onClick handler for fetching popular vote leaderboard, putting it into a grid and exporting data
1616
const exportPopularVoteLeaderboardToCsv = async () => {
17-
const popularVoteLeaderboard = await getPopularVoteLeaderboard(assessmentId, visibleEntries, tokens);
17+
const popularVoteLeaderboard = await getPopularVoteLeaderboard(
18+
assessmentId,
19+
visibleEntries,
20+
tokens
21+
);
1822
const gridContainer = document.createElement('div');
1923
const gridOptions: GridOptions = {
2024
rowData: popularVoteLeaderboard,

src/pages/leaderboard/subcomponents/ContestLeaderboard.tsx

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ type Props = {
2626
};
2727

2828
const ContestLeaderboard: React.FC<Props> = ({ type, contestID }) => {
29-
3029
const courseID = useTypedSelector(store => store.session.courseId);
3130
const dispatch = useDispatch();
3231

@@ -48,7 +47,9 @@ const ContestLeaderboard: React.FC<Props> = ({ type, contestID }) => {
4847
}, [dispatch, contestID, type]);
4948

5049
// Retrieve contests (For dropdown)
51-
const contestDetails: LeaderboardContestDetails[] = useTypedSelector(store => store.leaderboard.contests);
50+
const contestDetails: LeaderboardContestDetails[] = useTypedSelector(
51+
store => store.leaderboard.contests
52+
);
5253
const contestName = contestDetails.find(contest => contest.contest_id === contestID)?.title;
5354

5455
useEffect(() => {
@@ -70,22 +71,24 @@ const ContestLeaderboard: React.FC<Props> = ({ type, contestID }) => {
7071
// const top3 = rankedLeaderboard.slice(0, 3);
7172
// const rest = rankedLeaderboard.slice(3, Number(visibleEntries));
7273
const top3 = rankedLeaderboard.filter(row => row.rank <= 3);
73-
const rest = rankedLeaderboard.filter(row => row.rank <= Number(visibleEntries)).slice(top3.length);
74-
74+
const rest = rankedLeaderboard
75+
.filter(row => row.rank <= Number(visibleEntries))
76+
.slice(top3.length);
77+
7578
// Set sample profile pictures (Seeded random)
76-
function convertToRandomNumber(id: string): number {
77-
const str = id.slice(1);
78-
let hash = 0;
79-
for (let i = 0; i < str.length; i++) {
80-
const char = str.charCodeAt(i);
81-
hash = (hash << 5) - hash + char;
82-
}
83-
return (Math.abs(hash) % 7) + 1;
79+
function convertToRandomNumber(id: string): number {
80+
const str = id.slice(1);
81+
let hash = 0;
82+
for (let i = 0; i < str.length; i++) {
83+
const char = str.charCodeAt(i);
84+
hash = (hash << 5) - hash + char;
8485
}
85-
86-
rankedLeaderboard.map((row: ContestLeaderboardRow) => {
87-
row.avatar = `/assets/Sample Profile ${convertToRandomNumber(row.username)}.jpg`;
88-
})
86+
return (Math.abs(hash) % 7) + 1;
87+
}
88+
89+
rankedLeaderboard.map((row: ContestLeaderboardRow) => {
90+
row.avatar = `/assets/Sample Profile ${convertToRandomNumber(row.username)}.jpg`;
91+
});
8992

9093
// const workspaceLocation = 'assessment';
9194
const navigate = useNavigate();
@@ -167,21 +170,37 @@ const ContestLeaderboard: React.FC<Props> = ({ type, contestID }) => {
167170
<LeaderboardDropdown contests={contestDetails} />
168171

169172
{/* Export Button */}
170-
<LeaderboardExportButton type={type} contest={contestName} data={rankedLeaderboard}/>
173+
<LeaderboardExportButton type={type} contest={contestName} data={rankedLeaderboard} />
171174
</div>
172175

173176
{/* Leaderboard Table (Top 3) */}
174177
<div className="ag-theme-alpine">
175178
<h2>Contest Winners</h2>
176-
<AgGridReact rowData={top3} columnDefs={columnDefs} domLayout="autoHeight" rowHeight={60} pagination={top3.length > 10} paginationPageSize={10} paginationPageSizeSelector={[10]}/>
179+
<AgGridReact
180+
rowData={top3}
181+
columnDefs={columnDefs}
182+
domLayout="autoHeight"
183+
rowHeight={60}
184+
pagination={top3.length > 10}
185+
paginationPageSize={10}
186+
paginationPageSizeSelector={[10]}
187+
/>
177188
</div>
178189

179190
<div className="table-gap"></div>
180191

181192
{/* Honourable Mentions */}
182193
<div className="ag-theme-alpine">
183194
<h2>Honourable Mentions</h2>
184-
<AgGridReact rowData={rest} columnDefs={columnDefs} domLayout="autoHeight" rowHeight={60} pagination={true} paginationPageSize={10} paginationPageSizeSelector={[10, 25, 50]} />
195+
<AgGridReact
196+
rowData={rest}
197+
columnDefs={columnDefs}
198+
domLayout="autoHeight"
199+
rowHeight={60}
200+
pagination={true}
201+
paginationPageSize={10}
202+
paginationPageSizeSelector={[10, 25, 50]}
203+
/>
185204
</div>
186205
</div>
187206
);

src/pages/leaderboard/subcomponents/ContestLeaderboardWrapper.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@ const ContestLeaderboardWrapper: React.FC = () => {
1414
);
1515

1616
const dispatch = useDispatch();
17-
const contestAssessments: LeaderboardContestDetails[] = useTypedSelector(store => store.leaderboard.contests);
17+
const contestAssessments: LeaderboardContestDetails[] = useTypedSelector(
18+
store => store.leaderboard.contests
19+
);
1820

1921
useEffect(() => {
2022
dispatch(LeaderboardActions.getContests());
2123
}, [dispatch]);
22-
23-
const defaultContest =
24-
contestAssessments?.find(
25-
assessment => assessment.published
26-
) ?? null;
24+
25+
const defaultContest = contestAssessments?.find(assessment => assessment.published) ?? null;
2726

2827
const courseId = useTypedSelector(store => store.session.courseId);
2928
const baseLink = `/courses/${courseId}/leaderboard`;

src/pages/leaderboard/subcomponents/LeaderboardExportButton.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import 'src/styles/Leaderboard.scss';
22

33
import React from 'react';
44
import { useTypedSelector } from 'src/commons/utils/Hooks';
5-
import { ContestLeaderboardRow, LeaderboardRow } from 'src/features/leaderboard/LeaderboardTypes';
5+
import { ContestLeaderboardRow, LeaderboardRow } from 'src/features/leaderboard/LeaderboardTypes';
66

77
import { Role } from '../../../commons/application/ApplicationTypes';
88

@@ -13,13 +13,21 @@ type Props =
1313
const LeaderboardExportButton: React.FC<Props> = ({ type, contest, data }) => {
1414
const role = useTypedSelector(store => store.session.role);
1515
const exportCSV = () => {
16-
const headers = ['Rank', 'Name', 'Username', (type === "overall" ? 'XP' : 'Score'), (type === "overall" ? 'Achievements' : 'Submission Id')];
16+
const headers = [
17+
'Rank',
18+
'Name',
19+
'Username',
20+
type === 'overall' ? 'XP' : 'Score',
21+
type === 'overall' ? 'Achievements' : 'Submission Id'
22+
];
1723
const rows = data?.map(player => [
18-
player.rank,
19-
player.name,
20-
player.username,
21-
type === "overall" ? (player as LeaderboardRow).xp : (player as ContestLeaderboardRow).score,
22-
type === "overall" ? (player as LeaderboardRow).achievements : (player as ContestLeaderboardRow).submissionId
24+
player.rank,
25+
player.name,
26+
player.username,
27+
type === 'overall' ? (player as LeaderboardRow).xp : (player as ContestLeaderboardRow).score,
28+
type === 'overall'
29+
? (player as LeaderboardRow).achievements
30+
: (player as ContestLeaderboardRow).submissionId
2331
]);
2432

2533
// Combine headers and rows
@@ -28,7 +36,12 @@ const LeaderboardExportButton: React.FC<Props> = ({ type, contest, data }) => {
2836
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
2937
const link = document.createElement('a');
3038
link.href = URL.createObjectURL(blob);
31-
link.download = type === "overall" ? 'Overall Leaderboard.csv' : type === "popularvote" ? `${contest} Popular Vote Leaderboard.csv` : `${contest} Score Leaderboard.csv`; // Filename for download
39+
link.download =
40+
type === 'overall'
41+
? 'Overall Leaderboard.csv'
42+
: type === 'popularvote'
43+
? `${contest} Popular Vote Leaderboard.csv`
44+
: `${contest} Score Leaderboard.csv`; // Filename for download
3245
link.click();
3346
};
3447

0 commit comments

Comments
 (0)