diff --git a/app/controllers/administrateurs/experts_procedures_controller.rb b/app/controllers/administrateurs/experts_procedures_controller.rb
index 64abc5c38..c9e3c5763 100644
--- a/app/controllers/administrateurs/experts_procedures_controller.rb
+++ b/app/controllers/administrateurs/experts_procedures_controller.rb
@@ -9,8 +9,8 @@ module Administrateurs
end
def create
- emails = params['emails'].presence || [].to_json
- emails = JSON.parse(emails).map { EmailSanitizer.sanitize(_1) }
+ emails = params['emails'].presence || []
+ emails = emails.map { EmailSanitizer.sanitize(_1) }
@maybe_typos, no_suggestions = emails
.map { |email| [email, EmailChecker.check(email:)[:suggestions]&.first] }
.partition { _1[1].present? }
diff --git a/app/controllers/administrateurs/groupe_instructeurs_controller.rb b/app/controllers/administrateurs/groupe_instructeurs_controller.rb
index 50a940690..4e566982b 100644
--- a/app/controllers/administrateurs/groupe_instructeurs_controller.rb
+++ b/app/controllers/administrateurs/groupe_instructeurs_controller.rb
@@ -218,8 +218,8 @@ module Administrateurs
end
def add_instructeur
- emails = params['emails'].presence || [].to_json
- emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
+ emails = params[:emails].presence || []
+ emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
instructeurs, invalid_emails = groupe_instructeur.add_instructeurs(emails:)
diff --git a/app/controllers/administrateurs/procedures_controller.rb b/app/controllers/administrateurs/procedures_controller.rb
index 874290617..98a3073e0 100644
--- a/app/controllers/administrateurs/procedures_controller.rb
+++ b/app/controllers/administrateurs/procedures_controller.rb
@@ -527,11 +527,10 @@ module Administrateurs
:accuse_lecture,
:api_entreprise_token,
:duree_conservation_dossiers_dans_ds,
- { zone_ids: [] },
:lien_dpo,
:opendata,
:procedure_expires_when_termine_enabled,
- :tags
+ { zone_ids: [], tags: [] }
]
editable_params << :piece_justificative_multiple if @procedure && !@procedure.piece_justificative_multiple?
@@ -544,9 +543,6 @@ module Administrateurs
if permited_params[:auto_archive_on].present?
permited_params[:auto_archive_on] = Date.parse(permited_params[:auto_archive_on]) + 1.day
end
- if permited_params[:tags].present?
- permited_params[:tags] = JSON.parse(permited_params[:tags])
- end
permited_params
end
diff --git a/app/controllers/concerns/create_avis_concern.rb b/app/controllers/concerns/create_avis_concern.rb
index f7b821a1f..ad29b06c0 100644
--- a/app/controllers/concerns/create_avis_concern.rb
+++ b/app/controllers/concerns/create_avis_concern.rb
@@ -4,7 +4,7 @@ module CreateAvisConcern
private
def create_avis_from_params(dossier, instructeur_or_expert, confidentiel = false)
- if create_avis_params[:emails].empty?
+ if create_avis_params[:emails].blank?
avis = Avis.new(create_avis_params)
errors = avis.errors
errors.add(:emails, :blank)
@@ -19,8 +19,8 @@ module CreateAvisConcern
# the :emails parameter is a 1-element array.
# Hence the call to first
# https://github.com/rails/rails/issues/17225
- expert_emails = create_avis_params[:emails].presence || [].to_json
- expert_emails = JSON.parse(expert_emails).map(&:strip).map(&:downcase)
+ expert_emails = create_avis_params[:emails].presence || []
+ expert_emails = expert_emails.map(&:strip).map(&:downcase)
allowed_dossiers = [dossier]
if create_avis_params[:invite_linked_dossiers].present?
@@ -84,6 +84,6 @@ module CreateAvisConcern
end
def create_avis_params
- params.require(:avis).permit(:introduction_file, :introduction, :confidentiel, :invite_linked_dossiers, :emails, :question_label)
+ params.require(:avis).permit(:introduction_file, :introduction, :confidentiel, :invite_linked_dossiers, :question_label, emails: [])
end
end
diff --git a/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb b/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb
index da05c8a4b..8b3843167 100644
--- a/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb
+++ b/app/controllers/gestionnaires/groupe_gestionnaire_administrateurs_controller.rb
@@ -6,8 +6,8 @@ module Gestionnaires
end
def create
- emails = [params.require(:administrateur)[:email]].to_json
- emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
+ emails = [params.require(:administrateur)[:email]].compact
+ emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
administrateurs_to_add, valid_emails, invalid_emails = Administrateur.find_all_by_identifier_with_emails(emails:)
not_found_emails = valid_emails - administrateurs_to_add.map(&:email)
diff --git a/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb b/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb
index bf7ba9fb9..c098d2d80 100644
--- a/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb
+++ b/app/controllers/gestionnaires/groupe_gestionnaire_gestionnaires_controller.rb
@@ -6,8 +6,8 @@ module Gestionnaires
end
def create
- emails = [params.require(:gestionnaire)[:email]].to_json
- emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
+ emails = [params.require(:gestionnaire)[:email]].compact
+ emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
gestionnaires_to_add, valid_emails, invalid_emails = Gestionnaire.find_all_by_identifier_with_emails(emails:)
not_found_emails = valid_emails - gestionnaires_to_add.map(&:email)
diff --git a/app/controllers/instructeurs/dossiers_controller.rb b/app/controllers/instructeurs/dossiers_controller.rb
index 884309712..1605c4de1 100644
--- a/app/controllers/instructeurs/dossiers_controller.rb
+++ b/app/controllers/instructeurs/dossiers_controller.rb
@@ -86,9 +86,9 @@ module Instructeurs
end
def send_to_instructeurs
- recipients = params['recipients'].presence || [].to_json
+ recipients = params['recipients'].presence || []
# instructeurs are scoped by groupe_instructeur to avoid enumeration
- recipients = dossier.groupe_instructeur.instructeurs.where(id: JSON.parse(recipients))
+ recipients = dossier.groupe_instructeur.instructeurs.where(id: recipients)
if recipients.present?
recipients.each do |recipient|
diff --git a/app/controllers/manager/groupe_gestionnaires_controller.rb b/app/controllers/manager/groupe_gestionnaires_controller.rb
index 66bdc82db..f009ae072 100644
--- a/app/controllers/manager/groupe_gestionnaires_controller.rb
+++ b/app/controllers/manager/groupe_gestionnaires_controller.rb
@@ -2,8 +2,8 @@ module Manager
class GroupeGestionnairesController < Manager::ApplicationController
def add_gestionnaire
groupe_gestionnaire = GroupeGestionnaire.find(params[:id])
- emails = [params['emails'].presence || ''].to_json
- emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
+ emails = [params['emails']].compact
+ emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
gestionnaires_to_add, valid_emails, invalid_emails = Gestionnaire.find_all_by_identifier_with_emails(emails:)
not_found_emails = valid_emails - gestionnaires_to_add.map(&:email)
diff --git a/app/controllers/manager/procedures_controller.rb b/app/controllers/manager/procedures_controller.rb
index 6fb14e6d2..92d5e321a 100644
--- a/app/controllers/manager/procedures_controller.rb
+++ b/app/controllers/manager/procedures_controller.rb
@@ -111,8 +111,7 @@ module Manager
end
def add_tags
- tags_h = { tags: JSON.parse(tags_params[:tags]) }
- if procedure.update(tags_h)
+ if procedure.update(tags: tags_params[:tags])
flash.notice = "Le modèle est mis à jour."
else
flash.alert = procedure.errors.full_messages.join(', ')
@@ -181,7 +180,7 @@ module Manager
end
def tags_params
- params.require(:procedure).permit(:tags)
+ params.require(:procedure).permit(tags: [])
end
def template_params
diff --git a/app/views/administrateurs/experts_procedures/index.html.haml b/app/views/administrateurs/experts_procedures/index.html.haml
index bffd9f792..865d1cb67 100644
--- a/app/views/administrateurs/experts_procedures/index.html.haml
+++ b/app/views/administrateurs/experts_procedures/index.html.haml
@@ -65,15 +65,13 @@
.instructeur-wrapper
%p#experts-emails Entrez les adresses emails des experts que vous souhaitez ajouter à la liste prédéfinie
- = hidden_field_tag :emails, nil
- = react_component("ComboMultiple",
- options: [],
- selected: [], disabled: [],
- group: '.instructeur-wrapper',
- name: 'emails',
- label: 'Emails',
- describedby: 'experts-emails',
- acceptNewValues: true)
+ %react-fragment
+ = render ReactComponent.new "ComboBox/MultiComboBox",
+ id: 'emails',
+ name: 'emails[]',
+ allows_custom_value: true,
+ 'aria-label': 'Emails',
+ 'aria-describedby': 'experts-emails'
= f.submit 'Ajouter à la liste', class: 'fr-btn'
diff --git a/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml b/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml
index 3e8dd7643..d4ff19e32 100644
--- a/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml
+++ b/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml
@@ -9,14 +9,8 @@
- if disabled_as_super_admin
= f.select :emails, available_instructeur_emails, {}, disabled: disabled_as_super_admin, id: 'instructeur_emails'
- else
- = hidden_field_tag :emails, nil
- = react_component("ComboMultiple",
- options: available_instructeur_emails, selected: [], disabled: [],
- group: '.instructeur-wrapper',
- id: 'instructeur_emails',
- name: 'emails',
- label: 'Emails',
- acceptNewValues: true)
+ %react-fragment
+ = render ReactComponent.new 'ComboBox/MultiComboBox', items: available_instructeur_emails, id: 'instructeur_emails', name: 'emails[]', allows_custom_value: true, 'aria-label': 'Emails'
= f.submit 'Affecter', class: 'fr-btn', disabled: disabled_as_super_admin
diff --git a/app/views/administrateurs/procedures/_informations.html.haml b/app/views/administrateurs/procedures/_informations.html.haml
index a3d361a52..98458512c 100644
--- a/app/views/administrateurs/procedures/_informations.html.haml
+++ b/app/views/administrateurs/procedures/_informations.html.haml
@@ -122,17 +122,16 @@
.fr-fieldset__element
= f.label :tags, 'Associez des thématiques à la démarche', class: 'fr-label'
%p.fr-hint-text Par des mots ou des expressions que vous attribuez aux démarches pour décrire leur contenu et pour les retrouver. Les tags sont partagés avec la communauté, ce qui vous permet de voir les tags attribués aux démarches créées par les autres administrateurs.
- = hidden_field_tag 'procedure[tags]', JSON.generate(@procedure.tags)
- = react_component("ComboMultiple",
- id: "procedure_tags_combo",
- options: Procedure.tags,
- selected: @procedure.tags,
- disabled: [],
- label: 'Tags',
- group: '.procedure_tags_combo',
- name: 'tags',
- describedby: 'procedure-tags',
- acceptNewValues: true)
+ %react-fragment
+ = render ReactComponent.new "ComboBox/MultiComboBox",
+ id: "procedure_tags_combo",
+ items: Procedure.tags,
+ selected_keys: @procedure.tags,
+ name: 'procedure[tags][]',
+ value_separator: ',|;',
+ allows_custom_value: true,
+ 'aria-label': 'Tags',
+ 'aria-describedby': 'procedure-tags'
%details.procedure-form__options-details
%summary.procedure-form__options-summary
diff --git a/app/views/instructeurs/dossiers/_envoyer_dossier_block.html.haml b/app/views/instructeurs/dossiers/_envoyer_dossier_block.html.haml
index b60bf1c32..9c5a6bb78 100644
--- a/app/views/instructeurs/dossiers/_envoyer_dossier_block.html.haml
+++ b/app/views/instructeurs/dossiers/_envoyer_dossier_block.html.haml
@@ -7,12 +7,7 @@
%p.tab-paragrah.mb-1
Le destinataire suivra automatiquement le dossier
= form_for dossier, url: send_to_instructeurs_instructeur_dossier_path(dossier.procedure, dossier), method: :post, html: { class: 'form recipients-form fr-mb-4w' } do |f|
- = hidden_field_tag :recipients, nil
- = react_component("ComboMultiple",
- options: potential_recipients.map{|r| [r.email, r.id]},
- selected: [], disabled: [],
- group: '.recipients-form',
- name: 'recipients',
- label: 'Emails')
+ %react-fragment
+ = render ReactComponent.new "ComboBox/MultiComboBox", items: potential_recipients.map { [_1.email, _1.id] }, name: 'recipients[]', 'aria-label': 'Emails'
= f.submit "Envoyer", class: "fr-btn fr-mt-2w"
diff --git a/app/views/manager/procedures/show.html.erb b/app/views/manager/procedures/show.html.erb
index 38e6919e9..17f815bdd 100644
--- a/app/views/manager/procedures/show.html.erb
+++ b/app/views/manager/procedures/show.html.erb
@@ -93,16 +93,15 @@ as well as a link to its edit page.
<% elsif attribute.name == 'tags' %>
<%= form_for procedure, url: add_tags_manager_procedure_path(procedure), html: { class: 'form procedure-form__column--form fr-background-alt--blue-france mt-1' } do %>
- <%= hidden_field_tag 'procedure[tags]', nil %>
- <%= react_component("ComboMultiple",
- options: Procedure.tags,
- selected: procedure.tags,
- disabled: [],
- label: 'Tags',
- group: '.procedure-form__column--form',
- name: 'tags',
- describedby: 'procedure-tags',
- acceptNewValues: true) %>
+
+ <%= render ReactComponent.new "ComboBox/MultiComboBox",
+ items: Procedure.tags,
+ selected_keys: procedure.tags,
+ value_separator: ',|;',
+ allows_custom_value: true,
+ name: 'procedure[tags][]',
+ 'aria-label': 'Tags' %>
+
<% end %>
diff --git a/app/views/shared/avis/_form.html.haml b/app/views/shared/avis/_form.html.haml
index 43f3dad28..2b5e00b05 100644
--- a/app/views/shared/avis/_form.html.haml
+++ b/app/views/shared/avis/_form.html.haml
@@ -10,16 +10,9 @@
= render NestedForms::FormOwnerComponent.new
= form_for avis, url: url, html: { multipart: true, data: { controller: 'persisted-form', persisted_form_key_value: dom_id(@dossier, :avis_by_instructeur) } } do |f|
- = hidden_field_tag 'avis[emails]', nil
.fr-input-group
- = react_component("ComboMultiple",
- options: current_expert_not_instructeur? ? [] : @experts_emails,
- selected: [], disabled: [],
- label: 'Emails',
- group: '.ask-avis',
- name: 'emails',
- describedby: 'avis-emails-description',
- acceptNewValues: !@dossier.procedure.experts_require_administrateur_invitation)
+ %react-fragment
+ = render ReactComponent.new "ComboBox/MultiComboBox", items: current_expert_not_instructeur? ? [] : @experts_emails, name: f.field_name(:emails, multiple: true), id: 'avis_emails', 'aria-label': 'Emails', 'aria-describedby': 'avis-emails-description', allows_custom_value: !@dossier.procedure.experts_require_administrateur_invitation
.fr-input-group
= f.label :introduction, t('helpers.label.introduction'), class: 'fr-label'