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 a19653e0d..4df4aad44 100644 --- a/app/components/editable_champ/textarea_component/textarea_component.html.haml +++ b/app/components/editable_champ/textarea_component/textarea_component.html.haml @@ -1,7 +1,3 @@ -- character_limit = @champ.textarea_character_limit.to_i if !@champ.textarea_character_limit&.empty? -- character_count = @champ.character_count(@champ.value) -- analyze_character_count = @champ.analyze_character_count(character_count, character_limit) - ~ @form.text_area :value, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, @@ -9,12 +5,10 @@ required: @champ.required?, value: html_to_string(@champ.value) -- if @champ.textarea_character_limit? +- 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 analyze_character_count == :info - %span.fr-icon-information-fill.fr-text-default--info.characters-count - = t('.remaining_characters', remaining_words: @champ.remaining_characters(character_count, character_limit)) - - - if analyze_character_count == :warning - %span.fr-icon-close-circle-fill.fr-text-default--error.characters-count - = t('.excess_characters', excess_words: @champ.excess_characters(character_count, character_limit)) +- if @champ.character_limit_warning? + %span.fr-icon-close-circle-fill.fr-text-default--error.characters-count + = t('.excess_characters', excess_words: @champ.excess_characters) diff --git a/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml b/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml index cb04139a3..9412c067e 100644 --- a/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml +++ b/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml @@ -36,8 +36,8 @@ fr: add_condition: Une condition a été ajoutée sur le champ « %{label} ». La nouvelle condition est « %{to} ». remove_condition: La condition du champ « %{label} » a été supprimée. update_condition: La condition du champ « %{label} » a été modifiée. La nouvelle condition est « %{to} ». - update_textarea_character_limit: La limite de caractères du champ texte « %{label} » a été modifiée. La nouvelle limite est « %{to} ». - remove_textarea_character_limit: La limite de caractères du champ texte « %{label} » a été supprimée. + update_character_limit: La limite de caractères du champ texte « %{label} » a été modifiée. La nouvelle limite est « %{to} ». + remove_character_limit: La limite de caractères du champ texte « %{label} » a été supprimée. private: add: L’annotation privée « %{label} » a été ajoutée. remove: L’annotation privée « %{label} » a été supprimée. diff --git a/app/components/procedure/revision_changes_component/revision_changes_component.html.haml b/app/components/procedure/revision_changes_component/revision_changes_component.html.haml index bc4b24c82..81e82b167 100644 --- a/app/components/procedure/revision_changes_component/revision_changes_component.html.haml +++ b/app/components/procedure/revision_changes_component/revision_changes_component.html.haml @@ -131,13 +131,13 @@ - if !total_dossiers.zero? && !change.can_rebase? .fr-alert.fr-alert--warning.fr-mt-1v %p= t('.breakigng_change', count: total_dossiers) - - when :textarea_character_limit - - if change.to.nil? + - when :character_limit + - if change.to.blank? - list.with_item do - = t(".#{prefix}.remove_textarea_character_limit", label: change.label, to: change.to) + = t(".#{prefix}.remove_character_limit", label: change.label, to: change.to) - else - list.with_item do - = t(".#{prefix}.update_textarea_character_limit", label: change.label, to: change.to) + = t(".#{prefix}.update_character_limit", label: change.label, to: change.to) - if @public_move_changes.present? - list.with_item do diff --git a/app/components/types_de_champ_editor/champ_component.rb b/app/components/types_de_champ_editor/champ_component.rb index b2e12aca6..1b1296126 100644 --- a/app/components/types_de_champ_editor/champ_component.rb +++ b/app/components/types_de_champ_editor/champ_component.rb @@ -121,4 +121,14 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent def conditional_enabled? !type_de_champ.private? end + + def options_for_character_limit + [ + [t('.character_limit.unlimited'), nil], + [t('.character_limit.limit', limit: 400), 400], + [t('.character_limit.limit', limit: 1000), 1000], + [t('.character_limit.limit', limit: 5000), 5000], + [t('.character_limit.limit', limit: 10000), 10000] + ] + end end diff --git a/app/components/types_de_champ_editor/champ_component/champ_component.fr.yml b/app/components/types_de_champ_editor/champ_component/champ_component.fr.yml index 8ba08f260..a37f69652 100644 --- a/app/components/types_de_champ_editor/champ_component/champ_component.fr.yml +++ b/app/components/types_de_champ_editor/champ_component/champ_component.fr.yml @@ -10,3 +10,6 @@ fr: natura_2000: Natura 2000 zones_humides: Zones humides d’importance internationale znieff: ZNIEFF + character_limit: + unlimited: Pas de limite de charactères + limit: Limité à %{limit} caractères diff --git a/app/components/types_de_champ_editor/champ_component/champ_component.html.haml b/app/components/types_de_champ_editor/champ_component/champ_component.html.haml index 6de2696fb..665c80759 100644 --- a/app/components/types_de_champ_editor/champ_component/champ_component.html.haml +++ b/app/components/types_de_champ_editor/champ_component/champ_component.html.haml @@ -103,9 +103,9 @@ = form.text_area :collapsible_explanation_text, class: "small-margin small", id: dom_id(type_de_champ, :collapsible_explanation_text) - if type_de_champ.textarea? .cell - = form.label :textarea_character_limit, for: dom_id(type_de_champ, :textarea_character_limit) do + = form.label :character_limit, for: dom_id(type_de_champ, :character_limit) do Spécifier un nombre maximal de caractères (non restrictif) : - = form.number_field :textarea_character_limit, min: 400, value: form.object.textarea_character_limit, id: dom_id(type_de_champ, :textarea_character_limit) + = form.select :character_limit, options_for_character_limit, id: dom_id(type_de_champ, :character_limit) - if type_de_champ.block? .flex.justify-start.section.ml-1 diff --git a/app/controllers/administrateurs/types_de_champ_controller.rb b/app/controllers/administrateurs/types_de_champ_controller.rb index 2b87a60ba..05dea205a 100644 --- a/app/controllers/administrateurs/types_de_champ_controller.rb +++ b/app/controllers/administrateurs/types_de_champ_controller.rb @@ -129,7 +129,7 @@ module Administrateurs :collapsible_explanation_enabled, :collapsible_explanation_text, :header_section_level, - :textarea_character_limit, + :character_limit, editable_options: [ :cadastres, :unesco, diff --git a/app/models/champ.rb b/app/models/champ.rb index 7ff1074d3..14793de0e 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -75,8 +75,8 @@ class Champ < ApplicationRecord :mandatory?, :prefillable?, :refresh_after_update?, - :textarea_character_limit?, - :textarea_character_limit, + :character_limit?, + :character_limit, to: :type_de_champ delegate :to_typed_id, :to_typed_id_for_query, to: :type_de_champ, prefix: true diff --git a/app/models/champs/textarea_champ.rb b/app/models/champs/textarea_champ.rb index e729bc1ad..ab2b229e0 100644 --- a/app/models/champs/textarea_champ.rb +++ b/app/models/champs/textarea_champ.rb @@ -25,28 +25,43 @@ class Champs::TextareaChamp < Champs::TextChamp value.present? ? ActionView::Base.full_sanitizer.sanitize(value) : nil end - def character_count(text) - return text&.bytesize + def remaining_characters + character_limit_base - character_count if character_count >= character_limit_threshold_75 end - def analyze_character_count(characters, limit) - if characters - threshold_75 = limit * 0.75 + def excess_characters + character_count - character_limit_base if character_count > character_limit_base + end - if characters >= limit + def character_limit_info? + analyze_character_count == :info + end + + def character_limit_warning? + analyze_character_count == :warning + end + + private + + def character_count + return value&.bytesize + end + + def character_limit_base + character_limit&.to_i + end + + def character_limit_threshold_75 + character_limit_base * 0.75 + end + + def analyze_character_count + if character_limit? && character_count.present? + if character_count >= character_limit_base return :warning - elsif characters >= threshold_75 + elsif character_count >= character_limit_threshold_75 return :info end end end - - def remaining_characters(characters, limit) - threshold_75 = limit * 0.75 - limit - characters if characters >= threshold_75 - end - - def excess_characters(characters, limit) - characters - limit if characters > limit - end end diff --git a/app/models/procedure_revision.rb b/app/models/procedure_revision.rb index 8a6a2168e..02ef041fe 100644 --- a/app/models/procedure_revision.rb +++ b/app/models/procedure_revision.rb @@ -378,11 +378,11 @@ class ProcedureRevision < ApplicationRecord to_type_de_champ.piece_justificative_template_filename) end elsif to_type_de_champ.textarea? - if from_type_de_champ.textarea_character_limit != to_type_de_champ.textarea_character_limit + if from_type_de_champ.character_limit != to_type_de_champ.character_limit changes << ProcedureRevisionChange::UpdateChamp.new(from_type_de_champ, - :textarea_character_limit, - from_type_de_champ.textarea_character_limit, - to_type_de_champ.textarea_character_limit) + :character_limit, + from_type_de_champ.character_limit, + to_type_de_champ.character_limit) end end changes diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 4c738da20..324b9f0a3 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -119,7 +119,7 @@ class TypeDeChamp < ApplicationRecord :drop_down_secondary_libelle, :drop_down_secondary_description, :drop_down_other, - :textarea_character_limit, + :character_limit, :collapsible_explanation_enabled, :collapsible_explanation_text, :header_section_level @@ -179,10 +179,10 @@ class TypeDeChamp < ApplicationRecord validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :type_champ, presence: true, allow_blank: false, allow_nil: false - validates :textarea_character_limit, numericality: { + validates :character_limit, numericality: { greater_than_or_equal_to: MINIMUM_TEXTAREA_CHARACTER_LIMIT_LENGTH, only_integer: true, - allow_nil: true + allow_blank: true } before_validation :check_mandatory @@ -242,8 +242,8 @@ class TypeDeChamp < ApplicationRecord drop_down_other == "1" || drop_down_other == true end - def textarea_character_limit? - textarea_character_limit.present? + def character_limit? + character_limit.present? end def collapsible_explanation_enabled?