refactor(combo): use new multicombobox

This commit is contained in:
Paul Chavard 2024-05-15 23:16:55 +02:00
parent 9f9243499c
commit c17351e50a
No known key found for this signature in database
15 changed files with 51 additions and 78 deletions

View file

@ -9,8 +9,8 @@ module Administrateurs
end end
def create def create
emails = params['emails'].presence || [].to_json emails = params['emails'].presence || []
emails = JSON.parse(emails).map { EmailSanitizer.sanitize(_1) } emails = emails.map { EmailSanitizer.sanitize(_1) }
@maybe_typos, no_suggestions = emails @maybe_typos, no_suggestions = emails
.map { |email| [email, EmailChecker.check(email:)[:suggestions]&.first] } .map { |email| [email, EmailChecker.check(email:)[:suggestions]&.first] }
.partition { _1[1].present? } .partition { _1[1].present? }

View file

@ -218,8 +218,8 @@ module Administrateurs
end end
def add_instructeur def add_instructeur
emails = params['emails'].presence || [].to_json emails = params[:emails].presence || []
emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
instructeurs, invalid_emails = groupe_instructeur.add_instructeurs(emails:) instructeurs, invalid_emails = groupe_instructeur.add_instructeurs(emails:)

View file

@ -527,11 +527,10 @@ module Administrateurs
:accuse_lecture, :accuse_lecture,
:api_entreprise_token, :api_entreprise_token,
:duree_conservation_dossiers_dans_ds, :duree_conservation_dossiers_dans_ds,
{ zone_ids: [] },
:lien_dpo, :lien_dpo,
:opendata, :opendata,
:procedure_expires_when_termine_enabled, :procedure_expires_when_termine_enabled,
:tags { zone_ids: [], tags: [] }
] ]
editable_params << :piece_justificative_multiple if @procedure && !@procedure.piece_justificative_multiple? editable_params << :piece_justificative_multiple if @procedure && !@procedure.piece_justificative_multiple?
@ -544,9 +543,6 @@ module Administrateurs
if permited_params[:auto_archive_on].present? if permited_params[:auto_archive_on].present?
permited_params[:auto_archive_on] = Date.parse(permited_params[:auto_archive_on]) + 1.day permited_params[:auto_archive_on] = Date.parse(permited_params[:auto_archive_on]) + 1.day
end end
if permited_params[:tags].present?
permited_params[:tags] = JSON.parse(permited_params[:tags])
end
permited_params permited_params
end end

View file

@ -4,7 +4,7 @@ module CreateAvisConcern
private private
def create_avis_from_params(dossier, instructeur_or_expert, confidentiel = false) 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) avis = Avis.new(create_avis_params)
errors = avis.errors errors = avis.errors
errors.add(:emails, :blank) errors.add(:emails, :blank)
@ -19,8 +19,8 @@ module CreateAvisConcern
# the :emails parameter is a 1-element array. # the :emails parameter is a 1-element array.
# Hence the call to first # Hence the call to first
# https://github.com/rails/rails/issues/17225 # https://github.com/rails/rails/issues/17225
expert_emails = create_avis_params[:emails].presence || [].to_json expert_emails = create_avis_params[:emails].presence || []
expert_emails = JSON.parse(expert_emails).map(&:strip).map(&:downcase) expert_emails = expert_emails.map(&:strip).map(&:downcase)
allowed_dossiers = [dossier] allowed_dossiers = [dossier]
if create_avis_params[:invite_linked_dossiers].present? if create_avis_params[:invite_linked_dossiers].present?
@ -84,6 +84,6 @@ module CreateAvisConcern
end end
def create_avis_params 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
end end

View file

@ -6,8 +6,8 @@ module Gestionnaires
end end
def create def create
emails = [params.require(:administrateur)[:email]].to_json emails = [params.require(:administrateur)[:email]].compact
emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
administrateurs_to_add, valid_emails, invalid_emails = Administrateur.find_all_by_identifier_with_emails(emails:) 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) not_found_emails = valid_emails - administrateurs_to_add.map(&:email)

View file

@ -6,8 +6,8 @@ module Gestionnaires
end end
def create def create
emails = [params.require(:gestionnaire)[:email]].to_json emails = [params.require(:gestionnaire)[:email]].compact
emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
gestionnaires_to_add, valid_emails, invalid_emails = Gestionnaire.find_all_by_identifier_with_emails(emails:) 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) not_found_emails = valid_emails - gestionnaires_to_add.map(&:email)

View file

@ -86,9 +86,9 @@ module Instructeurs
end end
def send_to_instructeurs def send_to_instructeurs
recipients = params['recipients'].presence || [].to_json recipients = params['recipients'].presence || []
# instructeurs are scoped by groupe_instructeur to avoid enumeration # 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? if recipients.present?
recipients.each do |recipient| recipients.each do |recipient|

View file

@ -2,8 +2,8 @@ module Manager
class GroupeGestionnairesController < Manager::ApplicationController class GroupeGestionnairesController < Manager::ApplicationController
def add_gestionnaire def add_gestionnaire
groupe_gestionnaire = GroupeGestionnaire.find(params[:id]) groupe_gestionnaire = GroupeGestionnaire.find(params[:id])
emails = [params['emails'].presence || ''].to_json emails = [params['emails']].compact
emails = JSON.parse(emails).map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) } emails = emails.map { EmailSanitizableConcern::EmailSanitizer.sanitize(_1) }
gestionnaires_to_add, valid_emails, invalid_emails = Gestionnaire.find_all_by_identifier_with_emails(emails:) 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) not_found_emails = valid_emails - gestionnaires_to_add.map(&:email)

View file

@ -111,8 +111,7 @@ module Manager
end end
def add_tags def add_tags
tags_h = { tags: JSON.parse(tags_params[:tags]) } if procedure.update(tags: tags_params[:tags])
if procedure.update(tags_h)
flash.notice = "Le modèle est mis à jour." flash.notice = "Le modèle est mis à jour."
else else
flash.alert = procedure.errors.full_messages.join(', ') flash.alert = procedure.errors.full_messages.join(', ')
@ -181,7 +180,7 @@ module Manager
end end
def tags_params def tags_params
params.require(:procedure).permit(:tags) params.require(:procedure).permit(tags: [])
end end
def template_params def template_params

View file

@ -65,15 +65,13 @@
.instructeur-wrapper .instructeur-wrapper
%p#experts-emails Entrez les adresses emails des experts que vous souhaitez ajouter à la liste prédéfinie %p#experts-emails Entrez les adresses emails des experts que vous souhaitez ajouter à la liste prédéfinie
= hidden_field_tag :emails, nil %react-fragment
= react_component("ComboMultiple", = render ReactComponent.new "ComboBox/MultiComboBox",
options: [], id: 'emails',
selected: [], disabled: [], name: 'emails[]',
group: '.instructeur-wrapper', allows_custom_value: true,
name: 'emails', 'aria-label': 'Emails',
label: 'Emails', 'aria-describedby': 'experts-emails'
describedby: 'experts-emails',
acceptNewValues: true)
= f.submit 'Ajouter à la liste', class: 'fr-btn' = f.submit 'Ajouter à la liste', class: 'fr-btn'

View file

@ -9,14 +9,8 @@
- if disabled_as_super_admin - if disabled_as_super_admin
= f.select :emails, available_instructeur_emails, {}, disabled: disabled_as_super_admin, id: 'instructeur_emails' = f.select :emails, available_instructeur_emails, {}, disabled: disabled_as_super_admin, id: 'instructeur_emails'
- else - else
= hidden_field_tag :emails, nil %react-fragment
= react_component("ComboMultiple", = render ReactComponent.new 'ComboBox/MultiComboBox', items: available_instructeur_emails, id: 'instructeur_emails', name: 'emails[]', allows_custom_value: true, 'aria-label': 'Emails'
options: available_instructeur_emails, selected: [], disabled: [],
group: '.instructeur-wrapper',
id: 'instructeur_emails',
name: 'emails',
label: 'Emails',
acceptNewValues: true)
= f.submit 'Affecter', class: 'fr-btn', disabled: disabled_as_super_admin = f.submit 'Affecter', class: 'fr-btn', disabled: disabled_as_super_admin

View file

@ -122,17 +122,16 @@
.fr-fieldset__element .fr-fieldset__element
= f.label :tags, 'Associez des thématiques à la démarche', class: 'fr-label' = 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. %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-fragment
= react_component("ComboMultiple", = render ReactComponent.new "ComboBox/MultiComboBox",
id: "procedure_tags_combo", id: "procedure_tags_combo",
options: Procedure.tags, items: Procedure.tags,
selected: @procedure.tags, selected_keys: @procedure.tags,
disabled: [], name: 'procedure[tags][]',
label: 'Tags', value_separator: ',|;',
group: '.procedure_tags_combo', allows_custom_value: true,
name: 'tags', 'aria-label': 'Tags',
describedby: 'procedure-tags', 'aria-describedby': 'procedure-tags'
acceptNewValues: true)
%details.procedure-form__options-details %details.procedure-form__options-details
%summary.procedure-form__options-summary %summary.procedure-form__options-summary

View file

@ -7,12 +7,7 @@
%p.tab-paragrah.mb-1 %p.tab-paragrah.mb-1
Le destinataire suivra automatiquement le dossier 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| = 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-fragment
= react_component("ComboMultiple", = render ReactComponent.new "ComboBox/MultiComboBox", items: potential_recipients.map { [_1.email, _1.id] }, name: 'recipients[]', 'aria-label': 'Emails'
options: potential_recipients.map{|r| [r.email, r.id]},
selected: [], disabled: [],
group: '.recipients-form',
name: 'recipients',
label: 'Emails')
= f.submit "Envoyer", class: "fr-btn fr-mt-2w" = f.submit "Envoyer", class: "fr-btn fr-mt-2w"

View file

@ -93,16 +93,15 @@ as well as a link to its edit page.
<% elsif attribute.name == 'tags' %> <% 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 %> <%= 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-fragment>
<%= react_component("ComboMultiple", <%= render ReactComponent.new "ComboBox/MultiComboBox",
options: Procedure.tags, items: Procedure.tags,
selected: procedure.tags, selected_keys: procedure.tags,
disabled: [], value_separator: ',|;',
label: 'Tags', allows_custom_value: true,
group: '.procedure-form__column--form', name: 'procedure[tags][]',
name: 'tags', 'aria-label': 'Tags' %>
describedby: 'procedure-tags', </react-fragment>
acceptNewValues: true) %>
<button class="mt-1">Ajouter des tags</button> <button class="mt-1">Ajouter des tags</button>
<% end %> <% end %>

View file

@ -10,16 +10,9 @@
= render NestedForms::FormOwnerComponent.new = 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| = 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 .fr-input-group
= react_component("ComboMultiple", %react-fragment
options: current_expert_not_instructeur? ? [] : @experts_emails, = 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
selected: [], disabled: [],
label: 'Emails',
group: '.ask-avis',
name: 'emails',
describedby: 'avis-emails-description',
acceptNewValues: !@dossier.procedure.experts_require_administrateur_invitation)
.fr-input-group .fr-input-group
= f.label :introduction, t('helpers.label.introduction'), class: 'fr-label' = f.label :introduction, t('helpers.label.introduction'), class: 'fr-label'