Commit b48291ec authored by Jean-Philippe Lang's avatar Jean-Philippe Lang

Adds an application setting to limit the number of items that can be displayed…

Adds an application setting to limit the number of items that can be displayed on the gantt chart (#6276).

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4513 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 6a586c39
...@@ -67,6 +67,11 @@ t_height = g_height + headers_height ...@@ -67,6 +67,11 @@ t_height = g_height + headers_height
%> %>
<% if @gantt.truncated %>
<p class="warning"><%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %></p>
<% end %>
<table width="100%" style="border:0; border-collapse: collapse;"> <table width="100%" style="border:0; border-collapse: collapse;">
<tr> <tr>
<td style="width:<%= subject_width %>px; padding:0px;"> <td style="width:<%= subject_width %>px; padding:0px;">
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
<p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p> <p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p>
<p><%= setting_text_field :issues_export_limit, :size => 6 %></p> <p><%= setting_text_field :issues_export_limit, :size => 6 %></p>
<p><%= setting_text_field :gantt_items_limit, :size => 6 %></p>
</div> </div>
<fieldset class="box settings"><legend><%= l(:setting_issue_list_default_columns) %></legend> <fieldset class="box settings"><legend><%= l(:setting_issue_list_default_columns) %></legend>
......
...@@ -163,6 +163,7 @@ en: ...@@ -163,6 +163,7 @@ en:
notice_unable_delete_version: Unable to delete version. notice_unable_delete_version: Unable to delete version.
notice_unable_delete_time_entry: Unable to delete time log entry. notice_unable_delete_time_entry: Unable to delete time log entry.
notice_issue_done_ratios_updated: Issue done ratios updated. 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_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." error_scm_not_found: "The entry or revision was not found in the repository."
...@@ -356,6 +357,7 @@ en: ...@@ -356,6 +357,7 @@ en:
setting_default_notification_option: Default notification option setting_default_notification_option: Default notification option
setting_commit_logtime_enabled: Enable time logging setting_commit_logtime_enabled: Enable time logging
setting_commit_logtime_activity_id: Activity for logged time 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_project: Create project
permission_add_subprojects: Create subprojects permission_add_subprojects: Create subprojects
......
...@@ -180,6 +180,7 @@ fr: ...@@ -180,6 +180,7 @@ fr:
notice_unable_delete_version: Impossible de supprimer cette version. notice_unable_delete_version: Impossible de supprimer cette version.
notice_issue_done_ratios_updated: L'avancement des demandes a été mis à jour. 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_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_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." 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: ...@@ -360,6 +361,7 @@ fr:
setting_cache_formatted_text: Mettre en cache le texte formaté setting_cache_formatted_text: Mettre en cache le texte formaté
setting_commit_logtime_enabled: Permettre la saisie de temps setting_commit_logtime_enabled: Permettre la saisie de temps
setting_commit_logtime_activity_id: Activité pour le temps saisi 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_project: Créer un projet
permission_add_subprojects: Créer des sous-projets permission_add_subprojects: Créer des sous-projets
......
...@@ -66,6 +66,9 @@ protocol: ...@@ -66,6 +66,9 @@ protocol:
feeds_limit: feeds_limit:
format: int format: int
default: 15 default: 15
gantt_items_limit:
format: int
default: 500
# Maximum size of files that can be displayed # Maximum size of files that can be displayed
# inline through the file viewer (in KB) # inline through the file viewer (in KB)
file_max_size_displayed: file_max_size_displayed:
......
...@@ -34,7 +34,7 @@ module Redmine ...@@ -34,7 +34,7 @@ module Redmine
end end
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 :query
attr_accessor :project attr_accessor :project
attr_accessor :view attr_accessor :view
...@@ -71,6 +71,13 @@ module Redmine ...@@ -71,6 +71,13 @@ module Redmine
@subjects = '' @subjects = ''
@lines = '' @lines = ''
@number_of_rows = nil @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 end
def common_params def common_params
...@@ -94,13 +101,15 @@ module Redmine ...@@ -94,13 +101,15 @@ module Redmine
def number_of_rows def number_of_rows
return @number_of_rows if @number_of_rows return @number_of_rows if @number_of_rows
if @project rows = if @project
return number_of_rows_on_project(@project) number_of_rows_on_project(@project)
else else
Project.roots.visible.has_module('issue_tracking').inject(0) do |total, project| Project.roots.visible.has_module('issue_tracking').inject(0) do |total, project|
total += number_of_rows_on_project(project) total += number_of_rows_on_project(project)
end end
end end
rows > @max_rows ? @max_rows : rows
end end
# Returns the number of rows that will be used to list a project on # Returns the number of rows that will be used to list a project on
...@@ -156,6 +165,7 @@ module Redmine ...@@ -156,6 +165,7 @@ module Redmine
else else
Project.roots.visible.has_module('issue_tracking').each do |project| Project.roots.visible.has_module('issue_tracking').each do |project|
render_project(project, options) render_project(project, options)
break if abort?
end end
end end
...@@ -176,22 +186,26 @@ module Redmine ...@@ -176,22 +186,26 @@ module Redmine
options[:top] += options[:top_increment] options[:top] += options[:top_increment]
options[:indent] += options[:indent_increment] options[:indent] += options[:indent_increment]
@number_of_rows += 1 @number_of_rows += 1
return if abort?
# Second, Issues without a version # 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) sort_issues!(issues)
if issues if issues
render_issues(issues, options) render_issues(issues, options)
return if abort?
end end
# Third, Versions # Third, Versions
project.versions.sort.each do |version| project.versions.sort.each do |version|
render_version(version, options) render_version(version, options)
return if abort?
end end
# Fourth, subprojects # Fourth, subprojects
project.children.visible.has_module('issue_tracking').each do |project| project.children.visible.has_module('issue_tracking').each do |project|
render_project(project, options) render_project(project, options)
return if abort?
end end
# Remove indent to hit the next sibling # Remove indent to hit the next sibling
...@@ -205,6 +219,7 @@ module Redmine ...@@ -205,6 +219,7 @@ module Redmine
options[:top] += options[:top_increment] options[:top] += options[:top_increment]
@number_of_rows += 1 @number_of_rows += 1
return if abort?
end end
end end
...@@ -215,13 +230,14 @@ module Redmine ...@@ -215,13 +230,14 @@ module Redmine
options[:top] += options[:top_increment] options[:top] += options[:top_increment]
@number_of_rows += 1 @number_of_rows += 1
return if abort?
# Remove the project requirement for Versions because it will # Remove the project requirement for Versions because it will
# restrict issues to only be on the current project. This # restrict issues to only be on the current project. This
# ends up missing issues which are assigned to shared versions. # ends up missing issues which are assigned to shared versions.
@query.project = nil if @query.project @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 if issues
sort_issues!(issues) sort_issues!(issues)
# Indent issues # Indent issues
...@@ -961,6 +977,20 @@ module Redmine ...@@ -961,6 +977,20 @@ module Redmine
end end
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) def pdf_new_page?(options)
if options[:top] > 180 if options[:top] > 180
options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top]) options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
......
...@@ -53,9 +53,9 @@ class Redmine::Helpers::GanttTest < ActiveSupport::TestCase ...@@ -53,9 +53,9 @@ class Redmine::Helpers::GanttTest < ActiveSupport::TestCase
end end
# Creates a Gantt chart for a 4 week span # Creates a Gantt chart for a 4 week span
def create_gantt(project=Project.generate!) def create_gantt(project=Project.generate!, options={})
@project = project @project = project
@gantt = Redmine::Helpers::Gantt.new @gantt = Redmine::Helpers::Gantt.new(options)
@gantt.project = @project @gantt.project = @project
@gantt.query = Query.generate_default!(:project => @project) @gantt.query = Query.generate_default!(:project => @project)
@gantt.view = build_view @gantt.view = build_view
...@@ -73,6 +73,22 @@ class Redmine::Helpers::GanttTest < ActiveSupport::TestCase ...@@ -73,6 +73,22 @@ class Redmine::Helpers::GanttTest < ActiveSupport::TestCase
should "return the total number of rows for all the projects, resursively" should "return the total number of rows for all the projects, resursively"
end 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 end
context "#number_of_rows_on_project" do context "#number_of_rows_on_project" do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment