From 9c7ee001bd4db29bc3babb793c6b805d7dc7dac9 Mon Sep 17 00:00:00 2001 From: Jens Kraemer Date: Tue, 14 Jun 2016 19:09:43 +0800 Subject: [PATCH 1/2] introduces a setting to have durations displayed as hours and minutes --- app/helpers/application_helper.rb | 2 +- app/helpers/queries_helper.rb | 9 ++++++++- app/views/issues/_attributes.html.erb | 2 +- app/views/issues/_edit.html.erb | 2 +- app/views/my/blocks/_timelog.html.erb | 6 +++--- app/views/settings/_display.html.erb | 2 ++ app/views/timelog/_form.html.erb | 2 +- app/views/timelog/_report_criteria.html.erb | 4 ++-- app/views/timelog/report.html.erb | 4 ++-- config/locales/de.yml | 1 + config/locales/en.yml | 1 + config/settings.yml | 2 ++ lib/redmine/i18n.rb | 16 ++++++++++++++-- test/unit/helpers/application_helper_test.rb | 18 ++++++++++++++++++ 14 files changed, 57 insertions(+), 14 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 4a421b1..6afc137 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -423,7 +423,7 @@ module ApplicationHelper end def html_hours(text) - text.gsub(%r{(\d+)\.(\d+)}, '\1.\2').html_safe + text.gsub(%r{(\d+)([\.:])(\d+)}, '\1\2\3').html_safe end def authoring(created, author, options={}) diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index 6bf8b31..600edd2 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -149,7 +149,12 @@ module QueriesHelper def total_tag(column, value) label = content_tag('span', "#{column.caption}:") - value = content_tag('span', format_object(value), :class => 'value') + value = if [:hours, :spent_hours, :total_spent_hours, :estimated_hours].include? column.name + format_hours(value) + else + format_object(value) + end + value = content_tag('span', value, :class => 'value') content_tag('span', label + " " + value, :class => "total-for-#{column.name.to_s.dasherize}") end @@ -184,6 +189,8 @@ module QueriesHelper content_tag('span', value.to_s(issue) {|other| link_to_issue(other, :subject => false, :tracker => false)}.html_safe, :class => value.css_classes_for(issue)) + when :hours, :spent_hours, :total_spent_hours, :estimated_hours + format_hours(value) else format_object(value) end diff --git a/app/views/issues/_attributes.html.erb b/app/views/issues/_attributes.html.erb index 960256e..f8acef5 100644 --- a/app/views/issues/_attributes.html.erb +++ b/app/views/issues/_attributes.html.erb @@ -65,7 +65,7 @@ <% end %> <% if @issue.safe_attribute? 'estimated_hours' %> -

<%= f.text_field :estimated_hours, :size => 3, :required => @issue.required_attribute?('estimated_hours') %> <%= l(:field_hours) %>

+

<%= f.text_field :estimated_hours, :size => 3, :required => @issue.required_attribute?('estimated_hours'), :value => format_hours(@issue.estimated_hours) %> <%= l(:field_hours) %>

<% end %> <% if @issue.safe_attribute?('done_ratio') && Issue.use_field_for_done_ratio? %> diff --git a/app/views/issues/_edit.html.erb b/app/views/issues/_edit.html.erb index 3291ba7..0a642f2 100644 --- a/app/views/issues/_edit.html.erb +++ b/app/views/issues/_edit.html.erb @@ -14,7 +14,7 @@ <%= labelled_fields_for :time_entry, @time_entry do |time_entry| %>
-

<%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %>

+

<%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time, :value => format_hours(@time_entry.hours) %> <%= l(:field_hours) %>

<%= time_entry.select :activity_id, activity_collection_for_select_options %>

diff --git a/app/views/my/blocks/_timelog.html.erb b/app/views/my/blocks/_timelog.html.erb index 14a0711..ec02087 100644 --- a/app/views/my/blocks/_timelog.html.erb +++ b/app/views/my/blocks/_timelog.html.erb @@ -14,7 +14,7 @@ entries_by_day = entries.group_by(&:spent_on) <% end %>
-

<%= l(:label_total_time) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %>

+

<%= l(:label_total_time) %>: <%= html_hours(l_hours_short(entries.sum(&:hours))) %>

<% if entries.any? %> @@ -31,7 +31,7 @@ entries_by_day = entries.group_by(&:spent_on) <%= day == User.current.today ? l(:label_today).titleize : format_date(day) %> - <%= html_hours("%.2f" % entries_by_day[day].sum(&:hours).to_f) %> + <%= html_hours(l_hours_short(entries_by_day[day].sum(&:hours))) %> <% entries_by_day[day].each do |entry| -%> @@ -39,7 +39,7 @@ entries_by_day = entries.group_by(&:spent_on) <%= entry.activity %> <%= entry.project %> <%= h(' - ') + link_to_issue(entry.issue, :truncate => 50) if entry.issue %> <%= entry.comments %> - <%= html_hours("%.2f" % entry.hours) %> + <%= html_hours(l_hours_short(entry.hours)) %> <% if entry.editable_by?(@user) -%> <%= link_to l(:button_edit), {:controller => 'timelog', :action => 'edit', :id => entry}, diff --git a/app/views/settings/_display.html.erb b/app/views/settings/_display.html.erb index be3e70e..93eaa6e 100644 --- a/app/views/settings/_display.html.erb +++ b/app/views/settings/_display.html.erb @@ -15,6 +15,8 @@

<%= setting_select :time_format, Setting::TIME_FORMATS.collect {|f| [::I18n.l(Time.now, :locale => locale, :format => f), f]}, :blank => :label_language_based %>

+

<%= setting_select :timespan_format, [["%.2f" % 0.75, 'decimal'], ['0:45 h', 'minutes']], :blank => false %>

+

<%= setting_select :user_format, @options[:user_format] %>

<%= setting_check_box :gravatar_enabled %>

diff --git a/app/views/timelog/_form.html.erb b/app/views/timelog/_form.html.erb index ebd9d39..ec35e8c 100644 --- a/app/views/timelog/_form.html.erb +++ b/app/views/timelog/_form.html.erb @@ -18,7 +18,7 @@ <% end %>

<%= f.date_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %>

-

<%= f.text_field :hours, :size => 6, :required => true %>

+

<%= f.text_field :hours, :size => 6, :required => true, :value => format_hours(@time_entry.hours) %>

<%= f.text_field :comments, :size => 100, :maxlength => 1024 %>

<%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %>

<% @time_entry.custom_field_values.each do |value| %> diff --git a/app/views/timelog/_report_criteria.html.erb b/app/views/timelog/_report_criteria.html.erb index c86b219..a74cdbf 100644 --- a/app/views/timelog/_report_criteria.html.erb +++ b/app/views/timelog/_report_criteria.html.erb @@ -8,9 +8,9 @@ <% total = 0 -%> <% @report.periods.each do |period| -%> <% sum = sum_hours(select_hours(hours_for_value, @report.columns, period.to_s)); total += sum -%> - <%= html_hours("%.2f" % sum) if sum > 0 %> + <%= html_hours(l_hours_short(sum)) if sum > 0 %> <% end -%> - <%= html_hours("%.2f" % total) if total > 0 %> + <%= html_hours(l_hours_short(total)) if total > 0 %> <% if criterias.length > level+1 -%> <%= render(:partial => 'report_criteria', :locals => {:criterias => criterias, :hours => hours_for_value, :level => (level + 1)}) %> diff --git a/app/views/timelog/report.html.erb b/app/views/timelog/report.html.erb index 05ad08b..ecab7de 100644 --- a/app/views/timelog/report.html.erb +++ b/app/views/timelog/report.html.erb @@ -52,9 +52,9 @@ <% total = 0 -%> <% @report.periods.each do |period| -%> <% sum = sum_hours(select_hours(@report.hours, @report.columns, period.to_s)); total += sum -%> - <%= html_hours("%.2f" % sum) if sum > 0 %> + <%= html_hours(l_hours_short(sum)) if sum > 0 %> <% end -%> - <%= html_hours("%.2f" % total) if total > 0 %> + <%= html_hours(l_hours_short(total)) if total > 0 %> diff --git a/config/locales/de.yml b/config/locales/de.yml index 5bdb484..60db8a6 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1047,6 +1047,7 @@ de: setting_thumbnails_enabled: Vorschaubilder von Dateianhängen anzeigen setting_thumbnails_size: Größe der Vorschaubilder (in Pixel) setting_time_format: Zeitformat + setting_timespan_format: Format für Zeitspannen setting_unsubscribe: Erlaubt Benutzern das eigene Benutzerkonto zu löschen setting_user_format: Benutzer-Anzeigeformat setting_welcome_text: Willkommenstext diff --git a/config/locales/en.yml b/config/locales/en.yml index 56a06c7..eae1469 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -389,6 +389,7 @@ en: setting_autologin: Autologin setting_date_format: Date format setting_time_format: Time format + setting_timespan_format: Time span format setting_cross_project_issue_relations: Allow cross-project issue relations setting_cross_project_subtasks: Allow cross-project subtasks setting_issue_list_default_columns: Default columns displayed on the issue list diff --git a/config/settings.yml b/config/settings.yml index 807f9b7..b9a8258 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -153,6 +153,8 @@ date_format: default: '' time_format: default: '' +timespan_format: + default: 'decimal' user_format: default: :firstname_lastname format: symbol diff --git a/lib/redmine/i18n.rb b/lib/redmine/i18n.rb index 7b4495e..dfeaf47 100644 --- a/lib/redmine/i18n.rb +++ b/lib/redmine/i18n.rb @@ -45,11 +45,11 @@ module Redmine def l_hours(hours) hours = hours.to_f - l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => ("%.2f" % hours.to_f)) + l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => format_hours(hours)) end def l_hours_short(hours) - l(:label_f_hour_short, :value => ("%.2f" % hours.to_f)) + l(:label_f_hour_short, :value => format_hours(hours.to_f)) end def ll(lang, str, arg=nil) @@ -82,6 +82,18 @@ module Redmine (include_date ? "#{format_date(local)} " : "") + ::I18n.l(local, options) end + def format_hours(hours) + return "" if hours.blank? + + if Setting.timespan_format == 'minutes' + h = hours.floor + m = ((hours - h) * 60).round + "%d:%02d" % [ h, m ] + else + "%.2f" % hours.to_f + end + end + def day_name(day) ::I18n.t('date.day_names')[day % 7] end diff --git a/test/unit/helpers/application_helper_test.rb b/test/unit/helpers/application_helper_test.rb index 7940ca1..acb7209 100644 --- a/test/unit/helpers/application_helper_test.rb +++ b/test/unit/helpers/application_helper_test.rb @@ -1543,4 +1543,22 @@ RAW stubs(:request).returns(stub(:env => {'HTTP_REFERER' => "/path?utf8=\u2713&foo=bar"})) assert_equal "/path?foo=bar", back_url end + + def test_hours_formatting + with_settings :timespan_format => 'minutes' do + assert_equal '0:45', format_hours(0.75) + assert_equal '0:45 h', l_hours_short(0.75) + assert_equal '0:45 hour', l_hours(0.75) + end + with_settings :timespan_format => 'decimal' do + assert_equal '0.75', format_hours(0.75) + assert_equal '0.75 h', l_hours_short(0.75) + assert_equal '0.75 hour', l_hours(0.75) + end + end + + def test_html_hours + assert_equal '0:45', html_hours('0:45') + assert_equal '0.75', html_hours('0.75') + end end -- 2.1.4