fix(dossier): show ineligibilite message on update
This commit is contained in:
parent
eb682f1e64
commit
009e426c31
9 changed files with 55 additions and 63 deletions
|
@ -1,18 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Dossiers::InvalidIneligibiliteRulesComponent < ApplicationComponent
|
||||
delegate :can_passer_en_construction?, to: :@dossier
|
||||
delegate :can_passer_en_construction?, to: :dossier
|
||||
|
||||
def initialize(dossier:)
|
||||
def initialize(dossier:, wrapped: true)
|
||||
@dossier = dossier
|
||||
@revision = dossier.revision
|
||||
|
||||
@opened = !dossier.can_passer_en_construction?
|
||||
@wrapped = wrapped
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :dossier
|
||||
|
||||
def render?
|
||||
!can_passer_en_construction?
|
||||
dossier.revision.ineligibilite_enabled?
|
||||
end
|
||||
|
||||
def error_message
|
||||
@dossier.revision.ineligibilite_message
|
||||
dossier.revision.ineligibilite_message
|
||||
end
|
||||
|
||||
def opened? = @opened
|
||||
def wrapped? = @wrapped
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
%div{ id: dom_id(@dossier, :ineligibilite_rules_broken), data: { controller: 'ineligibilite-rules-match', turbo_force: :server } }
|
||||
%button.fr-sr-only{ aria: {controls: 'modal-eligibilite-rules-dialog' }, data: {'fr-opened': "false" } }
|
||||
- modal_content = capture do
|
||||
%button.fr-sr-only{ aria: { controls: 'modal-eligibilite-rules-dialog' }, data: { 'fr-opened': opened?.to_s } }
|
||||
show modal
|
||||
|
||||
%dialog.fr-modal{ "aria-labelledby" => "fr-modal-title-modal-1", role: "dialog", id: 'modal-eligibilite-rules-dialog', data: { 'ineligibilite-rules-match-target' => 'dialog' } }
|
||||
%dialog.fr-modal{ "aria-labelledby" => "fr-modal-title-modal-1", role: "dialog", id: 'modal-eligibilite-rules-dialog', data: { 'turbo-permanent' => true } }
|
||||
.fr-container.fr-container--fluid.fr-container-md
|
||||
.fr-grid-row.fr-grid-row--center
|
||||
.fr-col-12.fr-col-md-8.fr-col-lg-6
|
||||
|
@ -14,3 +14,9 @@
|
|||
%span.fr-icon-arrow-right-line.fr-icon--lg>
|
||||
= t('.modal.title')
|
||||
%p= error_message
|
||||
|
||||
- if wrapped?
|
||||
%div{ id: dom_id(@dossier, :ineligibilite_rules_broken) }
|
||||
= modal_content
|
||||
- else
|
||||
= modal_content
|
||||
|
|
|
@ -280,9 +280,7 @@ module Users
|
|||
def update
|
||||
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
|
||||
@dossier = dossier_with_champs(pj_template: false)
|
||||
@can_passer_en_construction_was, @can_passer_en_construction_is = dossier.track_can_passer_en_construction do
|
||||
update_dossier_and_compute_errors
|
||||
end
|
||||
update_dossier_and_compute_errors
|
||||
|
||||
respond_to do |format|
|
||||
format.turbo_stream do
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
import { ApplicationController } from './application_controller';
|
||||
declare interface modal {
|
||||
disclose: () => void;
|
||||
}
|
||||
declare interface dsfr {
|
||||
modal: modal;
|
||||
}
|
||||
declare const window: Window &
|
||||
typeof globalThis & { dsfr: (elem: HTMLElement) => dsfr };
|
||||
|
||||
export class InvalidIneligibiliteRulesController extends ApplicationController {
|
||||
static targets = ['dialog'];
|
||||
|
||||
declare dialogTarget: HTMLElement;
|
||||
|
||||
connect() {
|
||||
setTimeout(() => window.dsfr(this.dialogTarget).modal.disclose(), 100);
|
||||
}
|
||||
}
|
|
@ -1025,18 +1025,6 @@ class Dossier < ApplicationRecord
|
|||
procedure.accuse_lecture? && termine?
|
||||
end
|
||||
|
||||
def track_can_passer_en_construction
|
||||
if !revision.ineligibilite_enabled
|
||||
yield
|
||||
[true, true] # without eligibilite rules, we never reach dossier.champs.visible?, don't cache anything
|
||||
else
|
||||
from = can_passer_en_construction? # with eligibilite rules, self.champ[x].visible is cached by passing thru conditions checks
|
||||
yield
|
||||
champs.map(&:reset_visible) # we must reset self.champs[x].visible?, because an update occurred and we should re-evaluate champs[x] visibility
|
||||
[from, can_passer_en_construction?]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_default_champs
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
= render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update, dossier: @dossier }
|
||||
|
||||
- if !params.key?(:validate)
|
||||
- if @can_passer_en_construction_was && !@can_passer_en_construction_is
|
||||
= turbo_stream.append('contenu', render(Dossiers::InvalidIneligibiliteRulesComponent.new(dossier: @dossier)))
|
||||
- else @ineligibilite_rules_is_computable
|
||||
= turbo_stream.remove(dom_id(@dossier, :ineligibilite_rules_broken))
|
||||
- if params[:validate].present? && @dossier.revision.ineligibilite_enabled?
|
||||
= turbo_stream.update dom_id(@dossier, :ineligibilite_rules_broken), render(Dossiers::InvalidIneligibiliteRulesComponent.new(dossier: @dossier, wrapped: false))
|
||||
|
||||
- if @update_contact_information
|
||||
= turbo_stream.update "contact_information", partial: 'shared/dossiers/update_contact_information', locals: { dossier: @dossier, procedure: @dossier.procedure }
|
||||
|
|
|
@ -775,9 +775,11 @@ describe Users::DossiersController, type: :controller do
|
|||
let(:types_de_champ_public) { [{ type: :text }, { type: :integer_number }] }
|
||||
let(:text_champ) { dossier.project_champs_public.first }
|
||||
let(:number_champ) { dossier.project_champs_public.last }
|
||||
let(:validate) { "true" }
|
||||
let(:submit_payload) do
|
||||
{
|
||||
id: dossier.id,
|
||||
validate:,
|
||||
dossier: {
|
||||
groupe_instructeur_id: dossier.groupe_instructeur_id,
|
||||
champs_public_attributes: {
|
||||
|
@ -805,28 +807,36 @@ describe Users::DossiersController, type: :controller do
|
|||
end
|
||||
render_views
|
||||
|
||||
context 'when it switches from true to false' do
|
||||
context 'when it becomes invalid' do
|
||||
let(:value) { must_be_greater_than + 1 }
|
||||
|
||||
it 'raises popup' do
|
||||
subject
|
||||
dossier.reload
|
||||
expect(dossier.can_passer_en_construction?).to be_falsey
|
||||
expect(assigns(:can_passer_en_construction_was)).to eq(true)
|
||||
expect(assigns(:can_passer_en_construction_is)).to eq(false)
|
||||
expect(response.body).to match(ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken))
|
||||
expect(response.body).to match(/aria-controls='modal-eligibilite-rules-dialog'[^>]*data-fr-opened='true'/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it stays true' do
|
||||
context 'when it says valid' do
|
||||
let(:value) { must_be_greater_than - 1 }
|
||||
it 'does nothing' do
|
||||
subject
|
||||
dossier.reload
|
||||
expect(dossier.can_passer_en_construction?).to be_truthy
|
||||
expect(assigns(:can_passer_en_construction_was)).to eq(true)
|
||||
expect(assigns(:can_passer_en_construction_is)).to eq(true)
|
||||
expect(response.body).not_to have_selector("##{ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken)}")
|
||||
expect(response.body).to match(/aria-controls='modal-eligibilite-rules-dialog'[^>]*data-fr-opened='false'/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not validating' do
|
||||
let(:validate) { nil }
|
||||
let(:value) { must_be_greater_than + 1 }
|
||||
|
||||
it 'does not render invalid ineligible modal' do
|
||||
subject
|
||||
dossier.reload
|
||||
expect(dossier.can_passer_en_construction?).to be_falsey
|
||||
expect(response.body).not_to include("aria-controls='modal-eligibilite-rules-dialog'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,21 +28,21 @@ describe 'Dossier Inéligibilité', js: true do
|
|||
visit brouillon_dossier_path(dossier)
|
||||
# no error while dossier is empty
|
||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||
|
||||
# does raise error when dossier is filled with condition that does not match
|
||||
# does nothing when dossier is filled with condition that does not match
|
||||
within "#champ-1" do
|
||||
find("label", text: "Non").click
|
||||
end
|
||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||
|
||||
# raise error when dossier is filled with condition that matches
|
||||
# open modal when dossier is filled with condition that matches
|
||||
within "#champ-1" do
|
||||
find("label", text: "Oui").click
|
||||
end
|
||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
||||
expect(page).to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
|
||||
|
||||
# reload page and see error
|
||||
visit brouillon_dossier_path(dossier)
|
||||
|
@ -51,6 +51,7 @@ describe 'Dossier Inéligibilité', js: true do
|
|||
|
||||
# modal is closable, and we can change our dossier response to be eligible
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
|
||||
expect(page).to have_text("Vous ne pouvez pas déposer votre dossier")
|
||||
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||
|
||||
|
@ -78,7 +79,7 @@ describe 'Dossier Inéligibilité', js: true do
|
|||
visit brouillon_dossier_path(dossier)
|
||||
# no error while dossier is empty
|
||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||
|
||||
# first condition matches (so ineligible), cannot submit dossier and error message is clear
|
||||
within "#champ-#{first_tdc.stable_id}" do
|
||||
|
@ -148,14 +149,14 @@ describe 'Dossier Inéligibilité', js: true do
|
|||
visit brouillon_dossier_path(dossier)
|
||||
# no error while dossier is empty
|
||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||
|
||||
# only one condition is matches, can submit dossier
|
||||
within "#champ-#{first_tdc.stable_id}" do
|
||||
find("label", text: "Oui").click
|
||||
end
|
||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||
|
||||
# Now test dossier modification
|
||||
click_on "Déposer le dossier"
|
||||
|
@ -196,7 +197,7 @@ describe 'Dossier Inéligibilité', js: true do
|
|||
scenario 'ineligibilite rules without validation on champ ensure to re-process cached champs.visible' do
|
||||
visit brouillon_dossier_path(dossier)
|
||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||
|
||||
within "#champ-1" do
|
||||
find("label", text: "Non").click
|
||||
|
|
|
@ -160,6 +160,7 @@ describe 'shared/dossiers/edit', type: :view do
|
|||
|
||||
before do
|
||||
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
|
||||
allow(dossier.revision).to receive(:ineligibilite_enabled?).and_return(true)
|
||||
end
|
||||
|
||||
it 'renders broken transitions rules dialog' do
|
||||
|
|
Loading…
Add table
Reference in a new issue