feat(routage): enable routage for everyone

This commit is contained in:
Paul Chavard 2021-09-14 19:54:35 +02:00
parent 0ff62c5a5e
commit 0c5c8faf16
7 changed files with 164 additions and 110 deletions

View file

@ -11,7 +11,15 @@ module NewAdministrateur
def index def index
@procedure = procedure @procedure = procedure
if procedure.routee?
@groupes_instructeurs = paginated_groupe_instructeurs @groupes_instructeurs = paginated_groupe_instructeurs
@instructeurs = []
@available_instructeur_emails = []
else
@groupes_instructeurs = []
@instructeurs = paginated_instructeurs
@available_instructeur_emails = available_instructeur_emails
end
end end
def show def show
@ -137,7 +145,11 @@ module NewAdministrateur
end end
end end
if procedure.routee?
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur) redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur)
else
redirect_to admin_procedure_groupe_instructeurs_path(procedure)
end
end end
def remove_instructeur def remove_instructeur
@ -162,7 +174,12 @@ module NewAdministrateur
end end
end end
end end
if procedure.routee?
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur) redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur)
else
redirect_to admin_procedure_groupe_instructeurs_path(procedure)
end
end end
def update_routing_criteria_name def update_routing_criteria_name
@ -172,6 +189,13 @@ module NewAdministrateur
notice: "Le libellé est maintenant « #{procedure.routing_criteria_name} »." notice: "Le libellé est maintenant « #{procedure.routing_criteria_name} »."
end end
def update_routing_enabled
procedure.update!(routing_enabled: true)
redirect_to admin_procedure_groupe_instructeurs_path(procedure),
notice: "Le routage est activé."
end
def import def import
if !CSV_ACCEPTED_CONTENT_TYPES.include?(group_csv_file.content_type) && !CSV_ACCEPTED_CONTENT_TYPES.include?(marcel_content_type) if !CSV_ACCEPTED_CONTENT_TYPES.include?(group_csv_file.content_type) && !CSV_ACCEPTED_CONTENT_TYPES.include?(marcel_content_type)
flash[:alert] = "Importation impossible : veuillez importer un fichier CSV" flash[:alert] = "Importation impossible : veuillez importer un fichier CSV"
@ -225,7 +249,11 @@ module NewAdministrateur
end end
def groupe_instructeur def groupe_instructeur
if params[:id].present?
procedure.groupe_instructeurs.find(params[:id]) procedure.groupe_instructeurs.find(params[:id])
else
procedure.defaut_groupe_instructeur
end
end end
def instructeur_id def instructeur_id

View file

@ -0,0 +1,52 @@
.card
= form_for procedure,
url: { action: :update_routing_criteria_name },
html: { class: 'form' } do |f|
= f.label :routing_criteria_name do
Libellé du routage
%p.notice Ce texte apparaitra sur le formulaire usager comme le libellé dune liste
= f.text_field :routing_criteria_name, placeholder: 'ex. Votre ville', required: true
= f.submit 'Renommer', class: 'button primary send'
.card
.card-title Gestion des Groupes
= form_for :groupe_instructeur, html: { class: 'form' } do |f|
= f.label :label do
Ajouter un groupe
%p.notice Ce groupe sera un choix de la liste « #{procedure.routing_criteria_name} » .
= f.text_field :label, placeholder: 'ex. Ville de Bordeaux', required: true
= f.submit 'Ajouter le groupe', class: 'button primary send'
- csv_max_size = NewAdministrateur::GroupeInstructeursController::CSV_MAX_SIZE
= form_tag import_admin_procedure_groupe_instructeurs_path(procedure), method: :post, multipart: true, class: "mt-4 form" do
= label_tag "Importer par fichier CSV"
%p.notice Le fichier csv doit comporter 2 colonnes (Groupe, Email) et être séparé par des virgules. L'import n'écrase pas les groupes et les instructeurs existants.
%p.notice Le poids du fichier doit être inférieur à #{number_to_human_size(csv_max_size)}
%p.mt-2.mb-2= link_to "Télécharger l'exemple de fichier CSV", "/import-groupe-test.csv"
= file_field_tag :group_csv_file, required: true, accept: 'text/csv', size: "1"
= submit_tag "Importer le fichier", class: 'button primary send', data: { disable_with: "Envoi..." }
%table.table.mt-2
%thead
%tr
%th{ colspan: 2 }= t(".existing_groupe", count: groupes_instructeurs.total_count)
%tbody
- groupes_instructeurs.each do |group|
%tr
%td= group.label
%td.actions= link_to "voir", admin_procedure_groupe_instructeur_path(procedure, group)
- if groupes_instructeurs.many?
- if group.dossiers.empty?
%td.actions
= link_to admin_procedure_groupe_instructeur_path(procedure, group), { method: :delete, class: 'button', data: { confirm: "Êtes-vous sûr de vouloir supprimer le groupe « #{group.label} » ?" }} do
%span.icon.delete
supprimer ce groupe
- else
%td.actions
= link_to reaffecter_dossiers_admin_procedure_groupe_instructeur_path(procedure, group), class: 'button', title:'Réaffecter les dossiers à un autre groupe afin de pouvoir le supprimer' do
%span.icon.follow
déplacer les dossiers
= paginate groupes_instructeurs

View file

@ -0,0 +1,37 @@
.card
.card-title Affectation des instructeurs
= form_for :instructeur, url: { action: :add_instructeur, id: groupe_instructeur.id }, html: { class: 'form' } do |f|
.instructeur-wrapper
- if !procedure.routee?
%p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche
- hidden_field_id = SecureRandom.uuid
= hidden_field_tag :emails, nil, data: { uuid: hidden_field_id }
= react_component("ComboMultipleDropdownList",
options: available_instructeur_emails, selected: [], disabled: [],
hiddenFieldId: hidden_field_id,
label: 'email instructeur',
acceptNewValues: true)
= f.submit 'Affecter', class: 'button primary send'
%table.table.mt-2
%thead
%tr
%th{ colspan: 2 }= t('.assigned_instructeur', count: instructeurs.count)
%tbody
- instructeurs.each do |instructeur|
%tr
%td
%span.icon.person
#{instructeur.email}
- confirmation_message = procedure.routee? ? "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » du groupe « #{groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » de la démarche ?"
%td.actions= button_to 'retirer',
{ action: :remove_instructeur, id: groupe_instructeur.id },
{ method: :delete,
data: { confirm: confirmation_message },
params: { instructeur: { id: instructeur.id }},
class: 'button' }
= paginate instructeurs

View file

@ -0,0 +1,12 @@
.card
.card-title Routage
%p.notice
Le routage est une fonctionnalité pour les démarches nécessitant le partage de linstruction entre différents groupes en fonction dun critère précis (territoire, thématique ou autre).
%br
%br
Cette fonctionnalité permet dacheminer les dossier vers chaque groupe, et de ne plus avoir besoin de filtrer ses dossiers parmi une grande quantité de demandes. Elle est donc particulièrement adaptée pour les démarches nationales instruites localement.
%br
%br
Les instructeurs ne voient que les dossiers les concernant et n'ont donc pas accès aux données extérieures à leur périmètre.
= link_to 'Activer le routage', update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure), class: 'button primary', method: 'patch'

View file

@ -1,57 +1,22 @@
- if @procedure.routee?
= render partial: 'new_administrateur/breadcrumbs', = render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Démarches', admin_procedures_path), locals: { steps: [link_to('Démarches', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)), link_to(@procedure.libelle, admin_procedure_path(@procedure)),
'Groupes dinstructeurs'] } 'Groupes dinstructeurs'] }
- else
= render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Démarches', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
'Instructeurs'] }
.container.groupe-instructeur .container.groupe-instructeur
.card - if @procedure.routee?
= form_for @procedure, = render partial: 'new_administrateur/groupe_instructeurs/edit', locals: { procedure: @procedure, groupes_instructeurs: @groupes_instructeurs }
url: { action: :update_routing_criteria_name },
html: { class: 'form' } do |f|
= f.label :routing_criteria_name do
Libellé du routage
%p.notice Ce texte apparaitra sur le formulaire usager comme le libellé dune liste
= f.text_field :routing_criteria_name, placeholder: 'ex. Votre ville', required: true
= f.submit 'Renommer', class: 'button primary send'
.card
.card-title Gestion des Groupes
= form_for :groupe_instructeur, html: { class: 'form' } do |f|
= f.label :label do
Ajouter un groupe
%p.notice Ce groupe sera un choix de la liste « #{@procedure.routing_criteria_name} » .
= f.text_field :label, placeholder: 'ex. Ville de Bordeaux', required: true
= f.submit 'Ajouter le groupe', class: 'button primary send'
- csv_max_size = NewAdministrateur::GroupeInstructeursController::CSV_MAX_SIZE
= form_tag import_admin_procedure_groupe_instructeurs_path(@procedure), method: :post, multipart: true, class: "mt-4 form" do
= label_tag "Importer par fichier CSV"
%p.notice Le fichier csv doit comporter 2 colonnes (Groupe, Email) et être séparé par des virgules. L'import n'écrase pas les groupes et les instructeurs existants.
%p.notice Le poids du fichier doit être inférieur à #{number_to_human_size(csv_max_size)}
%p.mt-2.mb-2= link_to "Télécharger l'exemple de fichier CSV", "/import-groupe-test.csv"
= file_field_tag :group_csv_file, required: true, accept: 'text/csv', size: "1"
= submit_tag "Importer le fichier", class: 'button primary send', data: { disable_with: "Envoi..." }
%table.table.mt-2
%thead
%tr
%th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.total_count)
%tbody
- @groupes_instructeurs.each do |group|
%tr
%td= group.label
%td.actions= link_to "voir", admin_procedure_groupe_instructeur_path(@procedure, group)
- if @groupes_instructeurs.many?
- if group.dossiers.empty?
%td.actions
= link_to admin_procedure_groupe_instructeur_path(@procedure, group), { method: :delete, class: 'button', data: { confirm: "Êtes-vous sûr de vouloir supprimer le groupe « #{group.label} » ?" }} do
%span.icon.delete
supprimer ce groupe
- else - else
%td.actions = render partial: 'new_administrateur/groupe_instructeurs/routing', locals: { procedure: @procedure }
= link_to reaffecter_dossiers_admin_procedure_groupe_instructeur_path(@procedure, group), class: 'button', title:'Réaffecter les dossiers à un autre groupe afin de pouvoir le supprimer' do = render partial: 'new_administrateur/groupe_instructeurs/instructeurs',
%span.icon.follow locals: { procedure: @procedure,
déplacer les dossiers groupe_instructeur: @procedure.defaut_groupe_instructeur,
= paginate @groupes_instructeurs instructeurs: @instructeurs,
available_instructeur_emails: @available_instructeur_emails }

View file

@ -1,55 +1,14 @@
- if feature_enabled?(:administrateur_routage)
= render partial: 'new_administrateur/breadcrumbs', = render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Démarches', admin_procedures_path), locals: { steps: [link_to('Démarches', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)), link_to(@procedure.libelle, admin_procedure_path(@procedure)),
link_to('Groupes dinstructeurs', admin_procedure_groupe_instructeurs_path(@procedure)), link_to('Groupes dinstructeurs', admin_procedure_groupe_instructeurs_path(@procedure)),
@groupe_instructeur.label] } @groupe_instructeur.label] }
- else
= render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Démarches', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
'Instructeurs'] }
.container.groupe-instructeur .container.groupe-instructeur
- if feature_enabled?(:administrateur_routage)
= render partial: 'new_administrateur/groups_header' = render partial: 'new_administrateur/groups_header'
= render partial: 'new_administrateur/groupe_instructeurs/instructeurs',
.card locals: { procedure: @procedure,
.card-title Affectation des instructeurs groupe_instructeur: @groupe_instructeur,
= form_for :instructeur, instructeurs: @instructeurs,
url: { action: :add_instructeur }, available_instructeur_emails: @available_instructeur_emails }
html: { class: 'form' } do |f|
.instructeur-wrapper
- if !@procedure.routee?
%p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche
- hidden_field_id = SecureRandom.uuid
= hidden_field_tag :emails, nil, data: { uuid: hidden_field_id }
= react_component("ComboMultipleDropdownList",
options: @available_instructeur_emails, selected: [], disabled: [],
hiddenFieldId: hidden_field_id,
label: 'email instructeur',
acceptNewValues: true)
= f.submit 'Affecter', class: 'button primary send'
%table.table.mt-2
%thead
%tr
%th{ colspan: 2 }= t('.assigned_instructeur', count: @instructeurs.count)
%tbody
- @instructeurs.each do |instructeur|
%tr
%td
%span.icon.person
#{instructeur.email}
%td.actions= button_to 'retirer',
{ action: :remove_instructeur },
{ method: :delete,
data: { confirm: feature_enabled?(:administrateur_routage) ? "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » du groupe  « #{@groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » de la démarche ?" },
params: { instructeur: { id: instructeur.id }},
class: 'button' }
= paginate @instructeurs

View file

@ -422,6 +422,7 @@ Rails.application.routes.draw do
collection do collection do
patch 'update_routing_criteria_name' patch 'update_routing_criteria_name'
patch 'update_routing_enabled'
post 'import' post 'import'
end end
end end