Merge pull request #8699 from mfo/US/8661
a11y(bloc-repetable): amélioration des interactions avec les répétitions d'un bloc répétable
This commit is contained in:
commit
54d88e7dd0
41 changed files with 173 additions and 52 deletions
|
@ -1,7 +0,0 @@
|
||||||
# Display a form for destroying a file attachment via a button, but since it might already be nested within a form
|
|
||||||
# put this component before the actual form containing the editcomponent
|
|
||||||
class Attachment::DeleteFormComponent < ApplicationComponent
|
|
||||||
def call
|
|
||||||
form_tag('/attachments/:id', method: :delete, data: { 'turbo-method': :delete, turbo: true }, id: dom_id(ActiveStorage::Attachment.new, :delete)) {}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -3,7 +3,7 @@
|
||||||
%div{ id: dom_id(attachment, :persisted_row) }
|
%div{ id: dom_id(attachment, :persisted_row) }
|
||||||
.flex.flex-gap-2{ class: class_names("attachment-error": attachment.virus_scanner_error?) }
|
.flex.flex-gap-2{ class: class_names("attachment-error": attachment.virus_scanner_error?) }
|
||||||
- if user_can_destroy?
|
- if user_can_destroy?
|
||||||
= button_tag(name: "action", formaction: destroy_attachment_path, class: "fr-btn fr-btn--tertiary fr-btn--sm fr-icon-delete-line", title: t(".delete_file", filename: attachment.filename), form: dom_id(ActiveStorage::Attachment.new, :delete), data: {turbo: true, 'turbo-method': 'delete'}) do
|
= render NestedForms::OwnedButtonComponent.new(formaction: destroy_attachment_path, http_method: :delete, opt: {class: "fr-btn fr-btn--tertiary fr-btn--sm fr-icon-delete-line", title: t(".delete_file", filename: attachment.filename)}) do
|
||||||
= t('.delete')
|
= t('.delete')
|
||||||
- elsif user_can_replace?
|
- elsif user_can_replace?
|
||||||
= button_tag t('.replace'), **replace_button_options, class: "fr-btn fr-btn--tertiary fr-btn--sm", title: t(".replace_file", filename: attachment.filename)
|
= button_tag t('.replace'), **replace_button_options, class: "fr-btn fr-btn--tertiary fr-btn--sm", title: t(".replace_file", filename: attachment.filename)
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
%legend.mandatory-explanation
|
%legend.mandatory-explanation
|
||||||
Sélectionnez une des valeurs
|
Sélectionnez une des valeurs
|
||||||
%label
|
%label
|
||||||
= @form.radio_button :value, Individual::GENDER_FEMALE
|
= @form.radio_button :value, Individual::GENDER_FEMALE, id: @champ.female_input_id
|
||||||
= Individual.human_attribute_name('gender.female')
|
= Individual.human_attribute_name('gender.female')
|
||||||
|
|
||||||
%label
|
%label
|
||||||
= @form.radio_button :value, Individual::GENDER_MALE
|
= @form.radio_button :value, Individual::GENDER_MALE, id: @champ.male_input_id
|
||||||
= Individual.human_attribute_name('gender.male')
|
= Individual.human_attribute_name('gender.male')
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
.cnaf-inputs
|
.cnaf-inputs
|
||||||
%div
|
%div
|
||||||
= @form.label :numero_allocataire, t('.numero_allocataire_label')
|
= @form.label :numero_allocataire, t('.numero_allocataire_label'), for: @champ.numero_allocataire_input_id
|
||||||
%p.notice= t('.numero_allocataire_notice')
|
%p.notice= t('.numero_allocataire_notice')
|
||||||
= @form.text_field :numero_allocataire,
|
= @form.text_field :numero_allocataire,
|
||||||
required: @champ.required?,
|
required: @champ.required?,
|
||||||
aria: { describedby: @champ.describedby_id },
|
aria: { describedby: @champ.describedby_id },
|
||||||
class: "width-33-desktop"
|
class: "width-33-desktop", id: @champ.numero_allocataire_input_id
|
||||||
|
|
||||||
%div
|
%div
|
||||||
= @form.label :code_postal, t('.code_postal_label')
|
= @form.label :code_postal, t('.code_postal_label'), for: @champ.code_postal_input_id
|
||||||
%p.notice= t('.code_postal_notice')
|
%p.notice= t('.code_postal_notice')
|
||||||
= @form.text_field :code_postal,
|
= @form.text_field :code_postal,
|
||||||
required: @champ.required?,
|
required: @champ.required?,
|
||||||
aria: { describedby: @champ.describedby_id },
|
aria: { describedby: @champ.describedby_id },
|
||||||
class: "width-33-desktop"
|
class: "width-33-desktop",
|
||||||
|
id: @champ.code_postal_input_id
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
.dgfip-inputs
|
.dgfip-inputs
|
||||||
%div
|
%div
|
||||||
= @form.label :numero_fiscal, t('.numero_fiscal_label')
|
= @form.label :numero_fiscal, t('.numero_fiscal_label'), for: @champ.numero_fiscal_input_id
|
||||||
%p.notice= t('.numero_fiscal_notice')
|
%p.notice= t('.numero_fiscal_notice')
|
||||||
= @form.text_field :numero_fiscal,
|
= @form.text_field :numero_fiscal,
|
||||||
required: @champ.required?,
|
required: @champ.required?,
|
||||||
aria: { describedby: @champ.describedby_id },
|
aria: { describedby: @champ.describedby_id },
|
||||||
class: "width-33-desktop"
|
class: "width-33-desktop", id: @champ.numero_fiscal_input_id
|
||||||
|
|
||||||
%div
|
%div
|
||||||
= @form.label :reference_avis, t('.reference_avis_label')
|
= @form.label :reference_avis, t('.reference_avis_label'), for: @champ.reference_avis_input_id
|
||||||
%p.notice= t('.reference_avis_notice')
|
%p.notice= t('.reference_avis_notice')
|
||||||
= @form.text_field :reference_avis,
|
= @form.text_field :reference_avis,
|
||||||
required: @champ.required?,
|
required: @champ.required?,
|
||||||
aria: { describedby: @champ.describedby_id },
|
aria: { describedby: @champ.describedby_id },
|
||||||
class: "width-33-desktop"
|
class: "width-33-desktop", id: @champ.reference_avis_input_id
|
||||||
|
|
|
@ -15,10 +15,6 @@ class EditableChamp::EpciComponent < EditableChamp::EditableChampBaseComponent
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def departement_input_id
|
|
||||||
"#{@champ.input_id}-departement"
|
|
||||||
end
|
|
||||||
|
|
||||||
def departement_select_options
|
def departement_select_options
|
||||||
{ selected: @champ.code_departement }.merge(@champ.mandatory? ? { prompt: '' } : { include_blank: '' })
|
{ selected: @champ.code_departement }.merge(@champ.mandatory? ? { prompt: '' } : { include_blank: '' })
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
%label.notice{ for: departement_input_id } Le département de l’EPCI
|
%label.notice{ for: @champ.code_departement_input_id } Le département de l’EPCI
|
||||||
= @form.select :code_departement, departement_options, departement_select_options, required: @champ.required?, id: departement_input_id, class: "width-33-desktop width-100-mobile"
|
= @form.select :code_departement, departement_options, departement_select_options, required: @champ.required?, id: @champ.code_departement_input_id, class: "width-33-desktop width-100-mobile"
|
||||||
- if @champ.departement?
|
- if @champ.departement?
|
||||||
= @form.select :value, epci_options, epci_select_options, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile"
|
= @form.label "EPCI", for: @champ.epci_input_id
|
||||||
|
= @form.select :value, epci_options, epci_select_options, required: @champ.required?, id: @champ.epci_input_id, aria: { describedby: @champ.describedby_id }, class: "width-33-desktop width-100-mobile"
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
.mesri-inputs
|
.mesri-inputs
|
||||||
%div
|
%div
|
||||||
= @form.label :ine, t('.ine_label')
|
= @form.label :ine, t('.ine_label'), for: @champ.input_id
|
||||||
%p.notice= t('.ine_notice')
|
%p.notice= t('.ine_notice')
|
||||||
= @form.text_field :ine,
|
= @form.text_field :ine,
|
||||||
required: @champ.required?,
|
required: @champ.required?,
|
||||||
aria: { describedby: @champ.describedby_id },
|
aria: { describedby: @champ.describedby_id },
|
||||||
class: "width-33-desktop"
|
class: "width-33-desktop", id: @champ.input_id
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
- if @champ.render_as_checkboxes?
|
- if @champ.render_as_checkboxes?
|
||||||
= @form.collection_check_boxes(:value, @champ.enabled_non_empty_options, :to_s, :to_s) do |b|
|
= @form.collection_check_boxes(:value, @champ.enabled_non_empty_options, :to_s, :to_s) do |b|
|
||||||
- tag.div(class: 'editable-champ editable-champ-checkbox') do
|
- tag.div(class: 'editable-champ editable-champ-checkbox') do
|
||||||
- b.label do
|
- b.label(for: @champ.checkbox_id(b.value)) do
|
||||||
- b.check_box({ multiple: true, checked: @champ&.selected_options&.include?(b.value), aria: { describedby: @champ.describedby_id } }) + b.text
|
- b.check_box({ multiple: true, checked: @champ&.selected_options&.include?(b.value), aria: { describedby: @champ.describedby_id }, id: @champ.checkbox_id(b.value) }) + b.text
|
||||||
- else
|
- else
|
||||||
= @form.hidden_field :value
|
= @form.hidden_field :value
|
||||||
= react_component("ComboMultipleDropdownList",
|
= react_component("ComboMultipleDropdownList",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
.pole-emploi-inputs
|
.pole-emploi-inputs
|
||||||
%div
|
%div
|
||||||
= @form.label :identifiant, t('.identifiant_label')
|
= @form.label :identifiant, t('.identifiant_label'), for: @champ.input_id
|
||||||
%p.notice= t('.identifiant_notice')
|
%p.notice= t('.identifiant_notice')
|
||||||
= @form.text_field :identifiant,
|
= @form.text_field :identifiant,
|
||||||
required: @champ.required?,
|
required: @champ.required?,
|
||||||
aria: { describedby: @champ.describedby_id },
|
aria: { describedby: @champ.describedby_id },
|
||||||
class: "width-33-desktop"
|
class: "width-33-desktop", id: @champ.input_id
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
en:
|
||||||
|
add: "Add an element to « %{libelle} »"
|
||||||
|
add_title: "Add an element to « %{libelle} »"
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
fr:
|
||||||
|
add: "Ajouter un élément pour « %{libelle} »"
|
||||||
|
add_title: Ajouter un élément pour « %{libelle} »
|
|
@ -3,5 +3,5 @@
|
||||||
= render EditableChamp::RepetitionRowComponent.new(form: @form, champ: @champ, row: champs, seen_at: @seen_at)
|
= 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: 'fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-circle-line fr-mb-3w' do
|
= render NestedForms::OwnedButtonComponent.new(formaction: champs_repetition_path(@champ.id), http_method: :create, opt: { class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-circle-line fr-mb-3w", title: t(".add_title", libelle: @champ.libelle), id: dom_id(@champ, :create_repetition)}) do
|
||||||
Ajouter un élément pour « #{@champ.libelle} »
|
= t(".add", libelle: @champ.libelle)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
en:
|
||||||
|
delete: Destroy element
|
||||||
|
delete_title: "Destroy the n°%{row_number} element"
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
fr:
|
||||||
|
delete: Supprimer l’élément
|
||||||
|
delete_title: "Supprimer l’élément n°%{row_number}"
|
|
@ -5,5 +5,5 @@
|
||||||
= render EditableChamp::EditableChampComponent.new form: form, champ: champ, seen_at: @seen_at
|
= 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, row_id: @row.first.row_id), data: { turbo_method: :delete }, class: 'fr-btn fr-btn--sm fr-btn--tertiary fr-text-action-high--red-marianne' do
|
= render NestedForms::OwnedButtonComponent.new(formaction: champs_repetition_path(@champ.id, row_id: @row.first.row_id), http_method: :delete, opt: { class: "fr-btn fr-btn--sm fr-btn--tertiary fr-text-action-high--red-marianne", title: t(".delete_title", row_number: @champ.rows.find_index(@row))}) do
|
||||||
Supprimer l’élément
|
= t(".delete")
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
%fieldset.radios
|
%fieldset.radios
|
||||||
%label
|
%label{ for: @champ.yes_input_id }
|
||||||
= @form.radio_button :value, true
|
= @form.radio_button :value, true, id: @champ.yes_input_id
|
||||||
Oui
|
Oui
|
||||||
|
|
||||||
%label
|
%label{ for: @champ.no_input_id }
|
||||||
= @form.radio_button :value, false
|
= @form.radio_button :value, false, id: @champ.no_input_id
|
||||||
Non
|
Non
|
||||||
|
|
17
app/components/nested_forms/form_owner_component.rb
Normal file
17
app/components/nested_forms/form_owner_component.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# context: https://github.com/demarches-simplifiees/demarches-simplifiees.fr/issues/8661
|
||||||
|
# a11y: a post/delete/patch/put action must be wrapped in a <button>, not in an <a>
|
||||||
|
# but we can't nest <forms>
|
||||||
|
# this component exposes each http methods within a form, and can be used with OwnedButtonComponent
|
||||||
|
# background: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes
|
||||||
|
# see: from attribute & formaction
|
||||||
|
|
||||||
|
class NestedForms::FormOwnerComponent < ApplicationComponent
|
||||||
|
HTTP_METHODS = [:create, :delete]
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def self.form_id(http_method)
|
||||||
|
raise ArgumentError, "invalid http_method: #{http_method}. supported methods are: #{HTTP_METHOD.join(',')}" if !HTTP_METHODS.include?(http_method)
|
||||||
|
"unested-form-#{http_method}"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,2 @@
|
||||||
|
- HTTP_METHODS.map do |http_method|
|
||||||
|
= form_tag('/', method: http_method, data: { 'turbo-method': http_method, turbo: true }, id: NestedForms::FormOwnerComponent.form_id(http_method)) {}
|
13
app/components/nested_forms/owned_button_component.rb
Normal file
13
app/components/nested_forms/owned_button_component.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
class NestedForms::OwnedButtonComponent < ApplicationComponent
|
||||||
|
renders_one :button_label
|
||||||
|
|
||||||
|
def initialize(formaction:, http_method:, opt: {})
|
||||||
|
@formaction = formaction
|
||||||
|
@http_method = http_method
|
||||||
|
@opt = opt
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
button_tag(content, @opt.merge(formaction: @formaction, form: NestedForms::FormOwnerComponent.form_id(@http_method)))
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,8 +7,9 @@ class Champs::RepetitionController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove
|
def remove
|
||||||
champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
@champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
||||||
champ.champs.where(row_id: params[:row_id]).destroy_all
|
@champ.champs.where(row_id: params[:row_id]).destroy_all
|
||||||
|
@champ.reload
|
||||||
@row_id = params[:row_id]
|
@row_id = params[:row_id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -232,6 +232,10 @@ class Champ < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def focusable_input_id
|
||||||
|
input_id
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def html_id
|
def html_id
|
||||||
|
|
|
@ -26,4 +26,16 @@ class Champs::CiviliteChamp < Champ
|
||||||
def html_label?
|
def html_label?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def female_input_id
|
||||||
|
"#{input_id}-female"
|
||||||
|
end
|
||||||
|
|
||||||
|
def male_input_id
|
||||||
|
"#{input_id}-male"
|
||||||
|
end
|
||||||
|
|
||||||
|
def focusable_input_id
|
||||||
|
female_input_id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,4 +51,16 @@ class Champs::CnafChamp < Champs::TextChamp
|
||||||
{ code_postal: code_postal, numero_allocataire: numero_allocataire }.to_json
|
{ code_postal: code_postal, numero_allocataire: numero_allocataire }.to_json
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def numero_allocataire_input_id
|
||||||
|
"#{input_id}-numero_alocataire"
|
||||||
|
end
|
||||||
|
|
||||||
|
def code_postal_input_id
|
||||||
|
"#{input_id}-code_postal"
|
||||||
|
end
|
||||||
|
|
||||||
|
def focusable_input_id
|
||||||
|
numero_allocataire_input_id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,4 +51,16 @@ class Champs::DgfipChamp < Champs::TextChamp
|
||||||
{ reference_avis: reference_avis, numero_fiscal: numero_fiscal }.to_json
|
{ reference_avis: reference_avis, numero_fiscal: numero_fiscal }.to_json
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def numero_fiscal_input_id
|
||||||
|
"#{input_id}-numero_fiscal"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reference_avis_input_id
|
||||||
|
"#{input_id}-reference_avis"
|
||||||
|
end
|
||||||
|
|
||||||
|
def focusable_input_id
|
||||||
|
numero_fiscal_input_id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -70,6 +70,18 @@ class Champs::EpciChamp < Champs::TextChamp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def code_departement_input_id
|
||||||
|
"#{input_id}-code_departement"
|
||||||
|
end
|
||||||
|
|
||||||
|
def epci_input_id
|
||||||
|
"#{input_id}-epci"
|
||||||
|
end
|
||||||
|
|
||||||
|
def focusable_input_id
|
||||||
|
code_departement_input_id
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def on_departement_change
|
def on_departement_change
|
||||||
|
|
|
@ -79,6 +79,14 @@ class Champs::MultipleDropDownListChamp < Champ
|
||||||
update_column(:value, (selected_options - options).to_json)
|
update_column(:value, (selected_options - options).to_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def focusable_input_id
|
||||||
|
render_as_checkboxes? ? checkbox_id(options.find(&:present?)) : input_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def checkbox_id(value)
|
||||||
|
"#{input_id}-#{value.parameterize}"
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def format_before_save
|
def format_before_save
|
||||||
|
|
|
@ -21,4 +21,15 @@
|
||||||
# type_de_champ_id :integer
|
# type_de_champ_id :integer
|
||||||
#
|
#
|
||||||
class Champs::YesNoChamp < Champs::BooleanChamp
|
class Champs::YesNoChamp < Champs::BooleanChamp
|
||||||
|
def yes_input_id
|
||||||
|
"#{input_id}-yes"
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_input_id
|
||||||
|
"#{input_id}-no"
|
||||||
|
end
|
||||||
|
|
||||||
|
def focusable_input_id
|
||||||
|
yes_input_id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
.procedure-form#attestation-template-edit
|
.procedure-form#attestation-template-edit
|
||||||
.procedure-form__columns.container
|
.procedure-form__columns.container
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= form_for @attestation_template,
|
= form_for @attestation_template,
|
||||||
url: admin_procedure_attestation_template_path(@procedure),
|
url: admin_procedure_attestation_template_path(@procedure),
|
||||||
html: { multipart: true, class: 'form form-ds-fr-white procedure-form__column--form' } do |f|
|
html: { multipart: true, class: 'form form-ds-fr-white procedure-form__column--form' } do |f|
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
.container
|
.container
|
||||||
%h1 Configuration des annotations privées
|
%h1 Configuration des annotations privées
|
||||||
%br
|
%br
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= render TypesDeChampEditor::EditorComponent.new(revision: @procedure.draft_revision, is_annotation: true)
|
= render TypesDeChampEditor::EditorComponent.new(revision: @procedure.draft_revision, is_annotation: true)
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
.container
|
.container
|
||||||
%h1 Configuration des champs
|
%h1 Configuration des champs
|
||||||
%br
|
%br
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= render TypesDeChampEditor::EditorComponent.new(revision: @procedure.draft_revision)
|
= render TypesDeChampEditor::EditorComponent.new(revision: @procedure.draft_revision)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
['Description']] }
|
['Description']] }
|
||||||
.procedure-form
|
.procedure-form
|
||||||
.procedure-form__columns.container
|
.procedure-form__columns.container
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= form_for @procedure,
|
= form_for @procedure,
|
||||||
url: url_for({ controller: 'administrateurs/procedures', action: :update, id: @procedure.id }),
|
url: url_for({ controller: 'administrateurs/procedures', action: :update, id: @procedure.id }),
|
||||||
html: { class: 'form procedure-form__column--form',
|
html: { class: 'form procedure-form__column--form',
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
.procedure-form
|
.procedure-form
|
||||||
.procedure-form__columns.container
|
.procedure-form__columns.container
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= form_for @procedure,
|
= form_for @procedure,
|
||||||
url: url_for({ controller: 'administrateurs/procedures', action: :create, id: @procedure.id }),
|
url: url_for({ controller: 'administrateurs/procedures', action: :create, id: @procedure.id }),
|
||||||
html: { class: 'form procedure-form__column--form', multipart: true } do |f|
|
html: { class: 'form procedure-form__column--form', multipart: true } do |f|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
- if @champs.present?
|
- if @champs.present?
|
||||||
= fields_for @champ.input_name, @champ do |form|
|
= fields_for @champ.input_name, @champ do |form|
|
||||||
= turbo_stream.append dom_id(@champ, :rows), render(EditableChamp::RepetitionRowComponent.new(form: form, champ: @champ, row: @champs))
|
= turbo_stream.append dom_id(@champ, :rows), render(EditableChamp::RepetitionRowComponent.new(form: form, champ: @champ, row: @champs))
|
||||||
|
- first_champ_id = @champs.map(&:focusable_input_id).compact.first
|
||||||
|
- if first_champ_id
|
||||||
|
= turbo_stream.focus(first_champ_id)
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
= turbo_stream.remove "safe-row-selector-#{@row_id}"
|
= turbo_stream.remove "safe-row-selector-#{@row_id}"
|
||||||
|
|
||||||
|
- if @champ.rows.size > 0 && @champ.rows.last&.first&.present?
|
||||||
|
= turbo_stream.focus @champ.rows.last&.first.focusable_input_id
|
||||||
|
- else
|
||||||
|
= turbo_stream.focus dom_id(@champ, :create_repetition)
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
- if @avis.introduction_file.attached?
|
- if @avis.introduction_file.attached?
|
||||||
= render Attachment::ShowComponent.new(attachment: @avis.introduction_file.attachment)
|
= render Attachment::ShowComponent.new(attachment: @avis.introduction_file.attachment)
|
||||||
|
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= form_for @avis, url: expert_avis_path(@avis.procedure, @avis), html: { data: { controller: 'persisted-form', persisted_form_key_value: dom_id(@avis) }, multipart: true } do |f|
|
= form_for @avis, url: expert_avis_path(@avis.procedure, @avis), html: { data: { controller: 'persisted-form', persisted_form_key_value: dom_id(@avis) }, multipart: true } do |f|
|
||||||
|
|
||||||
- if @avis.question_label.present?
|
- if @avis.question_label.present?
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
%p#avis-emails-description.avis-notice
|
%p#avis-emails-description.avis-notice
|
||||||
Entrez les adresses email des experts à qui vous souhaitez demander un avis
|
Entrez les adresses email des experts à qui vous souhaitez demander un avis
|
||||||
|
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= form_for avis, url: url, html: { multipart: true, data: { controller: 'persisted-form', persisted_form_key_value: dom_id(@dossier, :avis_by_instructeur) } } do |f|
|
= form_for avis, url: url, html: { multipart: true, data: { controller: 'persisted-form', persisted_form_key_value: dom_id(@dossier, :avis_by_instructeur) } } do |f|
|
||||||
= hidden_field_tag 'avis[emails]', nil
|
= hidden_field_tag 'avis[emails]', nil
|
||||||
.fr-input-group
|
.fr-input-group
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
- form_options = { url: brouillon_dossier_url(dossier), method: :patch }
|
- form_options = { url: brouillon_dossier_url(dossier), method: :patch }
|
||||||
- else
|
- else
|
||||||
- form_options = { url: modifier_dossier_url(dossier), method: :patch }
|
- form_options = { url: modifier_dossier_url(dossier), method: :patch }
|
||||||
= render Attachment::DeleteFormComponent.new
|
= 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, form_options.merge({ html: { id: 'dossier-edit-form', class: 'form', multipart: true, novalidate: 'novalidate' } }) do |f|
|
||||||
|
|
||||||
%header.mb-6
|
%header.mb-6
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.container.dossier-edit
|
.container.dossier-edit
|
||||||
- if dossier.champs_private.present?
|
- if dossier.champs_private.present?
|
||||||
%section.counter-start-header-section
|
%section.counter-start-header-section
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= 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|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= render Attachment::DeleteFormComponent.new
|
= render NestedForms::FormOwnerComponent.new
|
||||||
= form_for(commentaire, url: form_url, html: { class: 'form', multipart: true, data: { controller: 'persisted-form', persisted_form_key_value: @dossier.present? ? dom_id(@dossier) : dom_id(@procedure, :bulk_message) } }) do |f|
|
= form_for(commentaire, url: form_url, html: { class: 'form', multipart: true, data: { controller: 'persisted-form', persisted_form_key_value: @dossier.present? ? dom_id(@dossier) : dom_id(@procedure, :bulk_message) } }) do |f|
|
||||||
- dossier = commentaire.dossier
|
- dossier = commentaire.dossier
|
||||||
- placeholder = t('views.shared.dossiers.messages.form.write_message_to_administration_placeholder')
|
- placeholder = t('views.shared.dossiers.messages.form.write_message_to_administration_placeholder')
|
||||||
|
|
|
@ -23,7 +23,8 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do
|
||||||
expect(page).to have_css('label', text: type_de_champ_multiple_drop_down_list.libelle)
|
expect(page).to have_css('label', text: type_de_champ_multiple_drop_down_list.libelle)
|
||||||
expect(page).to have_content(multiple_drop_down_list_values.first)
|
expect(page).to have_content(multiple_drop_down_list_values.first)
|
||||||
expect(page).to have_content(multiple_drop_down_list_values.last)
|
expect(page).to have_content(multiple_drop_down_list_values.last)
|
||||||
expect(page).to have_field(type_de_champ_epci.libelle, with: epci_value.last)
|
expect(page).to have_field("Le département de l’EPCI", with: epci_value.first)
|
||||||
|
expect(page).to have_selector("option[value='#{epci_value.last}'][selected]")
|
||||||
expect(page).to have_field(type_de_champ_dossier_link.libelle, with: dossier_link_value)
|
expect(page).to have_field(type_de_champ_dossier_link.libelle, with: dossier_link_value)
|
||||||
expect(page).to have_field(commune_libelle, with: '01457')
|
expect(page).to have_field(commune_libelle, with: '01457')
|
||||||
expect(page).to have_content(annuaire_education_value.last)
|
expect(page).to have_content(annuaire_education_value.last)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue