Merge pull request #6469 from tchak/feat-routage-pour-tous
Routage pour tous !
This commit is contained in:
commit
ba1a898b0c
17 changed files with 201 additions and 149 deletions
|
@ -11,7 +11,15 @@ module NewAdministrateur
|
||||||
def index
|
def index
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
|
|
||||||
@groupes_instructeurs = paginated_groupe_instructeurs
|
if procedure.routee?
|
||||||
|
@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
|
||||||
|
@ -131,15 +139,17 @@ module NewAdministrateur
|
||||||
else
|
else
|
||||||
|
|
||||||
if instructeurs.present?
|
if instructeurs.present?
|
||||||
instructeurs.each do |instructeur|
|
procedure.defaut_groupe_instructeur.instructeurs << instructeurs
|
||||||
instructeur.assign_to_procedure(procedure)
|
|
||||||
end
|
|
||||||
flash[:notice] = "Les instructeurs ont bien été affectés à la démarche"
|
flash[:notice] = "Les instructeurs ont bien été affectés à la démarche"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur)
|
if procedure.routee?
|
||||||
|
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
|
||||||
|
@ -164,7 +174,12 @@ module NewAdministrateur
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur)
|
|
||||||
|
if procedure.routee?
|
||||||
|
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
|
||||||
|
@ -174,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"
|
||||||
|
@ -227,7 +249,11 @@ module NewAdministrateur
|
||||||
end
|
end
|
||||||
|
|
||||||
def groupe_instructeur
|
def groupe_instructeur
|
||||||
procedure.groupe_instructeurs.find(params[:id])
|
if params[:id].present?
|
||||||
|
procedure.groupe_instructeurs.find(params[:id])
|
||||||
|
else
|
||||||
|
procedure.defaut_groupe_instructeur
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def instructeur_id
|
def instructeur_id
|
||||||
|
|
|
@ -73,19 +73,15 @@ class Instructeur < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_to_procedure(procedure)
|
def assign_to_procedure(procedure)
|
||||||
begin
|
if !procedure.defaut_groupe_instructeur.in?(groupe_instructeurs)
|
||||||
assign_to.create({
|
groupe_instructeurs << procedure.defaut_groupe_instructeur
|
||||||
procedure: procedure,
|
|
||||||
groupe_instructeur: procedure.defaut_groupe_instructeur
|
|
||||||
})
|
|
||||||
true
|
|
||||||
rescue ActiveRecord::RecordNotUnique
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_from_procedure(procedure)
|
def remove_from_procedure(procedure)
|
||||||
!!(procedure.defaut_groupe_instructeur.in?(groupe_instructeurs) && groupe_instructeurs.destroy(procedure.defaut_groupe_instructeur))
|
if procedure.defaut_groupe_instructeur.in?(groupe_instructeurs)
|
||||||
|
groupe_instructeurs.destroy(procedure.defaut_groupe_instructeur)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def last_week_overview
|
def last_week_overview
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
# path :string not null
|
# path :string not null
|
||||||
# published_at :datetime
|
# published_at :datetime
|
||||||
# routing_criteria_name :text default("Votre ville")
|
# routing_criteria_name :text default("Votre ville")
|
||||||
|
# routing_enabled :boolean
|
||||||
# test_started_at :datetime
|
# test_started_at :datetime
|
||||||
# unpublished_at :datetime
|
# unpublished_at :datetime
|
||||||
# web_hook_url :string
|
# web_hook_url :string
|
||||||
|
@ -628,7 +629,7 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def routee?
|
def routee?
|
||||||
groupe_instructeurs.size > 1
|
routing_enabled? || groupe_instructeurs.size > 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def defaut_groupe_instructeur_for_new_dossier
|
def defaut_groupe_instructeur_for_new_dossier
|
||||||
|
|
|
@ -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é d’une 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
|
|
@ -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 l’instructeur « #{instructeur.email} » du groupe « #{groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer l’instructeur « #{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
|
|
@ -0,0 +1,5 @@
|
||||||
|
.card
|
||||||
|
.card-title Routage
|
||||||
|
%p.notice= t('.notice_html')
|
||||||
|
|
||||||
|
= link_to 'Activer le routage', update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure), class: 'button primary', method: 'patch'
|
|
@ -1,57 +1,22 @@
|
||||||
= render partial: 'new_administrateur/breadcrumbs',
|
- if @procedure.routee?
|
||||||
locals: { steps: [link_to('Démarches', admin_procedures_path),
|
= render partial: 'new_administrateur/breadcrumbs',
|
||||||
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
|
locals: { steps: [link_to('Démarches', admin_procedures_path),
|
||||||
'Groupes d’instructeurs'] }
|
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
|
||||||
|
'Groupes d’instructeurs'] }
|
||||||
|
- 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 },
|
- else
|
||||||
html: { class: 'form' } do |f|
|
= render partial: 'new_administrateur/groupe_instructeurs/routing', locals: { procedure: @procedure }
|
||||||
|
= render partial: 'new_administrateur/groupe_instructeurs/instructeurs',
|
||||||
|
locals: { procedure: @procedure,
|
||||||
|
groupe_instructeur: @procedure.defaut_groupe_instructeur,
|
||||||
|
instructeurs: @instructeurs,
|
||||||
|
available_instructeur_emails: @available_instructeur_emails }
|
||||||
|
|
||||||
= f.label :routing_criteria_name do
|
|
||||||
Libellé du routage
|
|
||||||
%p.notice Ce texte apparaitra sur le formulaire usager comme le libellé d’une 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
|
|
||||||
|
|
|
@ -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 d’instructeurs', admin_procedure_groupe_instructeurs_path(@procedure)),
|
||||||
link_to('Groupes d’instructeurs', 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
|
||||||
|
= render partial: 'new_administrateur/groups_header'
|
||||||
- if feature_enabled?(:administrateur_routage)
|
= render partial: 'new_administrateur/groupe_instructeurs/instructeurs',
|
||||||
= render partial: 'new_administrateur/groups_header'
|
locals: { procedure: @procedure,
|
||||||
|
groupe_instructeur: @groupe_instructeur,
|
||||||
.card
|
instructeurs: @instructeurs,
|
||||||
.card-title Affectation des instructeurs
|
available_instructeur_emails: @available_instructeur_emails }
|
||||||
= form_for :instructeur,
|
|
||||||
url: { action: :add_instructeur },
|
|
||||||
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 l’instructeur « #{instructeur.email} » du groupe « #{@groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » de la démarche ?" },
|
|
||||||
params: { instructeur: { id: instructeur.id }},
|
|
||||||
class: 'button' }
|
|
||||||
|
|
||||||
= paginate @instructeurs
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
.admin-procedures-list-row.actions.flex.justify-between
|
.admin-procedures-list-row.actions.flex.justify-between
|
||||||
%div
|
%div
|
||||||
- if feature_enabled?(:administrateur_routage)
|
- if procedure.routee?
|
||||||
%span.icon.person
|
%span.icon.person
|
||||||
%span.badge.baseline= procedure.groupe_instructeurs.count
|
%span.badge.baseline= procedure.groupe_instructeurs.count
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -107,14 +107,8 @@
|
||||||
%p.card-admin-subtitle Gestion de la démarche
|
%p.card-admin-subtitle Gestion de la démarche
|
||||||
%p.button Modifier
|
%p.button Modifier
|
||||||
|
|
||||||
|
= link_to admin_procedure_groupe_instructeurs_path(@procedure), id: 'groupe-instructeurs', class: 'card-admin' do
|
||||||
- if feature_enabled?(:administrateur_routage)
|
- if @procedure.routee? || @procedure.instructeurs.count > 1
|
||||||
- instructeur_link = admin_procedure_groupe_instructeurs_path(@procedure)
|
|
||||||
- else
|
|
||||||
- instructeur_link = admin_procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur)
|
|
||||||
|
|
||||||
= link_to instructeur_link, id: 'groupe-instructeurs', class: 'card-admin' do
|
|
||||||
- if feature_enabled?(:administrateur_routage) || @procedure.instructeurs.count > 1
|
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
%p.card-admin-status-accept Validé
|
%p.card-admin-status-accept Validé
|
||||||
|
@ -124,12 +118,12 @@
|
||||||
%p.card-admin-status-todo À faire
|
%p.card-admin-status-todo À faire
|
||||||
%div
|
%div
|
||||||
%p.card-admin-title
|
%p.card-admin-title
|
||||||
- if feature_enabled?(:administrateur_routage)
|
- if @procedure.routee?
|
||||||
%span.badge.baseline= @procedure.groupe_instructeurs.count
|
%span.badge.baseline= @procedure.groupe_instructeurs.count
|
||||||
- else
|
- else
|
||||||
%span.badge.baseline= @procedure.instructeurs.count
|
%span.badge.baseline= @procedure.instructeurs.count
|
||||||
|
|
||||||
= feature_enabled?(:administrateur_routage) ? "Groupe Instructeurs" : "#{"Instructeur".pluralize(@procedure.instructeurs.count)}"
|
= @procedure.routee? ? "Groupe Instructeurs" : "#{"Instructeur".pluralize(@procedure.instructeurs.count)}"
|
||||||
%p.card-admin-subtitle Suivi des dossiers
|
%p.card-admin-subtitle Suivi des dossiers
|
||||||
%p.button Modifier
|
%p.button Modifier
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ end
|
||||||
|
|
||||||
# A list of features to be deployed on first push
|
# A list of features to be deployed on first push
|
||||||
features = [
|
features = [
|
||||||
:administrateur_routage,
|
|
||||||
:administrateur_web_hook,
|
:administrateur_web_hook,
|
||||||
:api_particulier,
|
:api_particulier,
|
||||||
:dossier_pdf_vide,
|
:dossier_pdf_vide,
|
||||||
|
|
|
@ -13,10 +13,6 @@ fr:
|
||||||
existing_groupe:
|
existing_groupe:
|
||||||
one: "%{count} groupe existe"
|
one: "%{count} groupe existe"
|
||||||
other: "%{count} groupes existent"
|
other: "%{count} groupes existent"
|
||||||
show:
|
|
||||||
assigned_instructeur:
|
|
||||||
one: "%{count} instructeur est affecté"
|
|
||||||
other: "%{count} instructeurs sont affectés"
|
|
||||||
add_instructeur:
|
add_instructeur:
|
||||||
wrong_address:
|
wrong_address:
|
||||||
one: "%{value} n’est pas une adresse email valide"
|
one: "%{value} n’est pas une adresse email valide"
|
||||||
|
@ -28,3 +24,18 @@ fr:
|
||||||
existing_groupe:
|
existing_groupe:
|
||||||
one: "%{count} groupe existe"
|
one: "%{count} groupe existe"
|
||||||
other: "%{count} groupes existent"
|
other: "%{count} groupes existent"
|
||||||
|
instructeurs:
|
||||||
|
assigned_instructeur:
|
||||||
|
one: "%{count} instructeur est affecté"
|
||||||
|
other: "%{count} instructeurs sont affectés"
|
||||||
|
edit:
|
||||||
|
existing_groupe:
|
||||||
|
one: "%{count} groupe existe"
|
||||||
|
other: "%{count} groupes existent"
|
||||||
|
routing:
|
||||||
|
notice_html: |
|
||||||
|
Le routage est une fonctionnalité pour les démarches nécessitant le partage de l’instruction entre différents groupes en fonction d’un critère précis (territoire, thématique ou autre).
|
||||||
|
<br><br>
|
||||||
|
Cette fonctionnalité permet d’acheminer 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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddRoutingEnabledToProcedures < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :procedures, :routing_enabled, :boolean
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2021_09_08_170019) do
|
ActiveRecord::Schema.define(version: 2021_09_15_170019) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -622,6 +622,7 @@ ActiveRecord::Schema.define(version: 2021_09_08_170019) do
|
||||||
t.text "api_particulier_scopes", default: [], array: true
|
t.text "api_particulier_scopes", default: [], array: true
|
||||||
t.jsonb "api_particulier_sources", default: {}
|
t.jsonb "api_particulier_sources", default: {}
|
||||||
t.index ["api_particulier_sources"], name: "index_procedures_on_api_particulier_sources", using: :gin
|
t.index ["api_particulier_sources"], name: "index_procedures_on_api_particulier_sources", using: :gin
|
||||||
|
t.boolean "routing_enabled"
|
||||||
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
|
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
|
||||||
t.index ["draft_revision_id"], name: "index_procedures_on_draft_revision_id"
|
t.index ["draft_revision_id"], name: "index_procedures_on_draft_revision_id"
|
||||||
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
||||||
|
|
|
@ -2,7 +2,7 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
render_views
|
render_views
|
||||||
|
|
||||||
let(:admin) { create(:administrateur) }
|
let(:admin) { create(:administrateur) }
|
||||||
let(:procedure) { create(:procedure, :published, :for_individual, administrateurs: [admin]) }
|
let(:procedure) { create(:procedure, :published, :for_individual, administrateurs: [admin], routing_enabled: true) }
|
||||||
let!(:gi_1_1) { procedure.defaut_groupe_instructeur }
|
let!(:gi_1_1) { procedure.defaut_groupe_instructeur }
|
||||||
|
|
||||||
let(:procedure2) { create(:procedure, :published) }
|
let(:procedure2) { create(:procedure, :published) }
|
||||||
|
@ -222,7 +222,7 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
it { expect(response.status).to eq(200) }
|
it { expect(response.status).to eq(200) }
|
||||||
it { expect(subject.request.flash[:alert]).to be_nil }
|
it { expect(subject.request.flash[:alert]).to be_nil }
|
||||||
it { expect(subject.request.flash[:notice]).to be_present }
|
it { expect(subject.request.flash[:notice]).to be_present }
|
||||||
it { expect(subject).to redirect_to admin_procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur) }
|
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when there is at least one bad email' do
|
context 'when there is at least one bad email' do
|
||||||
|
@ -230,13 +230,13 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
it { expect(response.status).to eq(200) }
|
it { expect(response.status).to eq(200) }
|
||||||
it { expect(subject.request.flash[:alert]).to be_present }
|
it { expect(subject.request.flash[:alert]).to be_present }
|
||||||
it { expect(subject.request.flash[:notice]).to be_present }
|
it { expect(subject.request.flash[:notice]).to be_present }
|
||||||
it { expect(subject).to redirect_to admin_procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur) }
|
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the admin wants to assign an instructor who is already assigned on this procedure' do
|
context 'when the admin wants to assign an instructor who is already assigned on this procedure' do
|
||||||
let(:emails) { ['instructeur_1@ministere_a.gouv.fr'].to_json }
|
let(:emails) { ['instructeur_1@ministere_a.gouv.fr'].to_json }
|
||||||
it { expect(subject.request.flash[:alert]).to be_present }
|
it { expect(subject.request.flash[:alert]).to be_present }
|
||||||
it { expect(subject).to redirect_to admin_procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur) }
|
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
it { expect(subject.request.flash[:notice]).to be_present }
|
it { expect(subject.request.flash[:notice]).to be_present }
|
||||||
it { expect(subject.request.flash[:alert]).to be_nil }
|
it { expect(subject.request.flash[:alert]).to be_nil }
|
||||||
it { expect(response.status).to eq(302) }
|
it { expect(response.status).to eq(302) }
|
||||||
it { expect(subject).to redirect_to admin_procedure_groupe_instructeur_path(procedure, gi_1_1) }
|
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the instructor is not assigned to the procedure' do
|
context 'when the instructor is not assigned to the procedure' do
|
||||||
|
@ -352,7 +352,7 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
it { expect(subject.request.flash[:alert]).to be_present }
|
it { expect(subject.request.flash[:alert]).to be_present }
|
||||||
it { expect(subject.request.flash[:notice]).to be_nil }
|
it { expect(subject.request.flash[:notice]).to be_nil }
|
||||||
it { expect(response.status).to eq(302) }
|
it { expect(response.status).to eq(302) }
|
||||||
it { expect(subject).to redirect_to admin_procedure_groupe_instructeur_path(procedure, gi_1_1) }
|
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ feature 'The routing', js: true do
|
||||||
let(:litteraire_user) { create(:user, password: password) }
|
let(:litteraire_user) { create(:user, password: password) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
procedure.update(routing_enabled: true)
|
||||||
procedure.defaut_groupe_instructeur.instructeurs << administrateur.instructeur
|
procedure.defaut_groupe_instructeur.instructeurs << administrateur.instructeur
|
||||||
Flipper.enable_actor(:administrateur_routage, administrateur.user)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'works' do
|
scenario 'works' do
|
||||||
|
@ -32,14 +32,14 @@ feature 'The routing', js: true do
|
||||||
# add victor to littéraire groupe
|
# add victor to littéraire groupe
|
||||||
find("input[aria-label='email instructeur'").send_keys('victor@inst.com', :enter)
|
find("input[aria-label='email instructeur'").send_keys('victor@inst.com', :enter)
|
||||||
perform_enqueued_jobs { click_on 'Affecter' }
|
perform_enqueued_jobs { click_on 'Affecter' }
|
||||||
expect(page).to have_text("Les instructeurs ont bien été affectés à la démarche")
|
expect(page).to have_text("L’instructeur victor@inst.com a été affecté au groupe « littéraire »")
|
||||||
|
|
||||||
victor = User.find_by(email: 'victor@inst.com').instructeur
|
victor = User.find_by(email: 'victor@inst.com').instructeur
|
||||||
|
|
||||||
# add superwoman to littéraire groupe
|
# add superwoman to littéraire groupe
|
||||||
find("input[aria-label='email instructeur'").send_keys('superwoman@inst.com', :enter)
|
find("input[aria-label='email instructeur'").send_keys('superwoman@inst.com', :enter)
|
||||||
perform_enqueued_jobs { click_on 'Affecter' }
|
perform_enqueued_jobs { click_on 'Affecter' }
|
||||||
expect(page).to have_text("Les instructeurs ont bien été affectés à la démarche")
|
expect(page).to have_text("L’instructeur superwoman@inst.com a été affecté au groupe « littéraire »")
|
||||||
|
|
||||||
superwoman = User.find_by(email: 'superwoman@inst.com').instructeur
|
superwoman = User.find_by(email: 'superwoman@inst.com').instructeur
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue