Project

General

Profile

Feature #39997 » 39997-WIP-20240713.patch

Go MAEDA, 2024-07-13 09:53

View differences:

app/helpers/application_helper.rb
251 251
  end
252 252

  
253 253
  # Helper that formats object for html or text rendering
254
  def format_object(object, html=true, &block)
254
  def format_object(object, *args, &block)
255
    options = args.last.is_a?(Hash) ? args.pop : {}
256
    # The :html option is supposed to be passed as a keyword argument like `format_object(object, html: true)`,
257
    # but a old syntax like `format_object(object, true)` is also supported for backward compatibility.
258
    # TODO: Remove the old syntax in Redmine 7.0.
259
    html = options.fetch(:html, args[0].nil? ? true : args[0])
260
    th_sep = options[:thousand_separator] || false
261

  
255 262
    if block
256 263
      object = yield object
257 264
    end
258 265
    case object
259 266
    when Array
260
      formatted_objects = object.map {|o| format_object(o, html)}
267
      formatted_objects = object.map {|o| format_object(o, html: html, thousand_separator: th_sep)}
261 268
      html ? safe_join(formatted_objects, ', ') : formatted_objects.join(', ')
262 269
    when Time, ActiveSupport::TimeWithZone
263 270
      format_time(object)
264 271
    when Date
265 272
      format_date(object)
266 273
    when Integer
267
      object.to_s
274
      delimiter = th_sep ? ::I18n.t('number.format.delimiter') : nil
275
      number_with_delimiter(object, delimiter: delimiter)
268 276
    when Float
269
      number_with_delimiter(sprintf('%.2f', object), delimiter: nil)
277
      delimiter = th_sep ? ::I18n.t('number.format.delimiter') : nil
278
      number_with_delimiter(sprintf('%.2f', object), delimiter: delimiter)
270 279
    when User, Group
271 280
      html ? link_to_principal(object) : object.to_s
272 281
    when Project
......
299 308

  
300 309
      if object.custom_field
301 310
        f = object.custom_field.format.formatted_custom_value(self, object, html)
311
        th_sep = object.custom_field.thousand_separator?
302 312
        if f.nil? || f.is_a?(String)
303 313
          f
304 314
        else
305
          format_object(f, html, &block)
315
          format_object(f, html: html, thousand_separator: th_sep, &block)
306 316
        end
307 317
      else
308 318
        object.value.to_s
app/helpers/custom_fields_helper.rb
164 164

  
165 165
  # Return a string used to display a custom value
166 166
  def show_value(custom_value, html=true)
167
    format_object(custom_value, html)
167
    format_object(custom_value, html: html)
168 168
  end
169 169

  
170 170
  # Return a string used to display a custom value
171 171
  def format_value(value, custom_field)
172
    format_object(custom_field.format.formatted_value(self, custom_field, value, false), false)
172
    format_object(custom_field.format.formatted_value(self, custom_field, value, false), html: false)
173 173
  end
174 174

  
175 175
  # Return an array of custom field formats which can be used in select_tag
app/helpers/queries_helper.rb
305 305
    when :watcher_users
306 306
      value.to_a.join("\n")
307 307
    else
308
      format_object(value, false) do |value|
308
      format_object(value, html: false) do |value|
309 309
        case value.class.name
310 310
        when 'Float'
311 311
          sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
app/helpers/roles_helper.rb
35 35
          ]
36 36
          fields = names + roles.collect do |role|
37 37
            if role.setable_permissions.include?(p)
38
              format_object(role.permissions.include?(p.name), false)
38
              format_object(role.permissions.include?(p.name), html: false)
39 39
            else
40 40
              ''
41 41
            end
app/helpers/timelog_helper.rb
84 84
          "##{obj.id}"
85 85
        end
86 86
      else
87
        format_object(obj, html)
87
        format_object(obj, html: html)
88 88
      end
89 89
    elsif cf = criteria_options[:custom_field]
90 90
      format_value(value, cf)
app/models/custom_field.rb
100 100
    'user_role',
101 101
    'version_status',
102 102
    'extensions_allowed',
103
    'full_width_layout')
103
    'full_width_layout',
104
    'thousand_separator'
105
  )
104 106

  
105 107
  def copy_from(arg, options={})
106 108
    return if arg.blank?
......
225 227
    text_formatting == 'full'
226 228
  end
227 229

  
230
  def thousand_separator?
231
    thousand_separator == '1'
232
  end
233

  
228 234
  # Returns a ORDER BY clause that can used to sort customized
229 235
  # objects by their value of the custom field.
230 236
  # Returns nil if the custom field can not be used for sorting.
app/views/custom_fields/formats/_numeric.html.erb
1 1
<%= render :partial => 'custom_fields/formats/regexp', :locals => {:f => f, :custom_field => custom_field} %>
2 2
<p><%= f.text_field(:default_value) %></p>
3
<p><%= f.check_box :thousand_separator %></p>
3 4
<p><%= f.text_field :url_pattern, :size => 50, :label => :label_link_values_to %></p>
config/locales/en.yml
74 74
  number:
75 75
    format:
76 76
      separator: "."
77
      delimiter: ""
77
      delimiter: ","
78 78
      precision: 3
79 79

  
80 80
    human:
lib/redmine/field_format.rb
250 250
        casted = cast_value(custom_field, value, customized)
251 251
        if html && custom_field.url_pattern.present?
252 252
          texts_and_urls = Array.wrap(casted).map do |single_value|
253
            text = view.format_object(single_value, false).to_s
253
            text = view.format_object(single_value, html: false).to_s
254 254
            url = url_from_pattern(custom_field, single_value, customized)
255 255
            [text, url]
256 256
          end
......
476 476
    class Numeric < Unbounded
477 477
      self.form_partial = 'custom_fields/formats/numeric'
478 478
      self.totalable_supported = true
479
      field_attributes :thousand_separator
479 480

  
480 481
      def order_statement(custom_field)
481 482
        # Make the database cast values into numeric
test/unit/lib/redmine/field_format/numeric_format_test.rb
56 56
    to_test = {'en' => '1234.56', 'de' => '1234,56'}
57 57
    to_test.each do |locale, expected|
58 58
      with_locale locale do
59
        assert_equal expected, format_object(issue.reload.custom_field_values.last, false)
59
        assert_equal expected, format_object(issue.reload.custom_field_values.last, html: false)
60 60
      end
61 61
    end
62 62
  end
(1-1/6)