diff --git a/app/components/attachment/delete_form_component.rb b/app/components/attachment/delete_form_component.rb deleted file mode 100644 index 2be43262e..000000000 --- a/app/components/attachment/delete_form_component.rb +++ /dev/null @@ -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 diff --git a/app/components/attachment/edit_component/edit_component.html.haml b/app/components/attachment/edit_component/edit_component.html.haml index ea1fd3261..2d81e9506 100644 --- a/app/components/attachment/edit_component/edit_component.html.haml +++ b/app/components/attachment/edit_component/edit_component.html.haml @@ -3,7 +3,7 @@ %div{ id: dom_id(attachment, :persisted_row) } .flex.flex-gap-2{ class: class_names("attachment-error": attachment.virus_scanner_error?) } - 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') - 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) diff --git a/app/components/editable_champ/civilite_component/civilite_component.html.haml b/app/components/editable_champ/civilite_component/civilite_component.html.haml index 321ff7c99..5959e45ca 100644 --- a/app/components/editable_champ/civilite_component/civilite_component.html.haml +++ b/app/components/editable_champ/civilite_component/civilite_component.html.haml @@ -2,9 +2,9 @@ %legend.mandatory-explanation Sélectionnez une des valeurs %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') %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') diff --git a/app/components/editable_champ/cnaf_component/cnaf_component.html.haml b/app/components/editable_champ/cnaf_component/cnaf_component.html.haml index 77c02b4d2..4eeb80fef 100644 --- a/app/components/editable_champ/cnaf_component/cnaf_component.html.haml +++ b/app/components/editable_champ/cnaf_component/cnaf_component.html.haml @@ -1,16 +1,18 @@ .cnaf-inputs %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') = @form.text_field :numero_allocataire, required: @champ.required?, aria: { describedby: @champ.describedby_id }, - class: "width-33-desktop" + class: "width-33-desktop", id: @champ.numero_allocataire_input_id %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') = @form.text_field :code_postal, required: @champ.required?, aria: { describedby: @champ.describedby_id }, - class: "width-33-desktop" + class: "width-33-desktop", + id: @champ.code_postal_input_id + diff --git a/app/components/editable_champ/dgfip_component/dgfip_component.html.haml b/app/components/editable_champ/dgfip_component/dgfip_component.html.haml index c5f5e08de..5399c5b6a 100644 --- a/app/components/editable_champ/dgfip_component/dgfip_component.html.haml +++ b/app/components/editable_champ/dgfip_component/dgfip_component.html.haml @@ -1,16 +1,16 @@ .dgfip-inputs %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') = @form.text_field :numero_fiscal, required: @champ.required?, aria: { describedby: @champ.describedby_id }, - class: "width-33-desktop" + class: "width-33-desktop", id: @champ.numero_fiscal_input_id %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') = @form.text_field :reference_avis, required: @champ.required?, aria: { describedby: @champ.describedby_id }, - class: "width-33-desktop" + class: "width-33-desktop", id: @champ.reference_avis_input_id diff --git a/app/components/editable_champ/epci_component.rb b/app/components/editable_champ/epci_component.rb index 37aeaea80..a511b6330 100644 --- a/app/components/editable_champ/epci_component.rb +++ b/app/components/editable_champ/epci_component.rb @@ -15,10 +15,6 @@ class EditableChamp::EpciComponent < EditableChamp::EditableChampBaseComponent end end - def departement_input_id - "#{@champ.input_id}-departement" - end - def departement_select_options { selected: @champ.code_departement }.merge(@champ.mandatory? ? { prompt: '' } : { include_blank: '' }) end diff --git a/app/components/editable_champ/epci_component/epci_component.html.haml b/app/components/editable_champ/epci_component/epci_component.html.haml index 85138d2fd..432ff72be 100644 --- a/app/components/editable_champ/epci_component/epci_component.html.haml +++ b/app/components/editable_champ/epci_component/epci_component.html.haml @@ -1,4 +1,5 @@ -%label.notice{ for: 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" +%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: @champ.code_departement_input_id, class: "width-33-desktop width-100-mobile" - 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" diff --git a/app/components/editable_champ/mesri_component/mesri_component.html.haml b/app/components/editable_champ/mesri_component/mesri_component.html.haml index b0ac7ee2e..173fe57f4 100644 --- a/app/components/editable_champ/mesri_component/mesri_component.html.haml +++ b/app/components/editable_champ/mesri_component/mesri_component.html.haml @@ -1,9 +1,9 @@ .mesri-inputs %div - = @form.label :ine, t('.ine_label') + = @form.label :ine, t('.ine_label'), for: @champ.input_id %p.notice= t('.ine_notice') = @form.text_field :ine, required: @champ.required?, aria: { describedby: @champ.describedby_id }, - class: "width-33-desktop" + class: "width-33-desktop", id: @champ.input_id diff --git a/app/components/editable_champ/multiple_drop_down_list_component/multiple_drop_down_list_component.html.haml b/app/components/editable_champ/multiple_drop_down_list_component/multiple_drop_down_list_component.html.haml index d088fb045..276ee8c47 100644 --- a/app/components/editable_champ/multiple_drop_down_list_component/multiple_drop_down_list_component.html.haml +++ b/app/components/editable_champ/multiple_drop_down_list_component/multiple_drop_down_list_component.html.haml @@ -2,8 +2,8 @@ - if @champ.render_as_checkboxes? = @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 - - b.label do - - b.check_box({ multiple: true, checked: @champ&.selected_options&.include?(b.value), aria: { describedby: @champ.describedby_id } }) + b.text + - 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 }, id: @champ.checkbox_id(b.value) }) + b.text - else = @form.hidden_field :value = react_component("ComboMultipleDropdownList", diff --git a/app/components/editable_champ/pole_emploi_component/pole_emploi_component.html.haml b/app/components/editable_champ/pole_emploi_component/pole_emploi_component.html.haml index 20bf0994f..b46bee8bc 100644 --- a/app/components/editable_champ/pole_emploi_component/pole_emploi_component.html.haml +++ b/app/components/editable_champ/pole_emploi_component/pole_emploi_component.html.haml @@ -1,8 +1,8 @@ .pole-emploi-inputs %div - = @form.label :identifiant, t('.identifiant_label') + = @form.label :identifiant, t('.identifiant_label'), for: @champ.input_id %p.notice= t('.identifiant_notice') = @form.text_field :identifiant, required: @champ.required?, aria: { describedby: @champ.describedby_id }, - class: "width-33-desktop" + class: "width-33-desktop", id: @champ.input_id diff --git a/app/components/editable_champ/repetition_component/repetition_component.en.yml b/app/components/editable_champ/repetition_component/repetition_component.en.yml new file mode 100644 index 000000000..b2ac2f0fa --- /dev/null +++ b/app/components/editable_champ/repetition_component/repetition_component.en.yml @@ -0,0 +1,4 @@ +--- +en: + add: "Add an element to « %{libelle} »" + add_title: "Add an element to « %{libelle} »" diff --git a/app/components/editable_champ/repetition_component/repetition_component.fr.yml b/app/components/editable_champ/repetition_component/repetition_component.fr.yml new file mode 100644 index 000000000..f4152793e --- /dev/null +++ b/app/components/editable_champ/repetition_component/repetition_component.fr.yml @@ -0,0 +1,4 @@ +--- +fr: + add: "Ajouter un élément pour « %{libelle} »" + add_title: Ajouter un élément pour « %{libelle} » diff --git a/app/components/editable_champ/repetition_component/repetition_component.html.haml b/app/components/editable_champ/repetition_component/repetition_component.html.haml index 572eee90c..1bcbe91a3 100644 --- a/app/components/editable_champ/repetition_component/repetition_component.html.haml +++ b/app/components/editable_champ/repetition_component/repetition_component.html.haml @@ -3,5 +3,5 @@ = render EditableChamp::RepetitionRowComponent.new(form: @form, champ: @champ, row: champs, seen_at: @seen_at) .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 - Ajouter un élément pour « #{@champ.libelle} » + = 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 + = t(".add", libelle: @champ.libelle) diff --git a/app/components/editable_champ/repetition_row_component/repetition_row_component.en.yml b/app/components/editable_champ/repetition_row_component/repetition_row_component.en.yml new file mode 100644 index 000000000..92be3099b --- /dev/null +++ b/app/components/editable_champ/repetition_row_component/repetition_row_component.en.yml @@ -0,0 +1,4 @@ +--- +en: + delete: Destroy element + delete_title: "Destroy the n°%{row_number} element" diff --git a/app/components/editable_champ/repetition_row_component/repetition_row_component.fr.yml b/app/components/editable_champ/repetition_row_component/repetition_row_component.fr.yml new file mode 100644 index 000000000..bfcf389c9 --- /dev/null +++ b/app/components/editable_champ/repetition_row_component/repetition_row_component.fr.yml @@ -0,0 +1,4 @@ +--- +fr: + delete: Supprimer l’élément + delete_title: "Supprimer l’élément n°%{row_number}" diff --git a/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml b/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml index 02b0bb3ce..c83cdadaa 100644 --- a/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml +++ b/app/components/editable_champ/repetition_row_component/repetition_row_component.html.haml @@ -5,5 +5,5 @@ = render EditableChamp::EditableChampComponent.new form: form, champ: champ, seen_at: @seen_at .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 - Supprimer l’élément + = 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 + = t(".delete") diff --git a/app/components/editable_champ/yes_no_component/yes_no_component.html.haml b/app/components/editable_champ/yes_no_component/yes_no_component.html.haml index 9fbd8d857..8bb26b90c 100644 --- a/app/components/editable_champ/yes_no_component/yes_no_component.html.haml +++ b/app/components/editable_champ/yes_no_component/yes_no_component.html.haml @@ -1,8 +1,8 @@ %fieldset.radios - %label - = @form.radio_button :value, true + %label{ for: @champ.yes_input_id } + = @form.radio_button :value, true, id: @champ.yes_input_id Oui - %label - = @form.radio_button :value, false + %label{ for: @champ.no_input_id } + = @form.radio_button :value, false, id: @champ.no_input_id Non diff --git a/app/components/nested_forms/form_owner_component.rb b/app/components/nested_forms/form_owner_component.rb new file mode 100644 index 000000000..ddd125e88 --- /dev/null +++ b/app/components/nested_forms/form_owner_component.rb @@ -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