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'