Skip to content

Commit

Permalink
Merge pull request #3080 from dodona-edu/feature/full-evaluation-stepper
Browse files Browse the repository at this point in the history
Make evaluation creation a full stepper
  • Loading branch information
chvp authored Sep 10, 2021
2 parents 92d0759 + 4d9ca5d commit f890c84
Show file tree
Hide file tree
Showing 29 changed files with 472 additions and 409 deletions.
91 changes: 70 additions & 21 deletions app/assets/javascripts/evaluation.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
import { fetch } from "util.js";

export function interceptAddMultiUserClicks(): void {
let running = false;
document.querySelectorAll(".user-select-option a").forEach(option => {
option.addEventListener("click", async event => {
if (!running) {
running = true;
event.preventDefault();
const button = option.querySelector(".button");
const loader = option.querySelector(".loader");
button.classList.add("hidden");
loader.classList.remove("hidden");
const response = await fetch(option.getAttribute("href"), { method: "POST" });
eval(await response.text());
loader.classList.add("hidden");
button.classList.remove("hidden");
running = false;
}
});
});
}

export function initCheckboxes(): void {
document.querySelectorAll(".evaluation-users-table .user-row").forEach(el => initCheckbox(el));
}
Expand All @@ -39,3 +18,73 @@ export function initCheckbox(row: HTMLTableRowElement): void {
}
});
}

export function initEvaluationStepper(): void {
const evalPanelElement = document.querySelector("#info-panel .panel-collapse");
const evalPanel = new bootstrap.Collapse(evalPanelElement, { toggle: false });
const userPanelElement = document.querySelector("#users-panel .panel-collapse");
const userPanel = new bootstrap.Collapse(userPanelElement, { toggle: false });
const scorePanelElement = document.querySelector("#items-panel .panel-collapse");
const scorePanel = new bootstrap.Collapse(scorePanelElement, { toggle: false });

function init(): void {
window.dodona.toUsersStep = toUsersStep;

evalPanelElement.addEventListener("show.bs.collapse", function () {
userPanel.hide();
scorePanel.hide();
});
userPanelElement.addEventListener("show.bs.collapse", function () {
evalPanel.hide();
scorePanel.hide();
});
scorePanelElement.addEventListener("show.bs.collapse", function () {
evalPanel.hide();
userPanel.hide();
});

document.querySelector("#users-step-finish-button").addEventListener("click", function () {
userPanel.hide();
scorePanel.show();
document.querySelector("#short-users-count-wrapper").classList.remove("hidden");
});
}


function toUsersStep(): void {
interceptAddMultiUserClicks();
initCheckboxes();
document.querySelector("#deadline-group .btn").classList.add("disabled");
evalPanelElement.querySelector(".stepper-actions").remove();
evalPanel.hide();
userPanel.show();
document.querySelector("#users-panel a[role=\"button\"]").setAttribute("href", "#users-step");
document.querySelector("#users-panel a[role=\"button\"]").classList.remove("disabled");
document.querySelector("#items-panel a[role=\"button\"]").setAttribute("href", "#items-step");
document.querySelector("#items-panel a[role=\"button\"]").classList.remove("disabled");
}

function interceptAddMultiUserClicks(): void {
let running = false;
document.querySelectorAll(".user-select-option a").forEach(option => {
option.addEventListener("click", async event => {
if (!running) {
running = true;
event.preventDefault();
const button = option.querySelector(".button");
const loader = option.querySelector(".loader");
button.classList.add("hidden");
loader.classList.remove("hidden");
const response = await fetch(option.getAttribute("href"), { method: "POST" });
eval(await response.text());
loader.classList.add("hidden");
button.classList.remove("hidden");
running = false;
}
});
});
}


init();
}
4 changes: 4 additions & 0 deletions app/assets/stylesheets/components/stepper.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@

a {
color: inherit;
&.disabled {
cursor: default;
color: $text-muted;
}
}

.answer {
Expand Down
44 changes: 26 additions & 18 deletions app/controllers/evaluations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class EvaluationsController < ApplicationController
include SeriesHelper
include EvaluationHelper

before_action :set_evaluation, only: %i[show edit add_users update destroy overview set_multi_user add_user remove_user mark_undecided_complete export_grades modify_grading_visibility]
before_action :set_evaluation, only: %i[show edit update destroy overview set_multi_user add_user remove_user mark_undecided_complete export_grades modify_grading_visibility]
before_action :set_series, only: %i[new]

has_scope :by_institution, as: 'institution_id'
Expand All @@ -16,7 +16,11 @@ class EvaluationsController < ApplicationController
end

def show
redirect_to add_users_evaluation_path(@evaluation) if @evaluation.users.count == 0
if @evaluation.users.count == 0
flash[:alert] = I18n.t('evaluations.edit.users_required')
redirect_to edit_evaluation_path(@evaluation)
return
end
@feedbacks = @evaluation.evaluation_sheet
@users = apply_scopes(@evaluation.users)
@course_labels = CourseLabel.where(course: @evaluation.series.course)
Expand All @@ -31,11 +35,17 @@ def new
end
@course = @series.course
@evaluation = Evaluation.new(series: @series, deadline: @series.deadline || Time.current)
@crumbs = [
[@series.course.name, course_url(@series.course)],
[@series.name, breadcrumb_series_path(@series, current_user)],
[I18n.t('evaluations.new.create_evaluation'), '#']
]
@title = I18n.t('evaluations.new.create_evaluation')
authorize @evaluation
end

def edit
@should_confirm = params[:confirm].present?
@course = @evaluation.series.course
@course_labels = CourseLabel.where(course: @course)
@course_memberships = apply_scopes(@course.course_memberships)
Expand All @@ -44,7 +54,7 @@ def edit
.order(Arel.sql('users.permission ASC'))
.order(Arel.sql('users.last_name ASC'), Arel.sql('users.first_name ASC'))
.where(status: %i[course_admin student])
.paginate(page: parse_pagination_param(params[:page]))
.paginate(page: parse_pagination_param(params[:page]), per_page: 15)

ActivityStatus.add_status_for_series(@evaluation.series, [:last_submission])

Expand All @@ -57,30 +67,28 @@ def edit
@title = I18n.t('evaluations.edit.title')
end

def add_users
edit
@user_count_course = @evaluation.series.course.enrolled_members.count
@user_count_series = @evaluation.series.course.enrolled_members.where(id: Submission.where(exercise_id: @evaluation.exercises, course_id: @evaluation.series.course_id).select('DISTINCT user_id')).count
@crumbs = [
[@evaluation.series.course.name, course_url(@evaluation.series.course)],
[@evaluation.series.name, breadcrumb_series_path(@evaluation.series, current_user)],
[I18n.t('evaluations.show.evaluation'), evaluation_url(@evaluation)],
[I18n.t('evaluations.add_users.title'), '#']
]
@title = I18n.t('evaluations.add_users.title')
end

def create
@evaluation = Evaluation.new(permitted_attributes(Evaluation))
authorize @evaluation
@evaluation.exercises = @evaluation.series.exercises
@course = @evaluation.series.course
@course_labels = CourseLabel.where(course: @course)
@course_memberships = apply_scopes(@course.course_memberships)
.includes(:course_labels, user: [:institution])
.order(status: :asc)
.order(Arel.sql('users.permission ASC'))
.order(Arel.sql('users.last_name ASC'), Arel.sql('users.first_name ASC'))
.where(status: %i[course_admin student])
.paginate(page: parse_pagination_param(params[:page]), per_page: 15)

respond_to do |format|
if @evaluation.save
format.html { redirect_to add_users_evaluation_path(@evaluation) }
@user_count_course = @evaluation.series.course.enrolled_members.count
@user_count_series = @evaluation.series.course.enrolled_members.where(id: Submission.where(exercise_id: @evaluation.exercises, course_id: @evaluation.series.course_id).select('DISTINCT user_id')).count
format.js {}
format.json { render :show, status: :created, location: @evaluation }
else
format.html { render :new }
format.js { render :new }
format.json { render json: @evaluation.errors, status: :unprocessable_entity }
end
end
Expand Down
16 changes: 2 additions & 14 deletions app/controllers/score_items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@ class ScoreItemsController < ApplicationController
before_action :set_score_item, only: %i[destroy update]
before_action :set_evaluation

def index
@crumbs << [I18n.t('score_items.index.title'), '#']
@title = I18n.t('score_items.index.title')
end

def new
@crumbs << [I18n.t('score_items.new.title'), '#']
@title = I18n.t('score_items.new.title')
end

def copy
from = EvaluationExercise.find(params[:copy][:from])
to = EvaluationExercise.find(params[:copy][:to])
Expand Down Expand Up @@ -67,12 +57,10 @@ def add_all
@evaluation.transaction do
@evaluation.evaluation_exercises.each do |evaluation_exercise|
new_score_item = @score_item.dup
new_score_item.evaluation_exercise = evaluation_exercise
new_score_item.save
evaluation_exercise.score_items << new_score_item
end
end

redirect_back fallback_location: new_evaluation_score_item_path(@evaluation)
@evaluation.reload
end

def destroy
Expand Down
6 changes: 3 additions & 3 deletions app/javascript/packs/evaluation.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { initDeadlinePicker } from "series.js";
import { interceptAddMultiUserClicks, initCheckboxes, initCheckbox } from "evaluation.ts";
import { initCheckboxes, initCheckbox, initEvaluationStepper } from "evaluation.ts";
import FeedbackActions from "feedback/actions";

window.dodona.initDeadlinePicker = initDeadlinePicker;
window.dodona.initCheckboxes = initCheckboxes;
window.dodona.initCheckbox = initCheckbox;
window.dodona.interceptAddMultiUserClicks = interceptAddMultiUserClicks;
window.dodona.initCheckboxes = initCheckboxes;
window.dodona.FeedbackActions = FeedbackActions;
window.dodona.initEvaluationStepper = initEvaluationStepper;
62 changes: 62 additions & 0 deletions app/views/evaluations/_add_users.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<div class="stepper-part evaluation-user-select">
<div class="row">
<div class="col-lg-6 col-md-12 order-lg-1">
<div class="callout callout-info">
<h4><%= t('evaluations.add_users.explanation_title') %></h4>
<p><%= t('evaluations.add_users.explanation_part1') %></p>
<p><%= t('evaluations.add_users.explanation_part2') %></p>
</div>
</div>
<div class="col-lg-6 col-md-12 order-lg-0">
<div class="card-subtitle">
<h4><%= t('evaluations.edit_users.mass_edit') %></h4>
</div>
<div class="row">
<div class="col-6">
<div class="user-select-option">
<%= link_to set_multi_user_evaluation_path(@evaluation, type: 'enrolled', format: :js) do %>
<%= t('evaluations.add_users.users_in_course_html', count: @user_count_course) %>
<div class="clearfix"></div>
<i class="loader mdi mdi-spin mdi-loading hidden"></i>
<div class="button btn-text"><%= t('.select_users') %></div>
<% end %>
</div>
</div>
<div class="col-6">
<div class="user-select-option">
<%= link_to set_multi_user_evaluation_path(@evaluation, type: 'submitted', format: :js) do %>
<%= t('evaluations.add_users.users_submitted_html', count: @user_count_series) %>
<div class="clearfix"></div>
<i class="loader mdi mdi-spin mdi-loading hidden"></i>
<div class="button btn-text"><%= t('.select_users') %></div>
<% end %>
</div>
</div>
</div>
<p class="selected-users">
<span id="users-count-wrapper">
<%= t("evaluations.edit_users.users_selected_html", count: @evaluation.users.count) %>
</span>
<%= link_to t('evaluations.edit_users.clear'), set_multi_user_evaluation_path(@evaluation, type: 'none', format: :js), remote: true, method: :post %>.
</p>
</div>
</div>
</div>
<div class="stepper-part stepper-border">
<div class="card-supporting-text">
<%= render partial: 'layouts/searchbar', locals: {
baseUrl: edit_evaluation_url(@evaluation),
eager: false,
course_labels: @course_labels,
institutions: Institution.of_course_by_members(@course),
} %>
<div id="users-table-wrapper">
<%= render partial: 'members_table',
locals: {
course_memberships: @course_memberships,
pagination_opts: @pagination_opts,
confirm: false
} %>
</div>
</div>
</div>
14 changes: 0 additions & 14 deletions app/views/evaluations/_edit_users.html.erb

This file was deleted.

23 changes: 9 additions & 14 deletions app/views/evaluations/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
<% content_for :javascripts do %>
<%= javascript_pack_tag 'evaluation' %>
<% end %>
<%= form_for evaluation, html: { class: "form-horizontal feedback-form" } do |f| %>
<%= form_for evaluation, html: { class: "form-horizontal feedback-form" }, remote: true do |f| %>
<div>
<%= f.hidden_field :series_id %>
<h4 class="evaluation-form-title"><%= evaluation.series.name %> <span class="small"><%= evaluation.series.course.name %></span></h4>

<%= render partial: 'exercises_table', locals: {
series: @evaluation.series,
exercises: @evaluation.series.exercises,
} %>

<br><b>Deadline</b><br>

<div class="field form-group<%= " has-error" if evaluation.deadline > Time.current %>">
<div class='col-sm-12'>
<div class="input-group" id='deadline-group' data-wrap=true data-enable-time=true data-time_24hr=true data-max-date="<%= Time.current.httpdate %>">
<%= f.text_field :deadline, class: "form-control", 'data-input': true %>
<button class="btn btn-secondary" type="button" data-toggle><i class='mdi mdi-calendar-blank mdi-18'></i></button>
<div class="row">
<div class="col-lg-6 col-sm-12">
<h6>Deadline</h6>
<%= t(".deadline-help_html") %>
<div class="input-group" id='deadline-group' data-wrap=true data-enable-time=true data-time_24hr=true data-max-date="<%= Time.current.httpdate %>">
<%= f.text_field :deadline, class: "form-control", 'data-input': true %>
<button class="btn btn-secondary" type="button" data-toggle><i class='mdi mdi-calendar-blank mdi-18'></i></button>
</div>
</div>
</div>
<span class="help-block col-sm-12"><%= t(".deadline-help_html") %></span>
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion app/views/evaluations/_members_table.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
<p class="text-center text-muted lead table-placeholder"><%= t 'users.index.no_users' %></p>
<% end %>
<center>
<%= page_navigation_links course_memberships, true, 'evaluations', action: 'edit' %>
<%= page_navigation_links course_memberships, true, 'evaluations', { id: @evaluation.id }, 'edit' %>
</center>
Loading

0 comments on commit f890c84

Please sign in to comment.