From 78d46eb37462dd9a7f17060473d9a64a6d56cbe1 Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Sun, 14 Jul 2024 18:07:37 +0900 Subject: [PATCH 3/3] Add option to render Integer and Float custom fields with thousands delimiters --- app/helpers/application_helper.rb | 14 ++++++++++---- app/models/custom_field.rb | 8 +++++++- app/views/custom_fields/formats/_numeric.html.erb | 1 + config/locales/en.yml | 1 + lib/redmine/field_format.rb | 1 + .../redmine/field_format/numeric_format_test.rb | 11 +++++++++++ 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8824b17d1..ab1023eeb 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -253,6 +253,7 @@ module ApplicationHelper # Helper that formats object for html or text rendering # Options: # * :html - If true, format the object as HTML (default: true) + # * :thousands_delimiter - If true, format the numeric object with thousands delimiter (default: false) def format_object(object, *args, &block) options = args.last.is_a?(Hash) ? args.pop : {} html = @@ -267,22 +268,26 @@ module ApplicationHelper ) args[0] end + thousands_delimiter = options.fetch(:thousands_delimiter, false) + delimiter = thousands_delimiter ? ::I18n.t('number.format.delimiter') : nil if block object = yield object end case object when Array - formatted_objects = object.map {|o| format_object(o, html: html)} + formatted_objects = object.map do |o| + format_object(o, html: html, thousands_delimiter: delimiter) + end html ? safe_join(formatted_objects, ', ') : formatted_objects.join(', ') when Time, ActiveSupport::TimeWithZone format_time(object) when Date format_date(object) when Integer - object.to_s + number_with_delimiter(object, delimiter: delimiter) when Float - number_with_delimiter(sprintf('%.2f', object), delimiter: nil) + number_with_delimiter(sprintf('%.2f', object), delimiter: delimiter) when User, Group html ? link_to_principal(object) : object.to_s when Project @@ -318,7 +323,8 @@ module ApplicationHelper if f.nil? || f.is_a?(String) f else - format_object(f, html: html, &block) + thousands_delimiter = object.custom_field.thousands_delimiter? + format_object(f, html: html, thousands_delimiter: thousands_delimiter, &block) end else object.value.to_s diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 97bc70228..136a336ed 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -100,7 +100,9 @@ class CustomField < ApplicationRecord 'user_role', 'version_status', 'extensions_allowed', - 'full_width_layout') + 'full_width_layout', + 'thousands_delimiter' + ) def copy_from(arg, options={}) return if arg.blank? @@ -225,6 +227,10 @@ class CustomField < ApplicationRecord text_formatting == 'full' end + def thousands_delimiter? + thousands_delimiter == '1' + end + # Returns a ORDER BY clause that can used to sort customized # objects by their value of the custom field. # Returns nil if the custom field can not be used for sorting. diff --git a/app/views/custom_fields/formats/_numeric.html.erb b/app/views/custom_fields/formats/_numeric.html.erb index cc0c798a6..e03124b45 100644 --- a/app/views/custom_fields/formats/_numeric.html.erb +++ b/app/views/custom_fields/formats/_numeric.html.erb @@ -1,3 +1,4 @@ <%= render :partial => 'custom_fields/formats/regexp', :locals => {:f => f, :custom_field => custom_field} %> +

<%= f.check_box :thousands_delimiter %>

<%= f.text_field(:default_value) %>

<%= f.text_field :url_pattern, :size => 50, :label => :label_link_values_to %>

diff --git a/config/locales/en.yml b/config/locales/en.yml index 471df368c..901bca6e9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -421,6 +421,7 @@ en: field_any_searchable: Any searchable text field_estimated_remaining_hours: Estimated remaining time field_last_activity_date: Last activity + field_thousands_delimiter: Thousands delimiter setting_app_title: Application title setting_welcome_text: Welcome text diff --git a/lib/redmine/field_format.rb b/lib/redmine/field_format.rb index 7d7fe42bc..93a279758 100644 --- a/lib/redmine/field_format.rb +++ b/lib/redmine/field_format.rb @@ -476,6 +476,7 @@ module Redmine class Numeric < Unbounded self.form_partial = 'custom_fields/formats/numeric' self.totalable_supported = true + field_attributes :thousands_delimiter def order_statement(custom_field) # Make the database cast values into numeric diff --git a/test/unit/lib/redmine/field_format/numeric_format_test.rb b/test/unit/lib/redmine/field_format/numeric_format_test.rb index db86a0f5c..4e074feea 100644 --- a/test/unit/lib/redmine/field_format/numeric_format_test.rb +++ b/test/unit/lib/redmine/field_format/numeric_format_test.rb @@ -60,4 +60,15 @@ class Redmine::NumericFieldFormatTest < ActionView::TestCase end end end + + def test_integer_field_should_format_with_thousands_delimiter + field = IssueCustomField.generate!(field_format: 'int', thousands_delimiter: '1') + custom_value = CustomValue.new(custom_field: field, customized: Issue.find(1), value: '1234567') + to_test = {'en' => '1,234,567', 'de' => '1.234.567', 'fr' => '1 234 567'} + to_test.each do |locale, expected| + with_locale locale do + assert_equal expected, format_object(custom_value, html: false), locale + end + end + end end -- 2.45.2