Poll for export readiness updates

This commit is contained in:
Paul Chavard 2020-01-29 12:16:38 +01:00
parent a7e1137eeb
commit 08400cdd4c
7 changed files with 58 additions and 24 deletions

View file

@ -187,23 +187,36 @@ module Instructeurs
end end
def download_export def download_export
format = params[:export_format] export_format = params[:export_format]
groupe_instructeurs = current_instructeur groupe_instructeurs = current_instructeur
.groupe_instructeurs .groupe_instructeurs
.where(procedure: procedure) .where(procedure: procedure)
export = Export.find_or_create_export(format, groupe_instructeurs) export = Export.find_or_create_export(export_format, groupe_instructeurs)
if export.ready? if export.ready?
redirect_to export.file.service_url
else
respond_to do |format| respond_to do |format|
notice_message = "Nous générons cet export. Veuillez revenir dans quelques minutes pour le télécharger."
format.js do format.js do
@procedure = procedure @procedure = procedure
assign_exports assign_exports
flash.notice = "Lexport au format \"#{export_format}\" est prêt."
end
format.html do
redirect_to export.file.service_url
end
end
else
respond_to do |format|
notice_message = "Nous générons cet export. Veuillez revenir dans quelques minutes pour le télécharger."
format.js do
@procedure = procedure
assign_exports
if !params[:no_progress_notification]
flash.notice = notice_message flash.notice = notice_message
end end
end
format.html do format.html do
redirect_to instructeur_procedure_url(procedure), notice: notice_message redirect_to instructeur_procedure_url(procedure), notice: notice_message
@ -262,7 +275,7 @@ module Instructeurs
def ensure_ownership! def ensure_ownership!
if !current_instructeur.procedures.include?(procedure) if !current_instructeur.procedures.include?(procedure)
flash[:alert] = "Vous n'avez pas accès à cette démarche" flash[:alert] = "Vous navez pas accès à cette démarche"
redirect_to root_path redirect_to root_path
end end
end end

View file

@ -10,7 +10,7 @@ import ReactRailsUJS from 'react_ujs';
import '../shared/page-update-event'; import '../shared/page-update-event';
import '../shared/activestorage/ujs'; import '../shared/activestorage/ujs';
import '../shared/activestorage/attachment-checker'; import '../shared/remote-poller';
import '../shared/rails-ujs-fix'; import '../shared/rails-ujs-fix';
import '../shared/safari-11-file-xhr-workaround'; import '../shared/safari-11-file-xhr-workaround';
import '../shared/remote-input'; import '../shared/remote-input';

View file

@ -1,32 +1,42 @@
import { ajax, delegate } from '@utils'; import { ajax, delegate } from '@utils';
addEventListener('turbolinks:load', () => { addEventListener('turbolinks:load', () => {
checker.deactivate(); attachementPoller.deactivate();
exportPoller.deactivate();
const attachments = document.querySelectorAll('[data-attachment-check-url]'); const attachments = document.querySelectorAll('[data-attachment-poll-url]');
const exports = document.querySelectorAll('[data-export-poll-url]');
for (let attachment of attachments) { for (let { dataset } of attachments) {
checker.add(attachment.dataset.attachmentCheckUrl); attachementPoller.add(dataset.attachmentPollUrl);
}
for (let { dataset } of exports) {
exportPoller.add(dataset.exportPollUrl);
} }
}); });
addEventListener('attachment:update', ({ detail: { url } }) => { addEventListener('attachment:update', ({ detail: { url } }) => {
checker.add(url); attachementPoller.add(url);
});
addEventListener('export:update', ({ detail: { url } }) => {
exportPoller.add(url);
}); });
delegate('click', '[data-attachment-refresh]', event => { delegate('click', '[data-attachment-refresh]', event => {
event.preventDefault(); event.preventDefault();
checker.check(); attachementPoller.check();
}); });
class AttachmentChecker { class RemotePoller {
urls = new Set(); urls = new Set();
timeout; timeout;
checks = 0; checks = 0;
constructor(settings = {}) { constructor(settings = {}) {
this.interval = settings.interval || 5000; this.interval = settings.interval;
this.maxChecks = settings.maxChecks || 5; this.maxChecks = settings.maxChecks;
} }
get isEnabled() { get isEnabled() {
@ -58,12 +68,14 @@ class AttachmentChecker {
clearTimeout(this.timeout); clearTimeout(this.timeout);
this.timeout = setTimeout(() => { this.timeout = setTimeout(() => {
this.checks++; this.checks++;
this.currentInterval = this.interval * 1.5;
this.check(); this.check();
}, this.interval); }, this.currentInterval);
} }
deactivate() { deactivate() {
this.checks = 0; this.checks = 0;
this.currentInterval = this.interval;
this.reset(); this.reset();
} }
@ -74,4 +86,5 @@ class AttachmentChecker {
} }
} }
const checker = new AttachmentChecker(); const attachementPoller = new RemotePoller({ interval: 2000, maxChecks: 5 });
const exportPoller = new RemotePoller({ interval: 4000, maxChecks: 10 });

View file

@ -9,6 +9,7 @@
- if export.nil? - if export.nil?
= link_to "Demander un export au format .#{format}", download_export_instructeur_procedure_path(procedure, export_format: format), remote: true = link_to "Demander un export au format .#{format}", download_export_instructeur_procedure_path(procedure, export_format: format), remote: true
- elsif export.ready? - elsif export.ready?
= link_to "Télécharger l'export au format .#{format}", url_for(export.file), target: "_blank", rel: "noopener" = link_to "Télécharger l'export au format .#{format}", export.file.service_url, target: "_blank", rel: "noopener"
- else - else
%span{ 'data-export-poll-url': download_export_instructeur_procedure_path(procedure, export_format: format, no_progress_notification: true) }
L'export au format .#{format} est en cours de préparation L'export au format .#{format} est en cours de préparation

View file

@ -1,3 +1,10 @@
<%= render_to_element('.procedure-actions', partial: "download_dossiers", <%= render_to_element('.procedure-actions', partial: "download_dossiers",
locals: { procedure: @procedure, xlsx_export: @xlsx_export, csv_export: @csv_export, ods_export: @ods_export }) %> locals: { procedure: @procedure, xlsx_export: @xlsx_export, csv_export: @csv_export, ods_export: @ods_export }) %>
<%= render_flash %>
<% [[@xlsx_export, :xlsx], [@csv_export, :csv], [@ods_export, :ods]].each do |(export, format)| %>
<% if export && !export.ready? %>
<%= fire_event('export:update', { url: download_export_instructeur_procedure_path(@procedure, export_format: format, no_progress_notification: true) }.to_json ) %>
<% end %>
<% end %>
<%= render_flash(timeout: 7000) %>

View file

@ -5,7 +5,7 @@
- else - else
- attachment_check_url = attachment_url(attachment.id, { signed_id: attachment.blob.signed_id, user_can_upload: user_can_upload }) - attachment_check_url = attachment_url(attachment.id, { signed_id: attachment.blob.signed_id, user_can_upload: user_can_upload })
.attachment-link{ 'data-attachment-id': attachment.id, 'data-attachment-check-url': attachment_check_url } .attachment-link{ 'data-attachment-id': attachment.id, 'data-attachment-poll-url': attachment_check_url }
- if should_display_link - if should_display_link
= link_to url_for(attachment.blob), target: '_blank', rel: 'noopener', title: "Télécharger la pièce jointe" do = link_to url_for(attachment.blob), target: '_blank', rel: 'noopener', title: "Télécharger la pièce jointe" do
%span.icon.attached %span.icon.attached

View file

@ -37,7 +37,7 @@ describe Instructeurs::ProceduresController, type: :controller do
it "redirects and flash" do it "redirects and flash" do
expect(@controller).to have_received(:redirect_to).with(root_path) expect(@controller).to have_received(:redirect_to).with(root_path)
expect(flash.alert).to eq("Vous n'avez pas accès à cette démarche") expect(flash.alert).to eq("Vous navez pas accès à cette démarche")
end end
end end
end end