diff --git a/app/assets/stylesheets/dossier_edit.scss b/app/assets/stylesheets/dossier_edit.scss index ca32e9e2be1..0d15e692aab 100644 --- a/app/assets/stylesheets/dossier_edit.scss +++ b/app/assets/stylesheets/dossier_edit.scss @@ -42,11 +42,6 @@ $dossier-actions-bar-border-width: 1px; } } - .characters-count { - position: relative; - top: -1rem; - } - .warning { margin-bottom: 20px; background-color: #f9b91666; diff --git a/app/assets/stylesheets/forms.scss b/app/assets/stylesheets/forms.scss index 274679c691c..0f8bec5c329 100644 --- a/app/assets/stylesheets/forms.scss +++ b/app/assets/stylesheets/forms.scss @@ -166,15 +166,16 @@ font-weight: normal; } } - - input[type=text], - input[type=email], + .fr-label { + // la description d'un champ peut contenir du markup (markdown->html), + // on herite donc la fontsize/mrgin/padding du fr-hint-text + .fr-hint-text > *{ + font-size: inherit; + margin: inherit; + padding: inherit; + } + } input[type=password], - input[type=date], - input[type=datetime-local], - input[type=number], - input[type=tel], - textarea, select { display: block; margin-bottom: $default-fields-spacer; @@ -201,13 +202,6 @@ } input[type=text]:not([data-address='true']), - input[type=email], - input[type=password], - input[type=date], - input[type=number], - input[type=tel], - input[type=datetime-local], - textarea, select { border-radius: 4px; border: solid 1px $border-grey; @@ -249,8 +243,8 @@ input[type=date], input[type=number], input[type=datetime-local], - input[type=tel], - textarea { + textarea, + input[type=tel], { @media (max-width: $two-columns-breakpoint) { width: 100%; } @@ -426,16 +420,6 @@ color: $dark-grey; } - .datetime { - input[type=date] { - display: inline-block; - } - - select { - display: inline-block; - } - } - .header-subsection { font-size: 22px; color: $blue-france-500; @@ -458,20 +442,6 @@ } } - .siret-info { - margin-top: -$default-fields-spacer; - margin-bottom: $default-fields-spacer; - // Ensure the bottom-margin is not collapsed when the element is empty - min-height: 1px; - } - - .rna-info { - margin-top: -$default-fields-spacer; - margin-bottom: $default-fields-spacer; - // Ensure the bottom-margin is not collapsed when the element is empty - min-height: 1px; - } - .send-wrapper { display: flex; width: 100%; diff --git a/app/components/dsfr/input_component.rb b/app/components/dsfr/input_component.rb index 2717624701f..2898377eda3 100644 --- a/app/components/dsfr/input_component.rb +++ b/app/components/dsfr/input_component.rb @@ -1,4 +1,6 @@ class Dsfr::InputComponent < ApplicationComponent + include Dsfr::InputErrorable + delegate :object, to: :@form delegate :errors, to: :object @@ -18,10 +20,10 @@ def initialize(form:, attribute:, input_type: :text_field, opts: {}, required: t # and and valid on input only if another input is invalid def input_group_opts opts = { - class: class_names('fr-input-group': true, - 'fr-password': password?, - "fr-input-group--error": errors_on_attribute?, - "fr-input-group--valid": !errors_on_attribute? && errors_on_another_attribute?) + class: class_names({ + 'fr-input-group': true, + 'fr-password': password? + }.merge(input_group_error_class_names)) } if email? opts[:data] = { controller: 'email-input' } @@ -33,38 +35,7 @@ def label_opts { class: class_names('fr-label': true, 'fr-password__label': password?) } end - def input_opts - @opts[:class] = class_names(map_array_to_hash_with_true(@opts[:class]) - .merge('fr-password__input': password?, - 'fr-input': true, - 'fr-mb-0': true, - 'fr-input--error': errors_on_attribute?)) - - if errors_on_attribute? || describedby? - @opts.deep_merge!(aria: { - describedby: describedby_id, - invalid: errors_on_attribute? - }) - end - - if @required - @opts[:required] = true - end - - if email? - @opts.deep_merge!(data: { - action: "blur->email-input#checkEmail", - 'email-input-target': 'input' - }) - end - @opts - end - # errors helpers - def errors_on_attribute? - errors.has_key?(attribute_or_rich_body) - end - def error_messages errors.full_messages_for(attribute_or_rich_body) end @@ -78,9 +49,6 @@ def label object.class.human_attribute_name(@attribute) end - def hint - I18n.t("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}") - end # kind of input helpers def password? @@ -97,26 +65,5 @@ def show_password_id private - def hint? - I18n.exists?("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}") - end - - def errors_on_another_attribute? - !errors.empty? - end - # lookup for edge case from `form.rich_text_area` - # rich text uses _rich_#{attribute}, but it is saved on #{attribute}, as well as error messages - def attribute_or_rich_body - case @input_type - when :rich_text_area - @attribute.to_s.sub(/\Arich_/, '').to_sym - else - @attribute - end - end - - def map_array_to_hash_with_true(array_or_string_or_nil) - Array(array_or_string_or_nil).to_h { [_1, true] } - end end diff --git a/app/components/dsfr/input_errorable.rb b/app/components/dsfr/input_errorable.rb new file mode 100644 index 00000000000..024d5e8adb4 --- /dev/null +++ b/app/components/dsfr/input_errorable.rb @@ -0,0 +1,106 @@ +module Dsfr + module InputErrorable + extend ActiveSupport::Concern + included do + delegate :object, to: :@form + delegate :errors, to: :object + + # lookup for edge case from `form.rich_text_area` + # rich text uses _rich_#{attribute}, but it is saved on #{attribute}, as well as error messages + def attribute_or_rich_body + case @input_type + when :rich_text_area + @attribute.to_s.sub(/\Arich_/, '').to_sym + else + @attribute + end + end + + def input_group_error_class_names + { + "fr-input-group--error": errors_on_attribute?, + "fr-input-group--valid": !errors_on_attribute? && errors_on_another_attribute? + } + end + + def input_error_class_names + { 'fr-input--error': errors_on_attribute? } + end + + def input_error_opts + { + aria: { + describedby: describedby_id, + invalid: errors_on_attribute? + } + } + end + + def input_opts(other_opts = {}) + @opts = @opts.deep_merge!(other_opts) + @opts[:class] = class_names(map_array_to_hash_with_true(@opts[:class]) + .merge({ + 'fr-password__input': password?, + 'fr-input': true, + 'fr-mb-0': true + }.merge(input_error_class_names))) + + if errors_on_attribute? + @opts.deep_merge!(aria: { + describedby: describedby_id, + invalid: errors_on_attribute? + }) + end + + if @required + @opts[:required] = true + end + + if email? + @opts.deep_merge!(data: { + action: "blur->email-input#checkEmail", + 'email-input-target': 'input' + }) + end + @opts + end + + def describedby_id + dom_id(@champ, :error_messages) + end + + def errors_on_another_attribute? + !errors.empty? + end + + def errors_on_attribute? + errors.has_key?(attribute_or_rich_body) + end + + # errors helpers + def error_messages + errors.full_messages_for(attribute_or_rich_body) + end + + def map_array_to_hash_with_true(array_or_string_or_nil) + Array(array_or_string_or_nil).to_h { [_1, true] } + end + + def hint + I18n.t("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}") + end + + def password? + false + end + + def email? + false + end + + def hint? + I18n.exists?("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}") + end + end + end +end diff --git a/app/components/editable_champ/champ_label_component.rb b/app/components/editable_champ/champ_label_component.rb index de0a6fea30b..967a95584d0 100644 --- a/app/components/editable_champ/champ_label_component.rb +++ b/app/components/editable_champ/champ_label_component.rb @@ -1,5 +1,8 @@ class EditableChamp::ChampLabelComponent < ApplicationComponent + include Dsfr::InputErrorable + def initialize(form:, champ:, seen_at: nil) @form, @champ, @seen_at = form, champ, seen_at + @attribute = :value end end diff --git a/app/components/editable_champ/champ_label_component/champ_label_component.html.haml b/app/components/editable_champ/champ_label_component/champ_label_component.html.haml index d860df31405..eda623420cc 100644 --- a/app/components/editable_champ/champ_label_component/champ_label_component.html.haml +++ b/app/components/editable_champ/champ_label_component/champ_label_component.html.haml @@ -1,10 +1,9 @@ = # 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 EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at + = @form.label @champ.main_value_name, id: @champ.labelledby_id, for: @champ.input_id, class: 'fr-label' do + - render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at - else - .form-label.mb-4{ id: @champ.labelledby_id } - = render EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at + .fr-label.mb-4{ id: @champ.labelledby_id } + = render EditableChamp::ChampLabelContentComponent.new form: @form, champ: @champ, seen_at: @seen_at + -- if @champ.description.present? - .notice{ id: @champ.describedby_id }= render SimpleFormatComponent.new(@champ.description, allow_a: true) diff --git a/app/components/editable_champ/champ_label_content_component.rb b/app/components/editable_champ/champ_label_content_component.rb index 60025939e67..21069fe98f0 100644 --- a/app/components/editable_champ/champ_label_content_component.rb +++ b/app/components/editable_champ/champ_label_content_component.rb @@ -1,8 +1,10 @@ class EditableChamp::ChampLabelContentComponent < ApplicationComponent include ApplicationHelper + include Dsfr::InputErrorable - def initialize(champ:, seen_at: nil) - @champ, @seen_at = champ, seen_at + def initialize(form:, champ:, seen_at: nil) + @form, @champ, @seen_at = form, champ, seen_at + @attribute = :value end def highlight_if_unseen_class diff --git a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.en.yml b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.en.yml index 9d642dd7263..fbbc60b2e67 100644 --- a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.en.yml +++ b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.en.yml @@ -4,3 +4,5 @@ en: modified_at: "modified on %{datetime}" check_content_rebased: The type of this field or its description has been modified by the administration. Check its content. optional_champ: (optional) + recommended_size: The recommended maximum size is %{size} characters. + titre_identite_notice: National identity card (front side only), passport, residency permit or other proof of identity. diff --git a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.fr.yml b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.fr.yml index 0201f614036..d129bfa1edc 100644 --- a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.fr.yml +++ b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.fr.yml @@ -4,3 +4,5 @@ fr: modified_at: "modifié le %{datetime}" check_content_rebased: Le type de ce champ ou sa description ont été modifiés par l'administration. Vérifier son contenu. optional_champ: (facultatif) + recommended_size: La taille maximale conseillée est de %{size} caractères. + titre_identite_notice: Carte nationale d’identité (uniquement le recto), passeport, titre de séjour ou autre justificatif d’identité. diff --git a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml index d5a578b42ec..42732e3279b 100644 --- a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml +++ b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml @@ -16,3 +16,15 @@ - if @champ.rebased_at.present? && @champ.rebased_at > (@seen_at || @champ.updated_at) && current_user.owns_or_invite?(@champ.dossier) %span.updated-at.highlighted = t('.check_content_rebased') + +- if @champ.titre_identite? + %span.fr-hint-text= t('.titre_identite_notice') + +- if hint? + %span.fr-hint-text= hint + +- if @champ.description.present? + %span.fr-hint-text{ id: @champ.describedby_id }= render SimpleFormatComponent.new(@champ.description, allow_a: true) + +- if @champ.textarea? + %span.sr-only= t('.recommended_size', size: @champ.character_limit_base) diff --git a/app/components/editable_champ/date_component/date_component.html.haml b/app/components/editable_champ/date_component/date_component.html.haml index 4e91abc009d..e6d6b332ce2 100644 --- a/app/components/editable_champ/date_component/date_component.html.haml +++ b/app/components/editable_champ/date_component/date_component.html.haml @@ -1,7 +1,6 @@ = @form.date_field :value, - id: @champ.input_id, + input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, value: @champ.value, required: @champ.required?, - placeholder: 'aaaa-mm-jj', - class: "width-33-desktop" + placeholder: 'aaaa-mm-jj', class: "width-33-desktop") diff --git a/app/components/editable_champ/datetime_component/datetime_component.html.haml b/app/components/editable_champ/datetime_component/datetime_component.html.haml index 5f0b4dab718..9b6931e72b6 100644 --- a/app/components/editable_champ/datetime_component/datetime_component.html.haml +++ b/app/components/editable_champ/datetime_component/datetime_component.html.haml @@ -1,2 +1 @@ -.datetime - = @form.datetime_field(:value, value: formatted_value_for_datetime_locale, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, data: { controller: 'datetime' }) += @form.datetime_field(:value, input_opts(value: formatted_value_for_datetime_locale, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, data: { controller: 'datetime' })) diff --git a/app/components/editable_champ/decimal_number_component/decimal_number_component.html.haml b/app/components/editable_champ/decimal_number_component/decimal_number_component.html.haml index f0cd272a5cd..0c9c6c0d70c 100644 --- a/app/components/editable_champ/decimal_number_component/decimal_number_component.html.haml +++ b/app/components/editable_champ/decimal_number_component/decimal_number_component.html.haml @@ -1,6 +1 @@ -= @form.number_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - step: :any, - placeholder: "3.14", - required: @champ.required? += @form.number_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, step: :any, placeholder: "3.14", required: @champ.required?)) diff --git a/app/components/editable_champ/dossier_link_component/dossier_link_component.html.haml b/app/components/editable_champ/dossier_link_component/dossier_link_component.html.haml index 3e4169f40a8..2db3bd8057c 100644 --- a/app/components/editable_champ/dossier_link_component/dossier_link_component.html.haml +++ b/app/components/editable_champ/dossier_link_component/dossier_link_component.html.haml @@ -1,18 +1,8 @@ -.dossier-link - = @form.text_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - inputmode: :numeric, - min: 1, - pattern: "[0-9]{1,12}", - placeholder: "Numéro de dossier", - autocomplete: 'off', - required: @champ.required?, - class: "width-33-desktop #{@champ.blank? ? '' : 'small-margin'}" += @form.text_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, inputmode: :numeric, min: 1, pattern: "[0-9]{1,12}", placeholder: "Numéro de dossier", autocomplete: 'off', required: @champ.required?, class: "width-33-desktop #{@champ.blank? ? '' : 'small-margin'}")) - - if !@champ.blank? - - if dossier.blank? - .fr-error-text.fr-mb-4w - = t('.not_found') - - else - .fr-info-text.fr-mb-4w= sanitize(dossier.text_summary) +- if !@champ.blank? + - if dossier.blank? + .fr-error-text.fr-mb-4w + = t('.not_found') + - else + .fr-info-text.fr-mb-4w= sanitize(dossier.text_summary) diff --git a/app/components/editable_champ/editable_champ_base_component.rb b/app/components/editable_champ/editable_champ_base_component.rb index 08408a95cff..21b0d49d4ad 100644 --- a/app/components/editable_champ/editable_champ_base_component.rb +++ b/app/components/editable_champ/editable_champ_base_component.rb @@ -1,5 +1,8 @@ class EditableChamp::EditableChampBaseComponent < ApplicationComponent - def initialize(form:, champ:, seen_at: nil) - @form, @champ, @seen_at = form, champ, seen_at + include Dsfr::InputErrorable + + def initialize(form:, champ:, seen_at: nil, opts: {}) + @form, @champ, @seen_at, @opts = form, champ, seen_at, opts + @attribute = :value end end diff --git a/app/components/editable_champ/editable_champ_component.rb b/app/components/editable_champ/editable_champ_component.rb index f2051df8a7f..c12ae9a7a8c 100644 --- a/app/components/editable_champ/editable_champ_component.rb +++ b/app/components/editable_champ/editable_champ_component.rb @@ -1,6 +1,9 @@ class EditableChamp::EditableChampComponent < ApplicationComponent + include Dsfr::InputErrorable + def initialize(form:, champ:, seen_at: nil) @form, @champ, @seen_at = form, champ, seen_at + @attribute = :value end private @@ -21,8 +24,12 @@ def component_class def html_options { class: class_names( - "editable-champ-#{@champ.type_champ}": true, - "hidden": !@champ.visible? + { + 'editable-champ': true, + "editable-champ-#{@champ.type_champ}": true, + "hidden": !@champ.visible?, + "fr-input-group": true, + }.merge(input_group_error_class_names) ), id: @champ.input_group_id, data: { controller: stimulus_controller, **data_dependent_conditions } diff --git a/app/components/editable_champ/editable_champ_component/editable_champ_component.en.yml b/app/components/editable_champ/editable_champ_component/editable_champ_component.en.yml index 48cb6286e8b..e944e6ca508 100644 --- a/app/components/editable_champ/editable_champ_component/editable_champ_component.en.yml +++ b/app/components/editable_champ/editable_champ_component/editable_champ_component.en.yml @@ -1,4 +1,4 @@ --- en: titre_identite_notice: National identity card (front side only), passport, residency permit or other proof of identity. - datetime_notice: "Expected format : dd/mm/yyyy hh:mm" + diff --git a/app/components/editable_champ/editable_champ_component/editable_champ_component.fr.yml b/app/components/editable_champ/editable_champ_component/editable_champ_component.fr.yml index c7e4f5d7e30..dc1731448ad 100644 --- a/app/components/editable_champ/editable_champ_component/editable_champ_component.fr.yml +++ b/app/components/editable_champ/editable_champ_component/editable_champ_component.fr.yml @@ -1,4 +1,3 @@ --- fr: titre_identite_notice: Carte nationale d’identité (uniquement le recto), passeport, titre de séjour ou autre justificatif d’identité. - datetime_notice: "Format attendu : jj/mm/aaaa hh:mm" diff --git a/app/components/editable_champ/editable_champ_component/editable_champ_component.html.haml b/app/components/editable_champ/editable_champ_component/editable_champ_component.html.haml index c73824c8156..5fba33f870b 100644 --- a/app/components/editable_champ/editable_champ_component/editable_champ_component.html.haml +++ b/app/components/editable_champ/editable_champ_component/editable_champ_component.html.haml @@ -1,10 +1,15 @@ -.editable-champ{ html_options } += content_tag(:div, html_options) do - if has_label?(@champ) = render EditableChamp::ChampLabelComponent.new form: @form, champ: @champ, seen_at: @seen_at - - if @champ.titre_identite? - %p.notice= t('.titre_identite_notice') - - elsif @champ.datetime? - %p.notice= t('.datetime_notice') + = render component_class.new(form: @form, champ: @champ, seen_at: @seen_at) + + - if errors_on_attribute? + - if error_messages.size == 1 + %p.fr-error-text{ id: describedby_id }= error_messages.first + - else + .fr-error-text{ id: describedby_id } + %ul.list-style-type-none.fr-pl-0 + - error_messages.map do |error_message| + %li= error_message = @form.hidden_field :id, value: @champ.id - = render component_class.new(form: @form, champ: @champ, seen_at: @seen_at) diff --git a/app/components/editable_champ/email_component.rb b/app/components/editable_champ/email_component.rb index fbc0774e2a4..b7dbcddb2c4 100644 --- a/app/components/editable_champ/email_component.rb +++ b/app/components/editable_champ/email_component.rb @@ -1,2 +1,5 @@ class EditableChamp::EmailComponent < EditableChamp::EditableChampBaseComponent + def email? + true + end end diff --git a/app/components/editable_champ/email_component/email_component.html.haml b/app/components/editable_champ/email_component/email_component.html.haml index 152253c70f8..9f77ce08abe 100644 --- a/app/components/editable_champ/email_component/email_component.html.haml +++ b/app/components/editable_champ/email_component/email_component.html.haml @@ -1,5 +1 @@ -= @form.email_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - placeholder: t(".placeholder"), - required: @champ.required? += @form.email_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: t(".placeholder"), required: @champ.required?)) diff --git a/app/components/editable_champ/iban_component/iban_component.html.haml b/app/components/editable_champ/iban_component/iban_component.html.haml index 151bfaa562e..3c2bc8425d6 100644 --- a/app/components/editable_champ/iban_component/iban_component.html.haml +++ b/app/components/editable_champ/iban_component/iban_component.html.haml @@ -1,8 +1 @@ -= @form.text_field :value, - id: @champ.input_id, - placeholder: t(".placeholder"), - required: @champ.required?, - aria: { describedby: @champ.describedby_id }, - data: { controller: 'format', format: 'iban' }, - class: "width-66-desktop", - maxlength: 34 + 9 # count space separator of 4 digits-groups += @form.text_field(:value, input_opts(id: @champ.input_id, placeholder: t(".placeholder"), required: @champ.required?, aria: { describedby: @champ.describedby_id }, data: { controller: 'format', format: 'iban' }, class: "width-66-desktop", maxlength: 34 + 9)) # count space separator of 4 digits-groups diff --git a/app/components/editable_champ/integer_number_component/integer_number_component.html.haml b/app/components/editable_champ/integer_number_component/integer_number_component.html.haml index cb30df24dae..fc2680744fe 100644 --- a/app/components/editable_champ/integer_number_component/integer_number_component.html.haml +++ b/app/components/editable_champ/integer_number_component/integer_number_component.html.haml @@ -1,5 +1 @@ -= @form.number_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - placeholder: 5, - required: @champ.required? += @form.number_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: 5, required: @champ.required?)) diff --git a/app/components/editable_champ/number_component/number_component.html.haml b/app/components/editable_champ/number_component/number_component.html.haml index 8ee884bcc20..4da3486d15e 100644 --- a/app/components/editable_champ/number_component/number_component.html.haml +++ b/app/components/editable_champ/number_component/number_component.html.haml @@ -1,5 +1 @@ -= @form.number_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - placeholder: @champ.libelle, - required: @champ.required? += @form.number_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: @champ.libelle, required: @champ.required?)) diff --git a/app/components/editable_champ/phone_component/phone_component.html.haml b/app/components/editable_champ/phone_component/phone_component.html.haml index 46258c29853..d9b0797839c 100644 --- a/app/components/editable_champ/phone_component/phone_component.html.haml +++ b/app/components/editable_champ/phone_component/phone_component.html.haml @@ -1,9 +1,4 @@ -# Allowed @formats: -# very light validation is made client-side -# stronger validation is made server-side -= @form.phone_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - placeholder: t(".placeholder"), - required: @champ.required?, - pattern: "[^a-z^A-Z]+" += @form.phone_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: t(".placeholder"), required: @champ.required?, pattern: "[^a-z^A-Z]+")) diff --git a/app/components/editable_champ/rna_component/rna_component.html.haml b/app/components/editable_champ/rna_component/rna_component.html.haml index ed679038332..b8684093be4 100644 --- a/app/components/editable_champ/rna_component/rna_component.html.haml +++ b/app/components/editable_champ/rna_component/rna_component.html.haml @@ -1,12 +1,3 @@ -= @form.text_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - placeholder: t(".placeholder"), - data: { controller: 'turbo-input', turbo_input_load_on_connect_value: @champ.prefilled? && @champ.value.present? && @champ.data.blank?, turbo_input_url_value: champs_rna_path(@champ.id) }, - required: @champ.required?, - pattern: "W[0-9]{9}", - title: t(".title"), - class: "width-33-desktop", - maxlength: 10 += @form.text_field(:value, input_opts( id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: t(".placeholder"), data: { controller: 'turbo-input', turbo_input_load_on_connect_value: @champ.prefilled? && @champ.value.present? && @champ.data.blank?, turbo_input_url_value: champs_rna_path(@champ.id) }, required: @champ.required?, pattern: "W[0-9]{9}", title: t(".title"), class: "width-33-desktop", maxlength: 10)) .rna-info{ id: dom_id(@champ, :rna_info) } = render 'shared/champs/rna/association', champ: @champ, error: nil diff --git a/app/components/editable_champ/siret_component/siret_component.html.haml b/app/components/editable_champ/siret_component/siret_component.html.haml index 1970d85cc91..fb39ad011da 100644 --- a/app/components/editable_champ/siret_component/siret_component.html.haml +++ b/app/components/editable_champ/siret_component/siret_component.html.haml @@ -1,13 +1,4 @@ -= @form.text_field :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - placeholder: t(".placeholder"), - data: { controller: 'turbo-input', turbo_input_load_on_connect_value: @champ.prefilled? && @champ.value.present? && @champ.etablissement.blank?, turbo_input_url_value: champs_siret_path(@champ.id) }, - required: @champ.required?, - pattern: "[0-9]{14}", - title: t(".title"), - class: "width-33-desktop", - maxlength: 14 += @form.text_field(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: t(".placeholder"), data: { controller: 'turbo-input', turbo_input_load_on_connect_value: @champ.prefilled? && @champ.value.present? && @champ.etablissement.blank?, turbo_input_url_value: champs_siret_path(@champ.id) }, required: @champ.required?, pattern: "[0-9]{14}", title: t(".title"), class: "width-33-desktop", maxlength: 14)) .spinner.right.hidden .siret-info{ id: dom_id(@champ, :siret_info) } - if @champ.etablissement.present? diff --git a/app/components/editable_champ/text_component/text_component.html.haml b/app/components/editable_champ/text_component/text_component.html.haml index 326166a21bd..e88fc333281 100644 --- a/app/components/editable_champ/text_component/text_component.html.haml +++ b/app/components/editable_champ/text_component/text_component.html.haml @@ -1,4 +1 @@ -= @form.text_field :value, - id: @champ.input_id, - required: @champ.required?, - aria: { describedby: @champ.describedby_id } += @form.text_field(:value, input_opts(id: @champ.input_id, required: @champ.required?, aria: { describedby: @champ.describedby_id })) diff --git a/app/components/editable_champ/textarea_component/textarea_component.en.yml b/app/components/editable_champ/textarea_component/textarea_component.en.yml index 18b61d2a0a3..8e9b499018a 100644 --- a/app/components/editable_champ/textarea_component/textarea_component.en.yml +++ b/app/components/editable_champ/textarea_component/textarea_component.en.yml @@ -1,4 +1,3 @@ en: remaining_characters: You have %{remaining_words} characters remaining. excess_characters: You have %{excess_words} characters too many. - recommended_size: The recommended maximum size is %{size} characters. diff --git a/app/components/editable_champ/textarea_component/textarea_component.fr.yml b/app/components/editable_champ/textarea_component/textarea_component.fr.yml index e9d5a7a1227..fa8fafdc1ec 100644 --- a/app/components/editable_champ/textarea_component/textarea_component.fr.yml +++ b/app/components/editable_champ/textarea_component/textarea_component.fr.yml @@ -1,4 +1,3 @@ fr: remaining_characters: Il vous reste %{remaining_words} caractères. excess_characters: Vous avez dépassé la taille conseillée de %{excess_words} caractères. Réduire le nombre de caractères. - recommended_size: La taille maximale conseillée est de %{size} caractères. diff --git a/app/components/editable_champ/textarea_component/textarea_component.html.haml b/app/components/editable_champ/textarea_component/textarea_component.html.haml index 8a18048ed0f..e3054de3357 100644 --- a/app/components/editable_champ/textarea_component/textarea_component.html.haml +++ b/app/components/editable_champ/textarea_component/textarea_component.html.haml @@ -1,16 +1,9 @@ -%span.sr-only= t('.recommended_size', size: @champ.character_limit_base) - -~ @form.text_area :value, - id: @champ.input_id, - aria: { describedby: @champ.describedby_id }, - rows: 6, - required: @champ.required?, - value: html_to_string(@champ.value) +~ @form.text_area(:value, input_opts(id: @champ.input_id, aria: { describedby: @champ.describedby_id }, rows: 6, required: @champ.required?, value: html_to_string(@champ.value))) - if @champ.character_limit_info? %span.fr-icon-information-fill.fr-text-default--info.characters-count = t('.remaining_characters', remaining_words: @champ.remaining_characters) - if @champ.character_limit_warning? - %span.fr-icon-warning-fill.fr-text-default--warning.characters-count + %p.fr-icon-warning-fill.fr-text-default--warning.characters-count = t('.excess_characters', excess_words: @champ.excess_characters) diff --git a/app/models/champ.rb b/app/models/champ.rb index 00211b1daa6..a1cd14a4491 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -57,6 +57,7 @@ class Champ < ApplicationRecord :dossier_link?, :departement?, :region?, + :textarea?, :titre_identite?, :header_section?, :checkbox?, diff --git a/app/views/shared/champs/rna/_association.html.haml b/app/views/shared/champs/rna/_association.html.haml index 572a214027e..f95ac29b6a9 100644 --- a/app/views/shared/champs/rna/_association.html.haml +++ b/app/views/shared/champs/rna/_association.html.haml @@ -1,11 +1,11 @@ - case error - when :invalid - %p.pt-1 + %p.fr-pt-1.fr-pb-0 Le numéro RNA doit commencer par un W majuscule suivi de 9 chiffres - when :not_found - %p.pt-1= t('.not_found') + %p.fr-pt-1.fr-pb-0= t('.not_found') - when :network_error - %p.pt-1= t('.network_error') + %p.fr-pt-1.fr-pb-0= t('.network_error') - else - if champ.value.present? - %p.pt-1= t('.data_fetched', title: champ.title) + %p.fr-pt-1.fr-pb-0= t('.data_fetched', title: champ.title) diff --git a/config/locales/models/champs/datetime_champ/en.yml b/config/locales/models/champs/datetime_champ/en.yml new file mode 100644 index 00000000000..eb0b92533e3 --- /dev/null +++ b/config/locales/models/champs/datetime_champ/en.yml @@ -0,0 +1,7 @@ +en: + activerecord: + attributes: + champs/datetime_champ: + hints: + value: "Expected format : dd/mm/yyyy hh:mm" + diff --git a/config/locales/models/champs/datetime_champ/fr.yml b/config/locales/models/champs/datetime_champ/fr.yml new file mode 100644 index 00000000000..1035c03d8f7 --- /dev/null +++ b/config/locales/models/champs/datetime_champ/fr.yml @@ -0,0 +1,7 @@ +fr: + activerecord: + attributes: + champs/datetime_champ: + hints: + value: "Format attendu : jj/mm/aaaa hh:mm" +