Skip to content

Commit 9df08f0

Browse files
committed
Added question selection option by overall question score
1 parent d96bacc commit 9df08f0

File tree

4 files changed

+96
-12
lines changed

4 files changed

+96
-12
lines changed

src/components/Assessment.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export default class Assessment extends React.Component<IBaseProps, AssessmentSt
154154
return results.json();
155155
})
156156
.then(data => {
157-
this.setState({certification: data as Certification, session: this.getDefaultState().session, activeQuestion: -1});
157+
this.setState({certification: data as Certification, session: this.getDefaultState().session, activeQuestion: -1, selectedQuestions: {}});
158158
});
159159
}
160160

src/components/AssessmentHistory.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export default class AssessmentHistory extends React.PureComponent<IBaseProps, A
108108
sortable = sortable.map(arr => {
109109
let question = this.state.certification.questions.find(q => q.id === arr[0]);
110110

111-
return [question.key, arr[1], question.position]
111+
return [question.key || question.id, arr[1], question.position]
112112
});
113113

114114
sortable = sortable.sort((a, b) => (a[2] as number) - (b[2] as number));
@@ -163,6 +163,7 @@ export default class AssessmentHistory extends React.PureComponent<IBaseProps, A
163163
}]
164164
}}
165165
options={{
166+
166167
responsive: true,
167168
scales: {
168169
yAxes: [{

src/components/QuestionSelectionList.tsx

+91-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as React from "react";
2-
import { InputGroup, FormControl, ButtonToolbar, ToggleButtonGroup, ToggleButton } from "react-bootstrap";
2+
import { InputGroup, FormControl, ButtonToolbar, ToggleButtonGroup, ToggleButton, Button, DropdownButton, MenuItem } from "react-bootstrap";
33
import Question from "../model/Question";
44
import AssessmentSession from "../model/AssessmentSession";
55
import QuestionSelection from "./QuestionSelection";
66
import FieldGroup from "./FieldGroup";
77
import IBaseProps from "../domain/IBaseProps";
88
import IAssociativeArray from "../domain/IAssociativeArray";
9-
import { checkIfAnsweredCorrectly } from "../domain/AssessmentLogic";
9+
import { checkIfAnsweredCorrectly, calculateScorePerQuestion } from "../domain/AssessmentLogic";
1010

1111
export interface QuestionSelectionListProps extends IBaseProps {
1212
questions: Array<Question>;
@@ -15,21 +15,46 @@ export interface QuestionSelectionListProps extends IBaseProps {
1515
selectedQuestions: IAssociativeArray<boolean>;
1616
}
1717

18-
export default class QuestionSelectionList extends React.PureComponent<QuestionSelectionListProps, undefined> {
18+
enum FilterType {
19+
GreaterEqual,
20+
LessEqual
21+
}
22+
23+
interface QuestionSelectionListState {
24+
selectionByQuestionScoreEnabled: boolean;
25+
filterType: FilterType;
26+
filterValue: number;
27+
}
28+
29+
export default class QuestionSelectionList extends React.PureComponent<QuestionSelectionListProps, QuestionSelectionListState> {
1930
constructor(props: QuestionSelectionListProps) {
2031
super(props);
2132

33+
this.state = {
34+
selectionByQuestionScoreEnabled: false,
35+
filterType: FilterType.LessEqual,
36+
filterValue: 99
37+
};
38+
2239
this.selectNone = this.selectNone.bind(this);
2340
this.selectAll = this.selectAll.bind(this);
2441
this.selectAnsweredIncorrectlyLastTime = this.selectAnsweredIncorrectlyLastTime.bind(this);
42+
this.selectByQuestionScore = this.selectByQuestionScore.bind(this);
43+
this.showByQuestionScoreFilter = this.showByQuestionScoreFilter.bind(this);
44+
this.hideByQuestionScoreFilter = this.hideByQuestionScoreFilter.bind(this);
45+
this.setFilterToLessEqual = this.setFilterToLessEqual.bind(this);
46+
this.setFilterToGreaterEqual = this.setFilterToGreaterEqual.bind(this);
47+
this.setFilterValue = this.setFilterValue.bind(this);
2548
}
2649

2750
selectNone(e: any){
28-
this.props.onSelectionChange(this.props.questions.reduce((acc, val) => { acc[val.id] = false; return acc; }, {} as IAssociativeArray<boolean>))
51+
this.props.onSelectionChange(this.props.questions.reduce((acc, val) => { acc[val.id] = false; return acc; }, {} as IAssociativeArray<boolean>));
52+
this.hideByQuestionScoreFilter();
2953
}
3054

3155
selectAll(e: any){
32-
this.props.onSelectionChange(this.props.questions.reduce((acc, val) => { acc[val.id] = true; return acc; }, {} as IAssociativeArray<boolean>))
56+
this.props.onSelectionChange(this.props.questions.reduce((acc, val) => { acc[val.id] = true; return acc; }, {} as IAssociativeArray<boolean>));
57+
this.hideByQuestionScoreFilter();
3358
}
3459

3560
selectAnsweredIncorrectlyLastTime(e: any){
@@ -41,21 +66,79 @@ export default class QuestionSelectionList extends React.PureComponent<QuestionS
4166
let lastSession = this.props.previousSessions[0];
4267
let incorrectLastTime = lastSession.certification.questions.filter(q => !checkIfAnsweredCorrectly(q.answers, lastSession.answers[q.id].reduce((acc, val) => { acc[val] = true; return acc; }, { } as IAssociativeArray<boolean>)));
4368

44-
this.props.onSelectionChange(this.props.questions.reduce((acc, val) => { acc[val.id] = incorrectLastTime.some(q => q.id === val.id); return acc; }, {} as IAssociativeArray<boolean>))
69+
this.props.onSelectionChange(this.props.questions.reduce((acc, val) => { acc[val.id] = incorrectLastTime.some(q => q.id === val.id); return acc; }, {} as IAssociativeArray<boolean>));
70+
this.hideByQuestionScoreFilter();
71+
}
72+
73+
selectByQuestionScore(e: any){
74+
let ratios = calculateScorePerQuestion(this.props.previousSessions);
75+
76+
// Sorted by created on descending in SQL query
77+
let filteredRatios = Object.keys(ratios).filter(key => this.state.filterType === FilterType.LessEqual ? ratios[key] <= this.state.filterValue : ratios[key] >= this.state.filterValue );
78+
this.props.onSelectionChange(this.props.questions.reduce((acc, val) => { acc[val.id] = filteredRatios.some(q => q === val.id); return acc; }, {} as IAssociativeArray<boolean>));
79+
}
80+
81+
hideByQuestionScoreFilter() {
82+
this.setState({
83+
selectionByQuestionScoreEnabled: false
84+
});
85+
}
86+
87+
showByQuestionScoreFilter(e: any) {
88+
if (!e.target.checked) {
89+
return;
90+
}
91+
92+
this.setState({
93+
selectionByQuestionScoreEnabled: true
94+
});
95+
}
96+
97+
setFilterToGreaterEqual () {
98+
this.setState({
99+
filterType: FilterType.GreaterEqual
100+
});
101+
}
102+
103+
setFilterToLessEqual () {
104+
this.setState({
105+
filterType: FilterType.LessEqual
106+
});
107+
}
108+
109+
setFilterValue (e: any) {
110+
this.setState({
111+
filterValue: parseInt(e.target.value)
112+
});
45113
}
46114

47115
render(){
48116
return (
49117
<div>
50118
<p>Please select the questions you want to train during this assessment</p>
51-
<ButtonToolbar>
119+
120+
<ButtonToolbar style={{"padding-bottom": "20px"}}>
52121
<ToggleButtonGroup type="radio" name="options" defaultValue={1}>
53122
<ToggleButton onClick={this.selectNone} value={1}>None</ToggleButton>
54123
<ToggleButton onClick={this.selectAll} value={2}>All</ToggleButton>
55124
<ToggleButton disabled={!this.props.previousSessions || !this.props.previousSessions.length} onClick={this.selectAnsweredIncorrectlyLastTime} value={3}>Answered Incorrectly Last Time</ToggleButton>
125+
<ToggleButton disabled={!this.props.previousSessions || !this.props.previousSessions.length} onClick={this.showByQuestionScoreFilter} value={4}>Filter by Question Score</ToggleButton>
56126
</ToggleButtonGroup>
57127
</ButtonToolbar>
58-
<br />
128+
129+
{this.state.selectionByQuestionScoreEnabled &&
130+
<div style={{"padding-bottom": "20px"}}>
131+
<InputGroup style={{"padding-bottom": "10px"}}>
132+
<DropdownButton defaultValue="1" componentClass={InputGroup.Button} id="input-dropdown" title={this.state.filterType === FilterType.LessEqual ? "Less Equal" : "Greater Equal"}>
133+
<MenuItem onClick={this.setFilterToLessEqual} key="1">Less Equal</MenuItem>
134+
<MenuItem onClick={this.setFilterToGreaterEqual} key="2">Greater Equal</MenuItem>
135+
</DropdownButton>
136+
<FormControl type="number" value={this.state.filterValue} onChange={this.setFilterValue} />
137+
</InputGroup>
138+
<Button onClick={this.selectByQuestionScore}>Apply</Button>
139+
</div>
140+
}
141+
59142
{
60143
this.props.questions.map(q => <QuestionSelection key={q.id} question={q} isSelected={this.props.selectedQuestions[q.id]} onSelectionChange={this.props.onSelectionChange} />)
61144
}

src/components/SessionRecap.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ export default class SessionRecap extends React.PureComponent<SessionRecapProps,
7171
datasets: [{
7272
label: `Session Score`,
7373
borderWidth: 1,
74-
backgroundColor: ['#008000', '#FF6384'],
75-
hoverBackgroundColor: ['#008000', '#FF6384'],
74+
backgroundColor: ['#008000', '#FF0000'],
75+
hoverBackgroundColor: ['#008000', '#FF0000'],
7676
data: [correctAnswerCount, incorrectAnswerCount]
7777
}]
7878
}}

0 commit comments

Comments
 (0)