@@ -67,6 +67,11 t_height = g_height + headers_height | |||||
67 |
|
67 | |||
68 |
|
68 | |||
69 | %> |
|
69 | %> | |
|
70 | ||||
|
71 | <% if @gantt.truncated %> | |||
|
72 | <p class="warning"><%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %></p> | |||
|
73 | <% end %> | |||
|
74 | ||||
70 | <table width="100%" style="border:0; border-collapse: collapse;"> |
|
75 | <table width="100%" style="border:0; border-collapse: collapse;"> | |
71 | <tr> |
|
76 | <tr> | |
72 | <td style="width:<%= subject_width %>px; padding:0px;"> |
|
77 | <td style="width:<%= subject_width %>px; padding:0px;"> |
@@ -8,6 +8,8 | |||||
8 | <p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p> |
|
8 | <p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p> | |
9 |
|
9 | |||
10 | <p><%= setting_text_field :issues_export_limit, :size => 6 %></p> |
|
10 | <p><%= setting_text_field :issues_export_limit, :size => 6 %></p> | |
|
11 | ||||
|
12 | <p><%= setting_text_field :gantt_items_limit, :size => 6 %></p> | |||
11 | </div> |
|
13 | </div> | |
12 |
|
14 | |||
13 | <fieldset class="box settings"><legend><%= l(:setting_issue_list_default_columns) %></legend> |
|
15 | <fieldset class="box settings"><legend><%= l(:setting_issue_list_default_columns) %></legend> |
@@ -163,6 +163,7 en: | |||||
163 | notice_unable_delete_version: Unable to delete version. |
|
163 | notice_unable_delete_version: Unable to delete version. | |
164 | notice_unable_delete_time_entry: Unable to delete time log entry. |
|
164 | notice_unable_delete_time_entry: Unable to delete time log entry. | |
165 | notice_issue_done_ratios_updated: Issue done ratios updated. |
|
165 | notice_issue_done_ratios_updated: Issue done ratios updated. | |
|
166 | notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed ({{max}})" | |||
166 |
|
167 | |||
167 | error_can_t_load_default_data: "Default configuration could not be loaded: {{value}}" |
|
168 | error_can_t_load_default_data: "Default configuration could not be loaded: {{value}}" | |
168 | error_scm_not_found: "The entry or revision was not found in the repository." |
|
169 | error_scm_not_found: "The entry or revision was not found in the repository." | |
@@ -356,6 +357,7 en: | |||||
356 | setting_default_notification_option: Default notification option |
|
357 | setting_default_notification_option: Default notification option | |
357 | setting_commit_logtime_enabled: Enable time logging |
|
358 | setting_commit_logtime_enabled: Enable time logging | |
358 | setting_commit_logtime_activity_id: Activity for logged time |
|
359 | setting_commit_logtime_activity_id: Activity for logged time | |
|
360 | setting_gantt_items_limit: Maximum number of items displayed on the gantt chart | |||
359 |
|
361 | |||
360 | permission_add_project: Create project |
|
362 | permission_add_project: Create project | |
361 | permission_add_subprojects: Create subprojects |
|
363 | permission_add_subprojects: Create subprojects |
@@ -180,6 +180,7 fr: | |||||
180 | notice_unable_delete_version: Impossible de supprimer cette version. |
|
180 | notice_unable_delete_version: Impossible de supprimer cette version. | |
181 | notice_issue_done_ratios_updated: L'avancement des demandes a Γ©tΓ© mis Γ jour. |
|
181 | notice_issue_done_ratios_updated: L'avancement des demandes a Γ©tΓ© mis Γ jour. | |
182 | notice_api_access_key_reseted: Votre clé d'accès API a été réinitialisée. |
|
182 | notice_api_access_key_reseted: Votre clé d'accès API a été réinitialisée. | |
|
183 | notice_gantt_chart_truncated: "Le diagramme a Γ©tΓ© tronquΓ© car il excΓ¨de le nombre maximal d'Γ©lΓ©ments pouvant Γͺtre affichΓ©s ({{max}})" | |||
183 |
|
184 | |||
184 | error_can_t_load_default_data: "Une erreur s'est produite lors du chargement du paramΓ©trage : {{value}}" |
|
185 | error_can_t_load_default_data: "Une erreur s'est produite lors du chargement du paramΓ©trage : {{value}}" | |
185 | error_scm_not_found: "L'entrΓ©e et/ou la rΓ©vision demandΓ©e n'existe pas dans le dΓ©pΓ΄t." |
|
186 | 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 | setting_cache_formatted_text: Mettre en cache le texte formatΓ© |
|
361 | setting_cache_formatted_text: Mettre en cache le texte formatΓ© | |
361 | setting_commit_logtime_enabled: Permettre la saisie de temps |
|
362 | setting_commit_logtime_enabled: Permettre la saisie de temps | |
362 | setting_commit_logtime_activity_id: ActivitΓ© pour le temps saisi |
|
363 | setting_commit_logtime_activity_id: ActivitΓ© pour le temps saisi | |
|
364 | setting_gantt_items_limit: Nombre maximum d'Γ©lΓ©ments affichΓ©s sur le gantt | |||
363 |
|
365 | |||
364 | permission_add_project: CrΓ©er un projet |
|
366 | permission_add_project: CrΓ©er un projet | |
365 | permission_add_subprojects: CrΓ©er des sous-projets |
|
367 | permission_add_subprojects: CrΓ©er des sous-projets |
@@ -66,6 +66,9 protocol: | |||||
66 | feeds_limit: |
|
66 | feeds_limit: | |
67 | format: int |
|
67 | format: int | |
68 | default: 15 |
|
68 | default: 15 | |
|
69 | gantt_items_limit: | |||
|
70 | format: int | |||
|
71 | default: 500 | |||
69 | # Maximum size of files that can be displayed |
|
72 | # Maximum size of files that can be displayed | |
70 | # inline through the file viewer (in KB) |
|
73 | # inline through the file viewer (in KB) | |
71 | file_max_size_displayed: |
|
74 | file_max_size_displayed: |
@@ -34,7 +34,7 module Redmine | |||||
34 | end |
|
34 | end | |
35 | end |
|
35 | end | |
36 |
|
36 | |||
37 | attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months |
|
37 | attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months, :truncated, :max_rows | |
38 | attr_accessor :query |
|
38 | attr_accessor :query | |
39 | attr_accessor :project |
|
39 | attr_accessor :project | |
40 | attr_accessor :view |
|
40 | attr_accessor :view | |
@@ -71,6 +71,13 module Redmine | |||||
71 | @subjects = '' |
|
71 | @subjects = '' | |
72 | @lines = '' |
|
72 | @lines = '' | |
73 | @number_of_rows = nil |
|
73 | @number_of_rows = nil | |
|
74 | ||||
|
75 | @truncated = false | |||
|
76 | if options.has_key?(:max_rows) | |||
|
77 | @max_rows = options[:max_rows] | |||
|
78 | else | |||
|
79 | @max_rows = Setting.gantt_items_limit.blank? ? nil : Setting.gantt_items_limit.to_i | |||
|
80 | end | |||
74 | end |
|
81 | end | |
75 |
|
82 | |||
76 | def common_params |
|
83 | def common_params | |
@@ -94,13 +101,15 module Redmine | |||||
94 | def number_of_rows |
|
101 | def number_of_rows | |
95 | return @number_of_rows if @number_of_rows |
|
102 | return @number_of_rows if @number_of_rows | |
96 |
|
103 | |||
97 | if @project |
|
104 | rows = if @project | |
98 |
|
|
105 | number_of_rows_on_project(@project) | |
99 | else |
|
106 | else | |
100 | Project.roots.visible.has_module('issue_tracking').inject(0) do |total, project| |
|
107 | Project.roots.visible.has_module('issue_tracking').inject(0) do |total, project| | |
101 | total += number_of_rows_on_project(project) |
|
108 | total += number_of_rows_on_project(project) | |
102 | end |
|
109 | end | |
103 | end |
|
110 | end | |
|
111 | ||||
|
112 | rows > @max_rows ? @max_rows : rows | |||
104 | end |
|
113 | end | |
105 |
|
114 | |||
106 | # Returns the number of rows that will be used to list a project on |
|
115 | # Returns the number of rows that will be used to list a project on | |
@@ -156,6 +165,7 module Redmine | |||||
156 | else |
|
165 | else | |
157 | Project.roots.visible.has_module('issue_tracking').each do |project| |
|
166 | Project.roots.visible.has_module('issue_tracking').each do |project| | |
158 | render_project(project, options) |
|
167 | render_project(project, options) | |
|
168 | break if abort? | |||
159 | end |
|
169 | end | |
160 | end |
|
170 | end | |
161 |
|
171 | |||
@@ -176,22 +186,26 module Redmine | |||||
176 | options[:top] += options[:top_increment] |
|
186 | options[:top] += options[:top_increment] | |
177 | options[:indent] += options[:indent_increment] |
|
187 | options[:indent] += options[:indent_increment] | |
178 | @number_of_rows += 1 |
|
188 | @number_of_rows += 1 | |
|
189 | return if abort? | |||
179 |
|
190 | |||
180 | # Second, Issues without a version |
|
191 | # Second, Issues without a version | |
181 | issues = project.issues.for_gantt.without_version.with_query(@query) |
|
192 | issues = project.issues.for_gantt.without_version.with_query(@query).all(:limit => current_limit) | |
182 | sort_issues!(issues) |
|
193 | sort_issues!(issues) | |
183 | if issues |
|
194 | if issues | |
184 | render_issues(issues, options) |
|
195 | render_issues(issues, options) | |
|
196 | return if abort? | |||
185 | end |
|
197 | end | |
186 |
|
198 | |||
187 | # Third, Versions |
|
199 | # Third, Versions | |
188 | project.versions.sort.each do |version| |
|
200 | project.versions.sort.each do |version| | |
189 | render_version(version, options) |
|
201 | render_version(version, options) | |
|
202 | return if abort? | |||
190 | end |
|
203 | end | |
191 |
|
204 | |||
192 | # Fourth, subprojects |
|
205 | # Fourth, subprojects | |
193 | project.children.visible.has_module('issue_tracking').each do |project| |
|
206 | project.children.visible.has_module('issue_tracking').each do |project| | |
194 | render_project(project, options) |
|
207 | render_project(project, options) | |
|
208 | return if abort? | |||
195 | end |
|
209 | end | |
196 |
|
210 | |||
197 | # Remove indent to hit the next sibling |
|
211 | # Remove indent to hit the next sibling | |
@@ -205,6 +219,7 module Redmine | |||||
205 |
|
219 | |||
206 | options[:top] += options[:top_increment] |
|
220 | options[:top] += options[:top_increment] | |
207 | @number_of_rows += 1 |
|
221 | @number_of_rows += 1 | |
|
222 | return if abort? | |||
208 | end |
|
223 | end | |
209 | end |
|
224 | end | |
210 |
|
225 | |||
@@ -215,13 +230,14 module Redmine | |||||
215 |
|
230 | |||
216 | options[:top] += options[:top_increment] |
|
231 | options[:top] += options[:top_increment] | |
217 | @number_of_rows += 1 |
|
232 | @number_of_rows += 1 | |
|
233 | return if abort? | |||
218 |
|
234 | |||
219 | # Remove the project requirement for Versions because it will |
|
235 | # Remove the project requirement for Versions because it will | |
220 | # restrict issues to only be on the current project. This |
|
236 | # restrict issues to only be on the current project. This | |
221 | # ends up missing issues which are assigned to shared versions. |
|
237 | # ends up missing issues which are assigned to shared versions. | |
222 | @query.project = nil if @query.project |
|
238 | @query.project = nil if @query.project | |
223 |
|
239 | |||
224 | issues = version.fixed_issues.for_gantt.with_query(@query) |
|
240 | issues = version.fixed_issues.for_gantt.with_query(@query).all(:limit => current_limit) | |
225 | if issues |
|
241 | if issues | |
226 | sort_issues!(issues) |
|
242 | sort_issues!(issues) | |
227 | # Indent issues |
|
243 | # Indent issues | |
@@ -961,6 +977,20 module Redmine | |||||
961 | end |
|
977 | end | |
962 | end |
|
978 | end | |
963 |
|
979 | |||
|
980 | def current_limit | |||
|
981 | if @max_rows | |||
|
982 | @max_rows - @number_of_rows | |||
|
983 | else | |||
|
984 | nil | |||
|
985 | end | |||
|
986 | end | |||
|
987 | ||||
|
988 | def abort? | |||
|
989 | if @max_rows && @number_of_rows >= @max_rows | |||
|
990 | @truncated = true | |||
|
991 | end | |||
|
992 | end | |||
|
993 | ||||
964 | def pdf_new_page?(options) |
|
994 | def pdf_new_page?(options) | |
965 | if options[:top] > 180 |
|
995 | if options[:top] > 180 | |
966 | options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top]) |
|
996 | options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top]) |
@@ -53,9 +53,9 class Redmine::Helpers::GanttTest < ActiveSupport::TestCase | |||||
53 | end |
|
53 | end | |
54 |
|
54 | |||
55 | # Creates a Gantt chart for a 4 week span |
|
55 | # Creates a Gantt chart for a 4 week span | |
56 | def create_gantt(project=Project.generate!) |
|
56 | def create_gantt(project=Project.generate!, options={}) | |
57 | @project = project |
|
57 | @project = project | |
58 | @gantt = Redmine::Helpers::Gantt.new |
|
58 | @gantt = Redmine::Helpers::Gantt.new(options) | |
59 | @gantt.project = @project |
|
59 | @gantt.project = @project | |
60 | @gantt.query = Query.generate_default!(:project => @project) |
|
60 | @gantt.query = Query.generate_default!(:project => @project) | |
61 | @gantt.view = build_view |
|
61 | @gantt.view = build_view | |
@@ -73,6 +73,22 class Redmine::Helpers::GanttTest < ActiveSupport::TestCase | |||||
73 | should "return the total number of rows for all the projects, resursively" |
|
73 | should "return the total number of rows for all the projects, resursively" | |
74 | end |
|
74 | end | |
75 |
|
75 | |||
|
76 | should "not exceed max_rows option" do | |||
|
77 | p = Project.generate! | |||
|
78 | 5.times do | |||
|
79 | Issue.generate_for_project!(p) | |||
|
80 | end | |||
|
81 | ||||
|
82 | create_gantt(p) | |||
|
83 | @gantt.render | |||
|
84 | assert_equal 6, @gantt.number_of_rows | |||
|
85 | assert !@gantt.truncated | |||
|
86 | ||||
|
87 | create_gantt(p, :max_rows => 3) | |||
|
88 | @gantt.render | |||
|
89 | assert_equal 3, @gantt.number_of_rows | |||
|
90 | assert @gantt.truncated | |||
|
91 | end | |||
76 | end |
|
92 | end | |
77 |
|
93 | |||
78 | context "#number_of_rows_on_project" do |
|
94 | context "#number_of_rows_on_project" do |
General Comments 0
You need to be logged in to leave comments.
Login now