From 75c37e25f6a5e5f8420c4aa65ad16f156a21847f Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 26 Mar 2019 17:35:28 +0100 Subject: [PATCH 1/7] stylesheet: fix dropdown triangle overflowing --- app/assets/stylesheets/new_design/buttons.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/assets/stylesheets/new_design/buttons.scss b/app/assets/stylesheets/new_design/buttons.scss index b228b8cc6..47f8b7093 100644 --- a/app/assets/stylesheets/new_design/buttons.scss +++ b/app/assets/stylesheets/new_design/buttons.scss @@ -137,6 +137,8 @@ position: relative; .dropdown-button { + white-space: nowrap; + &::after { content: "▾"; margin-left: $default-spacer; From 48b89062c836bf0d89ef2c48aac41e9ae3dc82a0 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Thu, 28 Mar 2019 13:57:07 +0100 Subject: [PATCH 2/7] stylesheet: fix clickable area of dropdown items --- app/assets/stylesheets/new_design/buttons.scss | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/new_design/buttons.scss b/app/assets/stylesheets/new_design/buttons.scss index 47f8b7093..0f84aff98 100644 --- a/app/assets/stylesheets/new_design/buttons.scss +++ b/app/assets/stylesheets/new_design/buttons.scss @@ -201,7 +201,7 @@ .dropdown-items { li { display: flex; - padding: 2 * $default-spacer; + padding: $default-padding; color: $grey; border-bottom: 1px solid $border-grey; font-size: 12px; @@ -226,10 +226,17 @@ } a { - display: flex; color: $grey; } + // Make child links fill the whole clickable area + > a { + display: flex; + flex-grow: 1; + margin: -$default-padding; + padding: $default-padding; + } + .icon { flex-shrink: 0; } From dd4eae7d6205864bf9023bfd1f0b9677adb7132a Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 27 Mar 2019 11:42:35 +0100 Subject: [PATCH 3/7] admin: add a `expects_multiple_submissions` property on procedures --- app/controllers/admin/procedures_controller.rb | 2 +- app/views/admin/procedures/_informations.html.haml | 11 ++++++++++- ...xpects_multiple_submissions_column_to_procedure.rb | 5 +++++ db/schema.rb | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20190327102357_add_expects_multiple_submissions_column_to_procedure.rb diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index ed180491d..7773f39a4 100644 --- a/app/controllers/admin/procedures_controller.rb +++ b/app/controllers/admin/procedures_controller.rb @@ -269,7 +269,7 @@ class Admin::ProceduresController < AdminController end def procedure_params - editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on] + editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :expects_multiple_submissions, :web_hook_url, :euro_flag, :logo, :auto_archive_on] if @procedure&.locked? params.require(:procedure).permit(*editable_params) else diff --git a/app/views/admin/procedures/_informations.html.haml b/app/views/admin/procedures/_informations.html.haml index cc2566d3a..c93d70c6b 100644 --- a/app/views/admin/procedures/_informations.html.haml +++ b/app/views/admin/procedures/_informations.html.haml @@ -116,7 +116,16 @@ .col-md-6 %h4 Options avancées - - if Flipflop.web_hook? + = f.label :expects_multiple_submissions do + = f.check_box :expects_multiple_submissions + Ajuster pour le dépôt récurrent de dossiers + %p.help-block + %i.fa.fa-info-circle + Si cette démarche est conçue pour qu’une même personne y dépose régulièrement plusieurs + dossiers, l’interface est ajustée pour rendre plus facile la création de plusieurs dossiers + à la suite. + + - if Flipflop.web_hook? %label{ for: :web_hook_url } Lien de rappel HTTP (webhook) = f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/' %p.help-block diff --git a/db/migrate/20190327102357_add_expects_multiple_submissions_column_to_procedure.rb b/db/migrate/20190327102357_add_expects_multiple_submissions_column_to_procedure.rb new file mode 100644 index 000000000..4dadc63fb --- /dev/null +++ b/db/migrate/20190327102357_add_expects_multiple_submissions_column_to_procedure.rb @@ -0,0 +1,5 @@ +class AddExpectsMultipleSubmissionsColumnToProcedure < ActiveRecord::Migration[5.2] + def change + add_column :procedures, :expects_multiple_submissions, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 6b3b6e255..aeceeaf2f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_03_18_154812) do +ActiveRecord::Schema.define(version: 2019_03_27_102357) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -478,6 +478,7 @@ ActiveRecord::Schema.define(version: 2019_03_18_154812) do t.boolean "juridique_required", default: true t.boolean "durees_conservation_required", default: true t.string "path" + t.boolean "expects_multiple_submissions", default: false, null: false t.index ["hidden_at"], name: "index_procedures_on_hidden_at" t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id" t.index ["service_id"], name: "index_procedures_on_service_id" From d03e3403453ddc471579a1af8d0bb38b9fd48b10 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 26 Mar 2019 16:55:40 +0000 Subject: [PATCH 4/7] dossiers: add an actions menu --- app/assets/images/icons/new-folder.svg | 1 + .../stylesheets/new_design/buttons.scss | 15 +++++++++++++ .../new_design/dossiers_table.scss | 4 ---- app/assets/stylesheets/new_design/icons.scss | 4 ++++ .../new_design/user_dossier_actions.scss | 6 ++++++ app/views/root/patron.html.haml | 1 + .../users/dossiers/_dossier_actions.html.haml | 15 +++++++++++++ app/views/users/dossiers/index.html.haml | 9 +++----- spec/features/users/list_dossiers_spec.rb | 8 +++++-- .../_dossier_actions.html.haml_spec.rb | 21 +++++++++++++++++++ 10 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 app/assets/images/icons/new-folder.svg create mode 100644 app/assets/stylesheets/new_design/user_dossier_actions.scss create mode 100644 app/views/users/dossiers/_dossier_actions.html.haml create mode 100644 spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb diff --git a/app/assets/images/icons/new-folder.svg b/app/assets/images/icons/new-folder.svg new file mode 100644 index 000000000..3eeb85f44 --- /dev/null +++ b/app/assets/images/icons/new-folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/new_design/buttons.scss b/app/assets/stylesheets/new_design/buttons.scss index 0f84aff98..16dc43c7b 100644 --- a/app/assets/stylesheets/new_design/buttons.scss +++ b/app/assets/stylesheets/new_design/buttons.scss @@ -221,6 +221,21 @@ background: $light-grey; } + &.danger { + &:hover { + background-color: $medium-red; + + &, + a { + color: $white; + } + + .icon { + filter: contrast(0) brightness(100); + } + } + } + &:last-child { border-bottom: none; } diff --git a/app/assets/stylesheets/new_design/dossiers_table.scss b/app/assets/stylesheets/new_design/dossiers_table.scss index 1f3468039..5dab7fa66 100644 --- a/app/assets/stylesheets/new_design/dossiers_table.scss +++ b/app/assets/stylesheets/new_design/dossiers_table.scss @@ -79,8 +79,4 @@ .follow-col { width: 200px; } - - .delete-col { - width: 150px; - } } diff --git a/app/assets/stylesheets/new_design/icons.scss b/app/assets/stylesheets/new_design/icons.scss index d5623b221..359641530 100644 --- a/app/assets/stylesheets/new_design/icons.scss +++ b/app/assets/stylesheets/new_design/icons.scss @@ -31,6 +31,10 @@ background-image: image-url("icons/folder.svg"); } + &.new-folder { + background-image: image-url("icons/new-folder.svg"); + } + &.accept { background-image: image-url("icons/accept.svg"); } diff --git a/app/assets/stylesheets/new_design/user_dossier_actions.scss b/app/assets/stylesheets/new_design/user_dossier_actions.scss new file mode 100644 index 000000000..d0d074729 --- /dev/null +++ b/app/assets/stylesheets/new_design/user_dossier_actions.scss @@ -0,0 +1,6 @@ +.user-dossier-actions { + .dropdown-description { + font-size: 14px; + align-self: center; + } +} diff --git a/app/views/root/patron.html.haml b/app/views/root/patron.html.haml index 06e7e45b1..892a010a0 100644 --- a/app/views/root/patron.html.haml +++ b/app/views/root/patron.html.haml @@ -7,6 +7,7 @@ %span.icon.archive %span.icon.unarchive %span.icon.folder + %span.icon.new-folder %span.icon.accept %span.icon.refuse %span.icon.without-continuation diff --git a/app/views/users/dossiers/_dossier_actions.html.haml b/app/views/users/dossiers/_dossier_actions.html.haml new file mode 100644 index 000000000..a2fbea919 --- /dev/null +++ b/app/views/users/dossiers/_dossier_actions.html.haml @@ -0,0 +1,15 @@ +- has_delete_action = dossier.can_be_deleted_by_user? +- has_actions = has_delete_action + +- if has_actions + %span.dropdown.user-dossier-actions + %button.button.dropdown-button + Actions + .dropdown-content.fade-in-down + %ul.dropdown-items + - if has_delete_action + %li.danger + = link_to ask_deletion_dossier_path(dossier), method: :post, data: { disable: true, confirm: "En continuant, vous allez supprimer ce dossier ainsi que les informations qu’il contient. Toute suppression entraine l’annulation de la démarche en cours.\n\nConfirmer la suppression ?" } do + %span.icon.delete + .dropdown-description + Supprimer le dossier diff --git a/app/views/users/dossiers/index.html.haml b/app/views/users/dossiers/index.html.haml index 42fa8bb30..8d49cd044 100644 --- a/app/views/users/dossiers/index.html.haml +++ b/app/views/users/dossiers/index.html.haml @@ -32,7 +32,7 @@ %th %tbody - @dossiers.each do |dossier| - %tr + %tr{ data: { 'dossier-id': dossier.id } } %td.folder-col = link_to(url_for_dossier(dossier), class: 'cell-link') do %span.icon.folder @@ -48,11 +48,8 @@ %td.updated-at-col = link_to(url_for_dossier(dossier), class: 'cell-link') do = dossier.updated_at.strftime("%d/%m/%Y") - %td.action-col.delete-col - - if dossier.can_be_deleted_by_user? - = link_to(ask_deletion_dossier_path(dossier), method: :post, class: 'button danger', data: { disable: true, confirm: "En continuant, vous allez supprimer ce dossier ainsi que les informations qu’il contient. Toute suppression entraine l’annulation de la démarche en cours.\n\nConfirmer la suppression ?" }) do - %span.icon.delete - Supprimer + %td.action-col.action-col + = render partial: 'dossier_actions', locals: { dossier: dossier } = paginate(@dossiers) - if current_user.feedbacks.empty? || current_user.feedbacks.last.created_at < 1.month.ago diff --git a/spec/features/users/list_dossiers_spec.rb b/spec/features/users/list_dossiers_spec.rb index ac0aeb80c..ee0cf27e9 100644 --- a/spec/features/users/list_dossiers_spec.rb +++ b/spec/features/users/list_dossiers_spec.rb @@ -71,11 +71,15 @@ describe 'user access to the list of their dossiers' do context 'when user clicks on delete button', js: true do scenario 'the dossier is deleted' do - page.accept_alert('Confirmer la suppression ?') do - find(:xpath, "//a[@href='#{ask_deletion_dossier_path(dossier_brouillon)}']").click + within(:css, "tr[data-dossier-id=\"#{dossier_brouillon.id}\"]") do + click_on 'Actions' + page.accept_alert('Confirmer la suppression ?') do + click_on 'Supprimer le dossier' + end end expect(page).to have_content('Votre dossier a bien été supprimé.') + expect(page).not_to have_content(dossier_brouillon.procedure.libelle) end end end diff --git a/spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb b/spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb new file mode 100644 index 000000000..cf632d474 --- /dev/null +++ b/spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb @@ -0,0 +1,21 @@ +describe 'users/dossiers/dossier_actions.html.haml', type: :view do + let(:procedure) { create(:procedure, :published, expects_multiple_submissions: true) } + let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } + + subject { render 'users/dossiers/dossier_actions.html.haml', dossier: dossier } + + it { is_expected.to have_link('Supprimer le dossier', href: ask_deletion_dossier_path(dossier)) } + + context 'when the dossier cannot be deleted' do + let(:dossier) { create(:dossier, :accepte, procedure: procedure) } + it { is_expected.not_to have_link('Supprimer le dossier') } + end + + context 'when there are no actions to display' do + let(:dossier) { create(:dossier, :accepte, procedure: procedure) } + + it 'doesn’t render the menu at all' do + expect(subject).not_to have_selector('.dropdown') + end + end +end From abeb58caa525da02988ba31caacf2a5fdb323b8c Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 27 Mar 2019 11:43:04 +0100 Subject: [PATCH 5/7] dossiers: displays an "Start an other dossier" item in action dropdown --- app/models/procedure.rb | 4 ++++ app/views/users/dossiers/_dossier_actions.html.haml | 11 ++++++++++- .../dossiers/_dossier_actions.html.haml_spec.rb | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 4e2c75f4c..62b1c7a34 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -123,6 +123,10 @@ class Procedure < ApplicationRecord publiee_ou_archivee? end + def accepts_new_dossiers? + !archivee? + end + # This method is needed for transition. Eventually this will be the same as brouillon?. def brouillon_avec_lien? brouillon? && path.present? diff --git a/app/views/users/dossiers/_dossier_actions.html.haml b/app/views/users/dossiers/_dossier_actions.html.haml index a2fbea919..57d39ceb8 100644 --- a/app/views/users/dossiers/_dossier_actions.html.haml +++ b/app/views/users/dossiers/_dossier_actions.html.haml @@ -1,5 +1,7 @@ - has_delete_action = dossier.can_be_deleted_by_user? -- has_actions = has_delete_action +- has_new_dossier_action = dossier.procedure.expects_multiple_submissions? && dossier.procedure.accepts_new_dossiers? + +- has_actions = has_delete_action || has_new_dossier_action - if has_actions %span.dropdown.user-dossier-actions @@ -7,6 +9,13 @@ Actions .dropdown-content.fade-in-down %ul.dropdown-items + - if has_new_dossier_action + %li + = link_to procedure_lien(dossier.procedure) do + %span.icon.new-folder + .dropdown-description + Commencer un autre dossier + - if has_delete_action %li.danger = link_to ask_deletion_dossier_path(dossier), method: :post, data: { disable: true, confirm: "En continuant, vous allez supprimer ce dossier ainsi que les informations qu’il contient. Toute suppression entraine l’annulation de la démarche en cours.\n\nConfirmer la suppression ?" } do diff --git a/spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb b/spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb index cf632d474..61c2ed107 100644 --- a/spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb +++ b/spec/views/users/dossiers/_dossier_actions.html.haml_spec.rb @@ -4,6 +4,7 @@ describe 'users/dossiers/dossier_actions.html.haml', type: :view do subject { render 'users/dossiers/dossier_actions.html.haml', dossier: dossier } + it { is_expected.to have_link('Commencer un autre dossier', href: commencer_url(path: procedure.path)) } it { is_expected.to have_link('Supprimer le dossier', href: ask_deletion_dossier_path(dossier)) } context 'when the dossier cannot be deleted' do @@ -11,7 +12,18 @@ describe 'users/dossiers/dossier_actions.html.haml', type: :view do it { is_expected.not_to have_link('Supprimer le dossier') } end + context 'when the procedure doesn’t expect multiple submissions' do + let(:procedure) { create(:procedure, :published, expects_multiple_submissions: false) } + it { is_expected.not_to have_link('Commencer un autre dossier') } + end + + context 'when the procedure is closed' do + let(:procedure) { create(:procedure, :archived, expects_multiple_submissions: true) } + it { is_expected.not_to have_link('Commencer un autre dossier') } + end + context 'when there are no actions to display' do + let(:procedure) { create(:procedure, :published, expects_multiple_submissions: false) } let(:dossier) { create(:dossier, :accepte, procedure: procedure) } it 'doesn’t render the menu at all' do From 0d71120f98c4ee9be14a9dbcf6d395261bd1ade1 Mon Sep 17 00:00:00 2001 From: clemkeirua Date: Fri, 1 Mar 2019 17:16:56 +0100 Subject: [PATCH 6/7] =?UTF-8?q?[fix=20#306]=20Possibilit=C3=A9=20de=20join?= =?UTF-8?q?dre=20un=20document=20=C3=A0=20un=20avis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gestionnaires/avis_controller.rb | 2 +- app/models/avis.rb | 10 +++++++ app/models/concerns/virus_scan_concern.rb | 21 +++++++++++++ .../gestionnaires/avis/instruction.html.haml | 2 ++ .../gestionnaires/shared/avis/_list.html.haml | 1 + .../shared/piece_jointe/_pj_link.html.haml | 20 +++++++++++++ .../shared/piece_jointe/_pj_upload_field.haml | 12 ++++++++ .../gestionnaires/avis_controller_spec.rb | 30 ++++++++++++++----- 8 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 app/models/concerns/virus_scan_concern.rb create mode 100644 app/views/shared/piece_jointe/_pj_link.html.haml create mode 100644 app/views/shared/piece_jointe/_pj_upload_field.haml diff --git a/app/controllers/gestionnaires/avis_controller.rb b/app/controllers/gestionnaires/avis_controller.rb index 7b7fede16..e6b1e3e87 100644 --- a/app/controllers/gestionnaires/avis_controller.rb +++ b/app/controllers/gestionnaires/avis_controller.rb @@ -134,7 +134,7 @@ module Gestionnaires end def avis_params - params.require(:avis).permit(:answer) + params.require(:avis).permit(:answer, :piece_justificative_file) end def commentaire_params diff --git a/app/models/avis.rb b/app/models/avis.rb index e755f946b..9a085d11b 100644 --- a/app/models/avis.rb +++ b/app/models/avis.rb @@ -1,10 +1,13 @@ class Avis < ApplicationRecord include EmailSanitizableConcern + include VirusScanConcern belongs_to :dossier, touch: true belongs_to :gestionnaire belongs_to :claimant, class_name: 'Gestionnaire' + has_one_attached :piece_justificative_file + validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, allow_nil: true validates :claimant, presence: true @@ -19,6 +22,9 @@ class Avis < ApplicationRecord scope :by_latest, -> { order(updated_at: :desc) } scope :updated_since?, -> (date) { where('avis.updated_at > ?', date) } + after_commit :create_avis_virus_scan + after_initialize { add_virus_scan_on(self.piece_justificative_file) } + # The form allows subtmitting avis requests to several emails at once, # hence this virtual attribute. attr_accessor :emails @@ -48,4 +54,8 @@ class Avis < ApplicationRecord self.email = nil end end + + def create_avis_virus_scan + create_virus_scan(self.piece_justificative_file) + end end diff --git a/app/models/concerns/virus_scan_concern.rb b/app/models/concerns/virus_scan_concern.rb new file mode 100644 index 000000000..c7bfd7013 --- /dev/null +++ b/app/models/concerns/virus_scan_concern.rb @@ -0,0 +1,21 @@ +module VirusScanConcern + extend ActiveSupport::Concern + + attr_reader :attachment_attribute + + def add_virus_scan_on(piece_justificative) + @attachment_attribute = piece_justificative + end + + def virus_scan + VirusScan.find_by(blob_key: self.attachment_attribute.blob.key) + end + + def create_virus_scan(piece_justificative) + if piece_justificative&.attachment&.blob.present? + VirusScan.find_or_create_by!(blob_key: piece_justificative.blob.key) do |virus_scan| + virus_scan.status = VirusScan.statuses.fetch(:pending) + end + end + end +end diff --git a/app/views/gestionnaires/avis/instruction.html.haml b/app/views/gestionnaires/avis/instruction.html.haml index 12c5f0537..3d81ac7b5 100644 --- a/app/views/gestionnaires/avis/instruction.html.haml +++ b/app/views/gestionnaires/avis/instruction.html.haml @@ -13,6 +13,8 @@ = form_for @avis, url: gestionnaire_avis_path(@avis), html: { class: 'form' } do |f| = f.text_area :answer, rows: 3, placeholder: 'Votre avis', required: true + = render partial: "shared/piece_jointe/pj_upload_field", locals: { pj: @avis.piece_justificative_file, object: @avis, form: f } + .flex.justify-between.align-baseline %p.confidentiel.flex - if @avis.confidentiel? diff --git a/app/views/gestionnaires/shared/avis/_list.html.haml b/app/views/gestionnaires/shared/avis/_list.html.haml index 3de3b5040..23acc5a0b 100644 --- a/app/views/gestionnaires/shared/avis/_list.html.haml +++ b/app/views/gestionnaires/shared/avis/_list.html.haml @@ -28,4 +28,5 @@ Réponse donnée le #{l(avis.updated_at, format: '%d/%m/%y à %H:%M')} - else %span.waiting En attente de réponse + = render partial: 'shared/piece_jointe/pj_link', locals: { object: avis, pj: avis.piece_justificative_file } %p= avis.answer diff --git a/app/views/shared/piece_jointe/_pj_link.html.haml b/app/views/shared/piece_jointe/_pj_link.html.haml new file mode 100644 index 000000000..656d1dd4a --- /dev/null +++ b/app/views/shared/piece_jointe/_pj_link.html.haml @@ -0,0 +1,20 @@ +- if pj.attached? + .pj-link + - if object.virus_scan.blank? || object.virus_scan.safe? + = link_to url_for(pj), target: '_blank', title: "Télécharger la pièce jointe" do + %span.icon.attachment + = pj.filename.to_s + - if object.virus_scan.blank? + (ce fichier n’a pas été analysé par notre antivirus, téléchargez-le avec précaution) + + - else + = pj.filename.to_s + - if object.virus_scan.pending? + (analyse antivirus en cours + = link_to "rafraichir", request.path + ) + - elsif object.virus_scan.infected? + - if user_can_upload + (virus détecté, merci d’envoyer un autre fichier) + - else + (virus détecté, le téléchargement de ce fichier est bloqué) diff --git a/app/views/shared/piece_jointe/_pj_upload_field.haml b/app/views/shared/piece_jointe/_pj_upload_field.haml new file mode 100644 index 000000000..1c2e95dce --- /dev/null +++ b/app/views/shared/piece_jointe/_pj_upload_field.haml @@ -0,0 +1,12 @@ +.piece-justificative + - if pj.attached? + .piece-justificative-actions{ id: "piece_justificative_#{object.id}" } + .piece-justificative-action + = render partial: "shared/piece_jointe/pj_link", locals: { object: object, pj: object.piece_justificative_file, user_can_upload: true } + .piece-justificative-action + = button_tag 'Remplacer', type: 'button', class: 'button small', data: { 'toggle-target': "#champs_#{object.id}" } + + = form.file_field :piece_justificative_file, + id: "champs_#{object.id}", + class: "piece-justificative-input #{'hidden' if pj.attached?}", + direct_upload: true diff --git a/spec/controllers/gestionnaires/avis_controller_spec.rb b/spec/controllers/gestionnaires/avis_controller_spec.rb index 35f9d5159..662937feb 100644 --- a/spec/controllers/gestionnaires/avis_controller_spec.rb +++ b/spec/controllers/gestionnaires/avis_controller_spec.rb @@ -53,14 +53,30 @@ describe Gestionnaires::AvisController, type: :controller do end describe '#update' do - before do - patch :update, params: { id: avis_without_answer.id, avis: { answer: 'answer' } } - avis_without_answer.reload - end + describe 'without attachment' do + before do + patch :update, params: { id: avis_without_answer.id, avis: { answer: 'answer' } } + avis_without_answer.reload + end - it { expect(response).to redirect_to(instruction_gestionnaire_avis_path(avis_without_answer)) } - it { expect(avis_without_answer.answer).to eq('answer') } - it { expect(flash.notice).to eq('Votre réponse est enregistrée.') } + it { expect(response).to redirect_to(instruction_gestionnaire_avis_path(avis_without_answer)) } + it { expect(avis_without_answer.answer).to eq('answer') } + it { expect(avis_without_answer.piece_justificative_file).to_not be_attached } + it { expect(flash.notice).to eq('Votre réponse est enregistrée.') } + end + describe 'with attachment' do + let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') } + + before do + post :update, params: { id: avis_without_answer.id, avis: { answer: 'answer', piece_justificative_file: file } } + avis_without_answer.reload + end + + it { expect(response).to redirect_to(instruction_gestionnaire_avis_path(avis_without_answer)) } + it { expect(avis_without_answer.answer).to eq('answer') } + it { expect(avis_without_answer.piece_justificative_file).to be_attached } + it { expect(flash.notice).to eq('Votre réponse est enregistrée.') } + end end describe '#create_commentaire' do From 4d021f1d853c3ec2c560608a646f581bfd3e71df Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Thu, 28 Mar 2019 15:47:29 +0100 Subject: [PATCH 7/7] [#2180] Handle additionnal wrapping layer in production --- app/services/carrierwave_active_storage_migration_service.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/services/carrierwave_active_storage_migration_service.rb b/app/services/carrierwave_active_storage_migration_service.rb index c9fd7df86..640643042 100644 --- a/app/services/carrierwave_active_storage_migration_service.rb +++ b/app/services/carrierwave_active_storage_migration_service.rb @@ -17,6 +17,11 @@ class CarrierwaveActiveStorageMigrationService def active_storage_openstack_client! service = ActiveStorage::Blob.service + if defined?(ActiveStorage::Service::DsProxyService) && + service.is_a?(ActiveStorage::Service::DsProxyService) + service = service.wrapped + end + if !defined?(ActiveStorage::Service::OpenStackService) || !service.is_a?(ActiveStorage::Service::OpenStackService) raise StandardError, 'ActiveStorage must be backed by OpenStack'