diff --git a/app/components/procedure/results_component.rb b/app/components/procedure/results_component.rb new file mode 100644 index 000000000..09b9c5a06 --- /dev/null +++ b/app/components/procedure/results_component.rb @@ -0,0 +1,5 @@ +class Procedure::ResultsComponent < ApplicationComponent + def initialize(grouped_procedures:) + @grouped_procedures = grouped_procedures + end +end diff --git a/app/components/procedure/results_component/results_component.html.haml b/app/components/procedure/results_component/results_component.html.haml new file mode 100644 index 000000000..78c0585bc --- /dev/null +++ b/app/components/procedure/results_component/results_component.html.haml @@ -0,0 +1,18 @@ +#procedure-results + - if !@grouped_procedures.nil? + - if @grouped_procedures.any? + %table.table.vertical.procedure-library-list + - @grouped_procedures.each do |_, procedures| + %tr + %th + = procedures.first.organisation_name + - procedures.sort_by(&:id).each do |procedure| + %tr + %td + = procedure.libelle + %td.flex + = link_to('Consulter', apercu_admin_procedure_path(id: procedure.id), target: "_blank", rel: "noopener", class: 'button small') + = link_to('Cloner', admin_procedure_clone_path(procedure.id, from_new_from_existing: true), 'data-method' => :put, class: 'button small primary') + = link_to('Contacter', "mailto:#{procedure.administrateurs.map(&:email) * ","}", class: 'button small') + - else + %p.mt-2 aucun résultat diff --git a/app/components/procedure/search_component.rb b/app/components/procedure/search_component.rb new file mode 100644 index 000000000..24f13a13f --- /dev/null +++ b/app/components/procedure/search_component.rb @@ -0,0 +1,5 @@ +class Procedure::SearchComponent < ApplicationComponent + def initialize(grouped_procedures:) + @grouped_procedures = grouped_procedures + end +end diff --git a/app/components/procedure/search_component/search_component.html.haml b/app/components/procedure/search_component/search_component.html.haml new file mode 100644 index 000000000..fde14bd1a --- /dev/null +++ b/app/components/procedure/search_component/search_component.html.haml @@ -0,0 +1,12 @@ += form_tag(search_admin_procedures_path, data: { turbo: true }, method: :post, class: 'form') do + = label_tag :query, 'Rechercher une procédure' + + .notice + %p Entrez au minimum 3 lettres + + + = text_field_tag :query, params[:query], required: true, placeholder: 'politique de la ville', minlength: "3" + + = submit_tag 'Rechercher', class: 'button primary' + + = render Procedure::ResultsComponent.new(grouped_procedures: @grouped_procedures) diff --git a/app/controllers/administrateurs/procedures_controller.rb b/app/controllers/administrateurs/procedures_controller.rb index 8f0bea669..cc27a63db 100644 --- a/app/controllers/administrateurs/procedures_controller.rb +++ b/app/controllers/administrateurs/procedures_controller.rb @@ -67,8 +67,15 @@ module Administrateurs SIGNIFICANT_DOSSIERS_THRESHOLD = 30 def new_from_existing + @grouped_procedures = nil + end + + def search + query = ActiveRecord::Base.sanitize_sql_like(params[:query]) + significant_procedure_ids = Procedure .publiees_ou_closes + .where('unaccent(libelle) ILIKE unaccent(?)', "%#{query}%") .joins(:dossiers) .group("procedures.id") .having("count(dossiers.id) >= ?", SIGNIFICANT_DOSSIERS_THRESHOLD) diff --git a/app/views/administrateurs/procedures/new_from_existing.html.haml b/app/views/administrateurs/procedures/new_from_existing.html.haml index a02b213b2..6f20bd594 100644 --- a/app/views/administrateurs/procedures/new_from_existing.html.haml +++ b/app/views/administrateurs/procedures/new_from_existing.html.haml @@ -41,19 +41,4 @@ %h2.header-section Créer une nouvelle démarche à partir d’une démarche existante - %p.notice - Pour rechercher dans cette liste, utilisez la fonction "Recherche" de votre navigateur (CTRL+F ou command+F) - - %table.table.vertical.procedure-library-list - - @grouped_procedures.each do |_, procedures| - %tr - %th - = procedures.first.organisation_name - - procedures.sort_by(&:id).each do |procedure| - %tr - %td - = procedure.libelle - %td.flex - = link_to('Consulter', apercu_admin_procedure_path(id: procedure.id), target: "_blank", rel: "noopener", class: 'button small') - = link_to('Cloner', admin_procedure_clone_path(procedure.id, from_new_from_existing: true), 'data-method' => :put, class: 'button small primary') - = link_to('Contacter', "mailto:#{procedure.administrateurs.map(&:email) * ","}", class: 'button small') + = render Procedure::SearchComponent.new(grouped_procedures: @grouped_procedures) diff --git a/app/views/administrateurs/procedures/search.turbo_stream.haml b/app/views/administrateurs/procedures/search.turbo_stream.haml new file mode 100644 index 000000000..546ac12ba --- /dev/null +++ b/app/views/administrateurs/procedures/search.turbo_stream.haml @@ -0,0 +1,2 @@ += turbo_stream.replace 'procedure-results' do + = render Procedure::ResultsComponent.new(grouped_procedures: @grouped_procedures) diff --git a/config/routes.rb b/config/routes.rb index 05f0284ec..a97046bb0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -418,6 +418,7 @@ Rails.application.routes.draw do collection do get 'new_from_existing' + post 'search' end member do diff --git a/spec/controllers/administrateurs/procedures_controller_spec.rb b/spec/controllers/administrateurs/procedures_controller_spec.rb index 4f325e555..8c034a712 100644 --- a/spec/controllers/administrateurs/procedures_controller_spec.rb +++ b/spec/controllers/administrateurs/procedures_controller_spec.rb @@ -70,12 +70,14 @@ describe Administrateurs::ProceduresController, type: :controller do it { expect(subject.status).to eq(200) } end - describe 'GET #new_from_existing' do + describe 'POST #search' do before do stub_const("Administrateurs::ProceduresController::SIGNIFICANT_DOSSIERS_THRESHOLD", 2) end - subject { get :new_from_existing } + let(:query) { 'Procedure' } + + subject { post :search, params: { query: query }, format: :turbo_stream } let(:grouped_procedures) { subject; assigns(:grouped_procedures) } let(:response_procedures) { grouped_procedures.map { |_o, procedures| procedures }.flatten } @@ -112,6 +114,18 @@ describe Administrateurs::ProceduresController, type: :controller do expect(grouped_procedures.find { |o, _p| o == 'DDT du Loiret' }.last).to contain_exactly(procedure_with_service_2, procedure_without_service) end end + + describe 'searching' do + let!(:matching_procedure) { create(:procedure_with_dossiers, :published, dossiers_count: 2, libelle: 'éléctriCITE') } + let!(:unmatching_procedure) { create(:procedure_with_dossiers, :published, dossiers_count: 2, libelle: 'temoin') } + + let(:query) { 'ELECTRIcité' } + + it 'is case insentivite and unaccented' do + expect(response_procedures).to include(matching_procedure) + expect(response_procedures).not_to include(unmatching_procedure) + end + end end describe 'GET #edit' do