From 411ec8fc758dd552ea6a5414a346994b54a149dc Mon Sep 17 00:00:00 2001 From: Simon Mayer <simon.mayer@onb.ac.at> Date: Mon, 10 Oct 2022 17:38:07 +0200 Subject: [PATCH] Fully implement progress bar for all notifications --- app/controllers/dataset_controller.rb | 22 +++++++---- .../channels/notification_channel.js | 8 +++- app/views/dataset/add_documents.js.erb | 3 +- app/views/dataset/set_working_dataset.js.erb | 3 +- app/views/shared/_notification.html.erb | 2 +- app/workers/export_dataset_worker.rb | 37 ++++++++++++------- app/workers/search_to_dataset_worker.rb | 5 ++- 7 files changed, 52 insertions(+), 28 deletions(-) diff --git a/app/controllers/dataset_controller.rb b/app/controllers/dataset_controller.rb index 5360107..e3d41a1 100644 --- a/app/controllers/dataset_controller.rb +++ b/app/controllers/dataset_controller.rb @@ -130,7 +130,7 @@ class DatasetController < ApplicationController message = "<p> #{@nb_added_docs} document#{@nb_added_docs > 1 ? "s were" : " was"} added to your dataset.</p>" message.concat "<p>#{existing.size} document#{existing.size > 1 ? "s" : ""} already exist in this dataset.</p>" unless existing.empty? # render partial: "shared/notification", locals: {notif_title: title, notif_content: message.html_safe} - out["notif"] = render_to_string layout: false, partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe } + out["notif"] = render_to_string layout: false, partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe, notif_autohide: "true" } out["nbissues"] = dataset.documents.select { |d| d["type"] == "issue" }.size out["nbarticles"] = dataset.documents.select { |d| d["type"] == "article" }.size out["nbdocs"] = out["nbissues"] + out["nbarticles"] @@ -145,7 +145,7 @@ class DatasetController < ApplicationController existing = dataset.add_compound params[:compound_id] # Add docs and return existing ids title = dataset.title message = "<p> The compound article was added to your dataset.</p>" - out["notif"] = render_to_string layout: false, partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe } + out["notif"] = render_to_string layout: false, partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe, notif_autohide: "true" } out["nbissues"] = dataset.documents.select { |d| d["type"] == "issue" }.size out["nbarticles"] = dataset.documents.select { |d| d["type"] == "article" }.size out["nbcompounds"] = dataset.documents.select { |d| d["type"] == "compound" }.size @@ -164,21 +164,27 @@ class DatasetController < ApplicationController end def add_all_documents - SearchToDatasetWorker.perform_async(current_user.id, session[:working_dataset], params[:search_params].to_unsafe_h) + time = Time.now.to_i + SearchToDatasetWorker.perform_async(current_user.id, session[:working_dataset], params[:search_params].to_unsafe_h, time) title = Dataset.find(session[:working_dataset]).title message = "<p>Documents are being added to your dataset.</p><div class=\"completion-rate mt-2\"> - <div class=\"progress\" id=\"progress-#{session[:working_dataset]}\"> + <div class=\"progress\" id=\"progress-#{session[:working_dataset]}#{time}\"> <div class=\"progress-bar progress-bar-striped\" role=\"progressbar\" style=\"width: 0%;\" aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\">0%</div> </div> </div>" - render partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe } + render partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe, notif_autohide: "false" } end def export_dataset - ExportDatasetWorker.perform_async(current_user.id, params[:dataset_id], params[:export_type]) + time = Time.now.to_i + ExportDatasetWorker.perform_async(current_user.id, params[:dataset_id], params[:export_type], time) title = Dataset.find(params[:dataset_id]).title - message = "<p>The export is being prepared. You will be notified when the operation is done.</p>" - render partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe } + message = "<p>The export is being prepared.</p><div class=\"completion-rate mt-2\"> + <div class=\"progress\" id=\"progress-#{session[:working_dataset]}#{time}\"> + <div class=\"progress-bar progress-bar-striped\" role=\"progressbar\" style=\"width: 0%;\" aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\">0%</div> + </div> +</div>" + render partial: "shared/notification", locals: { notif_title: title, notif_content: message.html_safe, notif_autohide: "false" } end def toggle_sharing_status diff --git a/app/javascript/channels/notification_channel.js b/app/javascript/channels/notification_channel.js index 7b32a09..031fd2e 100644 --- a/app/javascript/channels/notification_channel.js +++ b/app/javascript/channels/notification_channel.js @@ -41,11 +41,15 @@ consumer.subscriptions.create("NotificationChannel", { progress_bar.attr("aria-valuenow", data.completion) progress_bar.html(`${data.completion}%`) } - if(window.location.pathname.endsWith("/search")) { - const progress_bar = $("#progress-".concat(data.dataset_id)).find('.progress-bar') + if(window.location.pathname.endsWith("/search") || window.location.pathname.endsWith("/dataset/".concat(data.dataset_id))) { + const progress_bar = $("#progress-".concat(data.dataset_id).concat(data.time)).find('.progress-bar') progress_bar.attr("style", `width: ${data.completion}%;`) progress_bar.attr("aria-valuenow", data.completion) progress_bar.html(`${data.completion}%`) + + if(data.completion == 100) { + progress_bar.closest(".toast").hide(2000); + } } break case "experiment_finished": diff --git a/app/views/dataset/add_documents.js.erb b/app/views/dataset/add_documents.js.erb index de326e7..6bfb328 100644 --- a/app/views/dataset/add_documents.js.erb +++ b/app/views/dataset/add_documents.js.erb @@ -2,7 +2,8 @@ $("#notifications").append("<%= j render(partial: "shared/notification", locals: { notif_title: "Dataset modified", - notif_content: content + notif_content: content, + notif_autohide: "true" }) %>") for(const notif of $('.toast')) { diff --git a/app/views/dataset/set_working_dataset.js.erb b/app/views/dataset/set_working_dataset.js.erb index 877d6fb..b0a2f4e 100644 --- a/app/views/dataset/set_working_dataset.js.erb +++ b/app/views/dataset/set_working_dataset.js.erb @@ -2,7 +2,8 @@ $("#notifications").append("<%= j render(partial: "shared/notification", locals: { notif_title: "Working dataset", - notif_content: content + notif_content: content, + notif_autohide: "true" }) %>") for(let notif of $('.toast')) { diff --git a/app/views/shared/_notification.html.erb b/app/views/shared/_notification.html.erb index 00ff707..9bdd00d 100644 --- a/app/views/shared/_notification.html.erb +++ b/app/views/shared/_notification.html.erb @@ -1,4 +1,4 @@ -<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"> +<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide=<%= notif_autohide %>> <div class="toast-header"> <strong class="me-auto"><%= notif_title %></strong> <small class="text-muted">just now</small> diff --git a/app/workers/export_dataset_worker.rb b/app/workers/export_dataset_worker.rb index 9ef8beb..e6fc2f0 100644 --- a/app/workers/export_dataset_worker.rb +++ b/app/workers/export_dataset_worker.rb @@ -4,14 +4,25 @@ class ExportDatasetWorker include Sidekiq::Worker include ActionView::Helpers::FormOptionsHelper - def perform(user_id, dataset_id, export_type) + def perform(user_id, dataset_id, export_type, time) dataset = Dataset.find(dataset_id) file = Tempfile.new(["export_#{dataset.title.parameterize(separator: "_")}_", ".#{export_type}"], "tmp") to_write = [] named_entities = dataset.named_entities named_entities = named_entities.values.map { |h| h.values }.flatten documents = dataset.fetch_paginated_documents(1, 100, "default", "asc", "all", recursive = true) - documents[:docs].map do |doc| + numDocuments = documents[:docs].size + documents[:docs].map.with_index do |doc, idx| + increase = (100 * (idx + 1) / numDocuments).to_i - (100 * idx / numDocuments).to_i + if increase > 0 + completion = (100 * (idx + 1) / numDocuments).to_i + ActionCable.server.broadcast("notifications.#{user_id}", { + type: "completion_rate", + dataset_id: dataset_id, + completion: completion, + time: time, + }) + end case export_type when "json" lang = doc.language @@ -28,16 +39,16 @@ class ExportDatasetWorker end entities = entities.map do |ne| { - mention: ne["mention_ssi"], - indexStart: ne["article_index_start_isi"], - indexEnd: ne["article_index_end_isi"], - stance: if ne["stance_fsi"] == 0 - "neutral" - else - ne["stance_fsi"] > 0 ? "positive" : "negative" - end, - linked_entity_url: ne["linked_entity_ssi"] == "" || ne["linked_entity_ssi"].nil? ? nil : "https://www.wikidata.org/wiki/#{ne["linked_entity_ssi"].split("_")[-1]}", - } + mention: ne["mention_ssi"], + indexStart: ne["article_index_start_isi"], + indexEnd: ne["article_index_end_isi"], + stance: if ne["stance_fsi"] == 0 + "neutral" + else + ne["stance_fsi"] > 0 ? "positive" : "negative" + end, + linked_entity_url: ne["linked_entity_ssi"] == "" || ne["linked_entity_ssi"].nil? ? nil : "https://www.wikidata.org/wiki/#{ne["linked_entity_ssi"].split("_")[-1]}", + } end unless under_copyright(lang, doc.date_created, User.find(user_id)) to_write << { id: doc.id, @@ -76,7 +87,7 @@ class ExportDatasetWorker content = "<p>Your dataset is ready. <a target=\"_blank\" href=\"/en/tool/newspapers-platform/send?filename=#{File.basename(file.path)}\">Click here</a> to download it.</p>" ActionCable.server.broadcast("notifications.#{user_id}", { type: "notify", - html: ApplicationController.render(partial: "shared/notification", locals: { notif_title: dataset.title, notif_content: content }), + html: ApplicationController.render(partial: "shared/notification", locals: { notif_title: dataset.title, notif_content: content, notif_autohide: "false" }), }) end diff --git a/app/workers/search_to_dataset_worker.rb b/app/workers/search_to_dataset_worker.rb index f1126cf..cc1bc1a 100644 --- a/app/workers/search_to_dataset_worker.rb +++ b/app/workers/search_to_dataset_worker.rb @@ -2,7 +2,7 @@ class SearchToDatasetWorker include Sidekiq::Worker include ActionView::Helpers::FormOptionsHelper - def perform(user_id, dataset_id, search_params) + def perform(user_id, dataset_id, search_params, time) puts "### #{search_params}" dataset = Dataset.find(dataset_id) search_params["fl"] = "id" @@ -22,6 +22,7 @@ class SearchToDatasetWorker ActionCable.server.broadcast("notifications.#{user_id}", { type: "completion_rate", dataset_id: dataset_id, + time: time, completion: completion, }) end @@ -33,7 +34,7 @@ class SearchToDatasetWorker dataset_options = options_for_select(User.find(user_id).datasets.map { |d| ["#{d.title} (#{d.documents.size} docs)", d.id] }) ActionCable.server.broadcast("notifications.#{user_id}", { type: "notify", - html: ApplicationController.render(partial: "shared/notification", locals: { notif_title: dataset.title, notif_content: content }), + html: ApplicationController.render(partial: "shared/notification", locals: { notif_title: dataset.title, notif_content: content, notif_autohide: "true" }), dataset_options: dataset_options, }) end -- GitLab