Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
zesje
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Réouven ASSOULY
zesje
Commits
d1649a3d
Commit
d1649a3d
authored
7 years ago
by
Thomas Roos
Browse files
Options
Downloads
Patches
Plain Diff
Refactor students page into seperate SearchPanel component
parent
2e4a8970
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
client/views/Students.js
+15
-140
15 additions, 140 deletions
client/views/Students.js
client/views/students/SearchPanel.jsx
+154
-0
154 additions, 0 deletions
client/views/students/SearchPanel.jsx
with
169 additions
and
140 deletions
client/views/Students.js
+
15
−
140
View file @
d1649a3d
import
React
from
'
react
'
;
import
getClosest
from
'
get-closest
'
;
import
Fuse
from
'
fuse.js
'
;
import
Mousetrap
from
'
mousetrap
'
;
import
NavBar
from
'
../components/NavBar
'
;
...
...
@@ -9,28 +8,13 @@ import Footer from '../components/Footer';
import
*
as
api
from
'
../api
'
;
import
StudentPanelBlock
from
'
./students/StudentPanelBlock.jsx
'
;
import
ProgressBar
from
'
./students/ProgressBar.jsx
'
;
import
SearchPanel
from
'
./students/SearchPanel.jsx
'
;
import
ExamSelector
from
'
./students/ExamSelector.jsx
'
;
import
AddModal
from
'
./students/AddModal.jsx
'
;
class
CheckStudents
extends
React
.
Component
{
students
=
[
{
id
:
0
,
firstName
:
""
,
lastName
:
""
,
email
:
""
}
];
state
=
{
search
:
{
input
:
''
,
selected
:
0
,
result
:
[]
},
exam
:
{
id
:
0
,
name
:
"
Loading...
"
,
...
...
@@ -96,16 +80,6 @@ class CheckStudents extends React.Component {
throw
err
})
api
.
get
(
'
students
'
)
.
then
(
students
=>
{
this
.
students
=
students
;
})
.
catch
(
err
=>
{
alert
(
'
failed to get students (see javascript console for details)
'
)
console
.
error
(
'
failed to get students:
'
,
err
)
throw
err
})
}
...
...
@@ -162,33 +136,6 @@ class CheckStudents extends React.Component {
}
}
search
=
(
event
)
=>
{
const
options
=
{
shouldSort
:
true
,
threshold
:
0.6
,
location
:
0
,
distance
:
100
,
maxPatternLength
:
32
,
minMatchCharLength
:
1
,
keys
:
[
"
id
"
,
"
firstName
"
,
"
lastName
"
]
};
const
fuse
=
new
Fuse
(
this
.
students
,
options
);
const
result
=
fuse
.
search
(
event
.
target
.
value
).
slice
(
0
,
10
);
this
.
setState
({
search
:
{
input
:
event
.
target
.
value
,
selected
:
0
,
result
:
result
}
})
}
setSubmission
=
()
=>
{
const
input
=
parseInt
(
this
.
state
.
submission
.
input
);
...
...
@@ -254,7 +201,7 @@ class CheckStudents extends React.Component {
validated
:
sub
.
validated
,
list
:
newList
}
},
this
.
listMatchedStudent
)
},
this
.
search
.
listMatchedStudent
)
})
.
catch
(
err
=>
{
alert
(
'
failed to get submission (see javascript console for details)
'
)
...
...
@@ -276,7 +223,7 @@ class CheckStudents extends React.Component {
imagePath
:
'
api/images/signature/
'
+
this
.
state
.
exam
.
id
+
'
/
'
+
subs
[
0
].
id
,
list
:
subs
}
},
this
.
listMatchedStudent
)
},
this
.
search
.
listMatchedStudent
)
})
.
catch
(
err
=>
{
alert
(
'
failed to get submissions (see javascript console for details)
'
)
...
...
@@ -285,43 +232,7 @@ class CheckStudents extends React.Component {
})
}
moveSelection
=
(
event
)
=>
{
if
(
event
.
keyCode
===
38
||
event
.
keyCode
===
40
)
{
event
.
preventDefault
();
let
sel
=
this
.
state
.
search
.
selected
;
if
(
event
.
keyCode
==
38
&&
sel
>
0
)
sel
--
;
if
(
event
.
keyCode
==
40
&&
sel
<
this
.
state
.
search
.
result
.
length
-
1
)
sel
++
;
this
.
setState
({
search
:
{
...
this
.
state
.
search
,
selected
:
sel
}
})
}
}
selectStudent
=
(
event
)
=>
{
if
(
event
.
target
.
selected
)
{
this
.
matchStudent
();
}
else
{
const
index
=
this
.
state
.
search
.
result
.
findIndex
(
result
=>
result
.
id
==
event
.
target
.
id
);
this
.
setState
({
search
:
{
...
this
.
state
.
search
,
selected
:
index
}
})
}
}
matchStudent
=
(
event
)
=>
{
if
(
event
)
event
.
preventDefault
();
const
stud
=
this
.
state
.
search
.
result
[
this
.
state
.
search
.
selected
];
if
(
!
stud
)
return
;
matchStudent
=
(
studID
)
=>
{
let
newList
=
this
.
state
.
submission
.
list
;
const
index
=
this
.
state
.
submission
.
index
;
...
...
@@ -329,12 +240,12 @@ class CheckStudents extends React.Component {
this
.
setState
({
submission
:
{
...
this
.
state
.
submission
,
studentID
:
stud
.
id
,
studentID
:
stud
ID
,
validated
:
true
}
},
this
.
nextUnchecked
)
api
.
put
(
'
submissions/
'
+
this
.
state
.
exam
.
id
+
'
/
'
+
this
.
state
.
submission
.
id
,
{
studentID
:
stud
.
id
})
api
.
put
(
'
submissions/
'
+
this
.
state
.
exam
.
id
+
'
/
'
+
this
.
state
.
submission
.
id
,
{
studentID
:
stud
ID
})
.
then
(
sub
=>
{
newList
[
index
]
=
sub
;
this
.
setState
({
...
...
@@ -351,24 +262,6 @@ class CheckStudents extends React.Component {
})
}
listMatchedStudent
=
()
=>
{
const
studIndex
=
this
.
students
.
findIndex
(
stud
=>
stud
.
id
===
this
.
state
.
submission
.
studentID
);
const
stud
=
studIndex
>
-
1
?
[
this
.
students
[
studIndex
]]
:
[];
this
.
setState
({
search
:
{
input
:
''
,
selected
:
0
,
result
:
stud
}
})
if
(
!
this
.
state
.
submission
.
validated
)
{
this
.
searchInput
.
focus
();
}
}
render
()
{
const
inputStyle
=
{
width
:
'
5em
'
...
...
@@ -394,31 +287,11 @@ class CheckStudents extends React.Component {
<
ExamSelector
exam
=
{
this
.
state
.
exam
}
selectExam
=
{
this
.
selectExam
}
/
>
<
/div
>
<
nav
className
=
"
panel
"
>
<
p
className
=
"
panel-heading
"
>
Students
<
/p
>
<
div
className
=
"
panel-block
"
>
<
form
onSubmit
=
{
this
.
matchStudent
}
>
<
p
className
=
"
control has-icons-left
"
>
<
input
className
=
"
input
"
type
=
"
text
"
ref
=
{(
input
)
=>
{
this
.
searchInput
=
input
;
}}
value
=
{
this
.
state
.
search
.
input
}
onChange
=
{
this
.
search
}
onKeyDown
=
{
this
.
moveSelection
}
/
>
<
span
className
=
"
icon is-left
"
>
<
i
className
=
"
fa fa-search
"
><
/i
>
<
/span
>
<
/p
>
<
/form
>
<
/div
>
{
this
.
state
.
search
.
result
.
map
((
student
,
index
)
=>
<
StudentPanelBlock
key
=
{
student
.
id
}
student
=
{
student
}
selected
=
{
index
===
this
.
state
.
search
.
selected
}
matched
=
{
student
.
id
===
this
.
state
.
submission
.
studentID
&&
this
.
state
.
submission
.
validated
}
selectStudent
=
{
this
.
selectStudent
}
/
>
)}
<
AddModal
/>
<
/nav
>
<
SearchPanel
ref
=
{(
search
)
=>
{
this
.
search
=
search
;
}}
matchStudent
=
{
this
.
matchStudent
}
studentID
=
{
this
.
state
.
submission
.
studentID
}
validated
=
{
this
.
state
.
submission
.
validated
}
/
>
<
/div
>
<
div
className
=
"
column
"
>
...
...
@@ -436,7 +309,8 @@ class CheckStudents extends React.Component {
<
div
className
=
"
control
"
>
<
button
type
=
"
submit
"
className
=
"
button is-info is-rounded is-hidden-mobile
"
onClick
=
{
this
.
prevUnchecked
}
>
unchecked
<
/button
>
<
button
type
=
"
submit
"
className
=
{
"
button
"
+
(
this
.
state
.
submission
.
validated
?
"
is-success
"
:
"
is-link
"
)}
onClick
=
{
this
.
prev
}
>
Previous
<
/button
>
<
button
type
=
"
submit
"
className
=
{
"
button
"
+
(
this
.
state
.
submission
.
validated
?
"
is-success
"
:
"
is-link
"
)}
onClick
=
{
this
.
prev
}
>
Previous
<
/button
>
<
/div
>
<
div
className
=
"
control
"
>
<
input
className
=
{
"
input is-rounded has-text-centered
"
+
(
this
.
state
.
submission
.
validated
?
"
is-success
"
:
"
is-link
"
)}
...
...
@@ -445,7 +319,8 @@ class CheckStudents extends React.Component {
onBlur
=
{
this
.
setSubmission
}
maxLength
=
"
4
"
size
=
"
6
"
style
=
{
inputStyle
}
/
>
<
/div
>
<
div
className
=
"
control
"
>
<
button
type
=
"
submit
"
className
=
{
"
button
"
+
(
this
.
state
.
submission
.
validated
?
"
is-success
"
:
"
is-link
"
)}
onClick
=
{
this
.
next
}
>
Next
<
/button
>
<
button
type
=
"
submit
"
className
=
{
"
button
"
+
(
this
.
state
.
submission
.
validated
?
"
is-success
"
:
"
is-link
"
)}
onClick
=
{
this
.
next
}
>
Next
<
/button
>
<
button
type
=
"
submit
"
className
=
"
button is-info is-rounded is-hidden-mobile
"
onClick
=
{
this
.
nextUnchecked
}
>
unchecked
<
/button
>
<
/div
>
...
...
This diff is collapsed.
Click to expand it.
client/views/students/SearchPanel.jsx
0 → 100644
+
154
−
0
View file @
d1649a3d
import
React
from
'
react
'
;
import
Fuse
from
'
fuse.js
'
;
import
*
as
api
from
'
../../api
'
;
import
StudentPanelBlock
from
'
./StudentPanelBlock.jsx
'
;
import
AddModal
from
'
./AddModal.jsx
'
;
class
SearchPanel
extends
React
.
Component
{
students
=
[
{
id
:
0
,
firstName
:
""
,
lastName
:
""
,
email
:
""
}
];
state
=
{
input
:
''
,
selected
:
0
,
result
:
[]
}
componentDidMount
=
()
=>
{
api
.
get
(
'
students
'
)
.
then
(
students
=>
{
this
.
students
=
students
;
})
.
catch
(
err
=>
{
alert
(
'
failed to get students (see javascript console for details)
'
)
console
.
error
(
'
failed to get students:
'
,
err
)
throw
err
})
}
search
=
(
event
)
=>
{
const
options
=
{
shouldSort
:
true
,
threshold
:
0.6
,
location
:
0
,
distance
:
100
,
maxPatternLength
:
32
,
minMatchCharLength
:
1
,
keys
:
[
"
id
"
,
"
firstName
"
,
"
lastName
"
]
};
const
fuse
=
new
Fuse
(
this
.
students
,
options
);
const
result
=
fuse
.
search
(
event
.
target
.
value
).
slice
(
0
,
10
);
this
.
setState
({
input
:
event
.
target
.
value
,
selected
:
0
,
result
:
result
})
}
moveSelection
=
(
event
)
=>
{
if
(
event
.
keyCode
===
38
||
event
.
keyCode
===
40
)
{
event
.
preventDefault
();
let
sel
=
this
.
state
.
selected
;
if
(
event
.
keyCode
==
38
&&
sel
>
0
)
sel
--
;
if
(
event
.
keyCode
==
40
&&
sel
<
this
.
state
.
result
.
length
-
1
)
sel
++
;
this
.
setState
({
...
this
.
state
,
selected
:
sel
})
}
}
selectStudent
=
(
event
)
=>
{
if
(
event
.
target
.
selected
)
{
this
.
formSubmit
();
}
else
{
const
index
=
this
.
state
.
result
.
findIndex
(
result
=>
result
.
id
==
event
.
target
.
id
);
this
.
setState
({
...
this
.
state
,
selected
:
index
})
}
}
formSubmit
=
(
event
)
=>
{
if
(
event
)
event
.
preventDefault
();
const
stud
=
this
.
state
.
result
[
this
.
state
.
selected
];
if
(
!
stud
)
return
;
this
.
props
.
matchStudent
(
stud
.
id
);
}
listMatchedStudent
=
()
=>
{
const
studIndex
=
this
.
students
.
findIndex
(
stud
=>
stud
.
id
===
this
.
props
.
studentID
);
const
stud
=
studIndex
>
-
1
?
[
this
.
students
[
studIndex
]]
:
[];
this
.
setState
({
input
:
''
,
selected
:
0
,
result
:
stud
})
if
(
!
this
.
props
.
validated
)
{
this
.
searchInput
.
focus
();
}
}
render
()
{
return
(
<
nav
className
=
"panel"
>
<
p
className
=
"panel-heading"
>
Students
</
p
>
<
div
className
=
"panel-block"
>
<
form
onSubmit
=
{
this
.
formSubmit
}
>
<
p
className
=
"control has-icons-left"
>
<
input
className
=
"input"
type
=
"text"
ref
=
{
(
input
)
=>
{
this
.
searchInput
=
input
;
}
}
value
=
{
this
.
state
.
input
}
onChange
=
{
this
.
search
}
onKeyDown
=
{
this
.
moveSelection
}
/>
<
span
className
=
"icon is-left"
>
<
i
className
=
"fa fa-search"
></
i
>
</
span
>
</
p
>
</
form
>
</
div
>
{
this
.
state
.
result
.
map
((
student
,
index
)
=>
<
StudentPanelBlock
key
=
{
student
.
id
}
student
=
{
student
}
selected
=
{
index
===
this
.
state
.
selected
}
matched
=
{
student
.
id
===
this
.
props
.
studentID
&&
this
.
props
.
validated
}
selectStudent
=
{
this
.
selectStudent
}
/>
)
}
<
AddModal
/>
</
nav
>
)
}
}
export
default
SearchPanel
;
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment