Project

General

Profile

Patch #42335 » 0001-progress-bar-field-format-1168755.patch

Jens Krämer, 2025-02-28 10:15

View differences:

config/locales/de.yml
843 843
  label_year: Jahr
844 844
  label_yesterday: gestern
845 845
  label_default_query: Standardabfrage
846
  label_progressbar: Fortschrittsbalken
846 847

  
847 848
  mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
848 849
  mail_body_account_information: Ihre Konto-Informationen
config/locales/en.yml
1150 1150
  label_edited: Edited
1151 1151
  label_time_by_author: "%{time} by %{author}"
1152 1152
  label_involved_principals: Author / Previous assignee
1153
  label_progressbar: Progress bar
1153 1154

  
1154 1155
  button_login: Login
1155 1156
  button_submit: Submit
config/locales/fr.yml
1025 1025
    for_this_user: For this user
1026 1026
  label_trackers_description: Description des trackers
1027 1027
  label_open_trackers_description: Afficher la description des trackers
1028
  label_progressbar: Barre de progression
1028 1029

  
1029 1030
  button_login: Connexion
1030 1031
  button_submit: Soumettre
lib/redmine/field_format.rb
1082 1082
            })
1083 1083
      end
1084 1084
    end
1085

  
1086
    class ProgressbarFormat < Numeric
1087
      add 'progressbar'
1088

  
1089
      self.form_partial = nil
1090
      self.totalable_supported = false
1091

  
1092
      def label
1093
        "label_progressbar"
1094
      end
1095

  
1096
      def cast_single_value(custom_field, value, customized=nil)
1097
        value.to_i.clamp(0, 100)
1098
      end
1099

  
1100
      def validate_single_value(custom_field, value, customized=nil)
1101
        errs = super
1102
        errs << ::I18n.t('activerecord.errors.messages.not_a_number') unless /^\d*$/.match?(value.to_s.strip)
1103
        errs << ::I18n.t('activerecord.errors.messages.invalid') unless value.to_i.between?(0, 100)
1104
        errs
1105
      end
1106

  
1107
      def query_filter_options(custom_field, query)
1108
        {:type => :integer}
1109
      end
1110

  
1111
      def group_statement(custom_field)
1112
        order_statement(custom_field)
1113
      end
1114

  
1115
      def edit_tag(view, tag_id, tag_name, custom_value, options={})
1116
        view.select_tag tag_name, view.options_for_select((0..100).step(Setting.issue_done_ratio_interval.to_i).to_a.collect {|r| ["#{r} %", r]}, custom_value.value), options.merge(id: tag_id, style: "width: 75px;")
1117
      end
1118

  
1119
      def bulk_edit_tag(view, tag_id, tag_name, custom_field, objects, value, options={})
1120
        opts = view.options_for_select([[l(:label_no_change_option), '']] + (0..100).step(Setting.issue_done_ratio_interval.to_i).to_a.collect {|r| ["#{r} %", r]})
1121
        view.select_tag(tag_name, opts, options.merge(id: tag_id, style: "width: 75px;")) +
1122
          bulk_clear_tag(view, tag_id, tag_name, custom_field, value)
1123
      end
1124

  
1125
      def formatted_value(view, custom_field, value, customized=nil, html=false)
1126
        text = "#{value}%"
1127
        if html
1128
          view.progress_bar(value.to_i, legend: (text if view.action_name == 'show'))
1129
        else
1130
          text
1131
        end
1132
      end
1133
    end
1085 1134
  end
1086 1135
end
test/unit/lib/redmine/field_format/progressbar_format_test.rb
1
require_relative '../../../../test_helper'
2
require 'redmine/field_format'
3

  
4
module Planio
5
  class ProgressbarFormatTest < ActiveSupport::TestCase
6

  
7
    def setup
8
      @field = IssueCustomField.new(name: 'ProgressbarTest', field_format: 'progressbar')
9
      @format = Redmine::FieldFormat::ProgressbarFormat.instance
10
    end
11

  
12
    def test_validate_invalid_value
13
      cv = CustomValue.new(custom_field: @field, value: '120')
14
      assert_include ::I18n.t('activerecord.errors.messages.invalid'), @format.validate_custom_value(cv)
15
    end
16

  
17
    def test_validate_numericality
18
      cv = CustomValue.new(custom_field: @field, value: 'abc')
19
      assert_include ::I18n.t('activerecord.errors.messages.not_a_number'), @format.validate_custom_value(cv)
20
    end
21

  
22
    def test_cast_value_clamping
23
      assert_equal 0, @field.cast_value('-10')
24
      assert_equal 0, @field.cast_value('0')
25
      assert_equal 50, @field.cast_value('50')
26
      assert_equal 100, @field.cast_value('120')
27
    end
28

  
29
    def test_empty_value
30
      assert_nil @field.cast_value('')
31
    end
32

  
33
    def test_totalable_support
34
      assert_not @format.totalable_supported?
35
    end
36

  
37
    def test_validate_non_numeric_value_should_fail
38
      assert_include ::I18n.t('activerecord.errors.messages.not_a_number'),
39
        @format.validate_single_value(@field, "abc")
40
    end
41

  
42
    def test_validate_negative_value_should_fail 
43
      assert_include ::I18n.t('activerecord.errors.messages.invalid'),
44
        @format.validate_single_value(@field, "-10")
45
    end
46

  
47
    def test_validate_value_above_100_should_fail
48
      assert_include ::I18n.t('activerecord.errors.messages.invalid'),
49
        @format.validate_single_value(@field, "150")
50
    end
51

  
52
    def test_validate_valid_value_should_pass
53
      assert_empty @format.validate_single_value(@field, "50")
54
      assert_empty @format.validate_single_value(@field, "0")
55
      assert_empty @format.validate_single_value(@field, "100")
56
    end
57

  
58
    def test_validate_blank_value_should_pass
59
      assert_empty @format.validate_single_value(@field, "")
60
    end
61

  
62
    def test_query_filter_options
63
      options = @format.query_filter_options(@field, nil)
64
      assert_equal :integer, options[:type]
65
    end
66

  
67
  end
68
end
69

  
test/unit/planio/progressbar_field_format_test.rb
1
require File.expand_path('../../../test_helper', __FILE__)
2
module Planio
3
  class ProgressbarFieldFormatTest < ActiveSupport::TestCase
4

  
5
    def setup
6
      @field = IssueCustomField.new(name: 'ProgressbarTest', field_format: 'progressbar')
7
      @format = Redmine::FieldFormat::ProgressbarFormat.instance
8
    end
9

  
10
    def test_validate_invalid_value
11
      cv = CustomValue.new(custom_field: @field, value: '120')
12
      assert_include ::I18n.t('activerecord.errors.messages.invalid'), @format.validate_custom_value(cv)
13
    end
14

  
15
    def test_validate_numericality
16
      cv = CustomValue.new(custom_field: @field, value: 'abc')
17
      assert_include ::I18n.t('activerecord.errors.messages.not_a_number'), @format.validate_custom_value(cv)
18
    end
19

  
20
    def test_cast_value_clamping
21
      assert_equal 0, @field.cast_value('-10')
22
      assert_equal 0, @field.cast_value('0')
23
      assert_equal 50, @field.cast_value('50')
24
      assert_equal 100, @field.cast_value('120')
25
    end
26

  
27
    def test_empty_value
28
      assert_nil @field.cast_value('')
29
    end
30

  
31
    def test_totalable_support
32
      assert_not @format.totalable_supported?
33
    end
34

  
35
    def test_validate_non_numeric_value_should_fail
36
      assert_include ::I18n.t('activerecord.errors.messages.not_a_number'),
37
        @format.validate_single_value(@field, "abc")
38
    end
39

  
40
    def test_validate_negative_value_should_fail 
41
      assert_include ::I18n.t('activerecord.errors.messages.invalid'),
42
        @format.validate_single_value(@field, "-10")
43
    end
44

  
45
    def test_validate_value_above_100_should_fail
46
      assert_include ::I18n.t('activerecord.errors.messages.invalid'),
47
        @format.validate_single_value(@field, "150")
48
    end
49

  
50
    def test_validate_valid_value_should_pass
51
      assert_empty @format.validate_single_value(@field, "50")
52
      assert_empty @format.validate_single_value(@field, "0")
53
      assert_empty @format.validate_single_value(@field, "100")
54
    end
55

  
56
    def test_validate_blank_value_should_pass
57
      assert_empty @format.validate_single_value(@field, "")
58
    end
59

  
60
    def test_query_filter_options
61
      options = @format.query_filter_options(@field, nil)
62
      assert_equal :integer, options[:type]
63
    end
64

  
65
  end
66
end
    (1-1/1)