diff --git a/app/views/gantts/show.html.erb b/app/views/gantts/show.html.erb index 4f3026065..d0f4f9f29 100644 --- a/app/views/gantts/show.html.erb +++ b/app/views/gantts/show.html.erb @@ -67,6 +67,11 @@ t_height = g_height + headers_height %> + +<% if @gantt.truncated %> +

<%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %>

+<% end %> +
diff --git a/app/views/settings/_issues.rhtml b/app/views/settings/_issues.rhtml index 4280e44b5..273d4b581 100644 --- a/app/views/settings/_issues.rhtml +++ b/app/views/settings/_issues.rhtml @@ -8,6 +8,8 @@

<%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %>

<%= setting_text_field :issues_export_limit, :size => 6 %>

+ +

<%= setting_text_field :gantt_items_limit, :size => 6 %>

<%= l(:setting_issue_list_default_columns) %> diff --git a/config/locales/en.yml b/config/locales/en.yml index e559d01c2..0cd45deed 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -163,6 +163,7 @@ en: notice_unable_delete_version: Unable to delete version. notice_unable_delete_time_entry: Unable to delete time log entry. notice_issue_done_ratios_updated: Issue done ratios updated. + notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed ({{max}})" error_can_t_load_default_data: "Default configuration could not be loaded: {{value}}" error_scm_not_found: "The entry or revision was not found in the repository." @@ -356,6 +357,7 @@ en: setting_default_notification_option: Default notification option setting_commit_logtime_enabled: Enable time logging setting_commit_logtime_activity_id: Activity for logged time + setting_gantt_items_limit: Maximum number of items displayed on the gantt chart permission_add_project: Create project permission_add_subprojects: Create subprojects diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 897c6312f..f7438c158 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -180,6 +180,7 @@ fr: notice_unable_delete_version: Impossible de supprimer cette version. notice_issue_done_ratios_updated: L'avancement des demandes a été mis à jour. notice_api_access_key_reseted: Votre clé d'accès API a été réinitialisée. + notice_gantt_chart_truncated: "Le diagramme a été tronqué car il excède le nombre maximal d'éléments pouvant être affichés ({{max}})" error_can_t_load_default_data: "Une erreur s'est produite lors du chargement du paramétrage : {{value}}" error_scm_not_found: "L'entrée et/ou la révision demandée n'existe pas dans le dépôt." @@ -360,6 +361,7 @@ fr: setting_cache_formatted_text: Mettre en cache le texte formaté setting_commit_logtime_enabled: Permettre la saisie de temps setting_commit_logtime_activity_id: Activité pour le temps saisi + setting_gantt_items_limit: Nombre maximum d'éléments affichés sur le gantt permission_add_project: Créer un projet permission_add_subprojects: Créer des sous-projets diff --git a/config/settings.yml b/config/settings.yml index 74647eb5a..6a9676a90 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -66,6 +66,9 @@ protocol: feeds_limit: format: int default: 15 +gantt_items_limit: + format: int + default: 500 # Maximum size of files that can be displayed # inline through the file viewer (in KB) file_max_size_displayed: diff --git a/lib/redmine/helpers/gantt.rb b/lib/redmine/helpers/gantt.rb index 79088dfe5..754d31de6 100644 --- a/lib/redmine/helpers/gantt.rb +++ b/lib/redmine/helpers/gantt.rb @@ -34,7 +34,7 @@ module Redmine end end - attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months + attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months, :truncated, :max_rows attr_accessor :query attr_accessor :project attr_accessor :view @@ -71,6 +71,13 @@ module Redmine @subjects = '' @lines = '' @number_of_rows = nil + + @truncated = false + if options.has_key?(:max_rows) + @max_rows = options[:max_rows] + else + @max_rows = Setting.gantt_items_limit.blank? ? nil : Setting.gantt_items_limit.to_i + end end def common_params @@ -94,13 +101,15 @@ module Redmine def number_of_rows return @number_of_rows if @number_of_rows - if @project - return number_of_rows_on_project(@project) + rows = if @project + number_of_rows_on_project(@project) else Project.roots.visible.has_module('issue_tracking').inject(0) do |total, project| total += number_of_rows_on_project(project) end end + + rows > @max_rows ? @max_rows : rows end # Returns the number of rows that will be used to list a project on @@ -156,6 +165,7 @@ module Redmine else Project.roots.visible.has_module('issue_tracking').each do |project| render_project(project, options) + break if abort? end end @@ -176,22 +186,26 @@ module Redmine options[:top] += options[:top_increment] options[:indent] += options[:indent_increment] @number_of_rows += 1 + return if abort? # Second, Issues without a version - issues = project.issues.for_gantt.without_version.with_query(@query) + issues = project.issues.for_gantt.without_version.with_query(@query).all(:limit => current_limit) sort_issues!(issues) if issues render_issues(issues, options) + return if abort? end # Third, Versions project.versions.sort.each do |version| render_version(version, options) + return if abort? end # Fourth, subprojects project.children.visible.has_module('issue_tracking').each do |project| render_project(project, options) + return if abort? end # Remove indent to hit the next sibling @@ -205,6 +219,7 @@ module Redmine options[:top] += options[:top_increment] @number_of_rows += 1 + return if abort? end end @@ -215,13 +230,14 @@ module Redmine options[:top] += options[:top_increment] @number_of_rows += 1 + return if abort? # Remove the project requirement for Versions because it will # restrict issues to only be on the current project. This # ends up missing issues which are assigned to shared versions. @query.project = nil if @query.project - issues = version.fixed_issues.for_gantt.with_query(@query) + issues = version.fixed_issues.for_gantt.with_query(@query).all(:limit => current_limit) if issues sort_issues!(issues) # Indent issues @@ -961,6 +977,20 @@ module Redmine end end + def current_limit + if @max_rows + @max_rows - @number_of_rows + else + nil + end + end + + def abort? + if @max_rows && @number_of_rows >= @max_rows + @truncated = true + end + end + def pdf_new_page?(options) if options[:top] > 180 options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top]) diff --git a/test/unit/lib/redmine/helpers/gantt_test.rb b/test/unit/lib/redmine/helpers/gantt_test.rb index f54dfe350..401eabf43 100644 --- a/test/unit/lib/redmine/helpers/gantt_test.rb +++ b/test/unit/lib/redmine/helpers/gantt_test.rb @@ -53,9 +53,9 @@ class Redmine::Helpers::GanttTest < ActiveSupport::TestCase end # Creates a Gantt chart for a 4 week span - def create_gantt(project=Project.generate!) + def create_gantt(project=Project.generate!, options={}) @project = project - @gantt = Redmine::Helpers::Gantt.new + @gantt = Redmine::Helpers::Gantt.new(options) @gantt.project = @project @gantt.query = Query.generate_default!(:project => @project) @gantt.view = build_view @@ -73,6 +73,22 @@ class Redmine::Helpers::GanttTest < ActiveSupport::TestCase should "return the total number of rows for all the projects, resursively" end + should "not exceed max_rows option" do + p = Project.generate! + 5.times do + Issue.generate_for_project!(p) + end + + create_gantt(p) + @gantt.render + assert_equal 6, @gantt.number_of_rows + assert !@gantt.truncated + + create_gantt(p, :max_rows => 3) + @gantt.render + assert_equal 3, @gantt.number_of_rows + assert @gantt.truncated + end end context "#number_of_rows_on_project" do