feat(dossier): fork dossier when editing en construction

This commit is contained in:
Paul Chavard 2023-03-21 18:24:39 +01:00 committed by Colin Darie
parent 025bd5beaf
commit 08a2a2c9aa
No known key found for this signature in database
GPG key ID: 4FB865FDBCA4BCC4
20 changed files with 193 additions and 99 deletions

View file

@ -3,10 +3,10 @@
%span.autosave-explanation-text
- if annotation?
= t('.annotations.explanation')
- elsif dossier.brouillon?
= t('.brouillon.explanation')
- else
- elsif dossier.editing_fork?
= t('.en_construction.explanation')
- 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
@ -15,10 +15,10 @@
%span.autosave-label
- if annotation?
= t('.annotations.confirmation')
- elsif dossier.brouillon?
= t('.brouillon.confirmation')
- else
- elsif dossier.editing_fork?
= t('.en_construction.confirmation')
- 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
@ -27,10 +27,10 @@
%span.autosave-label
- if annotation?
= t('.annotations.error')
- elsif dossier.brouillon?
= t('.brouillon.error')
- else
- elsif dossier.editing_fork?
= t('.en_construction.error')
- else
= t('.brouillon.error')
%button.button.small.autosave-retry{ type: :button, data: { action: 'autosave-status#onClickRetryButton', autosave_status_target: 'retryButton' } }
%span.autosave-retry-label réessayer
%span.autosave-retrying-label enregistrement en cours…

View file

@ -14,7 +14,7 @@ class Dossiers::EditFooterComponent < ApplicationComponent
@annotation.present?
end
def button_options
def submit_draft_button_options
{
class: 'fr-btn fr-btn--sm',
disabled: !owner?,
@ -23,6 +23,14 @@ class Dossiers::EditFooterComponent < ApplicationComponent
}
end
def submit_en_construction_button_options
{
class: 'fr-btn fr-btn--sm',
method: :post,
data: { 'disable-with': t('.submitting'), controller: 'autosave-submit' }
}
end
def render?
!@dossier.for_procedure_preview?
end

View file

@ -1,5 +1,6 @@
---
en:
submit: Submit the file
submit_changes: Submit file changes
submitting: Submitting…
invite_notice: You are invited to make amendments to this file but only the owner themselves can submit it.

View file

@ -1,5 +1,6 @@
---
fr:
submit: Déposer le dossier
submit_changes: Déposer les modifications
submitting: Envoi en cours…
invite_notice: En tant quinvité, vous pouvez remplir ce formulaire mais le titulaire du dossier doit le déposer lui-même.

View file

@ -3,7 +3,10 @@
= render Dossiers::AutosaveFooterComponent.new(dossier: @dossier, annotation: annotation?)
- if !annotation? && @dossier.can_transition_to_en_construction?
= button_to t('.submit'), brouillon_dossier_url(@dossier), button_options
= button_to t('.submit'), brouillon_dossier_url(@dossier), submit_draft_button_options
- elsif @dossier.forked_with_changes?
= button_to t('.submit_changes'), modifier_dossier_url(@dossier.editing_fork_origin), submit_en_construction_button_options
- if @dossier.brouillon? && !owner?
.send-notice.invite-cannot-submit

View file

@ -3,7 +3,7 @@
= @form.label @champ.main_value_name, id: @champ.labelledby_id, for: @champ.input_id do
- render EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at
- else
.form-label.mb-4
.form-label.mb-4{ id: @champ.labelledby_id }
= render EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at
- if @champ.description.present?

View file

@ -2,7 +2,10 @@
- if @champ.mandatory?
%span.mandatory *
- if @champ.updated_at.present? && @seen_at.present?
- if @champ.forked_with_changes?
%span.updated-at.highlighted
= @champ.updated_at > 1.minutes.ago ? "modifié à linstant" : "modification à déposer"
- elsif @champ.updated_at.present? && @seen_at.present?
%span.updated-at{ class: highlight_if_unseen_class }
= "modifié le #{try_format_datetime(@champ.updated_at)}"

View file

@ -6,7 +6,7 @@ module TurboChampsConcern
def champs_to_turbo_update(params, champs)
champ_ids = params.keys.map(&:to_i)
to_update = champs.filter { _1.id.in?(champ_ids) && _1.refresh_after_update? }
to_update = champs.filter { _1.id.in?(champ_ids) && (_1.refresh_after_update? || _1.forked_with_changes?) }
to_show, to_hide = champs.filter(&:conditional?)
.partition(&:visible?)
.map { champs_to_one_selector(_1 - to_update) }

View file

@ -6,12 +6,12 @@ module Users
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new, :transferer_all]
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :destroy, :demande, :messagerie, :brouillon, :update_brouillon, :submit_brouillon, :modifier, :update, :create_commentaire, :papertrail, :restore]
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :destroy, :demande, :messagerie, :brouillon, :submit_brouillon, :submit_en_construction, :modifier, :update, :create_commentaire, :papertrail, :restore]
before_action :ensure_ownership!, except: ACTIONS_ALLOWED_TO_ANY_USER + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
before_action :ensure_ownership_or_invitation!, only: ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
before_action :ensure_dossier_can_be_updated, only: [:update_identite, :update_siret, :brouillon, :update_brouillon, :submit_brouillon, :modifier, :update]
before_action :ensure_dossier_can_be_filled, only: [:brouillon, :modifier, :update_brouillon, :submit_brouillon, :update]
before_action :ensure_dossier_can_be_updated, only: [:update_identite, :update_siret, :brouillon, :submit_brouillon, :submit_en_construction, :modifier, :update]
before_action :ensure_dossier_can_be_filled, only: [:brouillon, :modifier, :submit_brouillon, :submit_en_construction, :update]
before_action :ensure_dossier_can_be_viewed, only: [:show]
before_action :forbid_invite_submission!, only: [:submit_brouillon]
before_action :forbid_closed_submission!, only: [:submit_brouillon]
@ -202,21 +202,30 @@ module Users
@dossier = dossier_with_champs
end
def update_brouillon
@dossier = dossier_with_champs
update_dossier_and_compute_errors
def submit_en_construction
@dossier = dossier.find_editing_fork(dossier.user)
@dossier = dossier_with_champs(pj_template: false)
errors = submit_dossier_and_compute_errors
respond_to do |format|
format.html { render :brouillon }
format.turbo_stream do
@to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_params.fetch(:champs_public_all_attributes), dossier.champs_public_all)
if errors.blank?
editing_fork_origin = @dossier.editing_fork_origin
editing_fork_origin.merge_fork(@dossier)
redirect_to dossier_path(editing_fork_origin)
else
flash.now.alert = errors
render(:update, layout: false)
respond_to do |format|
format.html { render :modifier }
format.turbo_stream do
@to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_params.fetch(:champs_public_all_attributes), dossier.champs_public_all)
render :update, layout: false
end
end
end
end
def update
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
@dossier = dossier_with_champs(pj_template: false)
errors = update_dossier_and_compute_errors
@ -225,9 +234,9 @@ module Users
end
respond_to do |format|
format.html { render :modifier }
format.turbo_stream do
@to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_params.fetch(:champs_public_all_attributes), dossier.champs_public_all)
render :update, layout: false
end
end
end
@ -425,8 +434,8 @@ module Users
end
def dossier_scope
if action_name == 'update_brouillon'
Dossier.visible_by_user.or(Dossier.for_procedure_preview)
if action_name == 'update'
Dossier.visible_by_user.or(Dossier.for_procedure_preview).or(Dossier.for_editing_fork)
elsif action_name == 'restore'
Dossier.hidden_by_user
else
@ -488,10 +497,6 @@ module Users
RoutingEngine.compute(@dossier)
end
if dossier.en_construction?
errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs)
end
errors
end
@ -528,9 +533,12 @@ module Users
def append_anchor_link(str_error, model)
return str_error.full_message if !model.is_a?(Champ)
route_helper = @dossier.editing_fork? ? :modifier_dossier_path : :brouillon_dossier_path
[
"Le champ « #{model.libelle.truncate(200)} » #{str_error}",
helpers.link_to(t('views.users.dossiers.fix_champ'), brouillon_dossier_path(anchor: model.input_id))
helpers.link_to(t('views.users.dossiers.fix_champ'), public_send(route_helper, anchor: model.input_id))
].join(", ")
rescue # case of invalid type de champ on champ
str_error

View file

@ -244,6 +244,10 @@ class Champ < ApplicationRecord
input_id
end
def forked_with_changes?
public? && dossier.champ_forked_with_changes?(self)
end
private
def html_id

View file

@ -1,17 +1,13 @@
- dossier_for_editing = dossier.en_construction? ? dossier.owner_editing_fork : dossier
- if dossier.france_connect_information.present?
- content_for(:notice_info) do
= render partial: "shared/dossiers/france_connect_informations_notice", locals: { user_information: dossier.france_connect_information }
.dossier-edit.container.counter-start-header-section
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: dossier }
- if dossier.brouillon?
- form_options = { url: brouillon_dossier_url(dossier), method: :patch }
- else
- form_options = { url: modifier_dossier_url(dossier), method: :patch }
= render NestedForms::FormOwnerComponent.new
= form_for dossier, form_options.merge({ html: { id: 'dossier-edit-form', class: 'form', multipart: true, novalidate: 'novalidate' } }) do |f|
= form_for dossier_for_editing, url: brouillon_dossier_url(dossier), method: :patch, html: { id: 'dossier-edit-form', class: 'form', multipart: true, novalidate: 'novalidate' } do |f|
%header.mb-6
.fr-highlight
%p.fr-text--sm
@ -42,5 +38,7 @@
= f.select :groupe_instructeur_id,
dossier.procedure.groupe_instructeurs.active.map { |gi| [gi.label, gi.id] },
{ include_blank: dossier.brouillon? }
= render EditableChamp::SectionComponent.new(champs: dossier.champs_public)
= render Dossiers::EditFooterComponent.new(dossier: dossier, annotation: false)
= render EditableChamp::SectionComponent.new(champs: dossier_for_editing.champs_public)
= render Dossiers::EditFooterComponent.new(dossier: dossier_for_editing, annotation: false)

View file

@ -4,8 +4,14 @@
= turbo_stream.hide_all(@to_hide)
- @to_update.each do |champ|
= fields_for champ.input_name, champ do |form|
= turbo_stream.replace champ.input_group_id do
= render EditableChamp::EditableChampComponent.new champ:, form:
- if champ.refresh_after_update?
= turbo_stream.replace champ.input_group_id do
= render EditableChamp::EditableChampComponent.new champ:, form:
- else
= turbo_stream.update champ.labelledby_id do
= render EditableChamp::ChampLabelContentComponent.new champ:
= turbo_stream.remove_all(".editable-champ .spinner-removable");
= turbo_stream.hide_all(".editable-champ .spinner");
= turbo_stream.replace_all '.dossier-edit-sticky-footer' do
= render Dossiers::EditFooterComponent.new(dossier: @dossier, annotation: false)