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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Dossiers::InvalidIneligibiliteRulesComponent < ApplicationComponent
|
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
|
@dossier = dossier
|
||||||
@revision = dossier.revision
|
@revision = dossier.revision
|
||||||
|
|
||||||
|
@opened = !dossier.can_passer_en_construction?
|
||||||
|
@wrapped = wrapped
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :dossier
|
||||||
|
|
||||||
def render?
|
def render?
|
||||||
!can_passer_en_construction?
|
dossier.revision.ineligibilite_enabled?
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_message
|
def error_message
|
||||||
@dossier.revision.ineligibilite_message
|
dossier.revision.ineligibilite_message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def opened? = @opened
|
||||||
|
def wrapped? = @wrapped
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
%div{ id: dom_id(@dossier, :ineligibilite_rules_broken), data: { controller: 'ineligibilite-rules-match', turbo_force: :server } }
|
- modal_content = capture do
|
||||||
%button.fr-sr-only{ aria: {controls: 'modal-eligibilite-rules-dialog' }, data: {'fr-opened': "false" } }
|
%button.fr-sr-only{ aria: { controls: 'modal-eligibilite-rules-dialog' }, data: { 'fr-opened': opened?.to_s } }
|
||||||
show modal
|
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-container.fr-container--fluid.fr-container-md
|
||||||
.fr-grid-row.fr-grid-row--center
|
.fr-grid-row.fr-grid-row--center
|
||||||
.fr-col-12.fr-col-md-8.fr-col-lg-6
|
.fr-col-12.fr-col-md-8.fr-col-lg-6
|
||||||
|
@ -14,3 +14,9 @@
|
||||||
%span.fr-icon-arrow-right-line.fr-icon--lg>
|
%span.fr-icon-arrow-right-line.fr-icon--lg>
|
||||||
= t('.modal.title')
|
= t('.modal.title')
|
||||||
%p= error_message
|
%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
|
def update
|
||||||
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
|
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
|
||||||
@dossier = dossier_with_champs(pj_template: false)
|
@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
|
||||||
update_dossier_and_compute_errors
|
|
||||||
end
|
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.turbo_stream do
|
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?
|
procedure.accuse_lecture? && termine?
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def build_default_champs
|
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 }
|
= 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 params[:validate].present? && @dossier.revision.ineligibilite_enabled?
|
||||||
- if @can_passer_en_construction_was && !@can_passer_en_construction_is
|
= turbo_stream.update dom_id(@dossier, :ineligibilite_rules_broken), render(Dossiers::InvalidIneligibiliteRulesComponent.new(dossier: @dossier, wrapped: false))
|
||||||
= 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 @update_contact_information
|
- if @update_contact_information
|
||||||
= turbo_stream.update "contact_information", partial: 'shared/dossiers/update_contact_information', locals: { dossier: @dossier, procedure: @dossier.procedure }
|
= 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(:types_de_champ_public) { [{ type: :text }, { type: :integer_number }] }
|
||||||
let(:text_champ) { dossier.project_champs_public.first }
|
let(:text_champ) { dossier.project_champs_public.first }
|
||||||
let(:number_champ) { dossier.project_champs_public.last }
|
let(:number_champ) { dossier.project_champs_public.last }
|
||||||
|
let(:validate) { "true" }
|
||||||
let(:submit_payload) do
|
let(:submit_payload) do
|
||||||
{
|
{
|
||||||
id: dossier.id,
|
id: dossier.id,
|
||||||
|
validate:,
|
||||||
dossier: {
|
dossier: {
|
||||||
groupe_instructeur_id: dossier.groupe_instructeur_id,
|
groupe_instructeur_id: dossier.groupe_instructeur_id,
|
||||||
champs_public_attributes: {
|
champs_public_attributes: {
|
||||||
|
@ -805,28 +807,36 @@ describe Users::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
render_views
|
render_views
|
||||||
|
|
||||||
context 'when it switches from true to false' do
|
context 'when it becomes invalid' do
|
||||||
let(:value) { must_be_greater_than + 1 }
|
let(:value) { must_be_greater_than + 1 }
|
||||||
|
|
||||||
it 'raises popup' do
|
it 'raises popup' do
|
||||||
subject
|
subject
|
||||||
dossier.reload
|
dossier.reload
|
||||||
expect(dossier.can_passer_en_construction?).to be_falsey
|
expect(dossier.can_passer_en_construction?).to be_falsey
|
||||||
expect(assigns(:can_passer_en_construction_was)).to eq(true)
|
expect(response.body).to match(/aria-controls='modal-eligibilite-rules-dialog'[^>]*data-fr-opened='true'/)
|
||||||
expect(assigns(:can_passer_en_construction_is)).to eq(false)
|
|
||||||
expect(response.body).to match(ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when it stays true' do
|
context 'when it says valid' do
|
||||||
let(:value) { must_be_greater_than - 1 }
|
let(:value) { must_be_greater_than - 1 }
|
||||||
it 'does nothing' do
|
it 'does nothing' do
|
||||||
subject
|
subject
|
||||||
dossier.reload
|
dossier.reload
|
||||||
expect(dossier.can_passer_en_construction?).to be_truthy
|
expect(dossier.can_passer_en_construction?).to be_truthy
|
||||||
expect(assigns(:can_passer_en_construction_was)).to eq(true)
|
expect(response.body).to match(/aria-controls='modal-eligibilite-rules-dialog'[^>]*data-fr-opened='false'/)
|
||||||
expect(assigns(:can_passer_en_construction_is)).to eq(true)
|
end
|
||||||
expect(response.body).not_to have_selector("##{ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken)}")
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,21 +28,21 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
visit brouillon_dossier_path(dossier)
|
visit brouillon_dossier_path(dossier)
|
||||||
# no error while dossier is empty
|
# no error while dossier is empty
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
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
|
within "#champ-1" do
|
||||||
find("label", text: "Non").click
|
find("label", text: "Non").click
|
||||||
end
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
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
|
within "#champ-1" do
|
||||||
find("label", text: "Oui").click
|
find("label", text: "Oui").click
|
||||||
end
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
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
|
# reload page and see error
|
||||||
visit brouillon_dossier_path(dossier)
|
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
|
# 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_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" }
|
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
||||||
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
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)
|
visit brouillon_dossier_path(dossier)
|
||||||
# no error while dossier is empty
|
# no error while dossier is empty
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
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
|
# first condition matches (so ineligible), cannot submit dossier and error message is clear
|
||||||
within "#champ-#{first_tdc.stable_id}" do
|
within "#champ-#{first_tdc.stable_id}" do
|
||||||
|
@ -148,14 +149,14 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
visit brouillon_dossier_path(dossier)
|
visit brouillon_dossier_path(dossier)
|
||||||
# no error while dossier is empty
|
# no error while dossier is empty
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
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
|
# only one condition is matches, can submit dossier
|
||||||
within "#champ-#{first_tdc.stable_id}" do
|
within "#champ-#{first_tdc.stable_id}" do
|
||||||
find("label", text: "Oui").click
|
find("label", text: "Oui").click
|
||||||
end
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
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
|
# Now test dossier modification
|
||||||
click_on "Déposer le dossier"
|
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
|
scenario 'ineligibilite rules without validation on champ ensure to re-process cached champs.visible' do
|
||||||
visit brouillon_dossier_path(dossier)
|
visit brouillon_dossier_path(dossier)
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
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
|
within "#champ-1" do
|
||||||
find("label", text: "Non").click
|
find("label", text: "Non").click
|
||||||
|
|
|
@ -160,6 +160,7 @@ describe 'shared/dossiers/edit', type: :view do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
|
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
|
||||||
|
allow(dossier.revision).to receive(:ineligibilite_enabled?).and_return(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders broken transitions rules dialog' do
|
it 'renders broken transitions rules dialog' do
|
||||||
|
|
Loading…
Add table
Reference in a new issue