From 376ceaece6fb341b3be5059a0d08ed75276ec73e Mon Sep 17 00:00:00 2001 From: Kester Date: Mon, 14 Apr 2025 03:34:32 -0400 Subject: [PATCH] Progress loading for manage submissions --- app/assets/javascripts/manage_submissions.js | 54 +++++++++++++++++++ .../stylesheets/manage_submissions.css.scss | 18 +++++++ app/controllers/assessment/autograde.rb | 14 ++--- app/views/submissions/index.html.erb | 25 +++++---- 4 files changed, 92 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/manage_submissions.js b/app/assets/javascripts/manage_submissions.js index eebca05ed..c89539aa9 100644 --- a/app/assets/javascripts/manage_submissions.js +++ b/app/assets/javascripts/manage_submissions.js @@ -329,9 +329,56 @@ $(document).ready(function() { } } + $(document).on("click", "#regrade-all-btn, #regrade-all-trigger", function (event) { + event.preventDefault(); + if (!confirm(`Are you sure you want to regrade all selected submissions?`)) return; + const icon = $("#regrade-all-icon"); + const button = $("#regrade-all-btn"); + const link = $('#regrade-all-trigger'); + let refreshInterval = setInterval(() => { + location.reload(); + }, 5000); + + $.ajax({ + url: "regradeAll", + type: "POST", + contentType: "application/json", + headers: { + "X-CSRF-Token": $('meta[name="csrf-token"]').attr("content") + }, + beforeSend: function () { + if (icon && button) { + button.addClass("disabled"); + link.addClass("disabled-link"); + icon.text("autorenew"); + icon.addClass("loading-icon"); + } + }, + success: function (response) { + clearInterval(refreshInterval); + if (response.redirect) { + console.log(response.redirect); + window.location.href = response.redirect; + return; + } + if (response.error) { + alert(response.error); + } + if (response.success) { + alert(response.success); + } + }, + error: function () { + clearInterval(refreshInterval); + alert("An error occurred while regrading."); + } + }); + }); + function changeButtonStates(state) { buttonIDs.forEach((id) => { const button = $(id); + const icon = button.find("i"); if (state) { if (id === "#download-selected") { $(id).prop('href', baseURLs[id]); @@ -374,6 +421,13 @@ $(document).ready(function() { headers: { "X-CSRF-Token": $('meta[name="csrf-token"]').attr("content"), }, + beforeSend: function () { + button.addClass('disabled'); + if (icon) { + icon.text("autorenew"); + icon.addClass("loading-icon"); + } + }, success: function (response) { clearInterval(refreshInterval); if (response.redirect) { diff --git a/app/assets/stylesheets/manage_submissions.css.scss b/app/assets/stylesheets/manage_submissions.css.scss index b6320862c..c1594e7ad 100644 --- a/app/assets/stylesheets/manage_submissions.css.scss +++ b/app/assets/stylesheets/manage_submissions.css.scss @@ -74,3 +74,21 @@ table.prettyBorder tr:hover { .i-no-margin { margin-left: 0; } + +.loading-icon { + animation: spin 1.5s linear infinite; + display: inline-block; +} + +.disabled-link { + pointer-events: none; + color: gray !important; + opacity: 0.6; + text-decoration: none; + cursor: default; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} \ No newline at end of file diff --git a/app/controllers/assessment/autograde.rb b/app/controllers/assessment/autograde.rb index a554aefe5..3cce5abb3 100644 --- a/app/controllers/assessment/autograde.rb +++ b/app/controllers/assessment/autograde.rb @@ -105,8 +105,7 @@ def regradeBatch # any handins that fail. submissions = submission_ids.filter_map do |sid| _is_i?(sid) ? @assessment.submissions.find_by_id(sid) : nil - end - + end.compact begin failed_list = sendJob_batch(@course, @assessment, submissions, @cud) rescue AssessmentAutogradeCore::AutogradeError => e @@ -119,7 +118,7 @@ def regradeBatch failure_jobs = failed_list.length if failure_jobs > 0 - flash[:error] = + flash[:error] = "Warning: Could not regrade #{ActionController::Base.helpers.pluralize(failure_jobs, "submission")}:
" failed_list.each do |failure| @@ -193,7 +192,10 @@ def regradeAll # For both :success and :error flash[:html_safe] = true - redirect_to([@course, @assessment, :submissions]) && return + respond_to do |format| + format.html { redirect_to [@course, @assessment, :submissions] } + format.json { render json: { redirect: url_for([@course, @assessment, :submissions]) } } + end end ## @@ -260,7 +262,7 @@ def sendJob_AddHTMLMessages(course, assessment, submissions) job end - def _is_i?(string) - !!(string =~ /\A[-+]?[0-9]+\z/) + def _is_i?(value) + value.is_a?(Integer) || (value.is_a?(String) && value =~ /\A[-+]?\d+\z/) end end diff --git a/app/views/submissions/index.html.erb b/app/views/submissions/index.html.erb index 7b8391308..f1fb124d6 100755 --- a/app/views/submissions/index.html.erb +++ b/app/views/submissions/index.html.erb @@ -84,21 +84,16 @@ class: "btn submissions-main" } %> -
- <%= link_to "cachedRegrade All".html_safe, - regradeAll_course_assessment_path(@course, @assessment), - { method: :post, - title: "Regrade all submissions for this assignment", - class: "btn submissions-main", - data: { confirm: "Are you sure you want to regrade all #{@assessment.submissions.where(special_type: [Submission::NORMAL, nil]).latest.count} latest submissions?" } } %> -
+ + cachedRegrade All + <%# Selected buttons, hidden so HTML can be accessed in DataTables %>
- <%= link_to "Regrade Selected", class: "btn submissions-selected", title: "Regrade selected submissions" do %> - cached Regrade Selected + <%= link_to "Regrade Selected", class: "btn submissions-selected", id: "regrade-selected-btn", title: "Regrade selected submissions" do %> + cachedRegrade Selected <% end %>
@@ -125,9 +120,13 @@