commit
83900b49c6
9 changed files with 62 additions and 12 deletions
2
Gemfile
2
Gemfile
|
@ -79,7 +79,7 @@ gem 'zipline'
|
||||||
gem 'zxcvbn-ruby', require: 'zxcvbn'
|
gem 'zxcvbn-ruby', require: 'zxcvbn'
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'capybara' # Integration testing
|
gem 'capybara', '3.13.2' # Integration testing
|
||||||
gem 'capybara-email' # Access emails during integration tests
|
gem 'capybara-email' # Access emails during integration tests
|
||||||
gem 'capybara-screenshot' # Save a dump of the page when an integration test fails
|
gem 'capybara-screenshot' # Save a dump of the page when an integration test fails
|
||||||
gem 'capybara-selenium'
|
gem 'capybara-selenium'
|
||||||
|
|
|
@ -119,13 +119,13 @@ GEM
|
||||||
browser (2.5.3)
|
browser (2.5.3)
|
||||||
builder (3.2.3)
|
builder (3.2.3)
|
||||||
byebug (10.0.2)
|
byebug (10.0.2)
|
||||||
capybara (3.29.0)
|
capybara (3.13.2)
|
||||||
addressable
|
addressable
|
||||||
mini_mime (>= 0.1.3)
|
mini_mime (>= 0.1.3)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
rack (>= 1.6.0)
|
rack (>= 1.6.0)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
regexp_parser (~> 1.5)
|
regexp_parser (~> 1.2)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
capybara-email (3.0.1)
|
capybara-email (3.0.1)
|
||||||
capybara (>= 2.4, < 4.0)
|
capybara (>= 2.4, < 4.0)
|
||||||
|
@ -722,7 +722,7 @@ DEPENDENCIES
|
||||||
brakeman
|
brakeman
|
||||||
browser
|
browser
|
||||||
byebug
|
byebug
|
||||||
capybara
|
capybara (= 3.13.2)
|
||||||
capybara-email
|
capybara-email
|
||||||
capybara-screenshot
|
capybara-screenshot
|
||||||
capybara-selenium
|
capybara-selenium
|
||||||
|
|
|
@ -207,16 +207,19 @@ module Instructeurs
|
||||||
|
|
||||||
def download_export
|
def download_export
|
||||||
export_format = params[:export_format]
|
export_format = params[:export_format]
|
||||||
|
notice_message = "Nous générons cet export. Lorsque celui-ci sera disponible, vous recevrez une notification par email accompagnée d'un lien de téléchargement."
|
||||||
if procedure.should_generate_export?(export_format)
|
if procedure.should_generate_export?(export_format)
|
||||||
procedure.queue_export(current_instructeur, export_format)
|
procedure.queue_export(current_instructeur, export_format)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.js do
|
format.js do
|
||||||
flash.notice = "Nous générons cet export. Lorsque celui-ci sera disponible, vous recevrez une notification par email accompagnée d'un lien de téléchargement."
|
flash.notice = notice_message
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
elsif procedure.export_queued?(export_format)
|
||||||
|
flash.notice = notice_message
|
||||||
|
redirect_to procedure
|
||||||
else
|
else
|
||||||
redirect_to url_for(procedure.export_file(export_format))
|
redirect_to url_for(procedure.export_file(export_format))
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,7 +31,7 @@ const TypeDeChamp = sortableElement(
|
||||||
!isHeaderSection && !isExplication && !state.isAnnotation;
|
!isHeaderSection && !isExplication && !state.isAnnotation;
|
||||||
|
|
||||||
const [ref, inView] = useInView({
|
const [ref, inView] = useInView({
|
||||||
threshold: [0.6]
|
threshold: 0.6
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateHandlers = createUpdateHandlers(
|
const updateHandlers = createUpdateHandlers(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import ProgressBar from './progress-bar';
|
import ProgressBar from './progress-bar';
|
||||||
|
import { fire } from '@utils';
|
||||||
|
|
||||||
const INITIALIZE_EVENT = 'direct-upload:initialize';
|
const INITIALIZE_EVENT = 'direct-upload:initialize';
|
||||||
const START_EVENT = 'direct-upload:start';
|
const START_EVENT = 'direct-upload:start';
|
||||||
|
@ -36,8 +37,18 @@ addUploadEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => {
|
||||||
ProgressBar.progress(id, progress);
|
ProgressBar.progress(id, progress);
|
||||||
});
|
});
|
||||||
|
|
||||||
addUploadEventListener(ERROR_EVENT, ({ detail: { id, error } }) => {
|
addUploadEventListener(ERROR_EVENT, event => {
|
||||||
ProgressBar.error(id, error);
|
// Display an error message
|
||||||
|
alert(
|
||||||
|
`Nous sommes désolés, une erreur s’est produite lors de l’envoi du fichier.
|
||||||
|
|
||||||
|
(${event.detail.error})`
|
||||||
|
);
|
||||||
|
// Prevent ActiveStorage from displaying its own error message
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
ProgressBar.error(event.detail.id, event.detail.error);
|
||||||
|
fire(document, 'sentry:capture-exception', new Error(event.detail.error));
|
||||||
});
|
});
|
||||||
|
|
||||||
addUploadEventListener(END_EVENT, ({ detail: { id } }) => {
|
addUploadEventListener(END_EVENT, ({ detail: { id } }) => {
|
||||||
|
|
|
@ -10,4 +10,10 @@ if (enabled && key) {
|
||||||
scope.setUser(user);
|
scope.setUser(user);
|
||||||
scope.setExtra('browser', browser.modern ? 'modern' : 'legacy');
|
scope.setExtra('browser', browser.modern ? 'modern' : 'legacy');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Register a way to explicitely capture messages from a different bundle.
|
||||||
|
addEventListener('sentry:capture-exception', event => {
|
||||||
|
const error = event.detail;
|
||||||
|
Sentry.captureException(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,25 @@ class CleanupStaleExportsJob < ApplicationJob
|
||||||
queue_as :cron
|
queue_as :cron
|
||||||
|
|
||||||
def perform(*args)
|
def perform(*args)
|
||||||
ActiveStorage::Attachment.where(
|
attachments = ActiveStorage::Attachment.where(
|
||||||
"name in ('csv_export_file', 'ods_export_file', 'xlsx_export_file') and created_at < ?",
|
"name in ('csv_export_file', 'ods_export_file', 'xlsx_export_file') and created_at < ?",
|
||||||
Procedure::MAX_DUREE_CONSERVATION_EXPORT.ago
|
Procedure::MAX_DUREE_CONSERVATION_EXPORT.ago
|
||||||
).find_each(&:purge_later)
|
)
|
||||||
|
attachments.each do |attachment|
|
||||||
|
procedure = Procedure.find(attachment.record_id)
|
||||||
|
# export can't be queued if it's already attached
|
||||||
|
# so we clean the flag up just in case it was not removed during
|
||||||
|
# the asynchronous generation
|
||||||
|
case attachment.name
|
||||||
|
when 'csv_export_file'
|
||||||
|
procedure.update(csv_export_queued: false)
|
||||||
|
when 'ods_export_file'
|
||||||
|
procedure.update(ods_export_queued: false)
|
||||||
|
when 'xlsx_export_file'
|
||||||
|
procedure.update(xlsx_export_queued: false)
|
||||||
|
end
|
||||||
|
# and we remove the stale attachment
|
||||||
|
attachment.purge_later
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -145,6 +145,18 @@ class Procedure < ApplicationRecord
|
||||||
!ods_export_file.attached? || ods_export_file.created_at < MAX_DUREE_CONSERVATION_EXPORT.ago
|
!ods_export_file.attached? || ods_export_file.created_at < MAX_DUREE_CONSERVATION_EXPORT.ago
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def export_queued?(format)
|
||||||
|
case format.to_sym
|
||||||
|
when :csv
|
||||||
|
return csv_export_queued?
|
||||||
|
when :xlsx
|
||||||
|
return xlsx_export_queued?
|
||||||
|
when :ods
|
||||||
|
return ods_export_queued?
|
||||||
|
end
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def should_generate_export?(format)
|
def should_generate_export?(format)
|
||||||
case format.to_sym
|
case format.to_sym
|
||||||
when :csv
|
when :csv
|
||||||
|
@ -169,7 +181,6 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def queue_export(instructeur, export_format)
|
def queue_export(instructeur, export_format)
|
||||||
ExportProcedureJob.perform_now(self, instructeur, export_format)
|
|
||||||
case export_format.to_sym
|
case export_format.to_sym
|
||||||
when :csv
|
when :csv
|
||||||
update(csv_export_queued: true)
|
update(csv_export_queued: true)
|
||||||
|
@ -178,6 +189,7 @@ class Procedure < ApplicationRecord
|
||||||
when :ods
|
when :ods
|
||||||
update(ods_export_queued: true)
|
update(ods_export_queued: true)
|
||||||
end
|
end
|
||||||
|
ExportProcedureJob.perform_later(self, instructeur, export_format)
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare_export_download(format)
|
def prepare_export_download(format)
|
||||||
|
|
|
@ -94,6 +94,8 @@ desc "Deploys the current version to the server."
|
||||||
task :deploy do
|
task :deploy do
|
||||||
command 'export PATH=$PATH:/home/ds/.rbenv/bin:/home/ds/.rbenv/shims'
|
command 'export PATH=$PATH:/home/ds/.rbenv/bin:/home/ds/.rbenv/shims'
|
||||||
command 'source /home/ds/.profile'
|
command 'source /home/ds/.profile'
|
||||||
|
# increase db timeout to 5 minutes to allow long migration
|
||||||
|
command 'export PG_STATEMENT_TIMEOUT=300000'
|
||||||
|
|
||||||
deploy do
|
deploy do
|
||||||
# Put things that will set up an empty directory into a fully set-up
|
# Put things that will set up an empty directory into a fully set-up
|
||||||
|
|
Loading…
Reference in a new issue