Merge pull request #10603 from demarches-simplifiees/bug-input-pj-apres-suppression
ETQ Admin (bug), je veux pouvoir modifier des PJ sans recharger la page
This commit is contained in:
commit
90e6c8a6f6
9 changed files with 41 additions and 23 deletions
|
@ -20,6 +20,7 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
@user_can_replace = user_can_replace
|
@user_can_replace = user_can_replace
|
||||||
@as_multiple = as_multiple
|
@as_multiple = as_multiple
|
||||||
@auto_attach_url = auto_attach_url
|
@auto_attach_url = auto_attach_url
|
||||||
|
|
||||||
# Adaptation pour la gestion des pièces jointes multiples
|
# Adaptation pour la gestion des pièces jointes multiples
|
||||||
@attachments = attachments.presence || (kwargs.key?(:attachment) ? [kwargs.delete(:attachment)] : [])
|
@attachments = attachments.presence || (kwargs.key?(:attachment) ? [kwargs.delete(:attachment)] : [])
|
||||||
@attachments << attached_file.attachment if attached_file.respond_to?(:attachment) && @attachments.empty?
|
@attachments << attached_file.attachment if attached_file.respond_to?(:attachment) && @attachments.empty?
|
||||||
|
@ -55,7 +56,11 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy_attachment_path
|
def destroy_attachment_path
|
||||||
attachment_path(dossier_id: champ&.dossier_id, stable_id: champ&.stable_id, row_id: champ&.row_id)
|
if champ.present?
|
||||||
|
attachment_path(dossier_id: champ&.dossier_id, stable_id: champ&.stable_id, row_id: champ&.row_id)
|
||||||
|
else
|
||||||
|
attachment_path(auto_attach_url: @auto_attach_url, view_as: @view_as, direct_upload: @direct_upload)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def attachment_input_class
|
def attachment_input_class
|
||||||
|
@ -66,7 +71,7 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
track_issue_with_missing_validators if missing_validators?
|
track_issue_with_missing_validators if missing_validators?
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
class: class_names("fr-upload attachment-input": true, "#{attachment_input_class}": true, "hidden": persisted?),
|
class: class_names("fr-upload attachment-input": true, "#{attachment_input_class}": true),
|
||||||
direct_upload: @direct_upload,
|
direct_upload: @direct_upload,
|
||||||
id: input_id,
|
id: input_id,
|
||||||
aria: { describedby: champ&.describedby_id },
|
aria: { describedby: champ&.describedby_id },
|
||||||
|
@ -78,7 +83,7 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
|
|
||||||
options.merge!(has_content_type_validator? ? { accept: accept_content_type } : {})
|
options.merge!(has_content_type_validator? ? { accept: accept_content_type } : {})
|
||||||
options[:multiple] = true if as_multiple?
|
options[:multiple] = true if as_multiple?
|
||||||
options[:disabled] = true if @max && @index >= @max
|
options[:disabled] = true if (@max && @index >= @max) || persisted?
|
||||||
|
|
||||||
options
|
options
|
||||||
end
|
end
|
||||||
|
@ -166,10 +171,10 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
def input_id
|
def input_id
|
||||||
if champ.present?
|
if champ.present?
|
||||||
# There is always a single input by champ, its id must match the label "for" attribute.
|
# There is always a single input by champ, its id must match the label "for" attribute.
|
||||||
return champ.input_id
|
champ.input_id
|
||||||
|
else
|
||||||
|
dom_id(@attached_file.record, attribute_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
helpers.field_id(@form_object_name || @attached_file.record, attribute_name)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def auto_attach_url
|
def auto_attach_url
|
||||||
|
|
|
@ -21,7 +21,11 @@ class AttachmentsController < ApplicationController
|
||||||
@attachment.purge_later
|
@attachment.purge_later
|
||||||
flash.notice = 'La pièce jointe a bien été supprimée.'
|
flash.notice = 'La pièce jointe a bien été supprimée.'
|
||||||
|
|
||||||
@champ = find_champ if params[:dossier_id]
|
if params[:dossier_id]
|
||||||
|
@champ = find_champ
|
||||||
|
else
|
||||||
|
@attachment_options = attachment_options
|
||||||
|
end
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.turbo_stream
|
format.turbo_stream
|
||||||
|
@ -35,4 +39,13 @@ class AttachmentsController < ApplicationController
|
||||||
dossier = policy_scope(Dossier).includes(:champs).find(params[:dossier_id])
|
dossier = policy_scope(Dossier).includes(:champs).find(params[:dossier_id])
|
||||||
dossier.champs.find_by(stable_id: params[:stable_id], row_id: params[:row_id])
|
dossier.champs.find_by(stable_id: params[:stable_id], row_id: params[:row_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def attachment_options
|
||||||
|
{
|
||||||
|
attached_file: @attachment.record.public_send(@attachment.name),
|
||||||
|
view_as: params[:view_as]&.to_sym,
|
||||||
|
direct_upload: params[:direct_upload] == "true",
|
||||||
|
auto_attach_url: params[:direct_upload] == "true" ? params[:auto_attach_url] : nil
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
- c.with_hint { "Exemple: Ministère de la Mer. 5 lignes maximum" }
|
- c.with_hint { "Exemple: Ministère de la Mer. 5 lignes maximum" }
|
||||||
|
|
||||||
.fr-fieldset__element{ data: { attestation_target: 'logoAttachmentFieldset' } }
|
.fr-fieldset__element{ data: { attestation_target: 'logoAttachmentFieldset' } }
|
||||||
%label.fr-label{ for: field_id(@attestation_template, :logo) }
|
%label.fr-label{ for: dom_id(@attestation_template, :logo) }
|
||||||
- if @attestation_template.official_layout?
|
- if @attestation_template.official_layout?
|
||||||
= AttestationTemplate.human_attribute_name(:logo_additional)
|
= AttestationTemplate.human_attribute_name(:logo_additional)
|
||||||
- else
|
- else
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
%h2.fr-h4 Pied de page
|
%h2.fr-h4 Pied de page
|
||||||
|
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
%label.fr-label{ for: field_id(@attestation_template, :signature) } Tampon ou signature
|
%label.fr-label{ for: dom_id(@attestation_template, :signature) } Tampon ou signature
|
||||||
%span.fr-hint-text
|
%span.fr-hint-text
|
||||||
Dimensions conseillées : au minimum 500px de largeur ou de hauteur.
|
Dimensions conseillées : au minimum 500px de largeur ou de hauteur.
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
.fr-input-group
|
.fr-input-group
|
||||||
= f.label :logo, 'Ajouter un logo de la démarche', class: 'fr-label'
|
= f.label :logo, 'Ajouter un logo de la démarche', class: 'fr-label', for: dom_id(@procedure, :logo)
|
||||||
= render Attachment::EditComponent.new(attached_file: @procedure.logo, view_as: :link)
|
= render Attachment::EditComponent.new(attached_file: @procedure.logo, view_as: :link)
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
.fr-input-group
|
.fr-input-group
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
|
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
.fr-input-group
|
.fr-input-group
|
||||||
= f.label :deliberation, 'Cadre juridique - texte à importer', class: 'fr-label'
|
= f.label :deliberation, 'Cadre juridique - texte à importer', class: 'fr-label', for: dom_id(@procedure, :deliberation)
|
||||||
= render Attachment::EditComponent.new(attached_file: @procedure.deliberation, view_as: :download)
|
= render Attachment::EditComponent.new(attached_file: @procedure.deliberation, view_as: :download)
|
||||||
|
|
||||||
%fieldset.fr-fieldset
|
%fieldset.fr-fieldset
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
|
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
.fr-input-group
|
.fr-input-group
|
||||||
= f.label :notice, 'Notice explicative de la démarche', class: 'fr-label'
|
= f.label :notice, 'Notice explicative de la démarche', class: 'fr-label', for: dom_id(@procedure, :notice)
|
||||||
%p.fr-hint-text
|
%p.fr-hint-text
|
||||||
Une notice explicative est un document que vous avez élaboré, destiné à guider l’usager dans sa démarche. Le bouton pour télécharger cette notice apparaît en haut du formulaire pour l’usager.
|
Une notice explicative est un document que vous avez élaboré, destiné à guider l’usager dans sa démarche. Le bouton pour télécharger cette notice apparaît en haut du formulaire pour l’usager.
|
||||||
%br
|
%br
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
= turbo_stream.remove dom_id(@attachment, :persisted_row)
|
|
||||||
|
|
||||||
= turbo_stream.show_all ".attachment-input-#{@attachment.id}"
|
|
||||||
|
|
||||||
- if @champ
|
- if @champ
|
||||||
= fields_for @champ.input_name, @champ do |form|
|
= fields_for @champ.input_name, @champ do |form|
|
||||||
= turbo_stream.replace @champ.input_group_id do
|
= turbo_stream.replace @champ.input_group_id do
|
||||||
= render EditableChamp::EditableChampComponent.new champ: @champ, form: form
|
= render EditableChamp::EditableChampComponent.new champ: @champ, form: form
|
||||||
= turbo_stream.focus_all "#attachment-multiple-empty-#{@champ.public_id} input"
|
= turbo_stream.focus_all "#attachment-multiple-empty-#{@champ.public_id} input"
|
||||||
|
- else
|
||||||
|
= turbo_stream.replace dom_id(@attachment, :edit) do
|
||||||
|
= render Attachment::EditComponent.new(**@attachment_options)
|
||||||
|
= turbo_stream.focus_all "##{dom_id(@attachment.record, @attachment.name)}"
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
- if local_assigns.has_key?(:dossier)
|
- if local_assigns.has_key?(:dossier)
|
||||||
.fr-mt-3w.fr-input-group
|
.fr-mt-3w.fr-input-group
|
||||||
= f.label :piece_jointe, class: "fr-label"
|
= f.label :piece_jointe, class: "fr-label", for: dom_id(commentaire, :piece_jointe)
|
||||||
%div{ data: { controller: "file-input-reset", delete_label: t('views.shared.messages.remove_file') } }
|
%div{ data: { controller: "file-input-reset", delete_label: t('views.shared.messages.remove_file') } }
|
||||||
= render Attachment::MultipleComponent.new(attached_file: commentaire.piece_jointe)
|
= render Attachment::MultipleComponent.new(attached_file: commentaire.piece_jointe)
|
||||||
%ul{ data: { 'file-input-reset-target': 'fileList' } }
|
%ul{ data: { 'file-input-reset-target': 'fileList' } }
|
||||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe Attachment::EditComponent, type: :component do
|
||||||
let(:attachment) { nil }
|
let(:attachment) { nil }
|
||||||
|
|
||||||
it 'renders a form field for uploading a file' do
|
it 'renders a form field for uploading a file' do
|
||||||
expect(subject).to have_selector('input[type=file]:not(.hidden)')
|
expect(subject).to have_selector('input[type=file]:not([disabled])')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders max size' do
|
it 'renders max size' do
|
||||||
|
@ -40,8 +40,8 @@ RSpec.describe Attachment::EditComponent, type: :component do
|
||||||
expect(subject).to have_content(attachment.filename.to_s)
|
expect(subject).to have_content(attachment.filename.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'hides the file field by default' do
|
it 'disabled the file field by default' do
|
||||||
expect(subject).to have_selector('input[type=file].hidden')
|
expect(subject).to have_selector('input[type=file][disabled]')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows the Delete button by default' do
|
it 'shows the Delete button by default' do
|
||||||
|
|
|
@ -50,7 +50,7 @@ describe AttachmentsController, type: :controller do
|
||||||
let(:signed_id) { attachment.blob.signed_id }
|
let(:signed_id) { attachment.blob.signed_id }
|
||||||
|
|
||||||
subject do
|
subject do
|
||||||
delete :destroy, params: { id: attachment.id, signed_id: signed_id }, format: :turbo_stream
|
delete :destroy, params: { id: attachment.id, signed_id: signed_id, dossier_id: dossier.id, stable_id: champ.stable_id }, format: :turbo_stream
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when authenticated" do
|
context "when authenticated" do
|
||||||
|
|
|
@ -30,6 +30,7 @@ describe "Dossier en_construction" do
|
||||||
visit_dossier(dossier)
|
visit_dossier(dossier)
|
||||||
|
|
||||||
click_on "Supprimer le fichier toto.txt"
|
click_on "Supprimer le fichier toto.txt"
|
||||||
|
expect(page).not_to have_text("toto.txt")
|
||||||
|
|
||||||
input_selector = "#attachment-multiple-empty-#{champ.public_id}"
|
input_selector = "#attachment-multiple-empty-#{champ.public_id}"
|
||||||
expect(page).to have_selector(input_selector)
|
expect(page).to have_selector(input_selector)
|
||||||
|
@ -37,7 +38,6 @@ describe "Dossier en_construction" do
|
||||||
|
|
||||||
wait_until { champ.reload.for_export == 'file.pdf' }
|
wait_until { champ.reload.for_export == 'file.pdf' }
|
||||||
expect(page).to have_text("file.pdf")
|
expect(page).to have_text("file.pdf")
|
||||||
expect(page).not_to have_text("toto.txt")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,13 +54,13 @@ describe "Dossier en_construction" do
|
||||||
visit_dossier(dossier)
|
visit_dossier(dossier)
|
||||||
|
|
||||||
click_on "Supprimer le fichier toto.png"
|
click_on "Supprimer le fichier toto.png"
|
||||||
|
expect(page).not_to have_text("toto.png")
|
||||||
|
|
||||||
input_selector = "##{champ.input_id}"
|
input_selector = "##{champ.input_id}"
|
||||||
expect(page).to have_selector(input_selector)
|
expect(page).to have_selector(input_selector)
|
||||||
find(input_selector).attach_file(Rails.root.join('spec/fixtures/files/file.pdf'))
|
find(input_selector).attach_file(Rails.root.join('spec/fixtures/files/file.pdf'))
|
||||||
|
|
||||||
expect(page).to have_text("file.pdf")
|
expect(page).to have_text("file.pdf")
|
||||||
expect(page).not_to have_text("toto.png")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue