Merge pull request #3374 from betagouv/frederic/fix_3356-balises_menus_lies
Balises pour les menus liés
This commit is contained in:
commit
01a1f77c54
6 changed files with 92 additions and 28 deletions
|
@ -30,7 +30,7 @@ class Champs::LinkedDropDownListChamp < Champ
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
value.present? ? [primary_value, secondary_value].compact.join(' / ') : ""
|
value.present? ? [primary_value, secondary_value].select(&:present?).join(' / ') : ""
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_export
|
def for_export
|
||||||
|
|
|
@ -167,13 +167,11 @@ module TagsSubstitutionConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def types_de_champ_tags(types_de_champ, available_for_states)
|
def types_de_champ_tags(types_de_champ, available_for_states)
|
||||||
types_de_champ.map do |tdc|
|
tags = types_de_champ.flat_map(&:tags_for_template)
|
||||||
{
|
tags.each do |tag|
|
||||||
libelle: tdc.libelle,
|
tag[:available_for_states] = available_for_states
|
||||||
description: tdc.description,
|
|
||||||
available_for_states: available_for_states
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_tags(text, dossier)
|
def replace_tags(text, dossier)
|
||||||
|
@ -181,10 +179,9 @@ module TagsSubstitutionConcern
|
||||||
return ''
|
return ''
|
||||||
end
|
end
|
||||||
|
|
||||||
text = replace_type_de_champ_tags(text, filter_tags(champ_public_tags), dossier.champs)
|
|
||||||
text = replace_type_de_champ_tags(text, filter_tags(champ_private_tags), dossier.champs_private)
|
|
||||||
|
|
||||||
tags_and_datas = [
|
tags_and_datas = [
|
||||||
|
[champ_public_tags, dossier.champs],
|
||||||
|
[champ_private_tags, dossier.champs_private],
|
||||||
[dossier_tags, dossier],
|
[dossier_tags, dossier],
|
||||||
[INDIVIDUAL_TAGS, dossier.individual],
|
[INDIVIDUAL_TAGS, dossier.individual],
|
||||||
[ENTREPRISE_TAGS, dossier.etablissement&.entreprise]
|
[ENTREPRISE_TAGS, dossier.etablissement&.entreprise]
|
||||||
|
@ -195,38 +192,29 @@ module TagsSubstitutionConcern
|
||||||
.inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) }
|
.inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_type_de_champ_tags(text, types_de_champ, dossier_champs)
|
|
||||||
types_de_champ.inject(text) do |acc, tag|
|
|
||||||
champ = dossier_champs
|
|
||||||
.select { |dossier_champ| dossier_champ.libelle == tag[:libelle] }
|
|
||||||
.first
|
|
||||||
|
|
||||||
replace_tag(acc, tag, champ)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def replace_tags_with_values_from_data(text, tags, data)
|
def replace_tags_with_values_from_data(text, tags, data)
|
||||||
if data.present?
|
if data.present?
|
||||||
tags.inject(text) do |acc, tag|
|
tags.inject(text) do |acc, tag|
|
||||||
if tag.key?(:target)
|
replace_tag(acc, tag, data)
|
||||||
value = data.send(tag[:target])
|
|
||||||
else
|
|
||||||
value = instance_exec(data, &tag[:lambda])
|
|
||||||
end
|
|
||||||
replace_tag(acc, tag, value)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
text
|
text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_tag(text, tag, value)
|
def replace_tag(text, tag, data)
|
||||||
libelle = Regexp.quote(tag[:libelle])
|
libelle = Regexp.quote(tag[:libelle])
|
||||||
|
|
||||||
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
||||||
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
||||||
libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]")
|
libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]")
|
||||||
|
|
||||||
|
if tag.key?(:target)
|
||||||
|
value = data.send(tag[:target])
|
||||||
|
else
|
||||||
|
value = instance_exec(data, &tag[:lambda])
|
||||||
|
end
|
||||||
|
|
||||||
text.gsub(/--#{libelle}--/, value.to_s)
|
text.gsub(/--#{libelle}--/, value.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,6 +38,7 @@ class TypeDeChamp < ApplicationRecord
|
||||||
has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', dependent: :destroy
|
has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', dependent: :destroy
|
||||||
|
|
||||||
store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj
|
store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj
|
||||||
|
delegate :tags_for_template, to: :dynamic_type
|
||||||
|
|
||||||
# TODO simplify after migrating `options` column to (non YAML encoded) JSON
|
# TODO simplify after migrating `options` column to (non YAML encoded) JSON
|
||||||
class MaybeYaml
|
class MaybeYaml
|
||||||
|
|
|
@ -21,6 +21,34 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas
|
||||||
secondary_options
|
secondary_options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tags_for_template
|
||||||
|
tags = super
|
||||||
|
l = libelle
|
||||||
|
tags.push(
|
||||||
|
{
|
||||||
|
libelle: "#{l}/primaire",
|
||||||
|
description: "#{description} (menu primaire)",
|
||||||
|
lambda: -> (champs) {
|
||||||
|
champs
|
||||||
|
.detect { |champ| champ.libelle == l }
|
||||||
|
&.primary_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
tags.push(
|
||||||
|
{
|
||||||
|
libelle: "#{l}/secondaire",
|
||||||
|
description: "#{description} (menu secondaire)",
|
||||||
|
lambda: -> (champs) {
|
||||||
|
champs
|
||||||
|
.detect { |champ| champ.libelle == l }
|
||||||
|
&.secondary_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
tags
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_presence_of_primary_options
|
def check_presence_of_primary_options
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
class TypesDeChamp::TypeDeChampBase
|
class TypesDeChamp::TypeDeChampBase
|
||||||
include ActiveModel::Validations
|
include ActiveModel::Validations
|
||||||
|
|
||||||
delegate :libelle, to: :@type_de_champ
|
delegate :description, :libelle, to: :@type_de_champ
|
||||||
|
|
||||||
def initialize(type_de_champ)
|
def initialize(type_de_champ)
|
||||||
@type_de_champ = type_de_champ
|
@type_de_champ = type_de_champ
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tags_for_template
|
||||||
|
l = libelle
|
||||||
|
[
|
||||||
|
{
|
||||||
|
libelle: l,
|
||||||
|
description: description,
|
||||||
|
lambda: -> (champs) {
|
||||||
|
champs.detect { |champ| champ.libelle == l }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -110,6 +110,40 @@ describe TagsSubstitutionConcern, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the procedure has a linked drop down menus type de champ' do
|
||||||
|
let(:types_de_champ) do
|
||||||
|
[
|
||||||
|
create(:type_de_champ_linked_drop_down_list, libelle: 'libelle')
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:template) { 'tout : --libelle--, primaire : --libelle/primaire--, secondaire : --libelle/secondaire--' }
|
||||||
|
|
||||||
|
context 'and the champ has no value' do
|
||||||
|
it { is_expected.to eq('tout : , primaire : , secondaire : ') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the champ has a primary value' do
|
||||||
|
before do
|
||||||
|
c = dossier.champs.detect { |champ| champ.libelle == 'libelle' }
|
||||||
|
c.primary_value = 'primo'
|
||||||
|
c.save
|
||||||
|
end
|
||||||
|
it { is_expected.to eq('tout : primo, primaire : primo, secondaire : ') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the champ has a primary and secondary value' do
|
||||||
|
before do
|
||||||
|
c = dossier.champs.detect { |champ| champ.libelle == 'libelle' }
|
||||||
|
c.primary_value = 'primo'
|
||||||
|
c.secondary_value = 'secundo'
|
||||||
|
c.save
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to eq('tout : primo / secundo, primaire : primo, secondaire : secundo') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the dossier has a motivation' do
|
context 'when the dossier has a motivation' do
|
||||||
let(:dossier) { create(:dossier, motivation: 'motivation') }
|
let(:dossier) { create(:dossier, motivation: 'motivation') }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue