Index: show.rhtml =================================================================== --- app/views/versions/show.rhtml (revision 1682) +++ app/views/versions/show.rhtml (working copy) @@ -9,14 +9,23 @@
<%= l(:label_time_tracking) %> - - + + <% if User.current.allowed_to?(:view_time_entries, @project) %> - - + + + + + + + + <% title = "#{l(:label_spent_time)} + #{l(:label_remaining_time)}" %> + + + <% end %>
<%= l(:field_estimated_hours) %><%= html_hours(lwr(:label_f_hour, @version.estimated_hours)) %><%= l(:field_estimated_hours) %><%= html_hours(lwr(:label_f_hour, @version.estimated_hours)) %>
<%= l(:label_spent_time) %><%= html_hours(lwr(:label_f_hour, @version.spent_hours)) %><%= l(:label_spent_time) %><%= html_hours(lwr(:label_f_hour, @version.spent_hours)) %>
<%= l(:label_remaining_time) %><%= html_hours(lwr(:label_f_hour, @version.remaining_hours)) %>
<%= l(:label_current_total_time) %><%= html_hours(lwr(:label_f_hour, @version.total_hours)) %>
Index: app/views/versions/_issue_counts.rhtml =================================================================== --- app/views/versions/_issue_counts.rhtml (revision 1682) +++ app/views/versions/_issue_counts.rhtml (working copy) @@ -8,26 +8,97 @@ :onchange => remote_function(:url => { :action => :status_by, :id => version }, :with => "Form.serialize('status_by_form')"))) %> -<% if counts.empty? %> +<% if grouped_metrics.empty? %>

<%= l(:label_no_data) %>

<% else %> - - <% counts.each do |count| %> - - - - +
- <%= link_to count[:group], {:controller => 'issues', - :action => 'index', - :project_id => version.project, - :set_filter => 1, - :fixed_version_id => version, - "#{criteria}_id" => count[:group]} %> - - <%= progress_bar((count[:closed].to_f / count[:total])*100, - :legend => "#{count[:closed]}/#{count[:total]}", - :width => "#{(count[:total].to_f / max * 200).floor}px;") %> -
+ <% grouped_metrics.each do |metrics_group| + category, metrics = *metrics_group + %> + <% color_class = cycle('odd', 'even')%> + + + + + + <% if spent_time_allowed %> + + <% end %> + + <% if spent_time_allowed %> + + + <% max_progress_width = 70 %> + <% else + max_progress_width = 150 + end %> + + + + <% + time = metrics[:time] + if spent_time_allowed %> + + <% end %> + <% hours = l(:text_hours_short) %> + + <% if spent_time_allowed %> + + + <% end %> + <% end %>
+ <%= criteria_operator = category ? "=" : "!*" + link_to category || "[#{l(:text_not_assigned)}]", + {:controller => 'issues', + :action => 'index', + :project_id => version.project, + :set_filter => 1, + :fields => ["#{criteria}_id", "fixed_version_id", "status_id"], + :values => {"#{criteria}_id" => [category], "fixed_version_id" => [version], "status_id" => [1]}, + :operators => {"#{criteria}_id" => criteria_operator, "fixed_version_id" => "=", "status_id" => "*"} + } + %> +
<%= l(:label_issues_count) %> <%= l(:label_time) %> + + <%= l(:label_estimated_time_short) %> + + + + <%= l(:label_spent_time_short) %> + + + + <%= l(:label_remaining_time_short) %> + +
+ <%= count = metrics[:count]; progress_bar((count[:closed].to_f / count[:total])*100, + :legend => + "" + + "#{count[:closed]}/" + + "" + + "#{count[:total]}", + :width => "#{(count[:total].to_f / max[:count] * max_progress_width).floor}px;") %> + + <%= progress_bar(time_progress(time)*100, + :legend => + "" + + "#{time[:spent].ceil}/" + + "" + + "#{time[:total].ceil}", + :width => "#{(time[:total] / max[:time] * max_progress_width).floor}px;") %> + + + <%= "#{time[:estimated].ceil}#{hours}" %> + + + + <%= "#{time[:spent].ceil}#{hours}" %> + + + + <%= "#{time[:remaining].ceil}#{hours}" %> + +
<% end %> Index: app/helpers/versions_helper.rb =================================================================== --- app/helpers/versions_helper.rb (revision 1682) +++ app/helpers/versions_helper.rb (working copy) @@ -23,23 +23,32 @@ criteria ||= 'category' raise 'Unknown criteria' unless STATUS_BY_CRITERIAS.include?(criteria) - h = Hash.new {|k,v| k[v] = [0, 0]} - begin - # Total issue count - Issue.count(:group => criteria, - :conditions => ["#{Issue.table_name}.fixed_version_id = ?", version.id]).each {|c,s| h[c][0] = s} - # Open issues count - Issue.count(:group => criteria, - :include => :status, - :conditions => ["#{Issue.table_name}.fixed_version_id = ? AND #{IssueStatus.table_name}.is_closed = ?", version.id, false]).each {|c,s| h[c][1] = s} - rescue ActiveRecord::RecordNotFound - # When grouping by an association, Rails throws this exception if there's no result (bug) + #sort them alphabetically by category name + metrics = version.get_grouped_metrics(criteria).to_a.sort {|x, y| x[0].to_s <=> y[0].to_s} + max = {} + + [{:count => :total}, {:time => :total}].each do |metric_info| + metrics_group, total_metric = metric_info.to_a.flatten + max[metrics_group] = metrics.map{|item| item[1]}.map {|item| item[metrics_group]}.map {|item| item[total_metric]}.max + max[metrics_group] = 1 if max[metrics_group] == 0 end - counts = h.keys.compact.sort.collect {|k| {:group => k, :total => h[k][0], :open => h[k][1], :closed => (h[k][0] - h[k][1])}} - max = counts.collect {|c| c[:total]}.max - render :partial => 'issue_counts', :locals => {:version => version, :criteria => criteria, :counts => counts, :max => max} + render :partial => 'issue_counts', :locals => {:version => version, + :criteria => criteria, :grouped_metrics => metrics, :max => max, + :spent_time_allowed => User.current.allowed_to?(:view_time_entries, @project), + } end + + def time_progress(time_info) + logger.debug "time_info[:spent] = #{time_info[:spent].inspect}" + logger.debug "time_info[:total] = #{time_info[:total].inspect}" + if (time_info[:total] != 0) + time_progress = time_info[:spent].to_f / time_info[:total] + else + time_progress = 0 #no total also means there's no spent time + end + time_progress + end def status_by_options_for_select(value) options_for_select(STATUS_BY_CRITERIAS.collect {|criteria| [l("field_#{criteria}".to_sym), criteria]}, value) Index: app/models/version.rb =================================================================== --- app/models/version.rb (revision 1682) +++ app/models/version.rb (working copy) @@ -43,7 +43,29 @@ def spent_hours @spent_hours ||= TimeEntry.sum(:hours, :include => :issue, :conditions => ["#{Issue.table_name}.fixed_version_id = ?", id]).to_f end + + def calc_remaining_and_total_time + @remaining_hours = 0 + @total_hours = 0 + get_grouped_metrics(:category).to_a.map{|item| item[1]}.map {|item| item[:time]}.each do |times| + @remaining_hours += times[:remaining] + @total_hours += times[:total] + end + end + + def remaining_hours + return @remaining_hours if @remaining_hours + calc_remaining_and_total_time + @remaining_hours + end + + def total_hours + return @total_hours if @total_hours + calc_remaining_and_total_time + @total_hours + end + # Returns true if the version is completed: due date reached and no open issues def completed? effective_date && (effective_date <= Date.today) && (open_issues_count == 0) @@ -99,7 +121,53 @@ end end -private + def get_grouped_metrics(criteria) + condition = issues_version_condition + + issues = Issue.find(:all, :include => [:status, criteria], + :conditions => condition) + + spent_times = {} + TimeEntry.sum(:hours, :group => :issue_id, :include => :issue, + :conditions => condition).each do |issue_id, hours| + + spent_times[issue_id] = hours + end + + categories_metrics = {} + issues.each do |issue| + category = issue.send(criteria) + categories_metrics[category] ||= {} + categories_metrics[category][:time] ||= {:estimated => 0, + :spent => 0, :remaining => 0, :total => 0} + metrics = categories_metrics[category][:time] + + estimated = issue.estimated_hours || 0 + metrics[:estimated] += estimated + spent = spent_times[issue.id] || 0 + metrics[:spent] += spent + remaining = issue.closed? ? 0 : estimated - spent + remaining = 0 if remaining < 0 + metrics[:remaining] += remaining + metrics[:total] += (remaining + spent) + + categories_metrics[category][:count] ||= {:open => 0, :closed => 0, :total => 0} + metrics = categories_metrics[category][:count] + metrics[:total] += 1 + if issue.closed? + metrics[:closed] += 1 + else + metrics[:open] += 1 + end + end + categories_metrics + end + + def issues_version_condition + ["#{Issue.table_name}.fixed_version_id = ?", id] + end + + private def check_integrity raise "Can't delete version" if self.fixed_issues.find(:first) end Index: public/stylesheets/application.css =================================================================== --- public/stylesheets/application.css (revision 1682) +++ public/stylesheets/application.css (working copy) @@ -616,3 +616,52 @@ #main { background: #fff; } #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; } } + +div.category_metrics { + padding: 0.5em 0 0.5em 0; +} + +table.category_metrics { + border-collapse: collapse; +} + +.category_metrics .header { + font-weight:bold; +} + +.category_metrics th { + text-align: left; + font-weight:normal; +} + +.category_metrics td.progress { + text-align: left; + white-space: nowrap; +} + +.category_metrics td.progress.count { + width: 30%; +} + +.category_metrics td.progress.time { + width: 30%; +} + +th.metric_comment, td.metric_comment { + font-weight:normal; + font-size:90%; + width: 5%; +} + +#version-summary td.label { + text-align:right; + width: 40%; +} + +#version-summary td.total-hours { + text-align:right; +} + +#version-summary table { + width:100%; +} Index: test/unit/version_test.rb =================================================================== --- test/unit/version_test.rb (revision 0) +++ test/unit/version_test.rb (revision 0) @@ -0,0 +1,61 @@ +# redMine - project management software +# Copyright (C) 2006-2008 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.dirname(__FILE__) + '/../test_helper' + +class VersionTest < Test::Unit::TestCase + fixtures :all + + def verify_counts(count_metrics, open, closed) + assert_equal open + closed, count_metrics[:total] + assert_equal open, count_metrics[:open] + assert_equal closed, count_metrics[:closed] + end + + def test_get_grouped_metrics_count + version = versions(:versions_002) + grouped_metrics = version.get_grouped_metrics(:tracker) + verify_counts(grouped_metrics[trackers(:trackers_001)][:count], 2, 1) + verify_counts(grouped_metrics[trackers(:trackers_002)][:count], 1, 0) + end + + def test_get_grouped_metrics_time + version = versions(:versions_002) + grouped_metrics = version.get_grouped_metrics(:tracker) + time_metrics = grouped_metrics[trackers(:trackers_001)][:time] + + estimated = [:issues_001, :issues_003, :issues_007].inject(0) do |prev, current| + issues(current).estimated_hours + prev + end + + assert_equal estimated, time_metrics[:estimated] + + spent = [:issues_001, :issues_003].inject(0) do |prev, current| + issues(current).spent_hours + prev + end + assert_equal spent, time_metrics[:spent] + + i3 = issues(:issues_003) + #issue 1 is not counted because it spent more than estimated; + # issue 7 not counted because because it's closed + remaining = i3.estimated_hours - i3.spent_hours + assert_equal remaining, time_metrics[:remaining] + + assert_equal spent + remaining, time_metrics[:total] + end + +end Index: test/unit/enumeration_test.rb =================================================================== --- test/unit/enumeration_test.rb (revision 1682) +++ test/unit/enumeration_test.rb (working copy) @@ -25,7 +25,7 @@ def test_objects_count # low priority - assert_equal 5, Enumeration.find(4).objects_count + assert_equal 7, Enumeration.find(4).objects_count # urgent assert_equal 0, Enumeration.find(7).objects_count end @@ -40,6 +40,6 @@ def test_destroy_with_reassign Enumeration.find(4).destroy(Enumeration.find(6)) assert_nil Issue.find(:first, :conditions => {:priority_id => 4}) - assert_equal 5, Enumeration.find(6).objects_count + assert_equal 7, Enumeration.find(6).objects_count end end Index: test/unit/user_test.rb =================================================================== --- test/unit/user_test.rb (revision 1682) +++ test/unit/user_test.rb (working copy) @@ -118,7 +118,7 @@ assert_equal "Manager", role.name # user with no role - assert !@dlopper.role_for_project(Project.find(2)).member? + assert !@dlopper.role_for_project(Project.find(3)).member? end def test_mail_notification_all Index: test/functional/versions_controller_test.rb =================================================================== --- test/functional/versions_controller_test.rb (revision 1682) +++ test/functional/versions_controller_test.rb (working copy) @@ -22,7 +22,7 @@ class VersionsController; def rescue_action(e) raise e end; end class VersionsControllerTest < Test::Unit::TestCase - fixtures :projects, :versions, :issues, :users, :roles, :members, :enabled_modules + fixtures :projects, :versions, :issues, :users, :roles, :members, :enabled_modules, :issue_statuses, :trackers def setup @controller = VersionsController.new @@ -31,15 +31,49 @@ User.current = nil end - def test_show - get :show, :id => 2 + {:view_time_entries_allowed => {:version_id => 2}, + :view_time_entries_not_allowed => {:user_id => 3, :version_id => 4} + }.each do |case_key, case_info| + define_method "test_show_when_#{case_key}" do + @request.session[:user_id] = case_info[:user_id] if case_info[:user_id] + if case_info[:verify] + case_info[:verify].call() + end + get :show, :id => case_info[:version_id] + assert_response :success + assert_template 'show' + assert_not_nil assigns(:version) + + assert_tag :tag => 'h2', :content => Version.find(case_info[:version_id]).name + end + + define_method "test_issue_status_by_when_#{case_key}" do + @request.session[:user_id] = case_info[:user_id] if case_info[:user_id] + xhr :get, :status_by, :id => case_info[:version_id] + assert_response :success + assert_template '_issue_counts' + end + end + + #specific bug was reproduced when there were no time records and all the issues were closed + def test_issue_status_by_no_division_by_zero + version = versions(:versions_003) + user = users(:users_002) + @request.session[:user_id] = user.id + + assert version.fixed_issues.size > 0, "version should have issues" + project = version.project + assert user.allowed_to?(:view_time_entries, project), "user should have :view_time_entries permission to project #{project.id}" + version.fixed_issues.all? do |i| + assert_equal 0, i.spent_hours + assert !i.estimated_hours || i.estimated_hours == 0 + assert i.closed? + end + xhr :get, :status_by, :id => version.id assert_response :success - assert_template 'show' - assert_not_nil assigns(:version) - - assert_tag :tag => 'h2', :content => /1.0/ + assert_template '_issue_counts' end - + def test_get_edit @request.session[:user_id] = 2 get :edit, :id => 2 @@ -60,14 +94,10 @@ def test_destroy @request.session[:user_id] = 2 - post :destroy, :id => 3 + version = versions(:versions_001) + assert version.fixed_issues.empty?, "version should have no issues" + post :destroy, :id => version.id assert_redirected_to 'projects/settings/ecookbook' - assert_nil Version.find_by_id(3) + assert_nil Version.find_by_id(version.id) end - - def test_issue_status_by - xhr :get, :status_by, :id => 2 - assert_response :success - assert_template '_issue_counts' - end end Index: test/fixtures/roles.yml =================================================================== --- test/fixtures/roles.yml (revision 1682) +++ test/fixtures/roles.yml (working copy) @@ -160,4 +160,20 @@ - :view_changesets position: 5 - \ No newline at end of file + +roles_006: + name: NoTimeEntries + id: 6 + builtin: 0 + permissions: | + --- + - :add_issue_notes + - :view_gantt + - :view_calendar + - :view_documents + - :view_wiki_pages + - :view_files + - :browse_repository + - :view_changesets + + position: 6 Index: test/fixtures/issues.yml =================================================================== --- test/fixtures/issues.yml (revision 1682) +++ test/fixtures/issues.yml (working copy) @@ -6,7 +6,7 @@ priority_id: 4 subject: Can't print recipes id: 1 - fixed_version_id: + fixed_version_id: 2 category_id: 1 description: Unable to print recipes tracker_id: 1 @@ -15,6 +15,7 @@ status_id: 1 start_date: <%= 1.day.ago.to_date.to_s(:db) %> due_date: <%= 10.day.from_now.to_date.to_s(:db) %> + estimated_hours: 100 issues_002: created_on: 2006-07-19 21:04:21 +02:00 project_id: 1 @@ -38,7 +39,7 @@ priority_id: 4 subject: Error 281 when updating a recipe id: 3 - fixed_version_id: + fixed_version_id: 2 category_id: description: Error 281 is encountered when saving a recipe tracker_id: 1 @@ -47,6 +48,7 @@ status_id: 1 start_date: <%= 1.day.from_now.to_date.to_s(:db) %> due_date: <%= 40.day.ago.to_date.to_s(:db) %> + estimated_hours: 2 issues_004: created_on: <%= 5.days.ago.to_date.to_s(:db) %> project_id: 2 @@ -54,7 +56,7 @@ priority_id: 4 subject: Issue on project 2 id: 4 - fixed_version_id: + fixed_version_id: 4 category_id: description: Issue on project 2 tracker_id: 1 @@ -91,4 +93,36 @@ status_id: 1 start_date: <%= Date.today.to_s(:db) %> due_date: <%= 1.days.from_now.to_date.to_s(:db) %> - \ No newline at end of file +issues_007: + created_on: 2006-07-19 21:07:27 +02:00 + project_id: 1 + updated_on: 2006-07-19 21:07:27 +02:00 + priority_id: 4 + subject: Some closed bug for version 1.0 + id: 7 + fixed_version_id: 2 + category_id: + description: Some closed bug for version 1.0 + tracker_id: 1 + assigned_to_id: 3 + author_id: 2 + status_id: 6 + start_date: <%= 1.day.from_now.to_date.to_s(:db) %> + due_date: <%= 40.day.ago.to_date.to_s(:db) %> + estimated_hours: 10 +issues_008: + created_on: <%= 1.minute.ago.to_date.to_s(:db) %> + project_id: 1 + updated_on: <%= 1.minute.ago.to_date.to_s(:db) %> + priority_id: 4 + subject: Issue of version 3 + id: 8 + fixed_version_id: 3 + category_id: + description: Issue of version 3 + tracker_id: 1 + assigned_to_id: + author_id: 2 + status_id: 6 + start_date: <%= Date.today.to_s(:db) %> + due_date: <%= 1.days.from_now.to_date.to_s(:db) %> Index: test/fixtures/members.yml =================================================================== --- test/fixtures/members.yml (revision 1682) +++ test/fixtures/members.yml (working copy) @@ -30,4 +30,9 @@ project_id: 5 role_id: 1 user_id: 2 - \ No newline at end of file +members_006: + created_on: 2006-07-19 19:35:36 +02:00 + project_id: 2 + role_id: 6 + id: 6 + user_id: 3 Index: test/fixtures/versions.yml =================================================================== --- test/fixtures/versions.yml (revision 1682) +++ test/fixtures/versions.yml (working copy) @@ -23,4 +23,12 @@ id: 3 description: Future version effective_date: - \ No newline at end of file +versions_004: + created_on: 2006-07-19 21:00:33 +02:00 + name: "1.0" + project_id: 2 + updated_on: 2006-07-19 21:00:33 +02:00 + id: 4 + description: 1.0 + effective_date: 2008-07-21 + Index: lang/en.yml =================================================================== --- lang/en.yml (revision 1682) +++ lang/en.yml (working copy) @@ -520,6 +520,13 @@ label_planning: Planning label_incoming_emails: Incoming emails label_generate_key: Generate a key +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time button_login: Login button_submit: Submit @@ -607,6 +614,8 @@ text_enumeration_destroy_question: '%d objects are assigned to this value.' text_enumeration_category_reassign_to: 'Reassign them to this value:' text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +text_not_assigned: Not assigned +text_hours_short: h default_role_manager: Manager default_role_developper: Developer @@ -633,3 +642,4 @@ enumeration_issue_priorities: Issue priorities enumeration_doc_categories: Document categories enumeration_activities: Activities (time tracking) + Index: lang/ru.yml =================================================================== --- lang/ru.yml (revision 1682) +++ lang/ru.yml (working copy) @@ -471,6 +471,13 @@ label_associated_revisions: Связанные редакции label_issues_by: Сортировать по %s label_display_per_page: 'На страницу: %s' +label_remaining_time: Осталось +label_current_total_time: Всего +label_estimated_time_short: Оценка +label_spent_time_short: Затр. +label_remaining_time_short: Ост. +label_issues_count: Число задач +label_time: Время button_login: Вход button_submit: Принять @@ -542,6 +549,8 @@ text_caracters_minimum: Должно быть не менее %d знаков. text_load_default_configuration: Загрузить конфигурацию по-умолчанию text_no_configuration_data: "Роли, трекеры, статусы задач и оперативный план не были сконфигурированы.\nНастоятельно рекомендуется загрузить конфигурацию по-умолчанию. Вы сможете её изменить потом." +text_not_assigned: Не назначено +text_hours_short: ч default_role_manager: Менеджер default_role_developper: Разработчик Index: lang/lt.yml =================================================================== --- lang/lt.yml (revision 1682) +++ lang/lt.yml (working copy) @@ -635,3 +635,12 @@ setting_mail_handler_api_key: API raktas text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/uk.yml =================================================================== --- lang/uk.yml (revision 1682) +++ lang/uk.yml (working copy) @@ -634,3 +634,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/ro.yml =================================================================== --- lang/ro.yml (revision 1682) +++ lang/ro.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/zh.yml =================================================================== --- lang/zh.yml (revision 1682) +++ lang/zh.yml (working copy) @@ -633,3 +633,12 @@ enumeration_doc_categories: 文档类别 enumeration_activities: 活动(时间跟踪) text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/pt.yml =================================================================== --- lang/pt.yml (revision 1682) +++ lang/pt.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/da.yml =================================================================== --- lang/da.yml (revision 1682) +++ lang/da.yml (working copy) @@ -634,3 +634,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/pt-br.yml =================================================================== --- lang/pt-br.yml (revision 1682) +++ lang/pt-br.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/sr.yml =================================================================== --- lang/sr.yml (revision 1682) +++ lang/sr.yml (working copy) @@ -633,3 +633,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/de.yml =================================================================== --- lang/de.yml (revision 1682) +++ lang/de.yml (working copy) @@ -633,3 +633,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/bg.yml =================================================================== --- lang/bg.yml (revision 1682) +++ lang/bg.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/sv.yml =================================================================== --- lang/sv.yml (revision 1682) +++ lang/sv.yml (working copy) @@ -633,3 +633,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/ja.yml =================================================================== --- lang/ja.yml (revision 1682) +++ lang/ja.yml (working copy) @@ -633,3 +633,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/he.yml =================================================================== --- lang/he.yml (revision 1682) +++ lang/he.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/fi.yml =================================================================== --- lang/fi.yml (revision 1682) +++ lang/fi.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/cs.yml =================================================================== --- lang/cs.yml (revision 1682) +++ lang/cs.yml (working copy) @@ -637,3 +637,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/fr.yml =================================================================== --- lang/fr.yml (revision 1682) +++ lang/fr.yml (working copy) @@ -633,3 +633,12 @@ enumeration_issue_priorities: Priorités des demandes enumeration_doc_categories: Catégories des documents enumeration_activities: Activités (suivi du temps) +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/es.yml =================================================================== --- lang/es.yml (revision 1682) +++ lang/es.yml (working copy) @@ -635,3 +635,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/nl.yml =================================================================== --- lang/nl.yml (revision 1682) +++ lang/nl.yml (working copy) @@ -633,3 +633,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/ko.yml =================================================================== --- lang/ko.yml (revision 1682) +++ lang/ko.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/zh-tw.yml =================================================================== --- lang/zh-tw.yml (revision 1682) +++ lang/zh-tw.yml (working copy) @@ -633,3 +633,12 @@ enumeration_issue_priorities: 項目優先權 enumeration_doc_categories: 文件分類 enumeration_activities: 活動 (時間追蹤) +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/pl.yml =================================================================== --- lang/pl.yml (revision 1682) +++ lang/pl.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/th.yml =================================================================== --- lang/th.yml (revision 1682) +++ lang/th.yml (working copy) @@ -635,3 +635,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/no.yml =================================================================== --- lang/no.yml (revision 1682) +++ lang/no.yml (working copy) @@ -633,3 +633,12 @@ setting_mail_handler_api_enabled: Enable WS for incoming emails setting_mail_handler_api_key: API key text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/it.yml =================================================================== --- lang/it.yml (revision 1682) +++ lang/it.yml (working copy) @@ -632,3 +632,12 @@ setting_mail_handler_api_enabled: Abilita WS per le e-mail in arrivo setting_mail_handler_api_key: chiave API text_email_delivery_not_configured: "La consegna via e-mail non è configurata e le notifiche sono disabilitate.\nConfigura il tuo server SMTP in config/email.yml e riavvia l'applicazione per abilitarle." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned Index: lang/hu.yml =================================================================== --- lang/hu.yml (revision 1682) +++ lang/hu.yml (working copy) @@ -633,3 +633,12 @@ setting_mail_handler_api_enabled: Web Service engedélyezése a beérkezett levelekhez setting_mail_handler_api_key: API kulcs text_email_delivery_not_configured: "Az E-mail küldés nincs konfigurálva, és az értesítések ki vannak kapcsolva.\nÁllítsd be az SMTP szervert a config/email.yml fájlban és indítsd újra az alkalmazást, hogy érvénybe lépjen." +label_remaining_time: Remaining time +label_current_total_time: Total +label_estimated_time_short: Est. +label_spent_time_short: Spent +label_remaining_time_short: Rem. +label_issues_count: Count +label_time: Time +text_hours_short: h +text_not_assigned: Not assigned