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
def download_export
format = params[:export_format]
export_format = params[:export_format]
groupe_instructeurs = current_instructeur
.groupe_instructeurs
.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?
redirect_to export.file.service_url
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
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
end
end
format.html do
redirect_to instructeur_procedure_url(procedure), notice: notice_message
@ -262,7 +275,7 @@ module Instructeurs
def ensure_ownership!
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
end
end

View file

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

View file

@ -1,32 +1,42 @@
import { ajax, delegate } from '@utils';
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) {
checker.add(attachment.dataset.attachmentCheckUrl);
for (let { dataset } of attachments) {
attachementPoller.add(dataset.attachmentPollUrl);
}
for (let { dataset } of exports) {
exportPoller.add(dataset.exportPollUrl);
}
});
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 => {
event.preventDefault();
checker.check();
attachementPoller.check();
});
class AttachmentChecker {
class RemotePoller {
urls = new Set();
timeout;
checks = 0;
constructor(settings = {}) {
this.interval = settings.interval || 5000;
this.maxChecks = settings.maxChecks || 5;
this.interval = settings.interval;
this.maxChecks = settings.maxChecks;
}
get isEnabled() {
@ -58,12 +68,14 @@ class AttachmentChecker {
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.checks++;
this.currentInterval = this.interval * 1.5;
this.check();
}, this.interval);
}, this.currentInterval);
}
deactivate() {
this.checks = 0;
this.currentInterval = this.interval;
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?
= link_to "Demander un export au format .#{format}", download_export_instructeur_procedure_path(procedure, export_format: format), remote: true
- 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
%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

View file

@ -1,3 +1,10 @@
<%= render_to_element('.procedure-actions', partial: "download_dossiers",
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
- 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
= link_to url_for(attachment.blob), target: '_blank', rel: 'noopener', title: "Télécharger la pièce jointe" do
%span.icon.attached

View file

@ -37,7 +37,7 @@ describe Instructeurs::ProceduresController, type: :controller do
it "redirects and flash" do
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