Skip to content

Commit c3145d1

Browse files
remo5000ning-y
authored andcommitted
Redesign MCQ choosing (#263)
* Use minimal, spread out mcq options - One option on each line, spaced out. - minimal button that only shows a differnce when it is active. * Make MCQ not display question Additionally: - Spread out the options * Remove mcq question css * Add solution and hint types * Add getButtonIntent function * Fix import order * Update mock questions * Add notification for ungraded questions * Format files * Make mock question's graded hints null * Make review changes
1 parent 0021d31 commit c3145d1

File tree

4 files changed

+83
-31
lines changed

4 files changed

+83
-31
lines changed

src/components/assessment/assessmentShape.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export interface IProgrammingQuestion extends IQuestion {
5252
}
5353

5454
export interface IMCQQuestion extends IQuestion {
55+
solution: number | null
5556
answer: number | null
5657
choices: MCQChoice[]
5758
type: 'mcq'
@@ -67,7 +68,7 @@ export interface IQuestion {
6768

6869
export type MCQChoice = {
6970
content: string
70-
hint: string
71+
hint: string | null
7172
}
7273

7374
/* The two kinds of Questions available */

src/components/workspace/MCQChooser.tsx

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { Button, Card, Text, Tooltip } from '@blueprintjs/core'
1+
import { Button, Card, Intent, Text } from '@blueprintjs/core'
22
import * as React from 'react'
33

4+
import { showSuccessMessage, showWarningMessage } from '../../utils/notification'
45
import { IMCQQuestion } from '../assessment/assessmentShape'
56

67
export interface IMCQChooserProps {
@@ -23,26 +24,19 @@ class MCQChooser extends React.PureComponent<IMCQChooserProps, State> {
2324
const options = this.props.mcq.choices.map((choice, i) => (
2425
<Button
2526
key={i}
26-
className="mcq-option col-xs-6"
27+
className="mcq-option col-xs-12"
2728
active={i === this.state.mcqOption}
29+
intent={this.getButtonIntent(i, this.state.mcqOption, this.props.mcq.solution)}
2830
onClick={this.onButtonClickFactory(i)}
31+
minimal={true}
2932
>
30-
<Tooltip content={choice.hint}>
31-
<Text className="Text"> {choice.content} </Text>
32-
</Tooltip>
33+
<Text className="Text"> {choice.content} </Text>
3334
</Button>
3435
))
3536
return (
36-
<div className="MCQChooser">
37-
<Card className="mcq-content-parent row center-xs">
38-
<div className="col-xs-12">
39-
<div className="mcq-task-parent row center-xs ">
40-
<Card className="mcq-task col-xs-12" elevation={2}>
41-
<Text className="Text"> {this.props.mcq.content} </Text>
42-
</Card>
43-
</div>
44-
<div className="row mcq-options-parent center-xs">{options}</div>
45-
</div>
37+
<div className="MCQChooser row">
38+
<Card className="mcq-content-parent col-xs-12 middle-xs">
39+
<div className="row mcq-options-parent between-xs">{options}</div>
4640
</Card>
4741
</div>
4842
)
@@ -53,16 +47,49 @@ class MCQChooser extends React.PureComponent<IMCQChooserProps, State> {
5347
* and mcq submission with a given answer id.
5448
*
5549
* Post-condition: the local state will be updated to store the
56-
* mcq option selected.
50+
* mcq option selected, and a notification will be displayed with
51+
* a hint, if the question is ungraded.
5752
*
5853
* @param i the id of the answer
5954
*/
6055
private onButtonClickFactory = (i: number) => (e: any) => {
6156
this.props.handleMCQSubmit(i)
57+
if (this.props.mcq.solution && i === this.props.mcq.solution) {
58+
showSuccessMessage(this.props.mcq.choices[i].hint!, 4000)
59+
} else if (this.props.mcq.solution && i !== this.props.mcq.solution) {
60+
showWarningMessage(this.props.mcq.choices[i].hint!, 4000)
61+
}
6262
this.setState({
6363
mcqOption: i
6464
})
6565
}
66+
67+
/**
68+
* Handles the logic for what intent an MCQ option should show up as.
69+
* This is dependent on the presence of an actual solution (for ungraded assessments),
70+
* the current selection, and whether the selected option is active.
71+
*
72+
* @param currentOption the current button key, corresponding to a choice ID
73+
* @param chosenOption the mcq option that is chosen in the state, i.e what should show up as "selected"
74+
* @param solution the solution to the mcq, if any
75+
*/
76+
private getButtonIntent = (
77+
currentOption: number,
78+
chosenOption: number | null,
79+
solution: number | null
80+
): Intent => {
81+
const active = currentOption === chosenOption
82+
const correctOptionSelected = active && solution && currentOption === solution
83+
if (!solution) {
84+
return Intent.NONE
85+
} else if (active && correctOptionSelected) {
86+
return Intent.SUCCESS
87+
} else if (active && !correctOptionSelected) {
88+
return Intent.DANGER
89+
} else {
90+
return Intent.NONE
91+
}
92+
}
6693
}
6794

6895
export default MCQChooser

src/mocks/assessmentAPI.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export const mockAssessmentQuestions: Array<IProgrammingQuestion | IMCQQuestion>
153153
{
154154
answer: 3,
155155
content:
156-
'This is the 3rd question. Oddly enough, it is an MCQ question that uses the curves library!',
156+
'This is the 3rd question. Oddly enough, it is an ungraded MCQ question that uses the curves library!',
157157
choices: [
158158
{
159159
content: 'A',
@@ -174,7 +174,35 @@ export const mockAssessmentQuestions: Array<IProgrammingQuestion | IMCQQuestion>
174174
],
175175
id: 2,
176176
library: mockCurveLibrary,
177-
type: 'mcq'
177+
type: 'mcq',
178+
solution: 2
179+
},
180+
{
181+
answer: 3,
182+
content:
183+
'This is the 4rth question. Oddly enough, it is a graded MCQ question that uses the curves library!',
184+
choices: [
185+
{
186+
content: 'A',
187+
hint: null
188+
},
189+
{
190+
content: 'B',
191+
hint: null
192+
},
193+
{
194+
content: 'C',
195+
hint: null
196+
},
197+
{
198+
content: 'D',
199+
hint: null
200+
}
201+
],
202+
id: 2,
203+
library: mockCurveLibrary,
204+
type: 'mcq',
205+
solution: null
178206
}
179207
]
180208

src/styles/_workspace.scss

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,15 @@ $code-color-error: #ff4444;
8282
.mcq-content-parent {
8383
height: 100%;
8484
overflow: auto;
85-
}
86-
.mcq-options-parent {
87-
margin-bottom: 20px;
88-
}
89-
.mcq-option {
90-
// use of !important to override a 'not' selector by BluePrint
91-
background-color: $cadet-color-3 !important;
9285
padding: 20px;
93-
}
94-
.mcq-task-parent {
95-
margin-bottom: 20px;
96-
.pt-card {
97-
background-color: $cadet-color-3;
86+
.mcq-options-parent {
87+
height: 100%;
88+
.mcq-option {
89+
padding: 20px;
90+
}
91+
.mcq-option:focus {
92+
outline: 0;
93+
}
9894
}
9995
}
10096
.pt-card {

0 commit comments

Comments
 (0)