Commit 798d5db0 authored by Adrià Labay's avatar Adrià Labay
Browse files

improve error message appearance in multiple views

parent 2422d4c8
......@@ -2,7 +2,7 @@ import React from 'react'
const Hero = (props) => {
return (
<section className='hero is-primary is-info is-small'>
<section className={'hero is-small ' + (props.colour ? props.colour : 'is-info')}>
<div className='hero-body'>
<div className='container'>
<h1 className='title'>
......
import React from 'react'
import Hero from '../components/Hero.jsx'
import Fail from './Fail.jsx'
import * as api from '../api.jsx'
import EmailControls from './email/EmailControls.jsx'
......@@ -42,7 +43,7 @@ class Email extends React.Component {
render () {
// This should happen when the exam does not exist.
if (this.state.error) {
return <Hero title='Oops!' subtitle={this.state.error} />
return <Fail message={this.state.error} />
}
return (
......
import React from 'react'
import Hero from '../components/Hero.jsx'
import Fail from './Fail.jsx'
import ConfirmationModal from '../components/ConfirmationModal.jsx'
import ExamTemplated from './exam/ExamTemplated.jsx'
import ExamUnstructured from './exam/ExamUnstructured.jsx'
......@@ -15,7 +16,6 @@ class Exams extends React.Component {
}
componentDidUpdate = (prevProps, prevState) => {
// in better days we should store and update the exam here and not in App.
if (prevProps.examID !== this.props.examID) {
this.loadExam(this.props.examID)
}
......@@ -66,6 +66,10 @@ class Exams extends React.Component {
render () {
const exam = this.state.exam
if (!exam && this.state.status) {
return <Fail message={this.state.status} />
}
return <div>
<Hero />
<section className='section'>
......
......@@ -6,7 +6,10 @@ const Home = (props) => {
return (
<div>
<Hero title='Oops!' subtitle={props.message ? props.message : "Something went wrong :'("} />
<Hero
title='Oops!'
subtitle={props.message ? props.message : "Something went wrong :'("}
colour='is-danger' />
<section className='section'>
......
import React from 'react'
import Notification from 'react-bulma-notification'
import Hero from '../components/Hero.jsx'
import Fail from './Fail.jsx'
import FeedbackPanel from '../components/feedback/FeedbackPanel.jsx'
import ProblemSelector from './grade/ProblemSelector.jsx'
......@@ -363,10 +364,16 @@ class Grade extends React.Component {
// This should happen when there are no submissions or problems for an exam.
// More specifically, if a user tries to enter a URL for an exam with no submissions.
// This will also happen while the initial call to update submission in the constructor is still pending.
if (!this.state.submission) {
if (this.state.submission === undefined) {
// submission is being loaded, we just want to show a loading screen
return hero
}
if (this.state.submission === null) {
// no stats, show the error message
const message = ((this.state.submissions && this.state.submissions.length > 0)
? 'Submission does not exist' : 'There are no submissions yet')
return <Hero title='Oops!' subtitle={message} />
return <Fail message={message} />
}
const examID = this.props.examID
......
......@@ -7,6 +7,7 @@ import {range, exp, sqrt, pow, pi, zeros, min, max} from 'mathjs'
import humanizeDuration from 'humanize-duration'
import Hero from '../components/Hero.jsx'
import Fail from './Fail.jsx'
import * as api from '../api.jsx'
const Plot = createPlotlyComponent(Plotly)
......@@ -118,8 +119,8 @@ const estimateGradingTime = (graders) => {
class Overview extends React.Component {
state = {
stats: null,
loadingText: 'Loading statistics...',
stats: undefined,
error: 'Loading statistics...',
selectedProblemId: null,
selectedStudentId: null
}
......@@ -131,7 +132,12 @@ class Overview extends React.Component {
componentDidUpdate = (prevProps, prevState) => {
const examID = this.props.examID
if (examID !== prevProps.examID) {
this.loadStats(examID)
this.setState({
stats: undefined,
error: '',
selectedProblemId: null,
selectedStudentId: null
}, () => this.loadStats(examID))
}
}
......@@ -147,7 +153,7 @@ class Overview extends React.Component {
err.json().then(res => {
this.setState({
stats: null,
loadingText: 'Error loading statistics: ' + res.message
error: 'Error loading statistics: ' + res.message
})
})
})
......@@ -633,44 +639,48 @@ class Overview extends React.Component {
}
render () {
const hero = <Hero title='Overview' subtitle='Analyse the exam results' />
if (this.state.stats === undefined) {
// stats are being loaded, we just want to show a loading screen
return hero
}
if (this.state.stats === null) {
// no stats, show the error message
return <Fail message={this.state.error} />
}
return (
<div>
<Hero title='Overview' subtitle='Analyse the exam results' />
{ this.state.stats
? (
<div className='container has-text-centered'>
<h1 className='is-size-1'> {this.state.stats.name} </h1>
<span className='select is-medium'>
<select
onChange={(e) => {
this.setState({
selectedProblemId: parseInt(e.target.value)
})
}}
>
<option key='key_0' value='0'>Overview</option>
{this.state.stats.problems.map((problem, index) => {
return <option key={'key_' + (index + 1)} value={problem.id}>{problem.name}</option>
})}
</select>
</span>
<section className='section'>
<div className='container'>
{ this.state.selectedProblemId === 0
? this.renderAtGlance()
: this.renderProblemSummary(this.state.selectedProblemId)
}
</div>
</section>
</div>
) : (
<div className='container has-text-centered'>
<h1 className='is-size-1'> {this.state.stats.name} </h1>
<span className='select is-medium'>
<select
onChange={(e) => {
this.setState({
selectedProblemId: parseInt(e.target.value)
})
}}
>
<option key='key_0' value='0'>Overview</option>
{this.state.stats.problems.map((problem, index) => {
return <option key={'key_' + (index + 1)} value={problem.id}>{problem.name}</option>
})}
</select>
</span>
<section className='section'>
<div className='container'>
<p className='container has-text-centered is-size-5'> {this.state.loadingText} </p>
{ this.state.selectedProblemId === 0
? this.renderAtGlance()
: this.renderProblemSummary(this.state.selectedProblemId)
}
</div>
)
}
</section>
</div>
</div >
)
......
......@@ -58,11 +58,8 @@ class PanelExamName extends React.Component {
}
onChange = () => {
// In order to change the name everywhere in the UI we are forced to
// update the whole exam here as well as the exam list in the navbar.
// This is not ideal and should be addressed in
// https://gitlab.kwant-project.org/zesje/zesje/issues/388
// TODO: implement data locality for this view
// In order to change the name everywhere in the UI we need to update the exam
// in the parent view and reload the exam list in the navbar
this.props.updateExam(this.state.examID)
this.props.updateExamList()
}
......
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