Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ETQ usager corrige le fait d'être informé d'un dossier inéligible dans certaines conditions #11131

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions app/assets/stylesheets/autosave.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
margin-right: 6px;
}

.autosave-more-infos {
white-space: nowrap;
}

.autosave-status {
// Position the status over the explanation text
position: absolute;
Expand Down
5 changes: 4 additions & 1 deletion app/assets/stylesheets/dossier_edit.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ $dossier-actions-bar-border-width: 1px;
border: $dossier-actions-bar-border-width solid #cccccc;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border-bottom: none;

z-index: 10; // above DSFR btn which are at 1
}
Expand Down Expand Up @@ -113,4 +112,8 @@ $dossier-actions-bar-border-width: 1px;
// to ensure the failed state has room to display its content.
flex-grow: 1;
}

a {
white-space: nowrap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ en:
confirmation: Draft saved
error: Impossible to save the draft
en_construction:
explanation: Your modifications are automatically saved. Submit them when you’re done.
explanation: Your modifications are automatically saved.
submit_them: Submit them when you’re done.
confirmation: Modifications saved
error: Impossible to save the modifications.
annotations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ fr:
confirmation: Brouillon enregistré
error: Impossible d’enregistrer le brouillon
en_construction:
explanation: Vos modifications sont automatiquement enregistrées. Déposez-les quand vous aurez terminé.
explanation: Vos modifications sont automatiquement enregistrées.
submit_them: Déposez-les quand vous aurez terminé.
confirmation: Modifications enregistrées.
error: Impossible d’enregistrer les modifications
annotations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
= t('.annotations.explanation')
- elsif dossier.editing_fork?
= t('.en_construction.explanation')
- if dossier.can_passer_en_construction?
= t('.en_construction.submit_them')
- else
= t('.brouillon.explanation')
- if !annotation?
= link_to t('.more_information'), t("links.common.faq.autosave_url"), class: 'autosave-more-infos fr-link fr-link--sm', **external_link_attributes
= link_to t('.more_information'), t("links.common.faq.autosave_url"), class: 'fr-link fr-link--sm', **external_link_attributes

%p.autosave-status.succeeded.fr-mb-0
= dsfr_icon('fr-icon-checkbox-circle-fill fr-text-default--success autosave-icon')
Expand All @@ -20,7 +22,7 @@
- else
= t('.brouillon.confirmation')
- if !annotation?
= link_to t('.more_information'), t("links.common.faq.autosave_url"), class: 'autosave-more-infos fr-link fr-link--sm', **external_link_attributes
= link_to t('.more_information'), t("links.common.faq.autosave_url"), class: 'fr-link fr-link--sm', **external_link_attributes

%p.autosave-status.failed.fr-mb-0
%span.autosave-icon ⚠️
Expand Down
10 changes: 7 additions & 3 deletions app/components/dossiers/invalid_ineligibilite_rules_component.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
# 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:)
@dossier = dossier
@revision = dossier.revision
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
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
%div{ id: dom_id(@dossier, :ineligibilite_rules_broken), data: { controller: 'ineligibilite-rules-match', turbo_force: :server } }
%div{ id: dom_id(@dossier, :ineligibilite_rules_broken), data: { controller: 'ineligibilite-rules-match',
ineligibilite_rules_match_open_value: (!can_passer_en_construction?).to_s } }
%button.fr-sr-only{ aria: {controls: 'modal-eligibilite-rules-dialog' }, data: {'fr-opened': "false" } }
show modal

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
= render Dsfr::AlertComponent.new(state: :warning) do |c|
= render Dsfr::AlertComponent.new(state: :warning, extra_class_names: "fr-mb-3w") do |c|
- c.with_body do
= t('.pending_republish_html', href: admin_procedure_path(@procedure.id))
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ def change
draft_revision.assign_attributes(procedure_revision_params)

if draft_revision.validate(:ineligibilite_rules_editor) && draft_revision.save
redirect_to edit_admin_procedure_ineligibilite_rules_path(@procedure)
flash[:notice] = "Les conditions d‘inéligibilité ont été modifiées."
redirect_to admin_procedure_path(@procedure)
else
flash[:alert] = draft_revision.errors.full_messages
render :edit
Expand Down
4 changes: 1 addition & 3 deletions app/controllers/users/dossiers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,7 @@
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

Check warning on line 283 in app/controllers/users/dossiers_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/users/dossiers_controller.rb#L283

Added line #L283 was not covered by tests

respond_to do |format|
format.turbo_stream do
Expand Down
9 changes: 6 additions & 3 deletions app/javascript/controllers/autosave_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,13 @@ export class AutosaveController extends ApplicationController {
// Wait next tick so champs having JS can interact
// with form elements before extracting form data.
setTimeout(() => {
this.enqueueAutosaveRequest();
this.enqueueAutosaveWithValidationRequest();
this.showConditionnalSpinner(target);
}, 0);
},
inputable: (target) => this.enqueueOnInput(target, true),
inputable: (target) => {
this.enqueueOnInput(target, true);
},
hidden: (target) => {
// In comboboxes we dispatch a "change" event on hidden inputs to trigger autosave.
// We want to debounce them.
Expand Down Expand Up @@ -152,7 +154,8 @@ export class AutosaveController extends ApplicationController {

private didRequestRetry() {
if (this.#needsRetry) {
this.enqueueAutosaveRequest();
console.log('didRequestRetry');
this.enqueueAutosaveWithValidationRequest();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,28 @@ declare const window: Window &

export class InvalidIneligibiliteRulesController extends ApplicationController {
static targets = ['dialog'];
static values = {
open: String
};

declare dialogTarget: HTMLElement;
declare openValue: 'true' | 'false';

connect() {
setTimeout(() => window.dsfr(this.dialogTarget).modal.disclose(), 100);
if (this.openValue == 'true') {
this.openModal();
}
}

openValueChanged() {
if (this.openValue == 'true') {
this.openModal();
}
}

private openModal() {
setTimeout(() => {
window.dsfr(this.dialogTarget).modal.disclose();
}, 100);
}
}
12 changes: 6 additions & 6 deletions app/models/concerns/dossier_clone_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ def editing_fork?
end

def forked_with_changes?
if forked_diff.present?
forked_diff.values.any?(&:present?) || forked_groupe_instructeur_changed?
end
return false if forked_diff.blank?

forked_diff.values.any?(&:present?) || forked_groupe_instructeur_changed?
end

def champ_forked_with_changes?(champ)
if forked_diff.present?
forked_diff.values.any? { |champs| champs.any? { _1.public_id == champ.public_id } }
end
return false if forked_diff.blank?

forked_diff.values.any? { |champs| champs.any? { _1.public_id == champ.public_id } }
end

def make_diff(editing_fork)
Expand Down
12 changes: 0 additions & 12 deletions app/models/dossier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1025,18 +1025,6 @@ def termine_and_accuse_lecture?
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
Expand Down
7 changes: 2 additions & 5 deletions app/views/users/dossiers/update.turbo_stream.haml
Original file line number Diff line number Diff line change
@@ -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))

- if @update_contact_information
= turbo_stream.update "contact_information", partial: 'shared/dossiers/update_contact_information', locals: { dossier: @dossier, procedure: @dossier.procedure }
44 changes: 44 additions & 0 deletions spec/components/dossiers/autosave_footer_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Dossiers::AutosaveFooterComponent, type: :component do
subject(:component) { render_inline(described_class.new(dossier:, annotation:)) }

let(:dossier) { create(:dossier) }
let(:annotation) { false }

context 'when showing brouillon state (default state)' do
it 'displays brouillon explanation' do
expect(component).to have_text("Votre brouillon")
end
end

context 'when editing fork and can pass en construction' do
let(:dossier) { create(:dossier, :en_construction).find_or_create_editing_fork(create(:user)) }

it 'displays en construction explanation' do
expect(component).to have_text("Vos modifications")
expect(component).to have_text("Déposez-les")
end

context 'when dossier is not eligible' do
before do
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
end

it 'displays en construction explanation' do
expect(component).to have_text("Vos modifications")
expect(component).not_to have_text("Déposez-les")
end
end
end

context 'when showing annotations' do
let(:annotation) { true }

it 'displays annotations explanation' do
expect(component).to have_text("Vos annotations")
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@
draft_revision = procedure.reload.draft_revision
expect(draft_revision.ineligibilite_message).to eq('panpan')
expect(draft_revision.ineligibilite_enabled).to eq(true)
expect(response).to redirect_to(edit_admin_procedure_ineligibilite_rules_path(procedure))
expect(response).to redirect_to(admin_procedure_path(procedure))
expect(flash.notice).not_to be_empty
end
end
end
Expand Down
26 changes: 18 additions & 8 deletions spec/controllers/users/dossiers_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -775,9 +775,11 @@
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: {
Expand Down Expand Up @@ -805,28 +807,36 @@
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 include("data-ineligibilite-rules-match-open-value='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 include("data-ineligibilite-rules-match-open-value='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("data-ineligibilite-rules-match-open-value")
end
end
end
Expand Down
1 change: 1 addition & 0 deletions spec/system/users/dossier_ineligibilite_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
visit brouillon_dossier_path(dossier)
# no error while dossier is empty
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
# TODO: modal message is considered as visible but hidden by modal JS
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")

# does raise error when dossier is filled with condition that does not match
Expand Down
2 changes: 2 additions & 0 deletions spec/views/shared/dossiers/_edit.html.haml_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,12 @@

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
expect(subject).to have_selector("##{ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken)}")
expect(subject).to include("data-ineligibilite-rules-match-open-value='true'")
end
end
end
Loading