Merge pull request #7734 from tchak/autosave-en-construction
feat(dossier): autosave en construction
This commit is contained in:
commit
eae06579f8
71 changed files with 201 additions and 364 deletions
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::AddressComponent < ApplicationComponent
|
class EditableChamp::AddressComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::AnnuaireEducationComponent < ApplicationComponent
|
class EditableChamp::AnnuaireEducationComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::CarteComponent < ApplicationComponent
|
class EditableChamp::CarteComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
class EditableChamp::ChampLabelComponent < ApplicationComponent
|
class EditableChamp::ChampLabelComponent < ApplicationComponent
|
||||||
def initialize(form:, champ:)
|
include StringToHtmlHelper
|
||||||
@form, @champ = form, champ
|
|
||||||
|
def initialize(form:, champ:, seen_at: nil)
|
||||||
|
@form, @champ, @seen_at = form, champ, seen_at
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
= # we do this trick because some html elements should use 'label' and some should be plain paragraphs
|
= # we do this trick because some html elements should use 'label' and some should be plain paragraphs
|
||||||
- if @champ.html_label?
|
- if @champ.html_label?
|
||||||
= @form.label @champ.main_value_name, id: champ.labelledby_id, for: champ.input_id do
|
= @form.label @champ.main_value_name, id: @champ.labelledby_id, for: @champ.input_id do
|
||||||
= render partial: 'shared/dossiers/editable_champs/champ_label_content', locals: { champ: champ, seen_at: seen_at }
|
= render EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at
|
||||||
- else
|
- else
|
||||||
.@form-label.mb-4
|
.form-label.mb-4
|
||||||
= render partial: 'shared/dossiers/editable_champs/champ_label_content', locals: { champ: champ, seen_at: seen_at }
|
= render EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at
|
||||||
|
|
||||||
- if @champ.description.present?
|
- if @champ.description.present?
|
||||||
.notice{ id: @champ.describedby_id }= string_to_html(champ.description)
|
.notice{ id: @champ.describedby_id }= string_to_html(@champ.description)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class EditableChamp::ChampLabelContentComponent < ApplicationComponent
|
class EditableChamp::ChampLabelContentComponent < ApplicationComponent
|
||||||
def initialize(form:, champ:)
|
def initialize(champ:, seen_at: nil)
|
||||||
@form, @champ = form, champ
|
@champ, @seen_at = champ, seen_at
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
- if @champ.type_de_champ.mandatory?
|
- if @champ.type_de_champ.mandatory?
|
||||||
%span.mandatory *
|
%span.mandatory *
|
||||||
|
|
||||||
- if @champ.updated_at.present? && seen_at.present?
|
- if @champ.updated_at.present? && @seen_at.present?
|
||||||
%span.updated-at{ class: highlight_if_unseen_class(seen_at, @champ.updated_at) }
|
%span.updated-at{ class: highlight_if_unseen_class(@seen_at, @champ.updated_at) }
|
||||||
= "modifié le #{try_format_datetime(@champ.updated_at)}"
|
= "modifié le #{try_format_datetime(@champ.updated_at)}"
|
||||||
|
|
||||||
- if @champ.rebased_at.present? && champ.rebased_at > (seen_at || champ.updated_at) && current_user.owns_or_invite?(champ.dossier)
|
- if @champ.rebased_at.present? && @champ.rebased_at > (@seen_at || @champ.updated_at) && controller.current_user.owns_or_invite?(@champ.dossier)
|
||||||
%span.updated-at.highlighted
|
%span.updated-at.highlighted
|
||||||
Le type de ce @champ où sa description a été modifiée par l'administration. Vérifier son contenu.
|
Le type de ce @champ où sa description a été modifiée par l'administration. Vérifier son contenu.
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::CheckboxComponent < ApplicationComponent
|
class EditableChamp::CheckboxComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::CiviliteComponent < ApplicationComponent
|
class EditableChamp::CiviliteComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::CnafComponent < ApplicationComponent
|
class EditableChamp::CnafComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::CommunesComponent < ApplicationComponent
|
class EditableChamp::CommunesComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::DateComponent < ApplicationComponent
|
class EditableChamp::DateComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
class EditableChamp::DatetimeComponent < ApplicationComponent
|
class EditableChamp::DatetimeComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
|
|
||||||
def datetime_start_year(date)
|
def datetime_start_year(date)
|
||||||
if date == nil || date.year == 0 || date.year >= Date.today.year - 1
|
if date == nil || date.year == 0 || date.year >= Date.today.year - 1
|
||||||
Date.today.year - 1
|
Date.today.year - 1
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::DecimalNumberComponent < ApplicationComponent
|
class EditableChamp::DecimalNumberComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::DepartementsComponent < ApplicationComponent
|
class EditableChamp::DepartementsComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::DgfipComponent < ApplicationComponent
|
class EditableChamp::DgfipComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::DossierLinkComponent < ApplicationComponent
|
class EditableChamp::DossierLinkComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::DropDownListComponent < ApplicationComponent
|
class EditableChamp::DropDownListComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::DropDownOtherInputComponent < ApplicationComponent
|
class EditableChamp::DropDownOtherInputComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class EditableChamp::EditableChampBaseComponent < ApplicationComponent
|
||||||
|
def initialize(form:, champ:, seen_at: nil)
|
||||||
|
@form, @champ, @seen_at = form, champ, seen_at
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,45 @@
|
||||||
class EditableChamp::EditableChampComponent < ApplicationComponent
|
class EditableChamp::EditableChampComponent < ApplicationComponent
|
||||||
def initialize(form:, champ:)
|
include StringToHtmlHelper
|
||||||
@form, @champ = form, champ
|
|
||||||
|
def initialize(form:, champ:, seen_at: nil)
|
||||||
|
@form, @champ, @seen_at = form, champ, seen_at
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def has_label?(champ)
|
||||||
|
types_without_label = [TypeDeChamp.type_champs.fetch(:header_section), TypeDeChamp.type_champs.fetch(:explication)]
|
||||||
|
!types_without_label.include?(@champ.type_champ)
|
||||||
|
end
|
||||||
|
|
||||||
|
def component_class
|
||||||
|
"EditableChamp::#{@champ.type_champ.camelcase}Component".constantize
|
||||||
|
end
|
||||||
|
|
||||||
|
def html_options
|
||||||
|
{
|
||||||
|
class: "editable-champ-#{@champ.type_champ} #{'hidden' if !@champ.visible?}",
|
||||||
|
id: @champ.input_group_id,
|
||||||
|
data: { controller: stimulus_controller }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def stimulus_controller
|
||||||
|
if !@champ.repetition? && @champ.fillable?
|
||||||
|
# This is an editable champ. Lets find what controllers it might need.
|
||||||
|
controllers = []
|
||||||
|
|
||||||
|
# This is a public champ – it can have an autosave controller.
|
||||||
|
if @champ.public?
|
||||||
|
controllers << 'autosave'
|
||||||
|
end
|
||||||
|
|
||||||
|
# This is a dropdown champ. Activate special behaviours it might have.
|
||||||
|
if @champ.simple_drop_down_list? || @champ.linked_drop_down_list?
|
||||||
|
controllers << 'champ-dropdown'
|
||||||
|
end
|
||||||
|
|
||||||
|
controllers.join(' ')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
.editable-@champ{ class: "editable-champ-#{champ.type_champ} #{champ.visible? ? '' : 'hidden'}", id: champ.input_group_id, data: editable_champ_controller(champ) }
|
.editable-champ{ html_options }
|
||||||
- if @champ.repetition?
|
- if @champ.repetition?
|
||||||
%h3.header-subsection= @champ.libelle
|
%h3.header-subsection= @champ.libelle
|
||||||
- if @champ.description.present?
|
- if @champ.description.present?
|
||||||
%p.notice= string_to_html(@champ.description, false)
|
%p.notice= string_to_html(@champ.description, false)
|
||||||
|
|
||||||
- elsif has_label?(@champ)
|
- elsif has_label?(@champ)
|
||||||
= render partial: 'shared/dossiers/editable_champs/champ_label', locals: { form: @form, champ: champ, seen_at: defined?(seen_at) ? seen_at : nil }
|
= render EditableChamp::ChampLabelComponent.new form: @form, champ: @champ, seen_at: @seen_at
|
||||||
- if @champ.type_champ == "titre_identite"
|
- if @champ.type_champ == "titre_identite"
|
||||||
%p.notice Carte nationale d’identité (uniquement le recto), passeport, titre de séjour ou autre justificatif d’identité. Formats acceptés : jpg/png
|
%p.notice Carte nationale d’identité (uniquement le recto), passeport, titre de séjour ou autre justificatif d’identité. Formats acceptés : jpg/png
|
||||||
|
|
||||||
= @form.hidden_field :id, value: @champ.id, data: champ.repetition? ? { id: true } : {}
|
= @form.hidden_field :id, value: @champ.id, data: @champ.repetition? ? { id: true } : {}
|
||||||
= render partial: "shared/dossiers/editable_champs/#{champ.type_champ}", locals: { form: @form, champ: champ }
|
= render component_class.new(form: @form, champ: @champ, seen_at: @seen_at)
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::EmailComponent < ApplicationComponent
|
class EditableChamp::EmailComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::EngagementComponent < ApplicationComponent
|
class EditableChamp::EngagementComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::ExplicationComponent < ApplicationComponent
|
class EditableChamp::ExplicationComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include StringToHtmlHelper
|
include StringToHtmlHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::HeaderSectionComponent < ApplicationComponent
|
class EditableChamp::HeaderSectionComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::IbanComponent < ApplicationComponent
|
class EditableChamp::IbanComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::IntegerNumberComponent < ApplicationComponent
|
class EditableChamp::IntegerNumberComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
class EditableChamp::LinkedDropDownListComponent < ApplicationComponent
|
class EditableChamp::LinkedDropDownListComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
include StringToHtmlHelper
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
- if @champ.type_de_champ.mandatory?
|
- if @champ.type_de_champ.mandatory?
|
||||||
%span.mandatory *
|
%span.mandatory *
|
||||||
- if @champ.drop_down_secondary_description.present?
|
- if @champ.drop_down_secondary_description.present?
|
||||||
.notice{ id: "#{@champ.describedby_id}-secondary" }= helpers.string_to_html(@champ.drop_down_secondary_description)
|
.notice{ id: "#{@champ.describedby_id}-secondary" }= string_to_html(@champ.drop_down_secondary_description)
|
||||||
= @form.select :secondary_value,
|
= @form.select :secondary_value,
|
||||||
@champ.secondary_options[@champ.primary_value],
|
@champ.secondary_options[@champ.primary_value],
|
||||||
{},
|
{},
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::MesriComponent < ApplicationComponent
|
class EditableChamp::MesriComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::MultipleDropDownListComponent < ApplicationComponent
|
class EditableChamp::MultipleDropDownListComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::NumberComponent < ApplicationComponent
|
class EditableChamp::NumberComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::PaysComponent < ApplicationComponent
|
class EditableChamp::PaysComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::PhoneComponent < ApplicationComponent
|
class EditableChamp::PhoneComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::PieceJustificativeComponent < ApplicationComponent
|
class EditableChamp::PieceJustificativeComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::PoleEmploiComponent < ApplicationComponent
|
class EditableChamp::PoleEmploiComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::RegionsComponent < ApplicationComponent
|
class EditableChamp::RegionsComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::RepetitionComponent < ApplicationComponent
|
class EditableChamp::RepetitionComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.repetition{ id: dom_id(@champ, :rows) }
|
.repetition{ id: dom_id(@champ, :rows) }
|
||||||
- @champ.rows.each do |champs|
|
- @champ.rows.each do |champs|
|
||||||
= render EditableChamp::RepetitionRowComponent.new(form: @form, champ: @champ, row: champs)
|
= render EditableChamp::RepetitionRowComponent.new(form: @form, champ: @champ, row: champs, seen_at: @seen_at)
|
||||||
|
|
||||||
.actions{ 'data-turbo': 'true' }
|
.actions{ 'data-turbo': 'true' }
|
||||||
= link_to champs_repetition_path(@champ.id), data: { turbo_method: :post }, class: 'button add-row' do
|
= link_to champs_repetition_path(@champ.id), data: { turbo_method: :post }, class: 'button add-row' do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class EditableChamp::RepetitionRowComponent < ApplicationComponent
|
class EditableChamp::RepetitionRowComponent < ApplicationComponent
|
||||||
def initialize(form:, champ:, row:)
|
def initialize(form:, champ:, row:, seen_at: nil)
|
||||||
@form, @champ, @row = form, champ, row
|
@form, @champ, @row, @seen_at = form, champ, row, seen_at
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.row{ id: row_dom_id }
|
.row{ id: row_dom_id }
|
||||||
- @row.each do |champ|
|
- @row.each do |champ|
|
||||||
= fields_for champ.input_name, champ do |form|
|
= fields_for champ.input_name, champ do |form|
|
||||||
= render partial: 'shared/dossiers/editable_champs/editable_champ', locals: { form: form, champ: champ }
|
= render EditableChamp::EditableChampComponent.new form: form, champ: champ, seen_at: @seen_at
|
||||||
|
|
||||||
.flex.row-reverse{ 'data-turbo': 'true' }
|
.flex.row-reverse{ 'data-turbo': 'true' }
|
||||||
= link_to champs_repetition_path(@champ.id, champ_ids: @row.map(&:id), row_id: row_dom_id), data: { turbo_method: :delete }, class: 'button danger remove-row' do
|
= link_to champs_repetition_path(@champ.id, champ_ids: @row.map(&:id), row_id: row_dom_id), data: { turbo_method: :delete }, class: 'button danger remove-row' do
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::SiretComponent < ApplicationComponent
|
class EditableChamp::SiretComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::TextComponent < ApplicationComponent
|
class EditableChamp::TextComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
class EditableChamp::TextareaComponent < ApplicationComponent
|
class EditableChamp::TextareaComponent < EditableChamp::EditableChampBaseComponent
|
||||||
include HtmlToStringHelper
|
include HtmlToStringHelper
|
||||||
|
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::TitreIdentiteComponent < ApplicationComponent
|
class EditableChamp::TitreIdentiteComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
class EditableChamp::YesNoComponent < ApplicationComponent
|
class EditableChamp::YesNoComponent < EditableChamp::EditableChampBaseComponent
|
||||||
def initialize(form:, champ:)
|
|
||||||
@form, @champ = form, champ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -188,19 +188,15 @@ module Users
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@dossier = dossier_with_champs
|
@dossier = dossier_with_champs
|
||||||
|
errors = update_dossier_and_compute_errors
|
||||||
|
|
||||||
if check_conditions?
|
if errors.present?
|
||||||
assign_dossier_and_check_conditions
|
flash.now.alert = errors
|
||||||
render :update_brouillon
|
end
|
||||||
else
|
|
||||||
errors = update_dossier_and_compute_errors
|
|
||||||
|
|
||||||
if errors.present?
|
respond_to do |format|
|
||||||
flash.now.alert = errors
|
format.html { render :modifier }
|
||||||
render :modifier
|
format.turbo_stream { render layout: false }
|
||||||
else
|
|
||||||
redirect_to demande_dossier_path(@dossier)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -308,18 +304,6 @@ module Users
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_conditions?
|
|
||||||
params[:check_conditions] && champs_params[:dossier]
|
|
||||||
end
|
|
||||||
|
|
||||||
def assign_dossier_and_check_conditions
|
|
||||||
@dossier.assign_attributes(champs_params[:dossier])
|
|
||||||
# We need to set dossier on champs, otherwise dossier will be reloaded
|
|
||||||
@dossier.champs.each do |champ|
|
|
||||||
champ.association(:dossier).target = @dossier
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# if the status tab is filled, then this tab
|
# if the status tab is filled, then this tab
|
||||||
# else first filled tab
|
# else first filled tab
|
||||||
# else en-cours
|
# else en-cours
|
||||||
|
|
|
@ -1,17 +1,4 @@
|
||||||
module ChampHelper
|
module ChampHelper
|
||||||
def has_label?(champ)
|
|
||||||
types_without_label = [TypeDeChamp.type_champs.fetch(:header_section), TypeDeChamp.type_champs.fetch(:explication)]
|
|
||||||
!types_without_label.include?(champ.type_champ)
|
|
||||||
end
|
|
||||||
|
|
||||||
def champ_carte_params(champ)
|
|
||||||
if champ.persisted?
|
|
||||||
{ champ_id: champ.id }
|
|
||||||
else
|
|
||||||
{ type_de_champ_id: champ.type_de_champ_id }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def format_text_value(text)
|
def format_text_value(text)
|
||||||
sanitized_text = sanitize(text)
|
sanitized_text = sanitize(text)
|
||||||
auto_linked_text = Anchored::Linker.auto_link(sanitized_text, target: '_blank', rel: 'noopener') do |link_href|
|
auto_linked_text = Anchored::Linker.auto_link(sanitized_text, target: '_blank', rel: 'noopener') do |link_href|
|
||||||
|
@ -27,36 +14,4 @@ module ChampHelper
|
||||||
piece_justificative_template_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id: object.procedure.id)
|
piece_justificative_template_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id: object.procedure.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def autosave_available?(champ)
|
|
||||||
# FIXME: enable autosave on champs private? once we figured out how to batch audit events
|
|
||||||
champ.dossier.brouillon? && !champ.repetition?
|
|
||||||
end
|
|
||||||
|
|
||||||
def editable_champ_controller(champ)
|
|
||||||
if !champ.repetition? && !champ.non_fillable?
|
|
||||||
# This is an editable champ. Lets find what controllers it might need.
|
|
||||||
controllers = []
|
|
||||||
|
|
||||||
# This is a public champ – it can have an autosave controller.
|
|
||||||
if champ.public?
|
|
||||||
# This is a champ on dossier in draft state. Activate autosave.
|
|
||||||
if champ.dossier.brouillon?
|
|
||||||
controllers << 'autosave'
|
|
||||||
# This is a champ on a dossier in en_construction state. Enable conditions checker.
|
|
||||||
elsif champ.public? && champ.dossier.en_construction?
|
|
||||||
controllers << 'check-conditions'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# This is a dropdown champ. Activate special behaviours it might have.
|
|
||||||
if champ.simple_drop_down_list? || champ.linked_drop_down_list?
|
|
||||||
controllers << 'champ-dropdown'
|
|
||||||
end
|
|
||||||
|
|
||||||
if controllers.present?
|
|
||||||
{ controller: controllers.join(' ') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,7 +42,10 @@ export class AutosaveController extends ApplicationController {
|
||||||
this.#latestPromise = Promise.resolve();
|
this.#latestPromise = Promise.resolve();
|
||||||
this.onGlobal('autosave:retry', () => this.didRequestRetry());
|
this.onGlobal('autosave:retry', () => this.didRequestRetry());
|
||||||
this.on('change', (event) => this.onChange(event));
|
this.on('change', (event) => this.onChange(event));
|
||||||
this.on('input', (event) => this.onInput(event));
|
|
||||||
|
if (this.saveOnInput) {
|
||||||
|
this.on('input', (event) => this.onInput(event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect() {
|
disconnect() {
|
||||||
|
@ -80,7 +83,8 @@ export class AutosaveController extends ApplicationController {
|
||||||
this.debounce(this.enqueueAutosaveRequest, AUTOSAVE_DEBOUNCE_DELAY);
|
this.debounce(this.enqueueAutosaveRequest, AUTOSAVE_DEBOUNCE_DELAY);
|
||||||
} else if (
|
} else if (
|
||||||
isSelectElement(target) ||
|
isSelectElement(target) ||
|
||||||
isCheckboxOrRadioInputElement(target)
|
isCheckboxOrRadioInputElement(target) ||
|
||||||
|
(!this.saveOnInput && isTextInputElement(target))
|
||||||
) {
|
) {
|
||||||
this.enqueueAutosaveRequest();
|
this.enqueueAutosaveRequest();
|
||||||
}
|
}
|
||||||
|
@ -99,6 +103,10 @@ export class AutosaveController extends ApplicationController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get saveOnInput() {
|
||||||
|
return !!this.form?.dataset.saveOnInput;
|
||||||
|
}
|
||||||
|
|
||||||
private didRequestRetry() {
|
private didRequestRetry() {
|
||||||
if (this.#needsRetry) {
|
if (this.#needsRetry) {
|
||||||
this.enqueueAutosaveRequest();
|
this.enqueueAutosaveRequest();
|
||||||
|
|
|
@ -51,6 +51,7 @@ class Champ < ApplicationRecord
|
||||||
:simple_drop_down_list?,
|
:simple_drop_down_list?,
|
||||||
:linked_drop_down_list?,
|
:linked_drop_down_list?,
|
||||||
:non_fillable?,
|
:non_fillable?,
|
||||||
|
:fillable?,
|
||||||
:cnaf?,
|
:cnaf?,
|
||||||
:dgfip?,
|
:dgfip?,
|
||||||
:pole_emploi?,
|
:pole_emploi?,
|
||||||
|
|
|
@ -186,6 +186,10 @@ class TypeDeChamp < ApplicationRecord
|
||||||
drop_down_other == "1" || drop_down_other == true
|
drop_down_other == "1" || drop_down_other == true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fillable?
|
||||||
|
!non_fillable?
|
||||||
|
end
|
||||||
|
|
||||||
def non_fillable?
|
def non_fillable?
|
||||||
type_champ.in?([
|
type_champ.in?([
|
||||||
TypeDeChamp.type_champs.fetch(:header_section),
|
TypeDeChamp.type_champs.fetch(:header_section),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
= fields_for @champ.input_name, @champ do |form|
|
= fields_for @champ.input_name, @champ do |form|
|
||||||
= turbo_stream.morph @champ.input_group_id, partial: "shared/dossiers/editable_champs/editable_champ", locals: { champ: @champ, form: form }
|
= turbo_stream.morph @champ.input_group_id do
|
||||||
|
= render EditableChamp::EditableChampComponent.new champ: @champ, form: form
|
||||||
|
|
||||||
- if @champ.piece_justificative_file.attached?
|
- if @champ.piece_justificative_file.attached?
|
||||||
- attachment = @champ.piece_justificative_file.attachment
|
- attachment = @champ.piece_justificative_file.attachment
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
.autosave.autosave-state-idle{ data: { controller: 'autosave-status' } }
|
|
||||||
%p.autosave-explanation
|
|
||||||
%span.autosave-explanation-text
|
|
||||||
= t('views.instructeurs.dossiers.autosave.autosave_draft')
|
|
||||||
|
|
||||||
%p.autosave-status.succeeded
|
|
||||||
%span.autosave-icon.icon.accept
|
|
||||||
%span.autosave-label
|
|
||||||
= t('views.instructeurs.dossiers.autosave.autosave_confirmation')
|
|
||||||
|
|
||||||
%p.autosave-status.failed
|
|
||||||
%span.autosave-icon ⚠️
|
|
||||||
%span.autosave-label Impossible d’enregistrer les annotations
|
|
||||||
%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…
|
|
||||||
|
|
|
@ -45,9 +45,7 @@
|
||||||
%form.form
|
%form.form
|
||||||
= form_for @dossier, url: '', html: { class: 'form' } do |f|
|
= form_for @dossier, url: '', html: { class: 'form' } do |f|
|
||||||
= f.fields_for :champs do |champ_form|
|
= f.fields_for :champs do |champ_form|
|
||||||
- champ = champ_form.object
|
= render EditableChamp::EditableChampComponent.new champ: champ_form.object, form: champ_form
|
||||||
= render partial: "shared/dossiers/editable_champs/editable_champ",
|
|
||||||
locals: { champ: champ, form: champ_form, seen_at: nil }
|
|
||||||
|
|
||||||
.editable-champ.editable-champ-text
|
.editable-champ.editable-champ-text
|
||||||
%label Mot de passe
|
%label Mot de passe
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
.autosave.autosave-state-idle{ data: { controller: 'autosave-status' } }
|
.autosave.autosave-state-idle{ data: { controller: 'autosave-status' } }
|
||||||
%p.autosave-explanation
|
%p.autosave-explanation
|
||||||
%span.autosave-explanation-text
|
%span.autosave-explanation-text
|
||||||
= t('views.users.dossiers.autosave.autosave_draft')
|
- if dossier.brouillon?
|
||||||
= link_to t('views.users.dossiers.autosave.more_infos'), FAQ_AUTOSAVE_URL, target: '_blank', rel: 'noopener', class: 'autosave-more-infos'
|
= t('views.users.dossiers.autosave.draft_explanation')
|
||||||
|
- else
|
||||||
|
= t('views.users.dossiers.autosave.explanation')
|
||||||
|
= link_to t('views.users.dossiers.autosave.more_information'), FAQ_AUTOSAVE_URL, target: '_blank', rel: 'noopener', class: 'autosave-more-infos'
|
||||||
|
|
||||||
%p.autosave-status.succeeded
|
%p.autosave-status.succeeded
|
||||||
%span.autosave-icon.icon.accept
|
%span.autosave-icon.icon.accept
|
||||||
%span.autosave-label
|
%span.autosave-label
|
||||||
= t('views.users.dossiers.autosave.autosave_confirmation')
|
- if dossier.brouillon?
|
||||||
|
= t('views.users.dossiers.autosave.draft_confirmation')
|
||||||
|
- else
|
||||||
|
= t('views.users.dossiers.autosave.confirmation')
|
||||||
= link_to t('views.users.dossiers.autosave.more_information'), FAQ_AUTOSAVE_URL, target: '_blank', rel: 'noopener', class: 'autosave-more-infos'
|
= link_to t('views.users.dossiers.autosave.more_information'), FAQ_AUTOSAVE_URL, target: '_blank', rel: 'noopener', class: 'autosave-more-infos'
|
||||||
|
|
||||||
%p.autosave-status.failed
|
%p.autosave-status.failed
|
|
@ -2,7 +2,7 @@
|
||||||
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: dossier }
|
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: dossier }
|
||||||
|
|
||||||
- if dossier.brouillon?
|
- if dossier.brouillon?
|
||||||
- form_options = { url: brouillon_dossier_url(dossier), method: :patch }
|
- form_options = { url: brouillon_dossier_url(dossier), method: :patch, data: { save_on_input: true } }
|
||||||
- else
|
- else
|
||||||
- form_options = { url: modifier_dossier_url(dossier), method: :patch }
|
- form_options = { url: modifier_dossier_url(dossier), method: :patch }
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
%hr
|
%hr
|
||||||
|
|
||||||
- if dossier.show_groupe_instructeur_selector?
|
- if dossier.show_groupe_instructeur_selector?
|
||||||
%span{ data: { controller: dossier.brouillon? ? 'autosave' : 'check-conditions' } }
|
%span{ data: { controller: 'autosave' } }
|
||||||
= f.label :groupe_instructeur_id do
|
= f.label :groupe_instructeur_id do
|
||||||
= dossier.procedure.routing_criteria_name
|
= dossier.procedure.routing_criteria_name
|
||||||
%span.mandatory *
|
%span.mandatory *
|
||||||
|
@ -33,25 +33,19 @@
|
||||||
|
|
||||||
- dossier.champs.each do |champ|
|
- dossier.champs.each do |champ|
|
||||||
= fields_for champ.input_name, champ do |form|
|
= fields_for champ.input_name, champ do |form|
|
||||||
= render partial: "shared/dossiers/editable_champs/editable_champ", locals: { form: form, champ: champ }
|
= render EditableChamp::EditableChampComponent.new form: form, champ: champ
|
||||||
|
|
||||||
- if !dossier.for_procedure_preview?
|
- if !dossier.for_procedure_preview?
|
||||||
.dossier-edit-sticky-footer
|
.dossier-edit-sticky-footer
|
||||||
.send-dossier-actions-bar
|
.send-dossier-actions-bar
|
||||||
- if dossier.brouillon?
|
= render partial: 'shared/dossiers/autosave', locals: { dossier: dossier }
|
||||||
= render partial: 'users/dossiers/autosave'
|
|
||||||
|
|
||||||
- if dossier.can_transition_to_en_construction?
|
- if dossier.can_transition_to_en_construction?
|
||||||
= f.button t('views.shared.dossiers.edit.submit_dossier'),
|
= f.button t('views.shared.dossiers.edit.submit_dossier'),
|
||||||
name: :submit_draft,
|
name: :submit_draft,
|
||||||
value: true,
|
value: true,
|
||||||
class: 'button send primary',
|
|
||||||
disabled: !current_user.owns?(dossier),
|
|
||||||
data: { 'disable-with': "Envoi en cours…" }
|
|
||||||
|
|
||||||
- else
|
|
||||||
= f.button t('views.shared.dossiers.edit.save_changes'),
|
|
||||||
class: 'button send primary',
|
class: 'button send primary',
|
||||||
|
disabled: !current_user.owns?(dossier),
|
||||||
data: { 'disable-with': "Envoi en cours…" }
|
data: { 'disable-with': "Envoi en cours…" }
|
||||||
|
|
||||||
- if dossier.brouillon? && !current_user.owns?(dossier)
|
- if dossier.brouillon? && !current_user.owns?(dossier)
|
||||||
|
|
|
@ -4,16 +4,11 @@
|
||||||
= form_for dossier, url: annotations_instructeur_dossier_path(dossier.procedure, dossier), html: { class: 'form', multipart: true } do |f|
|
= form_for dossier, url: annotations_instructeur_dossier_path(dossier.procedure, dossier), html: { class: 'form', multipart: true } do |f|
|
||||||
- dossier.champs_private.each do |champ|
|
- dossier.champs_private.each do |champ|
|
||||||
= fields_for champ.input_name, champ do |form|
|
= fields_for champ.input_name, champ do |form|
|
||||||
= render partial: "shared/dossiers/editable_champs/editable_champ", locals: { form: form, champ: champ, seen_at: seen_at }
|
= render EditableChamp::EditableChampComponent.new form: form, champ: champ, seen_at: seen_at
|
||||||
|
|
||||||
- if !dossier.for_procedure_preview?
|
- if !dossier.for_procedure_preview?
|
||||||
- if autosave_available?(dossier.champs_private.first)
|
.send-wrapper
|
||||||
.dossier-edit-sticky-footer
|
= f.submit 'Sauvegarder', class: 'button primary send', data: { disable: true }
|
||||||
.send-dossier-actions-bar
|
|
||||||
= render partial: 'autosave'
|
|
||||||
- else
|
|
||||||
.send-wrapper
|
|
||||||
= f.submit 'Sauvegarder', class: 'button primary send', data: { disable: true }
|
|
||||||
|
|
||||||
- else
|
- else
|
||||||
%h2.empty-text Aucune annotation privée
|
%h2.empty-text Aucune annotation privée
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
= # we do this trick because some html elements should use 'label' and some should be plain paragraphs
|
|
||||||
- if champ.html_label?
|
|
||||||
= form.label champ.main_value_name, id: champ.labelledby_id, for: champ.input_id do
|
|
||||||
= render partial: 'shared/dossiers/editable_champs/champ_label_content', locals: { champ: champ, seen_at: seen_at }
|
|
||||||
- else
|
|
||||||
.form-label.mb-4
|
|
||||||
= render partial: 'shared/dossiers/editable_champs/champ_label_content', locals: { champ: champ, seen_at: seen_at }
|
|
||||||
|
|
||||||
- if champ.description.present?
|
|
||||||
.notice{ id: champ.describedby_id }= string_to_html(champ.description)
|
|
|
@ -1,11 +0,0 @@
|
||||||
#{champ.libelle}
|
|
||||||
- if champ.type_de_champ.mandatory?
|
|
||||||
%span.mandatory *
|
|
||||||
|
|
||||||
- if champ.updated_at.present? && seen_at.present?
|
|
||||||
%span.updated-at{ class: highlight_if_unseen_class(seen_at, champ.updated_at) }
|
|
||||||
= "modifié le #{try_format_datetime(champ.updated_at)}"
|
|
||||||
|
|
||||||
- if champ.rebased_at.present? && champ.rebased_at > (seen_at || champ.updated_at) && current_user.owns_or_invite?(champ.dossier)
|
|
||||||
%span.updated-at.highlighted
|
|
||||||
Le type de ce champ où sa description a été modifiée par l'administration. Vérifier son contenu.
|
|
|
@ -1,13 +0,0 @@
|
||||||
.editable-champ{ class: "editable-champ-#{champ.type_champ} #{champ.visible? ? '' : 'hidden'}", id: champ.input_group_id, data: editable_champ_controller(champ) }
|
|
||||||
- if champ.repetition?
|
|
||||||
%h3.header-subsection= champ.libelle
|
|
||||||
- if champ.description.present?
|
|
||||||
%p.notice= string_to_html(champ.description, false)
|
|
||||||
|
|
||||||
- elsif has_label?(champ)
|
|
||||||
= render partial: 'shared/dossiers/editable_champs/champ_label', locals: { form: form, champ: champ, seen_at: defined?(seen_at) ? seen_at : nil }
|
|
||||||
- if champ.type_champ == "titre_identite"
|
|
||||||
%p.notice Carte nationale d’identité (uniquement le recto), passeport, titre de séjour ou autre justificatif d’identité. Formats acceptés : jpg/png
|
|
||||||
|
|
||||||
= form.hidden_field :id, value: champ.id, data: champ.repetition? ? { id: true } : {}
|
|
||||||
= render "EditableChamp::#{champ.type_champ.camelcase}Component".constantize.new(form: form, champ: champ)
|
|
5
app/views/users/dossiers/update.turbo_stream.haml
Normal file
5
app/views/users/dossiers/update.turbo_stream.haml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
- @dossier.champs.filter(&:conditional?).each do |champ|
|
||||||
|
- if champ.visible?
|
||||||
|
= turbo_stream.show champ.input_group_id
|
||||||
|
- else
|
||||||
|
= turbo_stream.hide champ.input_group_id
|
|
@ -137,7 +137,6 @@ en:
|
||||||
edit:
|
edit:
|
||||||
autosave: Your file is automatically saved after each modification. You can close the window at any time and pick up where you left off later.
|
autosave: Your file is automatically saved after each modification. You can close the window at any time and pick up where you left off later.
|
||||||
submit_dossier: Submit the file
|
submit_dossier: Submit the file
|
||||||
save_changes: Save the changes of the file
|
|
||||||
messages:
|
messages:
|
||||||
form:
|
form:
|
||||||
send_message: "Send message"
|
send_message: "Send message"
|
||||||
|
@ -151,9 +150,6 @@ en:
|
||||||
edit_identity: "Edit identity data"
|
edit_identity: "Edit identity data"
|
||||||
instructeurs:
|
instructeurs:
|
||||||
dossiers:
|
dossiers:
|
||||||
autosave:
|
|
||||||
autosave_draft: Your annotations are automatically saved.
|
|
||||||
autosave_confirmation: Annotations saved
|
|
||||||
tab_steps:
|
tab_steps:
|
||||||
to_follow: to follow
|
to_follow: to follow
|
||||||
total: total
|
total: total
|
||||||
|
@ -192,8 +188,10 @@ en:
|
||||||
dossiers:
|
dossiers:
|
||||||
archived_dossier: "Your file will be kept %{duree_conservation_dossiers_dans_ds} more months"
|
archived_dossier: "Your file will be kept %{duree_conservation_dossiers_dans_ds} more months"
|
||||||
autosave:
|
autosave:
|
||||||
autosave_draft: Your draft is automatically saved.
|
explanation: Your file is automatically saved.
|
||||||
autosave_confirmation: Draft saved
|
confirmation: File saved
|
||||||
|
draft_explanation: Your draft is automatically saved.
|
||||||
|
draft_confirmation: Draft saved
|
||||||
more_information: More informations
|
more_information: More informations
|
||||||
identite:
|
identite:
|
||||||
identity_data: Identity data
|
identity_data: Identity data
|
||||||
|
|
|
@ -132,7 +132,6 @@ fr:
|
||||||
edit:
|
edit:
|
||||||
autosave: Votre dossier est enregistré automatiquement après chaque modification. Vous pouvez à tout moment fermer la fenêtre et reprendre plus tard là où vous en étiez.
|
autosave: Votre dossier est enregistré automatiquement après chaque modification. Vous pouvez à tout moment fermer la fenêtre et reprendre plus tard là où vous en étiez.
|
||||||
submit_dossier: Déposer le dossier
|
submit_dossier: Déposer le dossier
|
||||||
save_changes: Enregistrer les modifications du dossier
|
|
||||||
messages:
|
messages:
|
||||||
form:
|
form:
|
||||||
send_message: "Envoyer le message"
|
send_message: "Envoyer le message"
|
||||||
|
@ -146,9 +145,6 @@ fr:
|
||||||
edit_identity: "Modifier l’identité"
|
edit_identity: "Modifier l’identité"
|
||||||
instructeurs:
|
instructeurs:
|
||||||
dossiers:
|
dossiers:
|
||||||
autosave:
|
|
||||||
autosave_draft: Vos annotations sont automatiquement enregistrées.
|
|
||||||
autosave_confirmation: Annotations enregistrées
|
|
||||||
tab_steps:
|
tab_steps:
|
||||||
to_follow: à suivre
|
to_follow: à suivre
|
||||||
total: au total
|
total: au total
|
||||||
|
@ -188,10 +184,11 @@ fr:
|
||||||
dossiers:
|
dossiers:
|
||||||
archived_dossier: "Votre dossier sera conservé %{duree_conservation_dossiers_dans_ds} mois supplémentaire"
|
archived_dossier: "Votre dossier sera conservé %{duree_conservation_dossiers_dans_ds} mois supplémentaire"
|
||||||
autosave:
|
autosave:
|
||||||
autosave_draft: Votre brouillon est automatiquement enregistré.
|
explanation: Votre dossier est automatiquement enregistré.
|
||||||
autosave_confirmation: Brouillon enregistré
|
confirmation: Dossier enregistré
|
||||||
more_information: More informations
|
draft_explanation: Votre brouillon est automatiquement enregistré.
|
||||||
more_infos: En savoir plus
|
draft_confirmation: Brouillon enregistré
|
||||||
|
more_information: En savoir plus
|
||||||
identite:
|
identite:
|
||||||
identity_data: Données d’identité
|
identity_data: Données d’identité
|
||||||
civility: Civilité
|
civility: Civilité
|
||||||
|
|
|
@ -1,46 +1,50 @@
|
||||||
describe ChampHelper, type: :helper do
|
describe EditableChamp::EditableChampComponent, type: :component do
|
||||||
|
let(:component) { described_class.new(form: nil, champ: champ) }
|
||||||
|
|
||||||
describe "editable_champ_controller" do
|
describe "editable_champ_controller" do
|
||||||
let(:dossier) { create(:dossier) }
|
let(:dossier) { create(:dossier) }
|
||||||
let(:champ) { create(:champ, dossier: dossier) }
|
let(:champ) { create(:champ, dossier: dossier) }
|
||||||
let(:controllers) { [] }
|
let(:controllers) { [] }
|
||||||
let(:data) { { controller: controllers.join(' ') } }
|
let(:data) { controllers.join(' ') }
|
||||||
|
|
||||||
|
subject { component.send(:stimulus_controller) }
|
||||||
|
|
||||||
context 'when an editable champ' do
|
context 'when an editable champ' do
|
||||||
let(:controllers) { ['autosave'] }
|
let(:controllers) { ['autosave'] }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(data) }
|
it { expect(subject).to eq(data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a repetition champ' do
|
context 'when a repetition champ' do
|
||||||
let(:champ) { create(:champ_repetition, dossier: dossier) }
|
let(:champ) { create(:champ_repetition, dossier: dossier) }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(nil) }
|
it { expect(subject).to eq(nil) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a private champ' do
|
context 'when a private champ' do
|
||||||
let(:champ) { create(:champ, dossier: dossier, private: true) }
|
let(:champ) { create(:champ, dossier: dossier, private: true) }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(nil) }
|
it { expect(subject).to eq('') }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a dossier is en_construction' do
|
context 'when a dossier is en_construction' do
|
||||||
let(:controllers) { ['check-conditions'] }
|
let(:controllers) { ['autosave'] }
|
||||||
let(:dossier) { create(:dossier, :en_construction) }
|
let(:dossier) { create(:dossier, :en_construction) }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(data) }
|
it { expect(subject).to eq(data) }
|
||||||
|
|
||||||
context 'when a public dropdown champ' do
|
context 'when a public dropdown champ' do
|
||||||
let(:controllers) { ['check-conditions', 'champ-dropdown'] }
|
let(:controllers) { ['autosave', 'champ-dropdown'] }
|
||||||
let(:champ) { create(:champ_drop_down_list, dossier: dossier) }
|
let(:champ) { create(:champ_drop_down_list, dossier: dossier) }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(data) }
|
it { expect(subject).to eq(data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a private dropdown champ' do
|
context 'when a private dropdown champ' do
|
||||||
let(:controllers) { ['champ-dropdown'] }
|
let(:controllers) { ['champ-dropdown'] }
|
||||||
let(:champ) { create(:champ_drop_down_list, dossier: dossier, private: true) }
|
let(:champ) { create(:champ_drop_down_list, dossier: dossier, private: true) }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(data) }
|
it { expect(subject).to eq(data) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -48,14 +52,14 @@ describe ChampHelper, type: :helper do
|
||||||
let(:controllers) { ['autosave', 'champ-dropdown'] }
|
let(:controllers) { ['autosave', 'champ-dropdown'] }
|
||||||
let(:champ) { create(:champ_drop_down_list, dossier: dossier) }
|
let(:champ) { create(:champ_drop_down_list, dossier: dossier) }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(data) }
|
it { expect(subject).to eq(data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a private dropdown champ' do
|
context 'when a private dropdown champ' do
|
||||||
let(:controllers) { ['champ-dropdown'] }
|
let(:controllers) { ['champ-dropdown'] }
|
||||||
let(:champ) { create(:champ_drop_down_list, dossier: dossier, private: true) }
|
let(:champ) { create(:champ_drop_down_list, dossier: dossier, private: true) }
|
||||||
|
|
||||||
it { expect(editable_champ_controller(champ)).to eq(data) }
|
it { expect(subject).to eq(data) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -649,7 +649,7 @@ describe Users::DossiersController, type: :controller do
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
||||||
end
|
end
|
||||||
|
|
||||||
it { is_expected.to redirect_to(demande_dossier_path(dossier)) }
|
it { is_expected.to have_http_status(:ok) }
|
||||||
|
|
||||||
context 'when only a single file champ are modified' do
|
context 'when only a single file champ are modified' do
|
||||||
# A bug in ActiveRecord causes records changed through grand-parent <-> parent <-> child
|
# A bug in ActiveRecord causes records changed through grand-parent <-> parent <-> child
|
||||||
|
@ -726,7 +726,7 @@ describe Users::DossiersController, type: :controller do
|
||||||
it 'does not raise any errors' do
|
it 'does not raise any errors' do
|
||||||
subject
|
subject
|
||||||
|
|
||||||
expect(response).to redirect_to(demande_dossier_path(dossier))
|
expect(response).to have_http_status(:ok)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -741,7 +741,7 @@ describe Users::DossiersController, type: :controller do
|
||||||
|
|
||||||
it { expect(first_champ.reload.value).to eq('beautiful value') }
|
it { expect(first_champ.reload.value).to eq('beautiful value') }
|
||||||
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction)) }
|
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction)) }
|
||||||
it { expect(response).to redirect_to(demande_dossier_path(dossier)) }
|
it { expect(response).to have_http_status(:ok) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the dossier is followed by an instructeur' do
|
context 'when the dossier is followed by an instructeur' do
|
||||||
|
|
|
@ -120,7 +120,8 @@ describe 'The routing', js: true do
|
||||||
click_on 'Modifier mon dossier'
|
click_on 'Modifier mon dossier'
|
||||||
|
|
||||||
fill_in litteraire_user.dossiers.first.champs.first.libelle, with: 'some value'
|
fill_in litteraire_user.dossiers.first.champs.first.libelle, with: 'some value'
|
||||||
click_on 'Enregistrer les modifications du dossier'
|
blur
|
||||||
|
expect(page).to have_css('span', text: 'Dossier enregistré', visible: true)
|
||||||
log_out
|
log_out
|
||||||
|
|
||||||
# the litteraires instructeurs should have a notification
|
# the litteraires instructeurs should have a notification
|
||||||
|
@ -214,7 +215,7 @@ describe 'The routing', js: true do
|
||||||
expect(page).not_to have_selector("option", text: "Groupe inactif")
|
expect(page).not_to have_selector("option", text: "Groupe inactif")
|
||||||
|
|
||||||
select(new_group, from: 'dossier_groupe_instructeur_id')
|
select(new_group, from: 'dossier_groupe_instructeur_id')
|
||||||
click_on "Enregistrer les modifications du dossier"
|
expect(page).to have_css('span', text: 'Dossier enregistré', visible: true)
|
||||||
expect(page).to have_text(new_group)
|
expect(page).to have_text(new_group)
|
||||||
|
|
||||||
log_out
|
log_out
|
||||||
|
|
|
@ -390,6 +390,9 @@ describe 'The user' do
|
||||||
expect(page).to have_no_css('label', text: 'tonnage', visible: true)
|
expect(page).to have_no_css('label', text: 'tonnage', visible: true)
|
||||||
|
|
||||||
fill_in('age', with: '18')
|
fill_in('age', with: '18')
|
||||||
|
blur
|
||||||
|
expect(page).to have_css('span', text: 'Dossier enregistré', visible: true)
|
||||||
|
|
||||||
# the champ keeps their previous value so they are all displayed
|
# the champ keeps their previous value so they are all displayed
|
||||||
expect(page).to have_css('label', text: 'permis de conduire', visible: true)
|
expect(page).to have_css('label', text: 'permis de conduire', visible: true)
|
||||||
expect(page).to have_css('label', text: 'tonnage', visible: true)
|
expect(page).to have_css('label', text: 'tonnage', visible: true)
|
||||||
|
|
|
@ -48,8 +48,10 @@ describe 'Dossier details:' do
|
||||||
expect(page).to have_current_path(dossier_path(dossier))
|
expect(page).to have_current_path(dossier_path(dossier))
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'the user can edit the submitted demande'
|
context 'with js', js: true do
|
||||||
it_behaves_like 'the user can send messages to the instructeur'
|
it_behaves_like 'the user can edit the submitted demande'
|
||||||
|
it_behaves_like 'the user can send messages to the instructeur'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,12 @@ RSpec.shared_examples 'the user can edit the submitted demande' do
|
||||||
|
|
||||||
expect(page).to have_current_path(modifier_dossier_path(dossier))
|
expect(page).to have_current_path(modifier_dossier_path(dossier))
|
||||||
fill_in('Texte obligatoire', with: 'Nouveau texte')
|
fill_in('Texte obligatoire', with: 'Nouveau texte')
|
||||||
click_on 'Enregistrer les modifications du dossier'
|
blur
|
||||||
|
expect(page).to have_css('span', text: 'Dossier enregistré', visible: true)
|
||||||
|
|
||||||
|
click_on 'Demande'
|
||||||
expect(page).to have_current_path(demande_dossier_path(dossier))
|
expect(page).to have_current_path(demande_dossier_path(dossier))
|
||||||
|
|
||||||
expect(page).to have_content('Nouveau texte')
|
expect(page).to have_content('Nouveau texte')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -127,7 +127,7 @@ describe 'Invitations' do
|
||||||
expect(page).to have_text("user_invite@exemple.fr")
|
expect(page).to have_text("user_invite@exemple.fr")
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'as an invited user' do
|
context 'as an invited user', js: true do
|
||||||
before do
|
before do
|
||||||
navigate_to_invited_dossier(invite)
|
navigate_to_invited_dossier(invite)
|
||||||
expect(page).to have_current_path(dossier_path(invite.dossier))
|
expect(page).to have_current_path(dossier_path(invite.dossier))
|
||||||
|
|
Loading…
Reference in a new issue