Skip to content

Commit 782e273

Browse files
authored
Added a button for exporting results from the results page on the UI. (#1644)
Closes SoftUni-Internal/exam-systems-issues#1719
1 parent 41492d4 commit 782e273

File tree

5 files changed

+62
-14
lines changed

5 files changed

+62
-14
lines changed

Servers/UI/OJS.Servers.Ui/ClientApp/src/components/administration/common/tabs/TabsInView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const TabsInView = (props: ITabsInViewProps) => {
2222
return (
2323
<Slide direction="left" in mountOnEnter unmountOnExit timeout={300}>
2424
<Box>
25-
{form && form()}
25+
{form?.()}
2626
<Box sx={{ padding: '2rem' }}>
2727
<Tabs
2828
sx={{ minWidth: '100%', display: 'flex', justifyContent: 'space-around' }}

Servers/UI/OJS.Servers.Ui/ClientApp/src/components/submissions/submission-grid-row/SubmissionGridRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ const SubmissionGridRow = ({
310310
</Popover>
311311
</td>
312312
)
313-
: <td />
313+
: <td aria-hidden="true" />
314314
: null
315315
}
316316
{

Servers/UI/OJS.Servers.Ui/ClientApp/src/pages/administration-new/contests/AdministrationContests.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,29 @@ const AdministrationContestsPage = () => {
103103
}
104104
}, [ searchParams, hasProcessedParams, setSearchParams ]);
105105

106+
// Handle query parameters for exporting contest results to excel
107+
useEffect(() => {
108+
const exportType = searchParams.get('exportType');
109+
const contestIdParam = searchParams.get('contestId');
110+
111+
if (exportType && contestIdParam && !hasProcessedParams) {
112+
const parsedId = Number(contestIdParam);
113+
const parsedType = exportType === 'compete'
114+
? 0
115+
: 1;
116+
117+
setContestId(parsedId);
118+
setExcelExportType(parsedType);
119+
exportResults({ id: parsedId, type: parsedType });
120+
121+
const newSearchParams = new URLSearchParams(searchParams);
122+
newSearchParams.delete('exportType');
123+
newSearchParams.delete('contestId');
124+
setSearchParams(newSearchParams);
125+
setHasProcessedParams(true);
126+
}
127+
}, [ searchParams, hasProcessedParams, setSearchParams, exportResults ]);
128+
106129
const onEditClick = (id: number) => {
107130
setOpenEditContestModal(true);
108131
setContestId(id);

Servers/UI/OJS.Servers.Ui/ClientApp/src/pages/contest-results/ContestResultPage.module.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,14 @@
1919
.paginationControlsLower {
2020
padding: spacings.$sp-8 0 spacings.$sp-16 0;
2121
}
22+
23+
.actionsWrapper {
24+
display: flex;
25+
align-items: center;
26+
justify-content: space-between;
27+
}
28+
29+
.exportResultsButton {
30+
margin: 0 0 1.2rem;
31+
place-self: end;
32+
}

Servers/UI/OJS.Servers.Ui/ClientApp/src/pages/contest-results/ContestResultsPage.tsx

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import React, { useEffect, useMemo } from 'react';
22
import { useParams } from 'react-router';
33
import isNil from 'lodash/isNil';
4+
import { CONTESTS_PATH } from 'src/common/urls/administration-urls';
45
import BackToTop from 'src/components/common/back-to-top/BackToTop';
6+
import AdministrationLink from 'src/components/guidelines/buttons/AdministrationLink';
57

68
import { ContestParticipationType, ContestResultType } from '../../common/constants';
79
import { contestParticipationType } from '../../common/contest-helpers';
@@ -110,30 +112,42 @@ const ContestResultsPage = () => {
110112
Results For
111113
{' '}
112114
<LinkButton
113-
to={getContestsDetailsPageUrl({ contestId: Number(contestId!), contestName: contestResults?.name })}
115+
to={getContestsDetailsPageUrl({
116+
contestId: Number(contestId!),
117+
contestName: contestResults?.name,
118+
})}
114119
text={contestResults?.name}
115120
type={LinkButtonType.plain}
116121
className={styles.contestName}
117122
/>
118123
</Heading>
119-
<PaginationControls
120-
isDataFetching={isFetching}
121-
count={contestResults?.pagedResults.pagesCount ?? 0}
122-
page={selectedPage}
123-
onChange={(page:number) => {
124-
searchParams.set('page', page.toString());
125-
setSearchParams(searchParams);
126-
}}
127-
className={`${styles.paginationControlsUpper}`}
128-
/>
124+
<div className={styles.actionsWrapper}>
125+
<PaginationControls
126+
isDataFetching={isFetching}
127+
count={contestResults?.pagedResults.pagesCount ?? 0}
128+
page={selectedPage}
129+
onChange={(page: number) => {
130+
searchParams.set('page', page.toString());
131+
setSearchParams(searchParams);
132+
}}
133+
className={`${styles.paginationControlsUpper}`}
134+
/>
135+
<div className={styles.exportResultsButton}>
136+
<AdministrationLink
137+
text="Export Results"
138+
type={LinkButtonType.primary}
139+
to={`/${CONTESTS_PATH}?exportType=${participationType.toLowerCase()}&contestId=${contestId}`}
140+
/>
141+
</div>
142+
</div>
129143
<ContestResultsGrid
130144
items={contestResults ?? null}
131145
/>
132146
<PaginationControls
133147
isDataFetching={isFetching}
134148
count={contestResults?.pagedResults.pagesCount ?? 0}
135149
page={selectedPage}
136-
onChange={(page:number) => {
150+
onChange={(page: number) => {
137151
searchParams.set('page', page.toString());
138152
setSearchParams(searchParams);
139153
}}

0 commit comments

Comments
 (0)