Skip to content

Commit

Permalink
feat(Users/Dossiers#update): track changes live and pop modal when el…
Browse files Browse the repository at this point in the history
…igibilite_rules is false
  • Loading branch information
mfo committed May 17, 2024
1 parent 06306f2 commit 8a118ed
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 2 deletions.
24 changes: 24 additions & 0 deletions app/components/dossiers/invalid_eligibilite_rules_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class Dossiers::InvalidEligibiliteRulesComponent < ApplicationComponent
delegate :can_passer_en_construction?, to: :@dossier

def initialize(dossier:)
@dossier = dossier
@revision = dossier.revision
end

def render?
eligibilite_rules_computable? && !can_passer_en_construction?
end

def error_message
@dossier.revision.eligibilite_message
end

private

def eligibilite_rules_computable?
@revision.eligibilite_enabled &&
@revision.eligibilite_message.present? &&
@revision&.eligibilite_rules&.computable?(@dossier.champs)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fr:
modal:
title: "Your file does not match submission criteria"
close: "Close"
close_alt: "Close this modal"
body: "The procedure « %{procedure_libelle} » have submission criteria, unfortunately your file does not match them. You can not submit your file"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fr:
modal:
title: "Vous ne pouvez pas déposer votre dossier"
close: "Fermer"
close_alt: "Fermer la fenêtre modale"
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
%div{ id: dom_id(@dossier, :eligibilite_rules_broken), data: { controller: 'invalid-eligibilite-rules', turbo_force: :server } }
%button.fr-sr-only{ aria: {controls: 'modal-eligibilite-rules-dialog' }, data: {'fr-opened': "false" } }
show modal

%dialog.fr-modal{ "aria-labelledby" => "fr-modal-title-modal-1", role: "dialog", id: 'modal-eligibilite-rules-dialog', data: { 'invalid-eligibilite-rules-target' => 'dialog' } }
.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
.fr-modal__body
.fr-modal__header
%button.fr-btn--close.fr-btn{ aria: { controls: 'modal-eligibilite-rules-dialog' }, title: t('.modal.close_alt') }= t('.modal.close')
.fr-modal__content
%h1#fr-modal-title-modal-1.fr-modal__title
%span.fr-icon-arrow-right-line.fr-icon--lg>
= t('.modal.title')
%p= error_message
6 changes: 5 additions & 1 deletion app/controllers/users/dossiers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,12 @@ def submit_en_construction
def update
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
@dossier = dossier_with_champs(pj_template: false)
@eligibilite_rules_was_computable = dossier.revision&.eligibilite_rules&.computable?(dossier.champs)
@can_passer_en_construction_was = @dossier.can_passer_en_construction?
@errors = update_dossier_and_compute_errors

@eligibilite_rules_is_computable = dossier.revision&.eligibilite_rules&.computable?(dossier.champs)
@can_passer_en_construction_is = @dossier.can_passer_en_construction?
@eligibilite_rules_computable_changed = !@eligibilite_rules_was_computable && @eligibilite_rules_is_computable
respond_to do |format|
format.turbo_stream do
@to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_attributes_params, dossier.champs.filter(&:public?))
Expand Down
19 changes: 19 additions & 0 deletions app/javascript/controllers/invalid_eligibilite_rules_controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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 InvalidEligibiliteRulesController extends ApplicationController {
static targets = ['dialog'];

declare dialogTarget: HTMLElement;

connect() {
setTimeout(() => window.dsfr(this.dialogTarget).modal.disclose(), 100);
}
}
2 changes: 2 additions & 0 deletions app/views/shared/dossiers/_edit.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@

= render Dossiers::PendingCorrectionCheckboxComponent.new(dossier: dossier)

= render Dossiers::InvalidEligibiliteRulesComponent.new(dossier: dossier)

= render Dossiers::EditFooterComponent.new(dossier: dossier_for_editing, annotation: false)
7 changes: 7 additions & 0 deletions app/views/users/dossiers/update.turbo_stream.haml
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
= 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 @eligibilite_rules_is_computable
= turbo_stream.remove(dom_id(@dossier, :eligibilite_rules_broken))

- if (@eligibilite_rules_computable_changed && !@can_passer_en_construction_is) || (@can_passer_en_construction_was && !@can_passer_en_construction_is)
= turbo_stream.append('contenu', render(Dossiers::InvalidEligibiliteRulesComponent.new(dossier: @dossier)))
61 changes: 60 additions & 1 deletion spec/controllers/users/dossiers_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,8 @@
describe '#update brouillon' do
before { sign_in(user) }

let(:procedure) { create(:procedure, :published, types_de_champ_public: [{}, { type: :piece_justificative }]) }
let(:procedure) { create(:procedure, :published, types_de_champ_public:) }
let(:types_de_champ_public) { [{}, { type: :piece_justificative }] }
let(:dossier) { create(:dossier, user:, procedure:) }
let(:first_champ) { dossier.champs_public.first }
let(:piece_justificative_champ) { dossier.champs_public.last }
Expand Down Expand Up @@ -770,6 +771,64 @@
end
end
end

context 'having eligibilite_rules setup' do
include Logic
render_views

let(:types_de_champ_public) { [{ type: :text }, { type: :integer_number }] }
let(:text_champ) { dossier.champs_public.first }
let(:number_champ) { dossier.champs_public.last }
let(:submit_payload) do
{
id: dossier.id,
dossier: {
groupe_instructeur_id: dossier.groupe_instructeur_id,
champs_public_attributes: {
text_champ.public_id => {
with_public_id: true,
value: "hello world"
},
number_champ.public_id => {
with_public_id: true,
value:
}
}
}
}
end
let(:must_be_greater_than) { 10 }

before do
procedure.published_revision.eligibilite_rules = greater_than(champ_value(number_champ.stable_id), constant(must_be_greater_than))
procedure.published_revision.save!
end
render_views

context 'when it pass from undefined to true' do
let(:value) { must_be_greater_than / 2 }

it 'raises popup' do
subject
dossier.reload
expect(dossier.can_passer_en_construction?).to be_falsey
expect(assigns(:eligibilite_rules_was_computable)).to eq(false)
expect(assigns(:eligibilite_rules_is_computable)).to eq(true)
expect(response.body).to match(ActionView::RecordIdentifier.dom_id(dossier, :eligibilite_rules_broken))
end
end
context 'when it pass from undefined to false' do
let(:value) { must_be_greater_than * 2 }
it 'does nothing' do
subject
dossier.reload
expect(dossier.can_passer_en_construction?).to be_truthy
expect(assigns(:eligibilite_rules_was_computable)).to eq(false)
expect(assigns(:eligibilite_rules_is_computable)).to eq(true)
expect(response.body).not_to have_selector("##{ActionView::RecordIdentifier.dom_id(dossier, :eligibilite_rules_broken)}")
end
end
end
end

describe '#update en_construction' do
Expand Down
14 changes: 14 additions & 0 deletions spec/views/shared/dossiers/_edit.html.haml_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,18 @@
end
end
end

context 'when dossier transitions rules are computable and passer_en_construction is false' do
let(:types_de_champ_public) { [] }
let(:dossier) { create(:dossier, procedure:) }

before do
allow_any_instance_of(Dossiers::InvalidEligibiliteRulesComponent).to receive(:eligibilite_rules_computable?).and_return(true)
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
end

it 'renders broken transitions rules dialog' do
expect(subject).to have_selector("##{ActionView::RecordIdentifier.dom_id(dossier, :eligibilite_rules_broken)}")
end
end
end

0 comments on commit 8a118ed

Please sign in to comment.