##// END OF EJS Templates
Introduce a setting to change the display format of timespans to h:mm (#23996)....
Jean-Philippe Lang -
r15583:5495e6f3424f
parent child
Show More
@@ -426,7 +426,7 module ApplicationHelper
426 426 end
427 427
428 428 def html_hours(text)
429 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>').html_safe
429 text.gsub(%r{(\d+)([\.:])(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">\2\3</span>').html_safe
430 430 end
431 431
432 432 def authoring(created, author, options={})
@@ -149,7 +149,12 module QueriesHelper
149 149
150 150 def total_tag(column, value)
151 151 label = content_tag('span', "#{column.caption}:")
152 value = content_tag('span', format_object(value), :class => 'value')
152 value = if [:hours, :spent_hours, :total_spent_hours, :estimated_hours].include? column.name
153 format_hours(value)
154 else
155 format_object(value)
156 end
157 value = content_tag('span', value, :class => 'value')
153 158 content_tag('span', label + " " + value, :class => "total-for-#{column.name.to_s.dasherize}")
154 159 end
155 160
@@ -184,6 +189,8 module QueriesHelper
184 189 content_tag('span',
185 190 value.to_s(issue) {|other| link_to_issue(other, :subject => false, :tracker => false)}.html_safe,
186 191 :class => value.css_classes_for(issue))
192 when :hours, :spent_hours, :total_spent_hours, :estimated_hours
193 format_hours(value)
187 194 else
188 195 format_object(value)
189 196 end
@@ -65,7 +65,7
65 65 <% end %>
66 66
67 67 <% if @issue.safe_attribute? 'estimated_hours' %>
68 <p><%= f.text_field :estimated_hours, :size => 3, :required => @issue.required_attribute?('estimated_hours') %> <%= l(:field_hours) %></p>
68 <p><%= f.text_field :estimated_hours, :size => 3, :required => @issue.required_attribute?('estimated_hours'), :value => format_hours(@issue.estimated_hours) %> <%= l(:field_hours) %></p>
69 69 <% end %>
70 70
71 71 <% if @issue.safe_attribute?('done_ratio') && Issue.use_field_for_done_ratio? %>
@@ -14,7 +14,7
14 14 <%= labelled_fields_for :time_entry, @time_entry do |time_entry| %>
15 15 <div class="splitcontent">
16 16 <div class="splitcontentleft">
17 <p><%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %></p>
17 <p><%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time, :value => format_hours(@time_entry.hours) %> <%= l(:field_hours) %></p>
18 18 </div>
19 19 <div class="splitcontentright">
20 20 <p><%= time_entry.select :activity_id, activity_collection_for_select_options %></p>
@@ -46,7 +46,7 entries_by_day = entries.group_by(&:spent_on)
46 46 <tr class="odd">
47 47 <td><strong><%= day == User.current.today ? l(:label_today).titleize : format_date(day) %></strong></td>
48 48 <td colspan="2"></td>
49 <td class="hours"><em><%= html_hours("%.2f" % entries_by_day[day].sum(&:hours).to_f) %></em></td>
49 <td class="hours"><em><%= html_hours(l_hours_short(entries_by_day[day].sum(&:hours))) %></em></td>
50 50 </tr>
51 51 <% entries_by_day[day].each do |entry| -%>
52 52 <tr class="time-entry hascontextmenu">
@@ -56,7 +56,7 entries_by_day = entries.group_by(&:spent_on)
56 56 </td>
57 57 <td class="subject"><%= entry.project %> <%= h(' - ') + link_to_issue(entry.issue, :truncate => 50) if entry.issue %></td>
58 58 <td class="comments"><%= entry.comments %></td>
59 <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
59 <td class="hours"><%= html_hours(l_hours_short(entry.hours)) %></td>
60 60 </tr>
61 61 <% end -%>
62 62 <% end -%>
@@ -15,6 +15,8
15 15
16 16 <p><%= setting_select :time_format, Setting::TIME_FORMATS.collect {|f| [::I18n.l(Time.now, :locale => locale, :format => f), f]}, :blank => :label_language_based %></p>
17 17
18 <p><%= setting_select :timespan_format, [["%.2f" % 0.75, 'decimal'], ['0:45 h', 'minutes']], :blank => false %></p>
19
18 20 <p><%= setting_select :user_format, @options[:user_format] %></p>
19 21
20 22 <p><%= setting_check_box :gravatar_enabled %></p>
@@ -18,7 +18,7
18 18 </span>
19 19 </p>
20 20 <p><%= f.date_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
21 <p><%= f.text_field :hours, :size => 6, :required => true %></p>
21 <p><%= f.text_field :hours, :size => 6, :required => true, :value => format_hours(@time_entry.hours) %></p>
22 22 <p><%= f.text_field :comments, :size => 100, :maxlength => 1024 %></p>
23 23 <p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
24 24 <% @time_entry.custom_field_values.each do |value| %>
@@ -8,9 +8,9
8 8 <% total = 0 -%>
9 9 <% @report.periods.each do |period| -%>
10 10 <% sum = sum_hours(select_hours(hours_for_value, @report.columns, period.to_s)); total += sum -%>
11 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
11 <td class="hours"><%= html_hours(l_hours_short(sum)) if sum > 0 %></td>
12 12 <% end -%>
13 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
13 <td class="hours"><%= html_hours(l_hours_short(total)) if total > 0 %></td>
14 14 </tr>
15 15 <% if criterias.length > level+1 -%>
16 16 <%= render(:partial => 'report_criteria', :locals => {:criterias => criterias, :hours => hours_for_value, :level => (level + 1)}) %>
@@ -52,9 +52,9
52 52 <% total = 0 -%>
53 53 <% @report.periods.each do |period| -%>
54 54 <% sum = sum_hours(select_hours(@report.hours, @report.columns, period.to_s)); total += sum -%>
55 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
55 <td class="hours"><%= html_hours(l_hours_short(sum)) if sum > 0 %></td>
56 56 <% end -%>
57 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
57 <td class="hours"><%= html_hours(l_hours_short(total)) if total > 0 %></td>
58 58 </tr>
59 59 </tbody>
60 60 </table>
@@ -1047,6 +1047,7 de:
1047 1047 setting_thumbnails_enabled: Vorschaubilder von Dateianhängen anzeigen
1048 1048 setting_thumbnails_size: Größe der Vorschaubilder (in Pixel)
1049 1049 setting_time_format: Zeitformat
1050 setting_timespan_format: Format für Zeitspannen
1050 1051 setting_unsubscribe: Erlaubt Benutzern das eigene Benutzerkonto zu löschen
1051 1052 setting_user_format: Benutzer-Anzeigeformat
1052 1053 setting_welcome_text: Willkommenstext
@@ -389,6 +389,7 en:
389 389 setting_autologin: Autologin
390 390 setting_date_format: Date format
391 391 setting_time_format: Time format
392 setting_timespan_format: Time span format
392 393 setting_cross_project_issue_relations: Allow cross-project issue relations
393 394 setting_cross_project_subtasks: Allow cross-project subtasks
394 395 setting_issue_list_default_columns: Default columns displayed on the issue list
@@ -401,6 +401,7 fr:
401 401 setting_autologin: Durée maximale de connexion automatique
402 402 setting_date_format: Format de date
403 403 setting_time_format: Format d'heure
404 setting_timespan_format: Format des temps en heures
404 405 setting_cross_project_issue_relations: Autoriser les relations entre demandes de différents projets
405 406 setting_cross_project_subtasks: Autoriser les sous-tâches dans des projets différents
406 407 setting_issue_list_default_columns: Colonnes affichées par défaut sur la liste des demandes
@@ -153,6 +153,8 date_format:
153 153 default: ''
154 154 time_format:
155 155 default: ''
156 timespan_format:
157 default: 'decimal'
156 158 user_format:
157 159 default: :firstname_lastname
158 160 format: symbol
@@ -45,11 +45,11 module Redmine
45 45
46 46 def l_hours(hours)
47 47 hours = hours.to_f
48 l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => ("%.2f" % hours.to_f))
48 l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => format_hours(hours))
49 49 end
50 50
51 51 def l_hours_short(hours)
52 l(:label_f_hour_short, :value => ("%.2f" % hours.to_f))
52 l(:label_f_hour_short, :value => format_hours(hours.to_f))
53 53 end
54 54
55 55 def ll(lang, str, arg=nil)
@@ -82,6 +82,18 module Redmine
82 82 (include_date ? "#{format_date(local)} " : "") + ::I18n.l(local, options)
83 83 end
84 84
85 def format_hours(hours)
86 return "" if hours.blank?
87
88 if Setting.timespan_format == 'minutes'
89 h = hours.floor
90 m = ((hours - h) * 60).round
91 "%d:%02d" % [ h, m ]
92 else
93 "%.2f" % hours.to_f
94 end
95 end
96
85 97 def day_name(day)
86 98 ::I18n.t('date.day_names')[day % 7]
87 99 end
@@ -1544,4 +1544,24 RAW
1544 1544 stubs(:request).returns(stub(:env => {'HTTP_REFERER' => "/path?utf8=\u2713&foo=bar"}))
1545 1545 assert_equal "/path?foo=bar", back_url
1546 1546 end
1547
1548 def test_hours_formatting
1549 set_language_if_valid 'en'
1550
1551 with_settings :timespan_format => 'minutes' do
1552 assert_equal '0:45', format_hours(0.75)
1553 assert_equal '0:45 h', l_hours_short(0.75)
1554 assert_equal '0:45 hour', l_hours(0.75)
1555 end
1556 with_settings :timespan_format => 'decimal' do
1557 assert_equal '0.75', format_hours(0.75)
1558 assert_equal '0.75 h', l_hours_short(0.75)
1559 assert_equal '0.75 hour', l_hours(0.75)
1560 end
1561 end
1562
1563 def test_html_hours
1564 assert_equal '<span class="hours hours-int">0</span><span class="hours hours-dec">:45</span>', html_hours('0:45')
1565 assert_equal '<span class="hours hours-int">0</span><span class="hours hours-dec">.75</span>', html_hours('0.75')
1566 end
1547 1567 end
General Comments 0
You need to be logged in to leave comments. Login now