Merge pull request #8916 from demarches-simplifiees/can-update-defaut-groupe-instructeur-2
feat(routage): permet de changer le groupe par défaut
This commit is contained in:
commit
586286cb08
14 changed files with 106 additions and 35 deletions
|
@ -1,6 +1,11 @@
|
|||
.groupe-instructeur {
|
||||
.actions {
|
||||
width: 200px;
|
||||
.setup {
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
text-align: center;
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
|
||||
.value {
|
||||
width: 200px;
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,4 +60,13 @@
|
|||
border-color: $dark-red;
|
||||
}
|
||||
}
|
||||
|
||||
.form.defaut-groupe {
|
||||
padding: $default-spacer;
|
||||
|
||||
label {
|
||||
width: 600px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
fr:
|
||||
select: Sélectionner
|
||||
apply_routing_rules: Appliquer des règles de routage
|
||||
apply_routing_rules: Règles de routage
|
||||
routing_rules_notice_html: |
|
||||
<p>Ajoutez des règles de routage à partir de champs « choix simple » créés dans le <a href="%{path}">formulaire</a>.</p>
|
||||
<p>Les dossiers seront routées vers le premier groupe affiché dont la règle correspond.</p>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
.card#routing-rules
|
||||
.card-title
|
||||
= t('.apply_routing_rules')
|
||||
%h2.card-title= t('.apply_routing_rules')
|
||||
- if can_route?
|
||||
.notice
|
||||
= t('.routing_rules_notice_html', path: champs_admin_procedure_path(@procedure_id))
|
||||
|
@ -28,5 +27,14 @@
|
|||
%td.target= targeted_champ_tag(targeted_champ, row_index)
|
||||
%td.operator est égal à
|
||||
%td.value= value_tag(targeted_champ, value, row_index)
|
||||
|
||||
= form_tag admin_procedure_update_defaut_groupe_instructeur_path(@procedure_id),
|
||||
class: 'form flex align-baseline defaut-groupe',
|
||||
data: { controller: 'autosave' } do
|
||||
= label_tag :defaut_groupe_instructeur_id, 'Et si aucune règle ne correspond, router vers :'
|
||||
= select_tag :defaut_groupe_instructeur_id,
|
||||
options_for_select(@groupe_instructeurs.pluck(:label, :id), selected: @revision.procedure.defaut_groupe_instructeur.id),
|
||||
class: 'width-100'
|
||||
|
||||
- else
|
||||
.notice= t('.routing_rules_warning_html', path: champs_admin_procedure_path(@procedure_id))
|
||||
|
|
|
@ -48,7 +48,10 @@ module Administrateurs
|
|||
def update
|
||||
@groupe_instructeur = groupe_instructeur
|
||||
|
||||
if @groupe_instructeur.update(groupe_instructeur_params)
|
||||
if closed_params? && @groupe_instructeur.id == procedure.defaut_groupe_instructeur.id
|
||||
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur),
|
||||
alert: "Il est impossible de désactiver le groupe d’instructeurs par défaut."
|
||||
elsif @groupe_instructeur.update(groupe_instructeur_params)
|
||||
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur),
|
||||
notice: "Le nom est à présent « #{@groupe_instructeur.label} »."
|
||||
else
|
||||
|
@ -68,6 +71,8 @@ module Administrateurs
|
|||
flash[:alert] = "Impossible de supprimer un groupe avec des dossiers. Il faut le réaffecter avant"
|
||||
elsif procedure.groupe_instructeurs.one?
|
||||
flash[:alert] = "Suppression impossible : il doit y avoir au moins un groupe instructeur sur chaque procédure"
|
||||
elsif @groupe_instructeur.id == procedure.defaut_groupe_instructeur.id
|
||||
flash[:alert] = "Suppression impossible : le groupe « #{@groupe_instructeur.label} » est le groupe par défaut."
|
||||
else
|
||||
@groupe_instructeur.destroy!
|
||||
if procedure.groupe_instructeurs.active.one?
|
||||
|
@ -258,6 +263,10 @@ module Administrateurs
|
|||
|
||||
private
|
||||
|
||||
def closed_params?
|
||||
groupe_instructeur_params[:closed] == "1"
|
||||
end
|
||||
|
||||
def procedure
|
||||
current_administrateur
|
||||
.procedures
|
||||
|
|
|
@ -12,6 +12,11 @@ module Administrateurs
|
|||
groupe_instructeur.update!(routing_rule: ds_eq(left, right))
|
||||
end
|
||||
|
||||
def update_defaut_groupe_instructeur
|
||||
new_defaut = @procedure.groupe_instructeurs.find(defaut_groupe_instructeur_id)
|
||||
@procedure.update!(defaut_groupe_instructeur: new_defaut)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def targeted_champ_changed?
|
||||
|
@ -19,11 +24,11 @@ module Administrateurs
|
|||
end
|
||||
|
||||
def targeted_champ
|
||||
Logic.from_json(routing_params[:targeted_champ])
|
||||
Logic.from_json(params[:targeted_champ])
|
||||
end
|
||||
|
||||
def value
|
||||
Logic.from_json(routing_params[:value])
|
||||
Logic.from_json(params[:value])
|
||||
end
|
||||
|
||||
def groupe_instructeur
|
||||
|
@ -31,11 +36,11 @@ module Administrateurs
|
|||
end
|
||||
|
||||
def groupe_instructeur_id
|
||||
routing_params[:groupe_instructeur_id]
|
||||
params[:groupe_instructeur_id]
|
||||
end
|
||||
|
||||
def routing_params
|
||||
params.permit(:targeted_champ, :value, :groupe_instructeur_id)
|
||||
def defaut_groupe_instructeur_id
|
||||
params[:defaut_groupe_instructeur_id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,6 +21,8 @@ class GroupeInstructeur < ApplicationRecord
|
|||
has_and_belongs_to_many :exports, dependent: :destroy
|
||||
has_and_belongs_to_many :bulk_messages, dependent: :destroy
|
||||
|
||||
has_one :defaut_procedure, -> { with_discarded }, class_name: 'Procedure', foreign_key: :defaut_groupe_instructeur_id, dependent: :nullify, inverse_of: :defaut_groupe_instructeur
|
||||
|
||||
validates :label, presence: true, allow_nil: false
|
||||
validates :label, uniqueness: { scope: :procedure }
|
||||
validates :closed, acceptance: { accept: [false] }, if: -> { closed_changed? && self.procedure.groupe_instructeurs.active.one? }
|
||||
|
|
|
@ -208,7 +208,7 @@ class Procedure < ApplicationRecord
|
|||
has_one :refused_mail, class_name: "Mails::RefusedMail", dependent: :destroy
|
||||
has_one :without_continuation_mail, class_name: "Mails::WithoutContinuationMail", dependent: :destroy
|
||||
|
||||
has_one :defaut_groupe_instructeur, -> { active.order(id: :asc) }, class_name: 'GroupeInstructeur', inverse_of: false
|
||||
belongs_to :defaut_groupe_instructeur, class_name: 'GroupeInstructeur', inverse_of: false, optional: true
|
||||
|
||||
has_one_attached :logo
|
||||
has_one_attached :notice
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
= f.submit t('.button.rename'), class: 'button primary send'
|
||||
|
||||
.card
|
||||
.card-title
|
||||
= t('.group_management.title')
|
||||
%h2.card-title= t('.group_management.title')
|
||||
|
||||
= form_for :groupe_instructeur, html: { class: 'form' } do |f|
|
||||
= f.label :label do
|
||||
|
@ -46,13 +45,13 @@
|
|||
%tr
|
||||
// i18n-tasks-use t('.existing_groupe')
|
||||
%th{ colspan: 2 }= t(".existing_groupe", count: groupes_instructeurs.total_count)
|
||||
%th
|
||||
%th.actions
|
||||
= link_to "Exporter au format CSV", export_groupe_instructeurs_admin_procedure_groupe_instructeurs_path(procedure, format: :csv)
|
||||
%tbody
|
||||
- groupes_instructeurs.each do |group|
|
||||
%tr
|
||||
%td= group.label
|
||||
%td.actions= link_to t('.set_up'), admin_procedure_groupe_instructeur_path(procedure, group)
|
||||
%td.setup= link_to t('.set_up'), admin_procedure_groupe_instructeur_path(procedure, group)
|
||||
- if group.can_delete?
|
||||
%td.actions
|
||||
= link_to admin_procedure_groupe_instructeur_path(procedure, group), { method: :delete, class: 'button', data: { confirm: t('.group_management.delete_confirmation', group_name: group.label) }} do
|
||||
|
|
|
@ -506,6 +506,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
patch :update, controller: 'routing', as: :routing_rules
|
||||
patch :update_defaut_groupe_instructeur, controller: 'routing', as: :update_defaut_groupe_instructeur
|
||||
|
||||
put 'clone'
|
||||
put 'archive'
|
||||
|
|
|
@ -83,15 +83,15 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
}
|
||||
end
|
||||
|
||||
context 'with only one group' do
|
||||
context 'default group' do
|
||||
before do
|
||||
delete_group gi_1_1
|
||||
delete_group gi_1_2
|
||||
end
|
||||
|
||||
it { expect(flash.alert).to be_present }
|
||||
it { expect(flash.alert).to eq "Suppression impossible : le groupe « défaut » est le groupe par défaut." }
|
||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeurs_path(procedure)) }
|
||||
it { expect(procedure.groupe_instructeurs.count).to eq(1) }
|
||||
it { expect(procedure.groupe_instructeurs.count).to eq(2) }
|
||||
end
|
||||
|
||||
context 'with many groups' do
|
||||
|
@ -181,7 +181,7 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
|
||||
describe '#update' do
|
||||
let(:new_name) { 'nouveau nom du groupe' }
|
||||
let(:closed_value) { false }
|
||||
let(:closed_value) { '0' }
|
||||
let!(:procedure_non_routee) { create(:procedure, :published, :for_individual, administrateurs: [admin]) }
|
||||
let!(:gi_1_1) { procedure_non_routee.defaut_groupe_instructeur }
|
||||
|
||||
|
@ -195,26 +195,33 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
gi_1_1.reload
|
||||
end
|
||||
|
||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure_non_routee, gi_1_1)) }
|
||||
it { expect(gi_1_1.label).to eq(new_name) }
|
||||
it { expect(gi_1_1.closed).to eq(false) }
|
||||
it { expect(flash.notice).to be_present }
|
||||
it do
|
||||
expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure_non_routee, gi_1_1))
|
||||
expect(gi_1_1.label).to eq(new_name)
|
||||
expect(gi_1_1.closed).to eq(false)
|
||||
expect(flash.notice).to be_present
|
||||
end
|
||||
|
||||
context 'when we try do disable the only groupe instructeur' do
|
||||
let(:closed_value) { true }
|
||||
context 'when we try do disable the default groupe instructeur' do
|
||||
let(:closed_value) { '1' }
|
||||
let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
|
||||
|
||||
it { expect(response).to render_template(:show) }
|
||||
it { expect(gi_1_1.label).not_to eq(new_name) }
|
||||
it { expect(gi_1_1.closed).to eq(false) }
|
||||
it { expect(flash.alert).to eq(['Il doit y avoir au moins un groupe instructeur actif sur chaque démarche']) }
|
||||
it do
|
||||
expect(subject).to redirect_to admin_procedure_groupe_instructeur_path(procedure_non_routee, gi_1_1)
|
||||
expect(gi_1_1.label).not_to eq(new_name)
|
||||
expect(gi_1_1.closed).to eq(false)
|
||||
expect(flash.alert).to eq('Il est impossible de désactiver le groupe d’instructeurs par défaut.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the name is already taken' do
|
||||
let!(:gi_1_2) { procedure_non_routee.groupe_instructeurs.create(label: 'groupe instructeur 2') }
|
||||
let(:new_name) { gi_1_2.label }
|
||||
|
||||
it { expect(gi_1_1.label).not_to eq(new_name) }
|
||||
it { expect(flash.alert).to eq(['Le libellé est déjà utilisé(e)']) }
|
||||
it do
|
||||
expect(gi_1_1.label).not_to eq(new_name)
|
||||
expect(flash.alert).to eq(['Le libellé est déjà utilisé(e)'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -49,4 +49,22 @@ describe Administrateurs::RoutingController, type: :controller do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update_defaut_groupe_instructeur" do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:gi_2) { procedure.groupe_instructeurs.create(label: 'groupe 2') }
|
||||
let(:params) do
|
||||
{
|
||||
procedure_id: procedure.id,
|
||||
defaut_groupe_instructeur_id: gi_2.id
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
post :update_defaut_groupe_instructeur, params: params, format: :turbo_stream
|
||||
procedure.reload
|
||||
end
|
||||
|
||||
it { expect(procedure.defaut_groupe_instructeur.id).to eq(gi_2.id) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,6 +27,7 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
after(:build) do |procedure, evaluator|
|
||||
procedure.defaut_groupe_instructeur = procedure.groupe_instructeurs.first
|
||||
initial_revision = build(:procedure_revision, procedure: procedure, dossier_submitted_message: evaluator.dossier_submitted_message)
|
||||
|
||||
if evaluator.types_de_champ_public.present?
|
||||
|
|
|
@ -100,9 +100,12 @@ describe GroupeInstructeur, type: :model do
|
|||
|
||||
describe "active group validations" do
|
||||
context "there is at least one active groupe instructeur" do
|
||||
let!(:gi_active) { create(:groupe_instructeur, procedure:, closed: false) }
|
||||
let!(:gi_closed) { create(:groupe_instructeur, procedure:, closed: true) }
|
||||
before { procedure.defaut_groupe_instructeur.destroy! }
|
||||
let(:gi_active) { procedure.defaut_groupe_instructeur }
|
||||
let(:gi_closed) { create(:groupe_instructeur, procedure:) }
|
||||
before do
|
||||
gi_active
|
||||
gi_closed.update(closed: true)
|
||||
end
|
||||
|
||||
it "closed is valid when there is one other active groupe" do
|
||||
expect(gi_active).to be_valid
|
||||
|
|
Loading…
Reference in a new issue