Commit 076c6d5c authored by Thomas Roos's avatar Thomas Roos

Visual working submission search

parent 92263f75
......@@ -6,6 +6,8 @@ import Hero from '../components/Hero.jsx'
import FeedbackPanel from './grade/FeedbackPanel.jsx'
import ProblemSelector from './grade/ProblemSelector.jsx'
import EditPanel from './grade/EditPanel.jsx'
import SubmissionField from './grade/SubmissionField.jsx'
const ProgressBar = () => null
class Grade extends React.Component {
......@@ -129,9 +131,10 @@ class Grade extends React.Component {
}
render () {
const submission = this.props.exam.submissions[this.state.sIndex]
const exam = this.props.exam
const submission = exam.submissions[this.state.sIndex]
const solution = submission.problems[this.state.pIndex]
const problem = this.props.exam.problems[this.state.pIndex]
const problem = exam.problems[this.state.pIndex]
return (
<div>
......@@ -143,10 +146,10 @@ class Grade extends React.Component {
<div className='container'>
<div className='columns'>
<div className='column is-one-quarter-desktop is-one-third-tablet'>
<ProblemSelector problems={this.props.exam.problems} changeProblem={this.changeProblem} />
<ProblemSelector problems={exam.problems} changeProblem={this.changeProblem} />
{this.state.editActive
? <EditPanel problem={problem} editFeedback={this.state.editFeedback} toggleEdit={this.toggleEdit} />
: <FeedbackPanel examID={this.props.exam.id} submissionID={submission.id}
: <FeedbackPanel examID={exam.id} submissionID={submission.id}
problem={problem} solution={solution} graderID={this.props.graderID}
toggleEdit={this.toggleEdit} updateSubmission={() => this.props.updateSubmission(this.state.sIndex)} />
}
......@@ -163,9 +166,7 @@ class Grade extends React.Component {
onClick={this.prev}>Previous</button>
</div>
<div className='control'>
<input className='input is-rounded has-text-centered is-link'
value={this.state.input} type='text'
onChange={this.setSubInput} onSubmit={this.setSubmission} onBlur={this.setSubmission} />
<SubmissionField student={submission.student} submissions={exam.submissions} />
</div>
<div className='control'>
<button type='submit' className='button is-link'
......@@ -177,10 +178,10 @@ class Grade extends React.Component {
</div>
</div>
<ProgressBar submissions={this.props.exam.submissions} />
<ProgressBar submissions={exam.submissions} />
<p className='box'>
<img src={this.props.exam.id ? ('api/images/solutions/' + this.props.exam.id + '/' +
<img src={exam.id ? ('api/images/solutions/' + exam.id + '/' +
problem.id + '/' + submission.id + '/' + (this.state.fullPage ? '1' : '0')) : ''} alt='' />
</p>
......
import React from 'react'
import Autosuggest from 'react-autosuggest'
import Fuse from 'fuse.js'
// When suggestion is clicked, Autosuggest needs to populate the input
// based on the clicked suggestion. Teach Autosuggest how to calculate the
// input value for every given suggestion.
const getSuggestionValue = (submission) => {
const stud = submission.student
return stud.firstName + ' ' + stud.lastName + ' (' + stud.id + ')'
}
// Use your imagination to render suggestions.
const renderSuggestion = submission => {
const stud = submission.student
return (
<div>
<b>{stud.firstName + ' ' + stud.lastName}</b>
<i> ({stud.id})</i>
</div>
)
}
class SubmissionField extends React.Component {
state = {
value: '',
suggestions: []
}
onChange = (event, { newValue }) => {
this.setState({
value: newValue
})
}
// Autosuggest will call this function every time you need to update suggestions.
// You already implemented this logic above, so just use it.
onSuggestionsFetchRequested = ({ value }) => {
const options = {
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: [
'student.id',
'student.firstName',
'student.lastName'
]
}
const fuse = new Fuse(this.props.submissions, options)
const result = fuse.search(value) // .slice(0, 10)
this.setState({
suggestions: result
})
}
// Autosuggest will call this function every time you need to clear suggestions.
onSuggestionsClearRequested = () => {
this.setState({
suggestions: []
})
}
render () {
const { value, suggestions } = this.state
// Autosuggest will pass through all these props to the input.
const inputProps = {
className: 'input is-rounded has-text-centered is-link',
type: 'text',
placeholder: 'Search for a submission',
value,
onChange: this.onChange,
onSubmit: this.setSubmission
}
return (
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
/>
)
}
}
export default SubmissionField
......@@ -14,7 +14,12 @@
},
"standard": {
"parser": "babel-eslint",
"globals": [ "__COMMIT_HASH__", "alert", "confirm", "PDFJS" ]
"globals": [
"__COMMIT_HASH__",
"alert",
"confirm",
"PDFJS"
]
},
"dependencies": {
"babel-plugin-syntax-dynamic-import": "^6.18.0",
......@@ -36,6 +41,7 @@
"path": "^0.12.7",
"raw-loader": "^0.5.1",
"react": "^16.4.0",
"react-autosuggest": "^9.3.4",
"react-dom": "^16.4.0",
"react-dropzone": "^4.2.12",
"react-loadable": "^5.4.0",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment