Merge pull request #11029 from tchak/refactor-type-de-champ-predicates

refactor(type_de_champ): cleanup type predicate methods
This commit is contained in:
Paul Chavard 2024-11-12 13:04:50 +00:00 committed by GitHub
commit 8db85b4de3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 50 additions and 161 deletions

View file

@ -26,7 +26,7 @@ class Dossiers::ChampsRowsShowComponent < ApplicationComponent
def blank_key(champ) def blank_key(champ)
key = ".blank_optional" key = ".blank_optional"
key += "_attachment" if champ.type_de_champ.piece_justificative? key += "_attachment" if champ.type_de_champ.piece_justificative_or_titre_identite?
key key
end end

View file

@ -84,6 +84,6 @@ class EditableChamp::EditableChampComponent < ApplicationComponent
end end
def autosave_enabled? def autosave_enabled?
!@champ.carte? && !@champ.block? && @champ.fillable? !@champ.carte? && !@champ.repetition? && @champ.fillable?
end end
end end

View file

@ -130,7 +130,7 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent
end end
def has_legacy_number? def has_legacy_number?
revision.types_de_champ.any?(&:legacy_number?) revision.types_de_champ.any?(&:number?)
end end
def options_for_character_limit def options_for_character_limit

View file

@ -68,7 +68,7 @@
.flex.justify-start.fr-mt-1w.flex-gap .flex.justify-start.fr-mt-1w.flex-gap
- if type_de_champ.drop_down_list? - if type_de_champ.any_drop_down_list?
.flex.column.justify-start.width-33 .flex.column.justify-start.width-33
.cell .cell
= form.label :drop_down_options_from_text, "Options de la liste", for: dom_id(type_de_champ, :drop_down_options_from_text) = form.label :drop_down_options_from_text, "Options de la liste", for: dom_id(type_de_champ, :drop_down_options_from_text)
@ -77,7 +77,7 @@
class: 'fr-input small-margin small width-100', class: 'fr-input small-margin small width-100',
rows: 7, rows: 7,
id: dom_id(type_de_champ, :drop_down_options_from_text) id: dom_id(type_de_champ, :drop_down_options_from_text)
- if type_de_champ.simple_drop_down_list? - if type_de_champ.drop_down_list?
.cell .cell
= form.label :drop_down_other, for: dom_id(type_de_champ, :drop_down_other) do = form.label :drop_down_other, for: dom_id(type_de_champ, :drop_down_other) do
Proposer une option « autre » avec un texte libre Proposer une option « autre » avec un texte libre
@ -91,7 +91,7 @@
.cell.fr-mt-1w .cell.fr-mt-1w
= form.label :drop_down_secondary_description, "Description du champ secondaire (optionnel)", for: dom_id(type_de_champ, :drop_down_secondary_description) = form.label :drop_down_secondary_description, "Description du champ secondaire (optionnel)", for: dom_id(type_de_champ, :drop_down_secondary_description)
= form.text_area :drop_down_secondary_description, class: 'fr-input small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :drop_down_secondary_description) = form.text_area :drop_down_secondary_description, class: 'fr-input small-margin small width-100', rows: 3, id: dom_id(type_de_champ, :drop_down_secondary_description)
- if type_de_champ.piece_justificative? - if type_de_champ.piece_justificative_or_titre_identite?
.cell .cell
= form.label :piece_justificative_template, "Modèle", for: dom_id(type_de_champ, :piece_justificative_template) = form.label :piece_justificative_template, "Modèle", for: dom_id(type_de_champ, :piece_justificative_template)
= render Attachment::EditComponent.new(**piece_justificative_template_options) = render Attachment::EditComponent.new(**piece_justificative_template_options)
@ -120,7 +120,7 @@
Spécifier un nombre maximal conseillé de caractères : Spécifier un nombre maximal conseillé de caractères :
= form.select :character_limit, options_for_character_limit, {}, { id: dom_id(type_de_champ, :character_limit), class: 'fr-select' } = form.select :character_limit, options_for_character_limit, {}, { id: dom_id(type_de_champ, :character_limit), class: 'fr-select' }
- if type_de_champ.block? - if type_de_champ.repetition?
.flex.justify-start.section.fr-ml-1w .flex.justify-start.section.fr-ml-1w
.editor-block.flex-grow.cell .editor-block.flex-grow.cell
= render TypesDeChampEditor::BlockComponent.new(block: coordinate, coordinates: coordinate.revision_types_de_champ, upper_coordinates: @upper_coordinates) = render TypesDeChampEditor::BlockComponent.new(block: coordinate, coordinates: coordinate.revision_types_de_champ, upper_coordinates: @upper_coordinates)

View file

@ -62,7 +62,7 @@ class RootController < ApplicationController
"option C" "option C"
] ]
type_de_champ.save type_de_champ.save
elsif type_de_champ.drop_down_list? elsif type_de_champ.any_drop_down_list?
type_de_champ.drop_down_options = type_de_champ.drop_down_options =
[ [
"option A", "option A",

View file

@ -110,13 +110,13 @@ module Types
end end
def champ_descriptors def champ_descriptors
if type_de_champ.block? if type_de_champ.repetition?
Loaders::Association.for(object.class, revision_types_de_champ: :type_de_champ).load(object) Loaders::Association.for(object.class, revision_types_de_champ: :type_de_champ).load(object)
end end
end end
def options def options
if type_de_champ.drop_down_list? if type_de_champ.any_drop_down_list?
type_de_champ.drop_down_options.reject(&:empty?) type_de_champ.drop_down_options.reject(&:empty?)
end end
end end

View file

@ -12,7 +12,7 @@ module ChampHelper
def auto_attach_url(object, procedure_id: nil) def auto_attach_url(object, procedure_id: nil)
if object.is_a?(Champ) if object.is_a?(Champ)
champs_piece_justificative_url(object.dossier, object.stable_id, row_id: object.row_id) champs_piece_justificative_url(object.dossier, object.stable_id, row_id: object.row_id)
elsif object.is_a?(TypeDeChamp) && object.piece_justificative? elsif object.is_a?(TypeDeChamp) && object.piece_justificative_or_titre_identite?
piece_justificative_template_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id:) piece_justificative_template_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id:)
elsif object.is_a?(TypeDeChamp) && object.explication? elsif object.is_a?(TypeDeChamp) && object.explication?
notice_explicative_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id:) notice_explicative_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id:)

View file

@ -38,39 +38,21 @@ class Champ < ApplicationRecord
:current_section_level, :current_section_level,
:exclude_from_export?, :exclude_from_export?,
:exclude_from_view?, :exclude_from_view?,
:repetition?,
:block?,
:dossier_link?,
:departement?,
:region?,
:textarea?,
:piece_justificative?,
:titre_identite?,
:header_section?,
:checkbox?,
:simple_drop_down_list?,
:linked_drop_down_list?,
:non_fillable?, :non_fillable?,
:fillable?, :fillable?,
:cnaf?,
:dgfip?,
:pole_emploi?,
:mesri?,
:rna?,
:siret?,
:carte?,
:datetime?,
:mandatory?, :mandatory?,
:prefillable?, :prefillable?,
:refresh_after_update?, :refresh_after_update?,
:character_limit?, :character_limit?,
:character_limit, :character_limit,
:yes_no?,
:expression_reguliere, :expression_reguliere,
:expression_reguliere_exemple_text, :expression_reguliere_exemple_text,
:expression_reguliere_error_message, :expression_reguliere_error_message,
to: :type_de_champ to: :type_de_champ
delegate(*TypeDeChamp.type_champs.values.map { "#{_1}?".to_sym }, to: :type_de_champ)
delegate :piece_justificative_or_titre_identite?, :any_drop_down_list?, to: :type_de_champ
delegate :to_typed_id, :to_typed_id_for_query, to: :type_de_champ, prefix: true delegate :to_typed_id, :to_typed_id_for_query, to: :type_de_champ, prefix: true
delegate :revision, to: :dossier, prefix: true delegate :revision, to: :dossier, prefix: true

View file

@ -391,7 +391,7 @@ class ProcedureRevision < ApplicationRecord
to_type_de_champ.condition&.to_s(to_coordinates.map(&:type_de_champ))) to_type_de_champ.condition&.to_s(to_coordinates.map(&:type_de_champ)))
end end
if to_type_de_champ.drop_down_list? if to_type_de_champ.any_drop_down_list?
if from_type_de_champ.drop_down_options != to_type_de_champ.drop_down_options if from_type_de_champ.drop_down_options != to_type_de_champ.drop_down_options
changes << ProcedureRevisionChange::UpdateChamp.new(from_type_de_champ, changes << ProcedureRevisionChange::UpdateChamp.new(from_type_de_champ,
:drop_down_options, :drop_down_options,
@ -425,7 +425,7 @@ class ProcedureRevision < ApplicationRecord
from_type_de_champ.carte_optional_layers, from_type_de_champ.carte_optional_layers,
to_type_de_champ.carte_optional_layers) to_type_de_champ.carte_optional_layers)
end end
elsif to_type_de_champ.piece_justificative? elsif to_type_de_champ.piece_justificative_or_titre_identite?
if from_type_de_champ.checksum_for_attachment(:piece_justificative_template) != to_type_de_champ.checksum_for_attachment(:piece_justificative_template) if from_type_de_champ.checksum_for_attachment(:piece_justificative_template) != to_type_de_champ.checksum_for_attachment(:piece_justificative_template)
changes << ProcedureRevisionChange::UpdateChamp.new(from_type_de_champ, changes << ProcedureRevisionChange::UpdateChamp.new(from_type_de_champ,
:piece_justificative_template, :piece_justificative_template,

View file

@ -66,7 +66,7 @@ class TypeDeChamp < ApplicationRecord
expression_reguliere: STANDARD expression_reguliere: STANDARD
} }
enum type_champs: { enum type_champ: {
engagement_juridique: 'engagement_juridique', engagement_juridique: 'engagement_juridique',
header_section: 'header_section', header_section: 'header_section',
@ -323,118 +323,10 @@ class TypeDeChamp < ApplicationRecord
]) ])
end end
def drop_down_list?
type_champ.in?([
TypeDeChamp.type_champs.fetch(:drop_down_list),
TypeDeChamp.type_champs.fetch(:multiple_drop_down_list),
TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
])
end
def simple_drop_down_list?
type_champ == TypeDeChamp.type_champs.fetch(:drop_down_list)
end
def multiple_drop_down_list?
type_champ == TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
end
def linked_drop_down_list?
type_champ == TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
end
def yes_no?
type_champ == TypeDeChamp.type_champs.fetch(:yes_no)
end
def block?
type_champ == TypeDeChamp.type_champs.fetch(:repetition)
end
def header_section?
type_champ == TypeDeChamp.type_champs.fetch(:header_section)
end
def exclude_from_view? def exclude_from_view?
type_champ == TypeDeChamp.type_champs.fetch(:explication) type_champ == TypeDeChamp.type_champs.fetch(:explication)
end end
def explication?
type_champ == TypeDeChamp.type_champs.fetch(:explication)
end
def repetition?
type_champ == TypeDeChamp.type_champs.fetch(:repetition)
end
def dossier_link?
type_champ == TypeDeChamp.type_champs.fetch(:dossier_link)
end
def siret?
type_champ == TypeDeChamp.type_champs.fetch(:siret)
end
def piece_justificative?
type_champ == TypeDeChamp.type_champs.fetch(:piece_justificative) || type_champ == TypeDeChamp.type_champs.fetch(:titre_identite)
end
def legacy_number?
type_champ == TypeDeChamp.type_champs.fetch(:number)
end
def textarea?
type_champ == TypeDeChamp.type_champs.fetch(:textarea)
end
def titre_identite?
type_champ == TypeDeChamp.type_champs.fetch(:titre_identite)
end
def carte?
type_champ == TypeDeChamp.type_champs.fetch(:carte)
end
def cnaf?
type_champ == TypeDeChamp.type_champs.fetch(:cnaf)
end
def rna?
type_champ == TypeDeChamp.type_champs.fetch(:rna)
end
def dgfip?
type_champ == TypeDeChamp.type_champs.fetch(:dgfip)
end
def pole_emploi?
type_champ == TypeDeChamp.type_champs.fetch(:pole_emploi)
end
def departement?
type_champ == TypeDeChamp.type_champs.fetch(:departements)
end
def region?
type_champ == TypeDeChamp.type_champs.fetch(:regions)
end
def mesri?
type_champ == TypeDeChamp.type_champs.fetch(:mesri)
end
def datetime?
type_champ == TypeDeChamp.type_champs.fetch(:datetime)
end
def checkbox?
type_champ == TypeDeChamp.type_champs.fetch(:checkbox)
end
def expression_reguliere?
type_champ == TypeDeChamp.type_champs.fetch(:expression_reguliere)
end
def public? def public?
!private? !private?
end end
@ -546,11 +438,11 @@ class TypeDeChamp < ApplicationRecord
end end
def options_for_select def options_for_select
if departement? if departements?
APIGeoService.departement_options APIGeoService.departement_options
elsif region? elsif regions?
APIGeoService.region_options APIGeoService.region_options
elsif drop_down_list? elsif any_drop_down_list?
drop_down_options drop_down_options
elsif yes_no? elsif yes_no?
Champs::YesNoChamp.options Champs::YesNoChamp.options
@ -757,6 +649,21 @@ class TypeDeChamp < ApplicationRecord
CHAMP_TYPE_TO_TYPE_CHAMP = type_champs.values.map { [type_champ_to_champ_class_name(_1), _1] }.to_h CHAMP_TYPE_TO_TYPE_CHAMP = type_champs.values.map { [type_champ_to_champ_class_name(_1), _1] }.to_h
def piece_justificative_or_titre_identite?
type_champ.in?([
TypeDeChamp.type_champs.fetch(:piece_justificative),
TypeDeChamp.type_champs.fetch(:titre_identite)
])
end
def any_drop_down_list?
type_champ.in?([
TypeDeChamp.type_champs.fetch(:drop_down_list),
TypeDeChamp.type_champs.fetch(:multiple_drop_down_list),
TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
])
end
private private
def castable_on_change?(from_type, to_type) def castable_on_change?(from_type, to_type)
@ -780,7 +687,7 @@ class TypeDeChamp < ApplicationRecord
end end
def remove_attachment def remove_attachment
if !piece_justificative? && piece_justificative_template.attached? if !piece_justificative_or_titre_identite? && piece_justificative_template.attached?
piece_justificative_template.purge_later piece_justificative_template.purge_later
elsif !explication? && notice_explicative.attached? elsif !explication? && notice_explicative.attached?
notice_explicative.purge_later notice_explicative.purge_later
@ -788,7 +695,7 @@ class TypeDeChamp < ApplicationRecord
end end
def set_drop_down_list_options def set_drop_down_list_options
if (simple_drop_down_list? || multiple_drop_down_list?) && drop_down_options.empty? if (drop_down_list? || multiple_drop_down_list?) && drop_down_options.empty?
self.drop_down_options = ['Fromage', 'Dessert'] self.drop_down_options = ['Fromage', 'Dessert']
elsif linked_drop_down_list? && drop_down_options.none?(/^--.*--$/) elsif linked_drop_down_list? && drop_down_options.none?(/^--.*--$/)
self.drop_down_options = ['--Fromage--', 'bleu de sassenage', 'picodon', '--Dessert--', 'éclair', 'tarte aux pommes'] self.drop_down_options = ['--Fromage--', 'bleu de sassenage', 'picodon', '--Dessert--', 'éclair', 'tarte aux pommes']

View file

@ -2,7 +2,7 @@
class TypesDeChamp::NoEmptyBlockValidator < ActiveModel::EachValidator class TypesDeChamp::NoEmptyBlockValidator < ActiveModel::EachValidator
def validate_each(procedure, attribute, types_de_champ) def validate_each(procedure, attribute, types_de_champ)
types_de_champ.filter(&:block?).each do |repetition| types_de_champ.filter(&:repetition?).each do |repetition|
validate_block_not_empty(procedure, attribute, repetition) validate_block_not_empty(procedure, attribute, repetition)
end end
end end

View file

@ -2,7 +2,7 @@
class TypesDeChamp::NoEmptyDropDownValidator < ActiveModel::EachValidator class TypesDeChamp::NoEmptyDropDownValidator < ActiveModel::EachValidator
def validate_each(procedure, attribute, types_de_champ) def validate_each(procedure, attribute, types_de_champ)
types_de_champ.filter(&:drop_down_list?).each do |drop_down| types_de_champ.filter(&:any_drop_down_list?).each do |drop_down|
validate_drop_down_not_empty(procedure, attribute, drop_down) validate_drop_down_not_empty(procedure, attribute, drop_down)
end end
end end

View file

@ -60,7 +60,7 @@ describe Procedure::ErrorsSummary, type: :component do
let(:validation_context) { :types_de_champ_public_editor } let(:validation_context) { :types_de_champ_public_editor }
before do before do
drop_down_public = procedure.draft_revision.types_de_champ_public.find(&:drop_down_list?) drop_down_public = procedure.draft_revision.types_de_champ_public.find(&:any_drop_down_list?)
drop_down_public.update!(drop_down_options: []) drop_down_public.update!(drop_down_options: [])
subject subject
end end

View file

@ -219,7 +219,7 @@ describe API::V2::GraphqlController do
description: tdc.description, description: tdc.description,
required: tdc.mandatory?, required: tdc.mandatory?,
champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { { id: _1.to_typed_id, __typename: format_type_champ(_1.type_champ) } } : nil, champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { { id: _1.to_typed_id, __typename: format_type_champ(_1.type_champ) } } : nil,
options: tdc.drop_down_list? ? tdc.drop_down_options.reject(&:empty?) : nil options: tdc.any_drop_down_list? ? tdc.drop_down_options.reject(&:empty?) : nil
}.compact }.compact
end, end,
dossiers: { dossiers: {

View file

@ -24,7 +24,7 @@ FactoryBot.define do
after(:create) do |dossier, evaluator| after(:create) do |dossier, evaluator|
if evaluator.populate_champs if evaluator.populate_champs
dossier.revision.types_de_champ_public.each do |type_de_champ| dossier.revision.types_de_champ_public.each do |type_de_champ|
value = if type_de_champ.simple_drop_down_list? value = if type_de_champ.drop_down_list?
type_de_champ.drop_down_options.first type_de_champ.drop_down_options.first
elsif type_de_champ.multiple_drop_down_list? elsif type_de_champ.multiple_drop_down_list?
type_de_champ.drop_down_options.first(2).to_json type_de_champ.drop_down_options.first(2).to_json
@ -36,7 +36,7 @@ FactoryBot.define do
if evaluator.populate_annotations if evaluator.populate_annotations
dossier.revision.types_de_champ_private.each do |type_de_champ| dossier.revision.types_de_champ_private.each do |type_de_champ|
value = if type_de_champ.simple_drop_down_list? value = if type_de_champ.drop_down_list?
type_de_champ.drop_down_options.first type_de_champ.drop_down_options.first
elsif type_de_champ.multiple_drop_down_list? elsif type_de_champ.multiple_drop_down_list?
type_de_champ.drop_down_options.first(2).to_json type_de_champ.drop_down_options.first(2).to_json

View file

@ -520,7 +520,7 @@ describe Dossier, type: :model do
context 'when titre identite' do context 'when titre identite' do
let(:types_de_champ_public) { [{ type: :titre_identite }] } let(:types_de_champ_public) { [{ type: :titre_identite }] }
let(:champ) { dossier.project_champs_public.find(&:piece_justificative?) } let(:champ) { dossier.project_champs_public.find(&:titre_identite?) }
context 'when not visible' do context 'when not visible' do
let(:visible) { false } let(:visible) { false }

View file

@ -407,7 +407,7 @@ describe Procedure do
end end
it 'validates that no drop-down type de champ is empty' do it 'validates that no drop-down type de champ is empty' do
drop_down = procedure.draft_revision.types_de_champ_public.find(&:drop_down_list?) drop_down = procedure.draft_revision.types_de_champ_public.find(&:any_drop_down_list?)
drop_down.update!(drop_down_options: []) drop_down.update!(drop_down_options: [])
procedure.reload.validate(:publication) procedure.reload.validate(:publication)
@ -440,7 +440,7 @@ describe Procedure do
end end
it 'validates that no drop-down type de champ is empty' do it 'validates that no drop-down type de champ is empty' do
drop_down = procedure.draft_revision.types_de_champ_private.find(&:drop_down_list?) drop_down = procedure.draft_revision.types_de_champ_private.find(&:any_drop_down_list?)
drop_down.update!(drop_down_options: []) drop_down.update!(drop_down_options: [])
procedure.reload.validate(:publication) procedure.reload.validate(:publication)

View file

@ -71,9 +71,9 @@ describe 'Publishing a procedure', js: true do
end end
before do before do
drop_down = procedure.draft_revision.types_de_champ_public.find(&:drop_down_list?) drop_down = procedure.draft_revision.types_de_champ_public.find(&:any_drop_down_list?)
drop_down.update!(drop_down_options: []) drop_down.update!(drop_down_options: [])
drop_down = procedure.draft_revision.types_de_champ_private.find(&:drop_down_list?) drop_down = procedure.draft_revision.types_de_champ_private.find(&:any_drop_down_list?)
drop_down.update!(drop_down_options: []) drop_down.update!(drop_down_options: [])
end end

View file

@ -122,7 +122,7 @@ describe "procedure filters" do
describe 'departements' do describe 'departements' do
let(:types_de_champ_public) { [{ type: :departements }] } let(:types_de_champ_public) { [{ type: :departements }] }
scenario "should be able to find by departements with custom enum lookup", js: true do scenario "should be able to find by departements with custom enum lookup", js: true do
departement_champ = new_unfollow_dossier.champs.find(&:departement?) departement_champ = new_unfollow_dossier.champs.find(&:departements?)
departement_champ.update!(value: 'Oise', external_id: '60') departement_champ.update!(value: 'Oise', external_id: '60')
departement_champ.reload departement_champ.reload
champ_select_value = "#{departement_champ.external_id} #{departement_champ.value}" champ_select_value = "#{departement_champ.external_id} #{departement_champ.value}"
@ -162,7 +162,7 @@ describe "procedure filters" do
describe 'region' do describe 'region' do
let(:types_de_champ_public) { [{ type: :regions }] } let(:types_de_champ_public) { [{ type: :regions }] }
scenario "should be able to find by region with custom enum lookup", js: true do scenario "should be able to find by region with custom enum lookup", js: true do
region_champ = new_unfollow_dossier.champs.find(&:region?) region_champ = new_unfollow_dossier.champs.find(&:regions?)
region_champ.update!(value: 'Bretagne', external_id: '53') region_champ.update!(value: 'Bretagne', external_id: '53')
region_champ.reload region_champ.reload