From f1f1af4e619a87e1ee221ca50743245f39ba5c22 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Mon, 6 May 2024 18:09:44 +0200 Subject: [PATCH] refactor(champ): update champ annuaire education --- .../annuaire_education_component.rb | 17 +++++---- .../annuaire_education_component.html.haml | 10 ++--- .../data_sources/education_controller.rb | 38 +++++++++++++++++++ app/models/champs/annuaire_education_champ.rb | 11 ++---- app/models/type_de_champ.rb | 3 +- config/routes.rb | 1 + 6 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 app/controllers/data_sources/education_controller.rb diff --git a/app/components/editable_champ/annuaire_education_component.rb b/app/components/editable_champ/annuaire_education_component.rb index 847b6cc21..fc38867bb 100644 --- a/app/components/editable_champ/annuaire_education_component.rb +++ b/app/components/editable_champ/annuaire_education_component.rb @@ -1,12 +1,15 @@ -class EditableChamp::AnnuaireEducationComponent < EditableChamp::ComboSearchComponent +class EditableChamp::AnnuaireEducationComponent < EditableChamp::EditableChampBaseComponent def dsfr_input_classname - 'fr-input' + 'fr-select' end - def react_input_opts - opts = input_opts(id: @champ.input_id, required: @champ.required?, aria: { describedby: @champ.describedby_id }) - opts[:className] = "#{opts.delete(:class)} fr-mt-1w" - - opts + def react_props + react_input_opts(id: @champ.input_id, + class: "fr-mt-1w", + name: @form.field_name(:external_id), + selected_key: @champ.external_id, + items: @champ.selected_items, + loader: data_sources_data_source_education_path, + minimum_input_length: 3) end end diff --git a/app/components/editable_champ/annuaire_education_component/annuaire_education_component.html.haml b/app/components/editable_champ/annuaire_education_component/annuaire_education_component.html.haml index 00ce7bbba..a3a489e4d 100644 --- a/app/components/editable_champ/annuaire_education_component/annuaire_education_component.html.haml +++ b/app/components/editable_champ/annuaire_education_component/annuaire_education_component.html.haml @@ -1,7 +1,3 @@ -- render_parent - -= @form.hidden_field :value -= @form.hidden_field :external_id -= react_component("ComboAnnuaireEducationSearch", - **react_input_opts, - **react_combo_props) +%react-fragment + = render ReactComponent.new "ComboBox/RemoteComboBox", **react_props do + = render ReactComponent.new "ComboBox/ComboBoxValueSlot", field: :label, name: @form.field_name(:value) diff --git a/app/controllers/data_sources/education_controller.rb b/app/controllers/data_sources/education_controller.rb new file mode 100644 index 000000000..99722ef33 --- /dev/null +++ b/app/controllers/data_sources/education_controller.rb @@ -0,0 +1,38 @@ +class DataSources::EducationController < ApplicationController + def search + if params[:q].present? && params[:q].length >= 3 + response = fetch_results + + if response.success? + results = JSON.parse(response.body, symbolize_names: true) + + return render json: format_results(results) + end + end + + render json: [] + + rescue JSON::ParserError => e + Sentry.set_extras(body: response.body, code: response.code) + Sentry.capture_exception(e) + render json: [] + end + + private + + def fetch_results + Typhoeus.get("#{API_EDUCATION_URL}/search", params: { q: params[:q], rows: 5, dataset: 'fr-en-annuaire-education' }, timeout: 3) + end + + def format_results(results) + results[:records].map do |record| + fields = record.fetch(:fields) + value = fields.fetch(:identifiant_de_l_etablissement) + { + label: "#{fields.fetch(:nom_etablissement)}, #{fields.fetch(:nom_commune)} (#{value})", + value:, + data: record + } + end + end +end diff --git a/app/models/champs/annuaire_education_champ.rb b/app/models/champs/annuaire_education_champ.rb index e691b707b..a36437902 100644 --- a/app/models/champs/annuaire_education_champ.rb +++ b/app/models/champs/annuaire_education_champ.rb @@ -7,14 +7,11 @@ class Champs::AnnuaireEducationChamp < Champs::TextChamp APIEducation::AnnuaireEducationAdapter.new(external_id).to_params end - def update_with_external_data!(data:) - if data&.is_a?(Hash) && data['nom_etablissement'].present? && data['nom_commune'].present? && data['identifiant_de_l_etablissement'].present? - update!( - data: data, - value: "#{data['nom_etablissement']}, #{data['nom_commune']} (#{data['identifiant_de_l_etablissement']})" - ) + def selected_items + if external_id.present? + [{ value: external_id, label: value }] else - update!(data: data) + [] end end end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 5ee6bc037..abc959a7b 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -641,8 +641,7 @@ class TypeDeChamp < ApplicationRecord # We should refresh all champs after update except for champs using react or custom refresh # logic (RNA, SIRET, etc.) case type_champ - when type_champs.fetch(:annuaire_education), - type_champs.fetch(:carte), + when type_champs.fetch(:carte), type_champs.fetch(:piece_justificative), type_champs.fetch(:titre_identite), type_champs.fetch(:rna), diff --git a/config/routes.rb b/config/routes.rb index 06f613da0..2c2c86ed0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -251,6 +251,7 @@ Rails.application.routes.draw do namespace :data_sources do get :adresse, to: 'adresse#search', as: :data_source_adresse get :commune, to: 'commune#search', as: :data_source_commune + get :education, to: 'education#search', as: :data_source_education get :search_domaine_fonct, to: 'chorus#search_domaine_fonct', as: :search_domaine_fonct get :search_centre_couts, to: 'chorus#search_centre_couts', as: :search_centre_couts