Merge pull request #10970 from demarches-simplifiees/add-multicombobox-in-instructeur-interface
ETQ instructeur je peux ajouter plusieurs instructeurs à la fois
This commit is contained in:
commit
56b1355f71
4 changed files with 77 additions and 48 deletions
|
@ -21,41 +21,51 @@ module Instructeurs
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_instructeur
|
def add_instructeur
|
||||||
email = instructeur_email.present? ? [instructeur_email] : []
|
emails = params['emails'].presence || []
|
||||||
email = check_if_typo(email)&.first
|
emails = check_if_typo(emails)
|
||||||
errors = Array.wrap(generate_emails_suggestions_message(@maybe_typos))
|
errors = Array.wrap(generate_emails_suggestions_message(@maybe_typos))
|
||||||
|
|
||||||
if !errors.empty?
|
instructeurs, invalid_emails = groupe_instructeur.add_instructeurs(emails:)
|
||||||
flash.now[:alert] = errors.join(". ") if !errors.empty?
|
|
||||||
|
if invalid_emails.present?
|
||||||
|
errors += [
|
||||||
|
t('.wrong_address',
|
||||||
|
count: invalid_emails.size,
|
||||||
|
emails: invalid_emails.join(', '))
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
if instructeurs.present?
|
||||||
|
flash[:notice] = if procedure.routing_enabled?
|
||||||
|
t('.assignment', count: instructeurs.size,
|
||||||
|
emails: instructeurs.map(&:email).join(', '),
|
||||||
|
groupe: groupe_instructeur.label)
|
||||||
|
else
|
||||||
|
"Les instructeurs ont bien été affectés à la démarche"
|
||||||
|
end
|
||||||
|
|
||||||
|
known_instructeurs, not_verified_instructeurs = instructeurs.partition { |instructeur| instructeur.user.email_verified_at }
|
||||||
|
|
||||||
|
not_verified_instructeurs.filter(&:should_receive_email_activation?).each do
|
||||||
|
InstructeurMailer.confirm_and_notify_added_instructeur(_1, groupe_instructeur, current_instructeur.email).deliver_later
|
||||||
|
end
|
||||||
|
|
||||||
|
if known_instructeurs.present?
|
||||||
|
GroupeInstructeurMailer
|
||||||
|
.notify_added_instructeurs(groupe_instructeur, known_instructeurs, current_instructeur.email)
|
||||||
|
.deliver_later
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
@groupe_instructeur = groupe_instructeur
|
@groupe_instructeur = groupe_instructeur
|
||||||
@instructeurs = paginated_instructeurs
|
@instructeurs = paginated_instructeurs
|
||||||
return render :show
|
|
||||||
|
if !errors.empty?
|
||||||
|
flash.now[:alert] = errors.join(". ") if !errors.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
instructeur = Instructeur.by_email(email) ||
|
render :show
|
||||||
create_instructeur(email)
|
|
||||||
|
|
||||||
if instructeur.blank?
|
|
||||||
flash[:alert] = "L’adresse email « #{email} » n’est pas valide."
|
|
||||||
elsif groupe_instructeur.instructeurs.include?(instructeur)
|
|
||||||
flash[:alert] = "L’instructeur « #{email} » est déjà dans le groupe."
|
|
||||||
else
|
|
||||||
groupe_instructeur.add(instructeur)
|
|
||||||
flash[:notice] = "L’instructeur « #{email} » a été affecté au groupe."
|
|
||||||
|
|
||||||
if instructeur.user.email_verified_at
|
|
||||||
GroupeInstructeurMailer
|
|
||||||
.notify_added_instructeurs(groupe_instructeur, [instructeur], current_user.email)
|
|
||||||
.deliver_later
|
|
||||||
elsif instructeur.should_receive_email_activation?
|
|
||||||
InstructeurMailer.confirm_and_notify_added_instructeur(instructeur, groupe_instructeur, current_user.email).deliver_later
|
|
||||||
end
|
|
||||||
# else instructeur already exists and email is not verified, so do not spam them
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to instructeur_groupe_path(procedure, groupe_instructeur)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_instructeur
|
def remove_instructeur
|
||||||
|
@ -115,10 +125,6 @@ module Instructeurs
|
||||||
.order(:email)
|
.order(:email)
|
||||||
end
|
end
|
||||||
|
|
||||||
def instructeur_email
|
|
||||||
params.dig('instructeur', 'email')&.strip&.downcase
|
|
||||||
end
|
|
||||||
|
|
||||||
def instructeur_id
|
def instructeur_id
|
||||||
params[:instructeur][:id]
|
params[:instructeur][:id]
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,11 +22,16 @@
|
||||||
|
|
||||||
.card.fr-mt-2w
|
.card.fr-mt-2w
|
||||||
= render Procedure::InvitationWithTypoComponent.new(maybe_typos: @maybe_typos, url: add_instructeur_instructeur_groupe_path(@procedure, @groupe_instructeur.id), title: "Avant d'ajouter l'email, veuillez confirmer" )
|
= render Procedure::InvitationWithTypoComponent.new(maybe_typos: @maybe_typos, url: add_instructeur_instructeur_groupe_path(@procedure, @groupe_instructeur.id), title: "Avant d'ajouter l'email, veuillez confirmer" )
|
||||||
%h2.fr-h3 Gestion des instructeurs
|
%h2.fr-h3= t('.title')
|
||||||
= form_for(Instructeur.new(user: User.new), url: { action: :add_instructeur }, html: { class: 'form' }) do |f|
|
|
||||||
%h3.fr-h4 Affecter un nouvel instructeur
|
= form_for :instructeur, url: { action: :add_instructeur, id: @groupe_instructeur.id }, html: { class: 'form' } do |f|
|
||||||
= render Dsfr::InputComponent.new(form: f, attribute: :email)
|
.instructeur-wrapper
|
||||||
= f.submit 'Affecter', class: 'fr-btn fr-primary'
|
%p= t('.instructeur_emails')
|
||||||
|
%p.fr-hint-text= t('.copy_paste_hint')
|
||||||
|
%react-fragment
|
||||||
|
= render ReactComponent.new 'ComboBox/MultiComboBox', id: 'instructeur_emails', name: 'emails[]', allows_custom_value: true, 'aria-label': 'Emails'
|
||||||
|
|
||||||
|
= f.submit t('.assign'), class: 'fr-btn fr-btn--tertiary'
|
||||||
|
|
||||||
%table.fr-table.fr-mt-2w.width-100
|
%table.fr-table.fr-mt-2w.width-100
|
||||||
%thead
|
%thead
|
||||||
|
|
16
config/locales/views/instructeurs/groupe_instructeurs/fr.yml
Normal file
16
config/locales/views/instructeurs/groupe_instructeurs/fr.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
fr:
|
||||||
|
instructeurs:
|
||||||
|
groupe_instructeurs:
|
||||||
|
show:
|
||||||
|
title: Affecter un nouvel instructeur
|
||||||
|
instructeur_emails: Adresse électronique des instructeurs que vous souhaitez affecter à cette démarche.
|
||||||
|
copy_paste_hint: "Vous pouvez saisir les adresses individuellement, ou bien copier-coller dans le champ ci-dessous une liste d’adresses séparées par des points-virgules (exemple : adresse1@mail.com; adresse2@mail.com; adresse3@mail.com)."
|
||||||
|
assign: Affecter
|
||||||
|
wrong_adress: "L’adresse électronique saisie n’est pas valide."
|
||||||
|
add_instructeur:
|
||||||
|
wrong_address:
|
||||||
|
one: "%{emails} n’est pas une adresse email valide"
|
||||||
|
other: "%{emails} ne sont pas des adresses emails valides"
|
||||||
|
assignment:
|
||||||
|
one: "L’instructeur %{emails} a été affecté au groupe « %{groupe} »."
|
||||||
|
other: "Les instructeurs %{emails} ont été affectés au groupe « %{groupe} »."
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
describe Instructeurs::GroupeInstructeursController, type: :controller do
|
describe Instructeurs::GroupeInstructeursController, type: :controller do
|
||||||
render_views
|
render_views
|
||||||
let(:administrateurs) { [create(:administrateur, user: instructeur.user)] }
|
let(:administrateur) { create(:administrateur) }
|
||||||
let(:instructeur) { create(:instructeur) }
|
let(:instructeur) { administrateur.instructeur }
|
||||||
let(:procedure) { create(:procedure, :published, administrateurs:) }
|
let(:procedure) { create(:procedure, :published, administrateurs: [administrateur]) }
|
||||||
let!(:gi_1_1) { procedure.defaut_groupe_instructeur }
|
let!(:gi_1_1) { procedure.defaut_groupe_instructeur }
|
||||||
let!(:gi_1_2) { create(:groupe_instructeur, label: 'groupe instructeur 2', procedure: procedure) }
|
let!(:gi_1_2) { create(:groupe_instructeur, label: 'groupe instructeur 2', procedure: procedure) }
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ describe Instructeurs::GroupeInstructeursController, type: :controller do
|
||||||
params: {
|
params: {
|
||||||
procedure_id: procedure.id,
|
procedure_id: procedure.id,
|
||||||
id: gi_1_2.id,
|
id: gi_1_2.id,
|
||||||
instructeur: { email: new_instructeur_email }
|
emails: [new_instructeur_email]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ describe Instructeurs::GroupeInstructeursController, type: :controller do
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(gi_1_2.instructeurs.map(&:email)).to include(new_instructeur_email)
|
expect(gi_1_2.instructeurs.map(&:email)).to include(new_instructeur_email)
|
||||||
expect(flash.notice).to be_present
|
expect(flash.notice).to be_present
|
||||||
expect(response).to redirect_to(instructeur_groupe_path(procedure, gi_1_2))
|
expect(response).to have_http_status(:success)
|
||||||
expect(InstructeurMailer).to have_received(:confirm_and_notify_added_instructeur).with(instance_of(Instructeur), gi_1_2, anything)
|
expect(InstructeurMailer).to have_received(:confirm_and_notify_added_instructeur).with(instance_of(Instructeur), gi_1_2, anything)
|
||||||
expect(GroupeInstructeurMailer).not_to have_received(:notify_added_instructeurs)
|
expect(GroupeInstructeurMailer).not_to have_received(:notify_added_instructeurs)
|
||||||
end
|
end
|
||||||
|
@ -114,7 +114,7 @@ describe Instructeurs::GroupeInstructeursController, type: :controller do
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(gi_1_2.instructeurs.map(&:email)).to include(new_instructeur_email)
|
expect(gi_1_2.instructeurs.map(&:email)).to include(new_instructeur_email)
|
||||||
expect(flash.notice).to be_present
|
expect(flash.notice).to be_present
|
||||||
expect(response).to redirect_to(instructeur_groupe_path(procedure, gi_1_2))
|
expect(response).to have_http_status(:success)
|
||||||
expect(InstructeurMailer).not_to have_received(:confirm_and_notify_added_instructeur)
|
expect(InstructeurMailer).not_to have_received(:confirm_and_notify_added_instructeur)
|
||||||
expect(GroupeInstructeurMailer).to have_received(:notify_added_instructeurs)
|
expect(GroupeInstructeurMailer).to have_received(:notify_added_instructeurs)
|
||||||
end
|
end
|
||||||
|
@ -129,7 +129,7 @@ describe Instructeurs::GroupeInstructeursController, type: :controller do
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(gi_1_2.instructeurs.map(&:email)).to include(new_instructeur_email)
|
expect(gi_1_2.instructeurs.map(&:email)).to include(new_instructeur_email)
|
||||||
expect(flash.notice).to be_present
|
expect(flash.notice).to be_present
|
||||||
expect(response).to redirect_to(instructeur_groupe_path(procedure, gi_1_2))
|
expect(response).to have_http_status(:success)
|
||||||
expect(InstructeurMailer).to have_received(:confirm_and_notify_added_instructeur)
|
expect(InstructeurMailer).to have_received(:confirm_and_notify_added_instructeur)
|
||||||
expect(GroupeInstructeurMailer).not_to have_received(:notify_added_instructeurs)
|
expect(GroupeInstructeurMailer).not_to have_received(:notify_added_instructeurs)
|
||||||
end
|
end
|
||||||
|
@ -137,11 +137,13 @@ describe Instructeurs::GroupeInstructeursController, type: :controller do
|
||||||
|
|
||||||
context 'of an instructeur already in the group' do
|
context 'of an instructeur already in the group' do
|
||||||
let(:new_instructeur_email) { instructeur.email }
|
let(:new_instructeur_email) { instructeur.email }
|
||||||
before { subject }
|
before do
|
||||||
|
instructeur.user.update(email_verified_at: 1.day.ago)
|
||||||
|
subject
|
||||||
|
end
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(flash.alert).to be_present
|
expect(response).to have_http_status(:success)
|
||||||
expect(response).to redirect_to(instructeur_groupe_path(procedure, gi_1_2))
|
|
||||||
expect(InstructeurMailer).not_to have_received(:confirm_and_notify_added_instructeur)
|
expect(InstructeurMailer).not_to have_received(:confirm_and_notify_added_instructeur)
|
||||||
expect(GroupeInstructeurMailer).not_to have_received(:notify_added_instructeurs)
|
expect(GroupeInstructeurMailer).not_to have_received(:notify_added_instructeurs)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue