Skip to content

Commit a6ec1a5

Browse files
committed
Refactor interact button and move to separate file
1 parent 07acff2 commit a6ec1a5

File tree

2 files changed

+92
-83
lines changed

2 files changed

+92
-83
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { Button } from '@blueprintjs/core';
2+
import { IconName, IconNames } from '@blueprintjs/icons';
3+
import { useDispatch } from 'react-redux';
4+
import { NavLink } from 'react-router';
5+
6+
import SessionActions from '../application/actions/SessionActions';
7+
import { filterNotificationsByAssessment } from '../notificationBadge/NotificationBadgeHelper';
8+
import Constants from '../utils/Constants';
9+
import { useTypedSelector } from '../utils/Hooks';
10+
import { assessmentTypeLink } from '../utils/ParamParseHelper';
11+
import { AssessmentOverview, AssessmentStatuses } from './AssessmentTypes';
12+
13+
type Props = {
14+
overview: AssessmentOverview;
15+
};
16+
17+
const AssessmentInteractButton: React.FC<Props> = ({ overview }) => {
18+
const courseId = useTypedSelector(state => state.session.courseId);
19+
const dispatch = useDispatch();
20+
const { icon, label, optionalLabel } = createButtonConfiguration(overview.status);
21+
22+
return (
23+
<NavLink
24+
to={`/courses/${courseId}/${assessmentTypeLink(overview.type)}/${overview.id.toString()}/${
25+
Constants.defaultQuestionId
26+
}`}
27+
>
28+
<Button
29+
icon={icon}
30+
minimal={true}
31+
onClick={() =>
32+
dispatch(
33+
SessionActions.acknowledgeNotifications(filterNotificationsByAssessment(overview.id))
34+
)
35+
}
36+
>
37+
<span data-testid="Assessment-Attempt-Button">{label}</span>
38+
{optionalLabel && <span className="custom-hidden-xxxs">{optionalLabel}</span>}
39+
</Button>
40+
</NavLink>
41+
);
42+
};
43+
44+
type ButtonConfiguration = {
45+
icon: IconName;
46+
label: string;
47+
optionalLabel?: string;
48+
};
49+
50+
const createButtonConfiguration = (
51+
overviewStatus: AssessmentOverview['status']
52+
): ButtonConfiguration => {
53+
let icon: IconName;
54+
let label: string;
55+
let optionalLabel: string | undefined;
56+
57+
switch (overviewStatus) {
58+
case AssessmentStatuses.not_attempted:
59+
icon = IconNames.PLAY;
60+
label = 'Attempt';
61+
break;
62+
case AssessmentStatuses.attempting:
63+
icon = IconNames.PLAY;
64+
label = 'Continue';
65+
optionalLabel = ' Attempt';
66+
break;
67+
case AssessmentStatuses.attempted:
68+
icon = IconNames.EDIT;
69+
label = 'Review';
70+
optionalLabel = ' Attempt';
71+
break;
72+
case AssessmentStatuses.submitted:
73+
icon = IconNames.EYE_OPEN;
74+
label = 'Review';
75+
optionalLabel = ' Submission';
76+
break;
77+
default:
78+
// If we reach this case, backend data did not fit IAssessmentOverview
79+
icon = IconNames.PLAY;
80+
label = 'Review';
81+
break;
82+
}
83+
84+
return { icon, label, optionalLabel };
85+
};
86+
87+
export default AssessmentInteractButton;

src/commons/assessment/AssessmentOverviewCard.tsx

Lines changed: 5 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,16 @@
1-
import {
2-
Button,
3-
Card,
4-
Elevation,
5-
H4,
6-
H6,
7-
Icon,
8-
Intent,
9-
Position,
10-
Text,
11-
Tooltip
12-
} from '@blueprintjs/core';
1+
import { Card, Elevation, H4, H6, Icon, Intent, Position, Text, Tooltip } from '@blueprintjs/core';
132
import { IconName, IconNames } from '@blueprintjs/icons';
143
import classNames from 'classnames';
15-
import { useDispatch } from 'react-redux';
16-
import { NavLink } from 'react-router';
174
import classes from 'src/styles/Academy.module.scss';
185

196
import defaultCoverImage from '../../assets/default_cover_image.jpg';
20-
import SessionActions from '../application/actions/SessionActions';
217
import Markdown from '../Markdown';
228
import NotificationBadge from '../notificationBadge/NotificationBadge';
239
import { filterNotificationsByAssessment } from '../notificationBadge/NotificationBadgeHelper';
24-
import Constants from '../utils/Constants';
2510
import { beforeNow, getPrettyDate, getPrettyDateAfterHours } from '../utils/DateHelper';
26-
import { useResponsive, useTypedSelector } from '../utils/Hooks';
27-
import { assessmentTypeLink } from '../utils/ParamParseHelper';
28-
import { AssessmentOverview, AssessmentStatuses } from './AssessmentTypes';
11+
import { useResponsive } from '../utils/Hooks';
12+
import AssessmentInteractButton from './AssessmentInteractButton';
13+
import { AssessmentOverview } from './AssessmentTypes';
2914

3015
type AssessmentOverviewCardProps = {
3116
/** The assessment overview to display */
@@ -41,9 +26,7 @@ type AssessmentOverviewCardProps = {
4126
makeSubmissionButton: (overview: AssessmentOverview, index: number) => JSX.Element;
4227
};
4328

44-
/**
45-
* A card to display `AssessmentOverview`s.
46-
*/
29+
/** A card to display `AssessmentOverview`s. */
4730
const AssessmentOverviewCard: React.FC<AssessmentOverviewCardProps> = ({
4831
overview,
4932
index,
@@ -157,67 +140,6 @@ const AssessmentOverviewCardTitle: React.FC<AssessmentOverviewCardTitleProps> =
157140
</div>
158141
);
159142

160-
type AssessmentInteractButtonProps = {
161-
overview: AssessmentOverview;
162-
};
163-
164-
const AssessmentInteractButton: React.FC<AssessmentInteractButtonProps> = ({ overview }) => {
165-
let icon: IconName;
166-
let label: string;
167-
let optionalLabel: string = '';
168-
169-
switch (overview.status) {
170-
case AssessmentStatuses.not_attempted:
171-
icon = IconNames.PLAY;
172-
label = 'Attempt';
173-
break;
174-
case AssessmentStatuses.attempting:
175-
icon = IconNames.PLAY;
176-
label = 'Continue';
177-
optionalLabel = ' Attempt';
178-
break;
179-
case AssessmentStatuses.attempted:
180-
icon = IconNames.EDIT;
181-
label = 'Review';
182-
optionalLabel = ' Attempt';
183-
break;
184-
case AssessmentStatuses.submitted:
185-
icon = IconNames.EYE_OPEN;
186-
label = 'Review';
187-
optionalLabel = ' Submission';
188-
break;
189-
default:
190-
// If we reach this case, backend data did not fit IAssessmentOverview
191-
icon = IconNames.PLAY;
192-
label = 'Review';
193-
break;
194-
}
195-
196-
const courseId = useTypedSelector(state => state.session.courseId);
197-
const dispatch = useDispatch();
198-
199-
return (
200-
<NavLink
201-
to={`/courses/${courseId}/${assessmentTypeLink(overview.type)}/${overview.id.toString()}/${
202-
Constants.defaultQuestionId
203-
}`}
204-
>
205-
<Button
206-
icon={icon}
207-
minimal={true}
208-
onClick={() =>
209-
dispatch(
210-
SessionActions.acknowledgeNotifications(filterNotificationsByAssessment(overview.id))
211-
)
212-
}
213-
>
214-
<span data-testid="Assessment-Attempt-Button">{label}</span>
215-
<span className="custom-hidden-xxxs">{optionalLabel}</span>
216-
</Button>
217-
</NavLink>
218-
);
219-
};
220-
221143
const showGradingTooltip = (isGradingPublished: boolean) => {
222144
let iconName: IconName;
223145
let intent: Intent;

0 commit comments

Comments
 (0)