Merge pull request #11062 from tchak/column-better-cast

ETQ dev, je souhaite obtenir la valeur humaine d'une colonne
This commit is contained in:
Paul Chavard 2024-11-26 13:41:52 +00:00 committed by GitHub
commit ee9a493877
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 57 additions and 39 deletions

View file

@ -48,31 +48,10 @@ class Instructeurs::FilterButtonsComponent < ApplicationComponent
def human_value(filter_column) def human_value(filter_column)
column, filter = filter_column.column, filter_column.filter column, filter = filter_column.column, filter_column.filter
if column.type_de_champ? if column.type == :date || column.type == :datetime
find_type_de_champ(column.stable_id).dynamic_type.filter_to_human(filter)
elsif column.dossier_state?
if filter == 'pending_correction'
Dossier.human_attribute_name("pending_correction.for_instructeur")
else
Dossier.human_attribute_name("state.#{filter}")
end
elsif column.groupe_instructeur?
current_instructeur.groupe_instructeurs
.find { _1.id == filter.to_i }&.label || filter
elsif column.dossier_labels?
Label.find(filter)&.name || filter
elsif column.type == :date
helpers.try_parse_format_date(filter) helpers.try_parse_format_date(filter)
else else
filter column.label_for_value(filter)
end end
end end
def find_type_de_champ(stable_id)
TypeDeChamp
.joins(:revision_types_de_champ)
.where(revision_types_de_champ: { revision_id: @procedure_presentation.procedure.revisions })
.order(created_at: :desc)
.find_by(stable_id:)
end
end end

View file

@ -51,6 +51,16 @@ class Column
def dossier_column? = false def dossier_column? = false
def champ_column? = false def champ_column? = false
def label_for_value(value)
if options_for_select.present?
# options for select store ["trad", :enum_value]
options_for_select.to_h { |(label, value)| [value.to_s, label] }
.fetch(value.to_s, value.to_s)
else
value
end
end
private private
def column_id = "#{table}/#{column}" def column_id = "#{table}/#{column}"

View file

@ -69,6 +69,8 @@ class Columns::ChampColumn < Column
parse_datetime(value) parse_datetime(value)
when :date when :date
parse_datetime(value)&.to_date parse_datetime(value)&.to_date
when :enum
parse_enum(value)
when :enums when :enums
parse_enums(value) parse_enums(value)
else else
@ -89,13 +91,13 @@ class Columns::ChampColumn < Column
when ['integer_number', 'text'], ['decimal_number', 'text'] # number to text when ['integer_number', 'text'], ['decimal_number', 'text'] # number to text
value value
when ['drop_down_list', 'multiple_drop_down_list'] # single list can become multi when ['drop_down_list', 'multiple_drop_down_list'] # single list can become multi
[value] [parse_enum(value)].compact_blank
when ['drop_down_list', 'text'] # single list can become text when ['drop_down_list', 'text'] # single list can become text
value parse_enum(value)
when ['multiple_drop_down_list', 'drop_down_list'] # multi list can become single when ['multiple_drop_down_list', 'drop_down_list'] # multi list can become single
parse_enums(value).first parse_enums(value)&.first
when ['multiple_drop_down_list', 'text'] # single list can become text when ['multiple_drop_down_list', 'text'] # multi list can become text
parse_enums(value).join(', ') parse_enums(value)&.join(', ')
when ['date', 'datetime'] # date <=> datetime when ['date', 'datetime'] # date <=> datetime
parse_datetime(value)&.to_datetime parse_datetime(value)&.to_datetime
when ['datetime', 'date'] # may lose some data, but who cares ? when ['datetime', 'date'] # may lose some data, but who cares ?
@ -114,7 +116,19 @@ class Columns::ChampColumn < Column
end end
end end
def parse_enums(value) = JSON.parse(value) rescue nil def parse_enum(value)
return value if options_for_select.blank?
value if options_for_select.to_set(&:second).member?(value)
end
def parse_enums(value)
values = JSON.parse(value)
return values if options_for_select.blank?
options = options_for_select.to_set(&:second)
values.filter { options.member?(_1) }
rescue JSON::ParserError
nil
end
def parse_datetime(value) = Time.zone.parse(value) rescue nil def parse_datetime(value) = Time.zone.parse(value) rescue nil
end end

View file

@ -443,7 +443,7 @@ class TypeDeChamp < ApplicationRecord
elsif regions? elsif regions?
APIGeoService.region_options APIGeoService.region_options
elsif any_drop_down_list? elsif any_drop_down_list?
drop_down_options drop_down_options.map { [_1, _1] }
elsif yes_no? elsif yes_no?
Champs::YesNoChamp.options Champs::YesNoChamp.options
elsif checkbox? elsif checkbox?

View file

@ -44,9 +44,6 @@ class ExportedColumnFormatter
end end
def self.format_enum(column:, raw_value:) def self.format_enum(column:, raw_value:)
# options for select store ["trad", :enum_value] column.label_for_value(raw_value)
selected_option = column.options_for_select.find { _1[1].to_s == raw_value }
selected_option ? selected_option.first : raw_value
end end
end end

View file

@ -35,7 +35,7 @@ describe Instructeurs::FilterButtonsComponent, type: :component do
let(:filter) { to_filter(['État du dossier', "en_construction"]) } let(:filter) { to_filter(['État du dossier', "en_construction"]) }
it 'should get i18n value' do it 'should get i18n value' do
expect(page).to have_text("En construction") expect(page).to have_text("En construction")
end end
end end
@ -57,7 +57,7 @@ describe Instructeurs::FilterButtonsComponent, type: :component do
end end
it 'should display all filters' do 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" 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) expect(page).to have_text(text)
end end
end end
@ -78,7 +78,7 @@ describe Instructeurs::FilterButtonsComponent, type: :component do
expect(page.all('form').count).to eq(2) expect(page.all('form').count).to eq(2)
del_en_construction = page.all('form').first del_en_construction = page.all('form').first
expect(del_en_construction).to have_text('En construction') 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[]', 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[][id]', with: column_id, type: 'hidden')
expect(del_en_construction).to have_field('filters[][filter]', with: 'en_instruction', type: 'hidden') expect(del_en_construction).to have_field('filters[][filter]', with: 'en_instruction', type: 'hidden')

View file

@ -100,21 +100,39 @@ describe Columns::ChampColumn do
end end
context 'from a drop_down_list' do context 'from a drop_down_list' do
let(:champ) { Champs::DropDownListChamp.new(value: 'val1') } let(:champ) { Champs::DropDownListChamp.new(value:) }
let(:value) { 'val1' }
it do it do
expect(column('multiple_drop_down_list').value(champ)).to eq(['val1']) expect(column('multiple_drop_down_list').value(champ)).to eq(['val1'])
expect(column('text').value(champ)).to eq('val1') expect(column('text').value(champ)).to eq('val1')
end end
context 'value not in options' do
let(:value) { 'toto' }
it do
expect(column('simple_drop_down_list').value(champ)).to eq(nil)
end
end
end end
context 'from a multiple_drop_down_list' do context 'from a multiple_drop_down_list' do
let(:champ) { Champs::MultipleDropDownListChamp.new(value: '["val1","val2"]') } let(:champ) { Champs::MultipleDropDownListChamp.new(value:) }
let(:value) { '["val1","val2"]' }
it do it do
expect(column('simple_drop_down_list').value(champ)).to eq('val1') expect(column('simple_drop_down_list').value(champ)).to eq('val1')
expect(column('text').value(champ)).to eq('val1, val2') expect(column('text').value(champ)).to eq('val1, val2')
end end
context 'value not in options' do
let(:value) { '["toto","val2"]' }
it do
expect(column('multiple_drop_down_list').value(champ)).to eq(['val2'])
end
end
end end
end end
end end