diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 74554d1b0..d777e6143 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -174,7 +174,7 @@ module Users respond_to do |format| format.html { render :brouillon } - format.js + format.turbo_stream end end diff --git a/app/helpers/dossier_helper.rb b/app/helpers/dossier_helper.rb index 032b5cf8d..c64d1e87a 100644 --- a/app/helpers/dossier_helper.rb +++ b/app/helpers/dossier_helper.rb @@ -29,14 +29,6 @@ module DossierHelper new_dossier_url(procedure_id: revision.procedure.id, brouillon: revision.draft? ? true : nil) end - def dossier_form_class(dossier) - classes = ['form'] - if autosave_available?(dossier) - classes << 'autosave-enabled' - end - classes.join(' ') - end - def autosave_available?(dossier) dossier.brouillon? end diff --git a/app/javascript/components/shared/hooks.ts b/app/javascript/components/shared/hooks.ts index 483d5477f..f91ed8d69 100644 --- a/app/javascript/components/shared/hooks.ts +++ b/app/javascript/components/shared/hooks.ts @@ -60,7 +60,7 @@ export function useHiddenField( if (hiddenField) { hiddenField.setAttribute('value', value); setValue(value); - fire(hiddenField, 'autosave:trigger'); + fire(hiddenField, 'change'); } }, hiddenField ?? undefined diff --git a/app/views/champs/piece_justificative/show.js.erb b/app/views/champs/piece_justificative/show.js.erb deleted file mode 100644 index ea8cb9ecb..000000000 --- a/app/views/champs/piece_justificative/show.js.erb +++ /dev/null @@ -1,10 +0,0 @@ -<%= fields_for @champ.input_name, @champ do |form| %> - <%= render_to_element("##{@champ.input_group_id}", partial: "shared/dossiers/editable_champs/editable_champ", locals: { champ: @champ, form: form }, outer: true) %> -<% end %> - -<% attachment = @champ.piece_justificative_file.attachment %> -<% if attachment.virus_scanner.pending? %> - <%= fire_event('attachment:update', { url: attachment_url(attachment.id, { signed_id: attachment.blob.signed_id, user_can_upload: true }) }.to_json ) %> -<% end %> - -<%= focus_element("button[data-toggle-target=\".attachment-input-#{attachment.id}\"]") %> diff --git a/app/views/champs/piece_justificative/show.turbo_stream.haml b/app/views/champs/piece_justificative/show.turbo_stream.haml new file mode 100644 index 000000000..8263d9cec --- /dev/null +++ b/app/views/champs/piece_justificative/show.turbo_stream.haml @@ -0,0 +1,6 @@ += fields_for @champ.input_name, @champ do |form| + = turbo_stream.replace @champ.input_group_id, partial: "shared/dossiers/editable_champs/editable_champ", locals: { champ: @champ, form: form } + +- if @champ.piece_justificative_file.attached? + - attachment = @champ.piece_justificative_file.attachment + = turbo_stream.focus_all "button[data-toggle-target=\".attachment-input-#{attachment.id}\"]" diff --git a/app/views/shared/attachment/_edit.html.haml b/app/views/shared/attachment/_edit.html.haml index 124680296..358b1a3a3 100644 --- a/app/views/shared/attachment/_edit.html.haml +++ b/app/views/shared/attachment/_edit.html.haml @@ -30,7 +30,7 @@ Une erreur s’est produite pendant l’envoi du fichier. %p.attachment-error-description Une erreur inconnue s'est produite pendant l'envoi du fichier - = button_tag type: 'button', class: 'button attachment-error-retry', data: { 'input-target': ".attachment-input-#{attachment_id}" } do + = button_tag type: 'button', class: 'button attachment-error-retry', data: { 'input-target': ".attachment-input-#{attachment_id}", action: 'autosave#onClickRetryButton' } do %span.icon.retry Ré-essayer diff --git a/app/views/shared/dossiers/_edit.html.haml b/app/views/shared/dossiers/_edit.html.haml index cbf21eb76..a195538bd 100644 --- a/app/views/shared/dossiers/_edit.html.haml +++ b/app/views/shared/dossiers/_edit.html.haml @@ -8,7 +8,7 @@ - else - form_options = { url: modifier_dossier_url(dossier), method: :patch } - = form_for dossier, form_options.merge({ html: { id: 'dossier-edit-form', class: dossier_form_class(dossier), multipart: true } }) do |f| + = form_for dossier, form_options.merge({ html: { id: 'dossier-edit-form', class: 'form', multipart: true } }) do |f| .prologue %p.mandatory-explanation= t('utils.asterisk_html') @@ -28,12 +28,13 @@ %hr - if dossier.show_groupe_instructeur_selector? - = f.label :groupe_instructeur_id do - = dossier.procedure.routing_criteria_name - %span.mandatory * - = f.select :groupe_instructeur_id, - dossier.procedure.groupe_instructeurs.order(:label).map { |gi| [gi.label, gi.id] }, - { include_blank: dossier.brouillon? } + %span{ data: autosave_available?(dossier) ? { controller: 'autosave', autosave_url_value: brouillon_dossier_path(dossier) } : {} } + = f.label :groupe_instructeur_id do + = dossier.procedure.routing_criteria_name + %span.mandatory * + = f.select :groupe_instructeur_id, + dossier.procedure.groupe_instructeurs.order(:label).map { |gi| [gi.label, gi.id] }, + { include_blank: dossier.brouillon? } - dossier.champs.each do |champ| = fields_for champ.input_name, champ do |form| diff --git a/app/views/shared/dossiers/editable_champs/_editable_champ.html.haml b/app/views/shared/dossiers/editable_champs/_editable_champ.html.haml index 3ce3a193b..32334011d 100644 --- a/app/views/shared/dossiers/editable_champs/_editable_champ.html.haml +++ b/app/views/shared/dossiers/editable_champs/_editable_champ.html.haml @@ -1,4 +1,5 @@ -.editable-champ{ class: "editable-champ-#{champ.type_champ}", id: champ.input_group_id } +- autosave_controller = autosave_available?(champ.dossier) && !champ.repetition? ? { controller: 'autosave', autosave_url_value: brouillon_dossier_path(champ.dossier) } : {} +.editable-champ{ class: "editable-champ-#{champ.type_champ}", id: champ.input_group_id, data: autosave_controller } - if champ.repetition? %h3.header-subsection= champ.libelle - if champ.description.present? @@ -9,5 +10,5 @@ - if champ.type_champ == "titre_identite" %p.notice Carte nationale d’identité (uniquement le recto), passeport, titre de séjour ou autre justificatif d’identité. Formats acceptés : jpg/png - = form.hidden_field :id, value: champ.id + = form.hidden_field :id, value: champ.id, data: champ.repetition? ? { id: true } : {} = render partial: "shared/dossiers/editable_champs/#{champ.type_champ}", locals: { form: form, champ: champ } diff --git a/app/views/users/dossiers/_autosave.html.haml b/app/views/users/dossiers/_autosave.html.haml index 382f182dc..73fb580b6 100644 --- a/app/views/users/dossiers/_autosave.html.haml +++ b/app/views/users/dossiers/_autosave.html.haml @@ -1,4 +1,4 @@ -.autosave.autosave-state-idle +.autosave.autosave-state-idle{ data: { controller: 'autosave-status' } } %p.autosave-explanation %span.autosave-explanation-text = t('views.users.dossiers.autosave.autosave_draft') @@ -13,7 +13,7 @@ %p.autosave-status.failed %span.autosave-icon ⚠️ %span.autosave-label Impossible d’enregistrer le brouillon - %button.button.small.autosave-retry + %button.button.small.autosave-retry{ type: :button, data: { action: 'autosave-status#onClickRetryButton', autosave_status_target: 'retryButton' } } %span.autosave-retry-label réessayer %span.autosave-retrying-label enregistrement en cours… diff --git a/spec/controllers/champs/piece_justificative_controller_spec.rb b/spec/controllers/champs/piece_justificative_controller_spec.rb index 700ca9ce9..6e6facb88 100644 --- a/spec/controllers/champs/piece_justificative_controller_spec.rb +++ b/spec/controllers/champs/piece_justificative_controller_spec.rb @@ -13,7 +13,7 @@ describe Champs::PieceJustificativeController, type: :controller do position: '1', champ_id: champ.id, blob_signed_id: file - }, format: 'js' + }, format: :turbo_stream end context 'when the file is valid' do @@ -29,7 +29,7 @@ describe Champs::PieceJustificativeController, type: :controller do it 'renders the attachment template as Javascript' do subject expect(response.status).to eq(200) - expect(response.body).to include("##{champ.input_group_id}") + expect(response.body).to include("action=\"replace\" target=\"#{champ.input_group_id}\"") end it 'updates dossier.last_champ_updated_at' do diff --git a/spec/system/users/brouillon_spec.rb b/spec/system/users/brouillon_spec.rb index 9ceca4599..68d41d392 100644 --- a/spec/system/users/brouillon_spec.rb +++ b/spec/system/users/brouillon_spec.rb @@ -247,14 +247,18 @@ describe 'The user' do fill_individual # Test auto-upload failure - logout(:user) # Make the subsequent auto-upload request fail + # Make the subsequent auto-upload request fail + allow_any_instance_of(Champs::PieceJustificativeController).to receive(:update) do |instance| + instance.render json: { errors: ['Error'] }, status: :bad_request + end attach_file('Pièce justificative 1', Rails.root + 'spec/fixtures/files/file.pdf') expect(page).to have_text('Une erreur s’est produite pendant l’envoi du fichier') expect(page).to have_button('Ré-essayer', visible: true) expect(page).to have_button('Déposer le dossier', disabled: false) + allow_any_instance_of(Champs::PieceJustificativeController).to receive(:update).and_call_original + # Test that retrying after a failure works - login_as(user, scope: :user) # Make the auto-upload request work again click_on('Ré-essayer', visible: true) expect(page).to have_text('analyse antivirus en cours') expect(page).to have_text('file.pdf')