1
1
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" ;
3
3
import Question from "../model/Question" ;
4
4
import AssessmentSession from "../model/AssessmentSession" ;
5
5
import QuestionSelection from "./QuestionSelection" ;
6
6
import FieldGroup from "./FieldGroup" ;
7
7
import IBaseProps from "../domain/IBaseProps" ;
8
8
import IAssociativeArray from "../domain/IAssociativeArray" ;
9
- import { checkIfAnsweredCorrectly } from "../domain/AssessmentLogic" ;
9
+ import { checkIfAnsweredCorrectly , calculateScorePerQuestion } from "../domain/AssessmentLogic" ;
10
10
11
11
export interface QuestionSelectionListProps extends IBaseProps {
12
12
questions : Array < Question > ;
@@ -15,21 +15,46 @@ export interface QuestionSelectionListProps extends IBaseProps {
15
15
selectedQuestions : IAssociativeArray < boolean > ;
16
16
}
17
17
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 > {
19
30
constructor ( props : QuestionSelectionListProps ) {
20
31
super ( props ) ;
21
32
33
+ this . state = {
34
+ selectionByQuestionScoreEnabled : false ,
35
+ filterType : FilterType . LessEqual ,
36
+ filterValue : 99
37
+ } ;
38
+
22
39
this . selectNone = this . selectNone . bind ( this ) ;
23
40
this . selectAll = this . selectAll . bind ( this ) ;
24
41
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 ) ;
25
48
}
26
49
27
50
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 ( ) ;
29
53
}
30
54
31
55
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 ( ) ;
33
58
}
34
59
35
60
selectAnsweredIncorrectlyLastTime ( e : any ) {
@@ -41,21 +66,79 @@ export default class QuestionSelectionList extends React.PureComponent<QuestionS
41
66
let lastSession = this . props . previousSessions [ 0 ] ;
42
67
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 > ) ) ) ;
43
68
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
+ } ) ;
45
113
}
46
114
47
115
render ( ) {
48
116
return (
49
117
< div >
50
118
< p > Please select the questions you want to train during this assessment</ p >
51
- < ButtonToolbar >
119
+
120
+ < ButtonToolbar style = { { "padding-bottom" : "20px" } } >
52
121
< ToggleButtonGroup type = "radio" name = "options" defaultValue = { 1 } >
53
122
< ToggleButton onClick = { this . selectNone } value = { 1 } > None</ ToggleButton >
54
123
< ToggleButton onClick = { this . selectAll } value = { 2 } > All</ ToggleButton >
55
124
< 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 >
56
126
</ ToggleButtonGroup >
57
127
</ 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
+
59
142
{
60
143
this . props . questions . map ( q => < QuestionSelection key = { q . id } question = { q } isSelected = { this . props . selectedQuestions [ q . id ] } onSelectionChange = { this . props . onSelectionChange } /> )
61
144
}
0 commit comments