feat(attestation): can toggle optional champs tags visibility
This commit is contained in:
parent
c5174f7d43
commit
8ba1c0e481
7 changed files with 112 additions and 6 deletions
|
@ -75,4 +75,14 @@
|
|||
background-color: var(--background-action-low-blue-france);
|
||||
}
|
||||
}
|
||||
|
||||
// scss-lint:disable SelectorFormat
|
||||
#show_maybe_null + label {
|
||||
margin-bottom: 0.25rem;
|
||||
|
||||
.fr-hint-text {
|
||||
position: absolute;
|
||||
top: 1.15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,4 +14,18 @@ class TagsButtonListComponent < ApplicationComponent
|
|||
def button_title(tag)
|
||||
tag[:description].presence || tag[:libelle]
|
||||
end
|
||||
|
||||
def each_category
|
||||
tags.each_pair do |category, tags|
|
||||
yield category, tags, can_toggle_nullable?(category)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_toggle_nullable?(category)
|
||||
return false if category != :champ_public
|
||||
|
||||
tags[category].any? { _1[:maybe_null] }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
- tags.each_pair do |category, tags|
|
||||
%p.fr-label.fr-text--sm.fr-text--bold.fr-mb-1w= t(category, scope: ".categories")
|
||||
%ul.fr-tags-group
|
||||
- each_category do |category, tags, can_toggle_nullable|
|
||||
.flex
|
||||
%p.fr-label.fr-text--sm.fr-text--bold.fr-mb-1w= t(category, scope: ".categories")
|
||||
|
||||
- if can_toggle_nullable
|
||||
.fr-fieldset__element.fr-ml-4w
|
||||
.fr-checkbox-group.fr-checkbox-group--sm
|
||||
= check_box_tag("show_maybe_null", 1, false, data: { "no-autosubmit" => true, action: "change->attestation#toggleMaybeNull"})
|
||||
= label_tag "show_maybe_null", for: :show_maybe_null do
|
||||
Voir les champs facultatifs
|
||||
%span.hidden.fr-hint-text Un champ non rempli restera vide dans l’attestation.
|
||||
|
||||
%ul.fr-tags-group{ data: { category: category } }
|
||||
- tags.each do |tag|
|
||||
%li
|
||||
%li{ class: class_names("hidden" => can_toggle_nullable && tag[:maybe_null]), data: { "maybe-null" => can_toggle_nullable && tag[:maybe_null].present? } }
|
||||
- label = button_label(tag)
|
||||
%button.fr-tag.fr-tag--sm{ type: "button", title: button_title(tag), data: { action: 'click->tiptap#insertTag', tiptap_target: 'tag', tag_id: tag[:id], tag_label: label } }
|
||||
= label
|
||||
|
|
|
@ -32,6 +32,20 @@ export class AttestationController extends ApplicationController {
|
|||
});
|
||||
}
|
||||
|
||||
toggleMaybeNull(event: Event) {
|
||||
const checkbox = event.target as HTMLInputElement;
|
||||
const visible = checkbox.checked;
|
||||
|
||||
// toggle hidden class on next label element
|
||||
checkbox.nextElementSibling
|
||||
?.querySelector('.fr-hint-text')
|
||||
?.classList?.toggle('hidden', !visible);
|
||||
|
||||
document.querySelectorAll('li[data-maybe-null]').forEach((tag) => {
|
||||
tag.classList.toggle('hidden', !visible);
|
||||
});
|
||||
}
|
||||
|
||||
private get isStateLayout() {
|
||||
return this.layoutToggleTarget.checked;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class TypesDeChamp::TypeDeChampBase
|
||||
include ActiveModel::Validations
|
||||
|
||||
delegate :description, :libelle, :mandatory, :stable_id, :fillable?, to: :@type_de_champ
|
||||
delegate :description, :libelle, :mandatory, :mandatory?, :stable_id, :fillable?, :public?, to: :@type_de_champ
|
||||
|
||||
FILL_DURATION_SHORT = 10.seconds
|
||||
FILL_DURATION_MEDIUM = 1.minute
|
||||
|
@ -19,6 +19,7 @@ class TypesDeChamp::TypeDeChampBase
|
|||
libelle: TagsSubstitutionConcern::TagsParser.normalize(libelle),
|
||||
id: "tdc#{stable_id}",
|
||||
description: description,
|
||||
maybe_null: public? && !mandatory?,
|
||||
lambda: -> (champs) {
|
||||
champs.find { |champ| champ.stable_id == stable_id }&.for_tag
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ class TagsButtonListComponentPreview < ViewComponent::Preview
|
|||
{
|
||||
id: 'tdc13',
|
||||
libelle: 'Votre avis très ' + 'long ' * 12,
|
||||
description: 'Ce libellé a été tronqué'
|
||||
description: 'Ce libellé a été tronqué',
|
||||
maybe_null: true
|
||||
}
|
||||
],
|
||||
|
||||
|
|
56
spec/components/tags_button_list_component_spec.rb
Normal file
56
spec/components/tags_button_list_component_spec.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
RSpec.describe TagsButtonListComponent, type: :component do
|
||||
let(:tags) do
|
||||
{
|
||||
individual: TagsSubstitutionConcern::INDIVIDUAL_TAGS,
|
||||
etablissement: TagsSubstitutionConcern::ENTREPRISE_TAGS,
|
||||
dossier: TagsSubstitutionConcern::DOSSIER_TAGS,
|
||||
champ_public: [
|
||||
{
|
||||
id: 'tdc12',
|
||||
libelle: 'Votre avis',
|
||||
description: 'Détaillez votre avis'
|
||||
},
|
||||
{
|
||||
id: 'tdc13',
|
||||
libelle: 'Un champ avec un nom très ' + 'long ' * 12,
|
||||
description: 'Ce libellé a été tronqué',
|
||||
maybe_null:
|
||||
}
|
||||
],
|
||||
|
||||
champ_private: [
|
||||
{
|
||||
id: 'tdc22',
|
||||
libelle: 'Montant accordé'
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
let(:maybe_null) { true }
|
||||
|
||||
let(:component) do
|
||||
described_class.new(tags:)
|
||||
end
|
||||
|
||||
subject { render_inline(component).to_html }
|
||||
|
||||
it 'renders' do
|
||||
expect(subject).to have_text("Identité")
|
||||
expect(subject).to have_text("civilité")
|
||||
expect(subject).to have_text("Votre avis")
|
||||
expect(subject).to have_text("Montant accordé")
|
||||
end
|
||||
|
||||
it "hide nullable tag" do
|
||||
expect(subject).to have_selector(".hidden button.fr-tag", text: "Un champ avec un nom")
|
||||
expect(subject).to have_selector(":not(.hidden) button.fr-tag", text: "Votre avis")
|
||||
expect(subject).to have_text("Voir les champs facultatifs")
|
||||
end
|
||||
|
||||
context "all champs are visible" do
|
||||
let(:maybe_null) { false }
|
||||
it {
|
||||
expect(subject).not_to have_text("Voir les champs facultatifs")
|
||||
}
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue