Merge pull request #8701 from demarches-simplifiees/improve-instruction-dropdown

[instructeurs] amelioration UX du bouton d'instruction
This commit is contained in:
Lisa Durand 2023-03-06 10:45:00 +00:00 committed by GitHub
commit d65050ff44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 36 additions and 25 deletions

View file

@ -246,6 +246,11 @@ ul.dropdown-items {
} }
} }
&.form-inside {
background-color: $white;
margin-top: -2px;
}
&.danger { &.danger {
&:hover { &:hover {
background-color: $medium-red; background-color: $medium-red;

View file

@ -15,7 +15,7 @@
%h4= opt[:label] %h4= opt[:label]
.motivation.accept .motivation.accept
= form.text_area :motivation, class: 'motivation-text-area' = form.text_area :motivation, class: 'fr-input'
#justificatif_motivation_suggest_accept.optional-justificatif #justificatif_motivation_suggest_accept.optional-justificatif
%button.button{ type: 'button', onclick: "DS.showImportJustificatif('accept');" } Ajouter un justificatif (optionnel) %button.button{ type: 'button', onclick: "DS.showImportJustificatif('accept');" } Ajouter un justificatif (optionnel)
#justificatif_motivation_import_accept.hidden #justificatif_motivation_import_accept.hidden

View file

@ -9,11 +9,13 @@ class Dropdown::MenuComponent < ApplicationComponent
def initialize(wrapper:, def initialize(wrapper:,
wrapper_options: {}, wrapper_options: {},
button_options: {}, button_options: {},
menu_options: {}) menu_options: {},
role: nil)
@wrapper = wrapper @wrapper = wrapper
@wrapper_options = wrapper_options @wrapper_options = wrapper_options
@button_options = button_options @button_options = button_options
@menu_options = menu_options @menu_options = menu_options
@role = role
end end
def wrapper_options def wrapper_options
@ -37,6 +39,7 @@ class Dropdown::MenuComponent < ApplicationComponent
end end
def menu_role def menu_role
return @role if @role
forms? ? :region : :menu forms? ? :region : :menu
end end

View file

@ -3,12 +3,19 @@ import { show, hide } from '@utils';
export function showMotivation(event, state) { export function showMotivation(event, state) {
event.preventDefault(); event.preventDefault();
motivationCancel(); motivationCancel();
show(document.querySelector(`.motivation.${state}`)); const stateElement = document.querySelector(`.motivation.${state}`);
show(stateElement.parentElement);
show(stateElement);
hide(document.querySelector('.dropdown-items')); hide(document.querySelector('.dropdown-items'));
} }
export function motivationCancel() { export function motivationCancel() {
document.querySelectorAll('.motivation').forEach(hide); document.querySelectorAll('.motivation').forEach(hide);
document
.querySelectorAll('.motivation')
.forEach((el) => hide(el.parentElement));
show(document.querySelector('.dropdown-items')); show(document.querySelector('.dropdown-items'));
} }

View file

@ -1,5 +1,5 @@
- if dossier.en_instruction? - if dossier.en_instruction?
= render Dropdown::MenuComponent.new(wrapper: :div, wrapper_options: { data: {'turbo-force': true} }, button_options: { class: [button_or_label_class(dossier)] }) do |menu| = render Dropdown::MenuComponent.new(wrapper: :div, wrapper_options: { data: {'turbo-force': true} }, button_options: { class: [button_or_label_class(dossier)]}, role: dossier.en_instruction? ? :region : :menu) do |menu|
- menu.with_button_inner_html do - menu.with_button_inner_html do
Instruire le dossier Instruire le dossier
@ -10,6 +10,9 @@
%h4 Accepter %h4 Accepter
Lusager sera notifié que son dossier a été accepté Lusager sera notifié que son dossier a été accepté
- menu.with_item(class: "hidden inactive form-inside") do
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier: dossier, placeholder: 'Expliquez au demandeur pourquoi ce dossier est accepté (facultatif)', popup_class: 'accept', process_action: 'accepter', title: 'Accepter', confirm: "Confirmez-vous l'acceptation ce dossier ?" }
- menu.with_item do - menu.with_item do
= link_to('#', onclick: "DS.showMotivation(event, 'without-continuation');", role: 'menuitem') do = link_to('#', onclick: "DS.showMotivation(event, 'without-continuation');", role: 'menuitem') do
@ -18,6 +21,8 @@
%h4 Classer sans suite %h4 Classer sans suite
Lusager sera notifié que son dossier a été classé sans suite Lusager sera notifié que son dossier a été classé sans suite
- menu.with_item(class: "hidden inactive form-inside") do
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier: dossier, placeholder: 'Expliquez au demandeur pourquoi ce dossier est classé sans suite (obligatoire)', popup_class: 'without-continuation', process_action: 'classer_sans_suite', title: 'Classer sans suite', confirm: 'Confirmez-vous le classement sans suite de ce dossier ?' }
- menu.with_item do - menu.with_item do
= link_to('#', onclick: "DS.showMotivation(event, 'refuse');", role: 'menuitem') do = link_to('#', onclick: "DS.showMotivation(event, 'refuse');", role: 'menuitem') do
@ -26,11 +31,5 @@
%h4 Refuser %h4 Refuser
Lusager sera notifié que son dossier a été refusé Lusager sera notifié que son dossier a été refusé
- menu.with_form do - menu.with_item(class: "hidden inactive form-inside") do
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier: dossier, popup_title: 'Accepter le dossier', placeholder: 'Expliquez au demandeur pourquoi ce dossier est accepté (facultatif)', popup_class: 'accept', process_action: 'accepter', title: 'Accepter', confirm: "Confirmez-vous l'acceptation ce dossier ?" } = render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier: dossier, placeholder: 'Expliquez au demandeur pourquoi ce dossier est refusé (obligatoire)', popup_class: 'refuse', process_action: 'refuser', title: 'Refuser', confirm: 'Confirmez-vous le refus de ce dossier ?' }
- menu.with_form do
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier: dossier, popup_title: 'Classer le dossier sans suite', placeholder: 'Expliquez au demandeur pourquoi ce dossier est classé sans suite (obligatoire)', popup_class: 'without-continuation', process_action: 'classer_sans_suite', title: 'Classer sans suite', confirm: 'Confirmez-vous le classement sans suite de ce dossier ?' }
- menu.with_form do
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier: dossier, popup_title: 'Refuser le dossier', placeholder: 'Expliquez au demandeur pourquoi ce dossier est refusé (obligatoire)', popup_class: 'refuse', process_action: 'refuser', title: 'Refuser', confirm: 'Confirmez-vous le refus de ce dossier ?' }

View file

@ -1,11 +1,7 @@
.motivation.hidden{ class: popup_class } .motivation.hidden{ class: popup_class }
%h3.fr-h5 = form_tag(terminer_instructeur_dossier_path(dossier.procedure, dossier), data: { turbo: true, turbo_confirm: confirm }, method: :post, multipart: true) do
%span.icon{ class: popup_class }
#{popup_title}
= form_tag(terminer_instructeur_dossier_path(dossier.procedure, dossier), data: { turbo: true, turbo_confirm: confirm }, method: :post, multipart: true, class: 'form') do
- if title == 'Accepter' - if title == 'Accepter'
= text_area :dossier, :motivation, class: 'motivation-text-area', placeholder: placeholder, required: false = text_area :dossier, :motivation, class: 'fr-input', placeholder: placeholder, required: false
- if dossier.attestation_template&.activated? - if dossier.attestation_template&.activated?
%p.help %p.help
Lacceptation du dossier envoie automatiquement Lacceptation du dossier envoie automatiquement
@ -30,11 +26,11 @@
- unspecified_annotations_privees.each do |unspecified_annotations_privee| - unspecified_annotations_privees.each do |unspecified_annotations_privee|
%li= unspecified_annotations_privee.libelle %li= unspecified_annotations_privee.libelle
- else - else
= text_area :dossier, :motivation, class: 'motivation-text-area', placeholder: placeholder, required: true = text_area :dossier, :motivation, class: 'fr-input', placeholder: placeholder, required: true
.optional-justificatif{ id: "justificatif_motivation_suggest_#{popup_class}", onclick: "DS.showImportJustificatif('#{popup_class}');" } .optional-justificatif{ id: "justificatif_motivation_suggest_#{popup_class}", onclick: "DS.showImportJustificatif('#{popup_class}');" }
.button Ajouter un justificatif (optionnel) .fr-btn.fr-btn--tertiary-no-outline.fr-btn--icon-left.fr-icon-attachment-line.fr-ml-0 Ajouter un justificatif (optionnel)
.hidden{ id: "justificatif_motivation_import_#{popup_class}" } .hidden{ id: "justificatif_motivation_import_#{popup_class}" }
= file_field :dossier, :justificatif_motivation, direct_upload: true = file_field :dossier, :justificatif_motivation, direct_upload: true
.text-right .text-right.fr-mt-2w
%span.button{ onclick: 'DS.motivationCancel();' } Annuler %span.fr-btn.fr-btn--secondary{ onclick: 'DS.motivationCancel();' } Annuler
= button_tag 'Valider la décision', name: :process_action, value: process_action, class: 'button primary', title: title = button_tag 'Valider la décision', name: :process_action, value: process_action, class: 'fr-btn fr-mr-0', title: title

View file

@ -14,7 +14,7 @@ describe 'instructeurs/dossiers/instruction_button.html.haml', type: :view do
matcher :have_dropdown_items do |options| matcher :have_dropdown_items do |options|
match do |rendered| match do |rendered|
expected_count = options[:count] || 1 expected_count = options[:count] || 1
expect(rendered).to have_selector('ul.dropdown-items li', count: expected_count) expect(rendered).to have_selector('ul.dropdown-items li:not(.hidden)', count: expected_count)
end end
end end

View file

@ -73,7 +73,8 @@ describe 'instructeurs/dossiers/show.html.haml', type: :view do
expect(subject).to have_link('Repasser en construction', href: repasser_en_construction_instructeur_dossier_path(dossier.procedure, dossier)) expect(subject).to have_link('Repasser en construction', href: repasser_en_construction_instructeur_dossier_path(dossier.procedure, dossier))
expect(subject).to have_link('Ne plus suivre', href: unfollow_instructeur_dossier_path(dossier.procedure, dossier)) expect(subject).to have_link('Ne plus suivre', href: unfollow_instructeur_dossier_path(dossier.procedure, dossier))
expect(subject).to have_button('Instruire le dossier') expect(subject).to have_button('Instruire le dossier')
expect(subject).to have_selector('.header-actions ul:first-child .fr-btn', count: 3) expect(subject).to have_selector('.header-actions ul:first-child > li a.fr-btn', count: 2)
expect(subject).to have_selector('.header-actions ul:first-child > li.instruction-button', count: 1)
end end
end end