move filter button to component and use plug it to new route

This commit is contained in:
simon lehericey 2024-10-26 21:14:05 +02:00
parent a0671a1321
commit 1268f323cb
No known key found for this signature in database
GPG key ID: CDE670D827C7B3C5
5 changed files with 136 additions and 56 deletions

View file

@ -0,0 +1,47 @@
# frozen_string_literal: true
class Instructeurs::FilterButtonsComponent < ApplicationComponent
def initialize(filters:, procedure_presentation:, statut:)
@filters = filters
@procedure_presentation = procedure_presentation
@statut = statut
end
def call
safe_join(filters_by_family, ' et ')
end
private
def filters_by_family
@filters
.group_by { _1.column.id }
.values
.map { |group| group.map { |f| filter_form(f) } }
.map { |group| safe_join(group, ' ou ') }
end
def filter_form(filter)
form_with(model: [:instructeur, @procedure_presentation], class: 'inline') do
safe_join([
hidden_field_tag('filters[]', ''), # to ensure the filters is not empty
*other_hidden_fields(filter), # other filters to keep
hidden_field_tag('statut', @statut), # collection to set
button_tag(button_content(filter), class: 'fr-tag fr-tag--dismiss fr-my-1w')
])
end
end
def other_hidden_fields(filter)
@filters.reject { _1 == filter }.flat_map do |f|
[
hidden_field_tag("filters[][id]", f.column.id),
hidden_field_tag("filters[][filter]", f.filter)
]
end
end
def button_content(filter)
"#{filter.column.label.truncate(50)} : #{@procedure_presentation.human_value_for_filter(filter)}"
end
end

View file

@ -1,17 +0,0 @@
- if current_filters.count > 0
.fr-mb-2w
- current_filters.group_by { |filter| filter.column.table }.each_with_index do |(table, filters), i|
- if i > 0
= " et "
- filters.each_with_index do |filter, i|
- if i > 0
= " ou "
= form_tag(add_filter_instructeur_procedure_path(procedure), class: 'inline') do
- prefix = procedure_presentation.filters_name_for(statut)
= hidden_field_tag "#{prefix}[]", ''
- (current_filters - [filter]).each do |f|
= hidden_field_tag "#{prefix}[][id]", f.column.id
= hidden_field_tag "#{prefix}[][filter]", f.filter
= button_tag "#{filter.column.label.truncate(50)} : #{procedure_presentation.human_value_for_filter(filter)}",
class: 'fr-tag fr-tag--dismiss fr-my-1w'

View file

@ -70,7 +70,7 @@
= render Dossiers::ExportDropdownComponent.new(procedure: @procedure, export_templates: current_instructeur.export_templates_for(@procedure), statut: @statut, count: @dossiers_count, class_btn: 'fr-btn--tertiary', export_url: method(:download_export_instructeur_procedure_path))
- if @filtered_sorted_paginated_ids.present? || @current_filters.count > 0
= render partial: "dossiers_filter_tags", locals: { procedure: @procedure, procedure_presentation: @procedure_presentation, current_filters: @current_filters, statut: @statut }
= render Instructeurs::FilterButtonsComponent.new(filters: @current_filters, procedure_presentation: @procedure_presentation, statut: @statut)
- batch_operation_component = Dossiers::BatchOperationComponent.new(statut: @statut, procedure: @procedure)

View file

@ -0,0 +1,88 @@
# frozen_string_literal: true
describe Instructeurs::FilterButtonsComponent, type: :component do
let(:component) { described_class.new(filters:, procedure_presentation:, statut:) }
let(:instructeur) { create(:instructeur) }
let(:assign_to) { create(:assign_to, procedure:, instructeur:) }
let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) }
let(:statut) { 'tous' }
let(:filters) { [filter] }
def to_filter((label, filter)) = FilteredColumn.new(column: procedure.find_column(label: label), filter: filter)
before { render_inline(component) }
describe "visible text" do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :text }]) }
let(:first_type_de_champ) { procedure.active_revision.types_de_champ_public.first }
let(:filter) { to_filter([first_type_de_champ.libelle, "true"]) }
context 'when type_de_champ text' do
it 'should passthrough value' do
expect(page).to have_text("true")
end
end
context 'when type_de_champ yes_no' do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :yes_no }]) }
it 'should transform value' do
expect(page).to have_text("oui")
end
end
context 'when filter is state' do
let(:filter) { to_filter(['État du dossier', "en_construction"]) }
it 'should get i18n value' do
expect(page).to have_text("En construction")
end
end
context 'when filter is a date' do
let(:filter) { to_filter(['Date de création', "15/06/2023"]) }
it 'should get formatted value' do
expect(page).to have_text("15/06/2023")
end
end
context 'when there are multiple filters' do
let(:filters) do
[
to_filter(['État du dossier', "en_construction"]),
to_filter(['État du dossier', "en_instruction"]),
to_filter(['Date de création', "15/06/2023"])
]
end
it 'should display all filters' do
text = "État du dossier : En construction ou État du dossier : En instruction et Date de création : 15/06/2023"
expect(page).to have_text(text)
end
end
end
describe "hidden inputs" do
let(:procedure) { create(:procedure) }
context 'with 2 filters' do
let(:en_construction_filter) { to_filter(['État du dossier', "en_construction"]) }
let(:en_instruction_filter) { to_filter(['État du dossier', "en_instruction"]) }
let(:column_id) { procedure.find_column(label: 'État du dossier').id }
let(:filters) { [en_construction_filter, en_instruction_filter] }
it 'should have the necessary inputs' do
expect(page).to have_field('statut', with: 'tous', type: 'hidden')
expect(page.all('form').count).to eq(2)
del_en_construction = page.all('form').first
expect(del_en_construction).to have_text('En construction')
expect(del_en_construction).to have_field('filters[]', with: '', type: 'hidden')
expect(del_en_construction).to have_field('filters[][id]', with: column_id, type: 'hidden')
expect(del_en_construction).to have_field('filters[][filter]', with: 'en_instruction', type: 'hidden')
end
end
end
end

View file

@ -55,44 +55,6 @@ describe ProcedurePresentation do
end
end
describe "#human_value_for_filter" do
let(:filtered_column) { to_filter([first_type_de_champ.libelle, "true"]) }
subject do
procedure_presentation.human_value_for_filter(filtered_column)
end
context 'when type_de_champ text' do
it 'should passthrough value' do
expect(subject).to eq("true")
end
end
context 'when type_de_champ yes_no' do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :yes_no }]) }
it 'should transform value' do
expect(subject).to eq("oui")
end
end
context 'when filter is state' do
let(:filtered_column) { to_filter(['État du dossier', "en_construction"]) }
it 'should get i18n value' do
expect(subject).to eq("En construction")
end
end
context 'when filter is a date' do
let(:filtered_column) { to_filter(['Date de création', "15/06/2023"]) }
it 'should get formatted value' do
expect(subject).to eq("15/06/2023")
end
end
end
describe '#update_displayed_fields' do
let(:en_construction_column) { procedure.find_column(label: 'Date de passage en construction') }
let(:mise_a_jour_column) { procedure.find_column(label: 'Date du dernier évènement') }