feat(attestation): can toggle optional champs tags visibility

This commit is contained in:
Colin Darie 2024-02-15 23:13:38 +01:00
parent c5174f7d43
commit 8ba1c0e481
No known key found for this signature in database
GPG key ID: 8C76CADD40253590
7 changed files with 112 additions and 6 deletions

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -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 lattestation.
%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

View file

@ -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;
}

View file

@ -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
}

View file

@ -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
}
],

View 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