Add submission deadline to exercises and allow teachers to view their submissions

This commit is contained in:
Sebastian Serth
2020-05-07 17:45:53 +02:00
parent 4c571c4fb2
commit 914eeb6035
21 changed files with 456 additions and 245 deletions

View File

@@ -16,6 +16,16 @@
= f.label(:instructions)
= f.hidden_field(:instructions)
.form-control.markdown
.form-group
= f.label(:submission_deadline)
.chosen-inline
= f.datetime_select(:submission_deadline, include_blank: true)
.help-block.form-text == t('.hints.submission_deadline')
.form-group
= f.label(:late_submission_deadline)
.chosen-inline
= f.datetime_select(:late_submission_deadline, include_blank: true)
.help-block.form-text == t('.hints.late_submission_deadline')
.form-check
label.form-check-label
= f.check_box(:public, class: 'form-check-input')

View File

@@ -1,4 +1,4 @@
h1 = "#{@exercise} (external user #{link_to_if(policy(@external_user).show?, @external_user.displayname, @external_user)})"
h1 = "#{@exercise} (external user #{link_to_if(policy(@external_user).show?, @external_user.displayname, @external_user)})".html_safe
- current_submission = @submissions.first
- if current_submission
- initial_files = current_submission.files.to_a
@@ -36,32 +36,54 @@ h1 = "#{@exercise} (external user #{link_to_if(policy(@external_user).show?, @ex
table.table
thead
tr
- ['.time', '.cause', '.score', '.tests', '.time_difference'].each do |title|
th.header = t(title)
th.header = t('.time')
th.header = t('.cause')
th.header = t('.score')
th.header = t('.tests')
th.header = t('.time_difference') if policy(@exercise).detailed_statistics?
tbody
- @all_events.each_with_index do |this, index|
- highlight = (index > 0 and @deltas[index] == 0 and this.created_at.to_s != @all_events[index - 1].created_at.to_s)
tr data-id=this.id class=('highlight' if highlight)
- row_classes = ''
- row_classes += ' highlight' if highlight
- row_classes += ' before_deadline' if this.is_a?(Submission) && this.before_deadline?
- row_classes += ' within_grace_period' if this.is_a?(Submission) && this.within_grace_period?
- row_classes += ' after_late_deadline' if this.is_a?(Submission) && this.after_late_deadline?
tr data-id=this.id class=row_classes
td.clickable = this.created_at.strftime("%F %T")
- if this.is_a?(Submission)
td = this.cause
td = this.score
td
td.align-middle
-this.testruns.each do |run|
- if run.passed
.unit-test-result.positive-result title=run.output
- else
.unit-test-result.unknown-result title=run.output
td = @working_times_until[index] if index > 0
td = @working_times_until[index] if index > 0 if policy(@exercise).detailed_statistics?
- elsif this.is_a? UserExerciseIntervention
td = this.intervention.name
td =
td =
td = @working_times_until[index] if index > 0
p = t('.addendum', delta: StatisticsHelper::WORKING_TIME_DELTA_IN_SECONDS / 60)
.d-none#wtimes data-working_times=ActiveSupport::JSON.encode(@working_times_until);
div#progress_chart.col-lg-12
.graph-functions-2
td = @working_times_until[index] if index > 0 if policy(@exercise).detailed_statistics?
small
b
= t('.legend')
.container.px-0.border
.row.w-100.mx-0
.col-sm-3.py-2
= t('.no_deadline')
.col-sm-3.before_deadline.py-2
= t('.before_deadline')
.col-sm-3.within_grace_period.py-2
= t('.within_grace_period')
.col-sm-3.after_late_deadline.py-2
= t('.after_late_deadline')
- if current_user.try(:admin?)
p = t('.addendum', delta: StatisticsHelper::WORKING_TIME_DELTA_IN_SECONDS / 60)
.d-none#wtimes data-working_times=ActiveSupport::JSON.encode(@working_times_until);
div#progress_chart.col-lg-12
.graph-functions-2
- else
p = t('.no_data_available')

View File

@@ -25,6 +25,8 @@ h1
= row(label: 'exercise.execution_environment', value: link_to_if(@exercise.execution_environment && policy(@exercise.execution_environment).show?, @exercise.execution_environment, @exercise.execution_environment))
/= row(label: 'exercise.instructions', value: render_markdown(@exercise.instructions))
= row(label: 'exercise.maximum_score', value: @exercise.maximum_score)
= row(label: 'exercise.submission_deadline', value: @exercise.submission_deadline)
= row(label: 'exercise.late_submission_deadline', value: @exercise.late_submission_deadline)
= row(label: 'exercise.public', value: @exercise.public?)
= row(label: 'exercise.unpublished', value: @exercise.unpublished?)
= row(label: 'exercise.hide_file_tree', value: @exercise.hide_file_tree?)

View File

@@ -25,12 +25,13 @@ h1 = @exercise
p = @exercise.average_working_time
- Hash[:internal_users => t('.internal_users'), :external_users => t('.external_users')].each_pair do |symbol, label|
strong = label
-if symbol==:external_users
-working_time_array = []
- if symbol==:internal_users && current_user.admin?
strong = label
- if symbol==:external_users
- working_time_array = []
- @exercise.send(symbol).distinct().each do |user|
-working_time = @exercise.average_working_time_for(user.id) or 0
-working_time_array.push working_time
- working_time = @exercise.average_working_time_for(user.id) or 0
- working_time_array.push working_time
hr
.d-none#data data-working-time=ActiveSupport::JSON.encode(working_time_array)
.working-time-graphs
@@ -38,19 +39,26 @@ h1 = @exercise
hr
div#chart_2
hr
- if current_user.admin?
- submissions = Submission.where(user: @exercise.send(symbol).distinct, exercise: @exercise).in_study_group_of(current_user)
- if !policy(@exercise).detailed_statistics?
- submissions = submissions.final
- any_viewable_submission = submissions.first
- if any_viewable_submission
.table-responsive
table.table.table-striped.sortable
thead
tr
- ['.user', '.score', '.runs', '.worktime'].each do |title|
th.header = t(title)
th.header = t('.user')
th.header = t('.score')
th.header = t('.runs') if policy(@exercise).detailed_statistics?
th.header = t('.worktime') if policy(@exercise).detailed_statistics?
tbody
- @exercise.send(symbol).distinct().each do |user|
- users = symbol.to_s.classify.constantize.where(id: submissions.joins(symbol).group(:user_id).select(:user_id).distinct)
- users.each do |user|
- if user_statistics[user.id] then us = user_statistics[user.id] else us = {"maximum_score" => nil, "runs" => nil}
- label = "#{user.displayname}"
tr
td = link_to_if symbol==:external_users && policy(user).statistics?, label, {controller: "exercises", action: "statistics", external_user_id: user.id, id: @exercise.id}
td = us['maximum_score'] or 0
td = us['runs']
td = @exercise.average_working_time_for(user.id) or 0
td = us['runs'] if policy(@exercise).detailed_statistics?
td = @exercise.average_working_time_for(user.id) or 0 if policy(@exercise).detailed_statistics?

View File

@@ -1,7 +1,7 @@
h1 = @user.displayname
= row(label: 'external_user.name', value: @user.name)
= row(label: 'external_user.email', value: @user.email)
= row(label: 'external_user.email', value: @user.email) if current_user.admin?
= row(label: 'external_user.external_id') do
code
= @user.external_id
@@ -10,10 +10,11 @@ h1 = @user.displayname
h4.mt-4 = link_to(t('.exercise_statistics'), statistics_external_user_path(@user)) if policy(@user).statistics?
h4.mt-4 = t('.tag_statistics')
#loading
.spinner
= t('.loading_tag_statistics')
#no-elements
= t('.empty_tag_statistics')
#tag-grid
- if current_user.admin?
h4.mt-4 = t('.tag_statistics')
#loading
.spinner
= t('.loading_tag_statistics')
#no-elements
= t('.empty_tag_statistics')
#tag-grid

View File

@@ -1,19 +1,30 @@
h1 = t('.title')
- exercises = Exercise.where(:id => @user.submissions.group(:exercise_id).select(:exercise_id).distinct)
- submissions = Submission.where(user: @user).in_study_group_of(current_user)
- exercises = Exercise.where(id: submissions.joins(:exercise).group(:exercise_id).select(:exercise_id).distinct)
- if !policy(exercises.first).detailed_statistics?
- submissions = submissions.final
- any_viewable_submission = submissions.first
.table-responsive
table.table.table-striped.sortable
thead
tr
- ['.exercise', '.score', '.runs', '.worktime'].each do |title|
th.header = t(title)
tbody
- exercises.each do |exercise|
- if statistics[exercise.id]
- stats = statistics[exercise.id]
tr
td = link_to_if policy(exercise).show?, exercise, controller: "exercises", action: "statistics", external_user_id: @user.id, id: exercise.id
td = stats["maximum_score"] or 0
td = stats["runs"] or 0
td = stats["working_time"] or 0
- if any_viewable_submission && policy(any_viewable_submission).show_study_group?
.table-responsive
table.table.table-striped.sortable
thead
tr
th.header = t('.exercise')
th.header = t('.score')
th.header = t('.runs') if policy(exercises.first).detailed_statistics?
th.header = t('.worktime') if policy(exercises.first).detailed_statistics?
tbody
- exercises.each do |exercise|
// Grab any submission in context of study group (or all if admin). Then check for permission
- any_submission = submissions.where(exercise: exercise).first
- if any_submission && policy(any_submission).show_study_group? && statistics[exercise.id]
- stats = statistics[exercise.id]
tr
td = link_to exercise, controller: "exercises", action: "statistics", external_user_id: @user.id, id: exercise.id
td = stats["maximum_score"] or 0
td = stats["runs"] or 0 if policy(exercises.first).detailed_statistics?
td = stats["working_time"] or 0 if policy(exercises.first).detailed_statistics?
- else
= t('exercises.external_users.statistics.no_data_available')