Mercurial > hg > soundsoftware-site
comparison app/helpers/.svn/text-base/issues_helper.rb.svn-base @ 523:0b6c82dead28 luisf
Merge from branch "cannam"
author | luisf <luis.figueira@eecs.qmul.ac.uk> |
---|---|
date | Mon, 25 Jul 2011 14:23:37 +0100 |
parents | cbce1fd3b1b7 |
children |
comparison
equal
deleted
inserted
replaced
318:f7c525dc7585 | 523:0b6c82dead28 |
---|---|
1 # redMine - project management software | 1 # Redmine - project management software |
2 # Copyright (C) 2006 Jean-Philippe Lang | 2 # Copyright (C) 2006-2011 Jean-Philippe Lang |
3 # | 3 # |
4 # This program is free software; you can redistribute it and/or | 4 # This program is free software; you can redistribute it and/or |
5 # modify it under the terms of the GNU General Public License | 5 # modify it under the terms of the GNU General Public License |
6 # as published by the Free Software Foundation; either version 2 | 6 # as published by the Free Software Foundation; either version 2 |
7 # of the License, or (at your option) any later version. | 7 # of the License, or (at your option) any later version. |
8 # | 8 # |
9 # This program is distributed in the hope that it will be useful, | 9 # This program is distributed in the hope that it will be useful, |
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 # GNU General Public License for more details. | 12 # GNU General Public License for more details. |
13 # | 13 # |
14 # You should have received a copy of the GNU General Public License | 14 # You should have received a copy of the GNU General Public License |
15 # along with this program; if not, write to the Free Software | 15 # along with this program; if not, write to the Free Software |
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | 17 |
18 module IssuesHelper | 18 module IssuesHelper |
52 "<strong>#{@cached_label_start_date}</strong>: #{format_date(issue.start_date)}<br />" + | 52 "<strong>#{@cached_label_start_date}</strong>: #{format_date(issue.start_date)}<br />" + |
53 "<strong>#{@cached_label_due_date}</strong>: #{format_date(issue.due_date)}<br />" + | 53 "<strong>#{@cached_label_due_date}</strong>: #{format_date(issue.due_date)}<br />" + |
54 "<strong>#{@cached_label_assigned_to}</strong>: #{issue.assigned_to}<br />" + | 54 "<strong>#{@cached_label_assigned_to}</strong>: #{issue.assigned_to}<br />" + |
55 "<strong>#{@cached_label_priority}</strong>: #{issue.priority.name}" | 55 "<strong>#{@cached_label_priority}</strong>: #{issue.priority.name}" |
56 end | 56 end |
57 | 57 |
58 def issue_heading(issue) | |
59 h("#{issue.tracker} ##{issue.id}") | |
60 end | |
61 | |
58 def render_issue_subject_with_tree(issue) | 62 def render_issue_subject_with_tree(issue) |
59 s = '' | 63 s = '' |
60 issue.ancestors.each do |ancestor| | 64 ancestors = issue.root? ? [] : issue.ancestors.visible.all |
65 ancestors.each do |ancestor| | |
61 s << '<div>' + content_tag('p', link_to_issue(ancestor)) | 66 s << '<div>' + content_tag('p', link_to_issue(ancestor)) |
62 end | 67 end |
63 s << '<div>' + content_tag('h3', h(issue.subject)) | 68 s << '<div>' |
64 s << '</div>' * (issue.ancestors.size + 1) | 69 subject = h(issue.subject) |
70 if issue.is_private? | |
71 subject = content_tag('span', l(:field_is_private), :class => 'private') + ' ' + subject | |
72 end | |
73 s << content_tag('h3', subject) | |
74 s << '</div>' * (ancestors.size + 1) | |
65 s | 75 s |
66 end | 76 end |
67 | 77 |
68 def render_descendants_tree(issue) | 78 def render_descendants_tree(issue) |
69 s = '<form><table class="list issues">' | 79 s = '<form><table class="list issues">' |
70 issue_list(issue.descendants.sort_by(&:lft)) do |child, level| | 80 issue_list(issue.descendants.visible.sort_by(&:lft)) do |child, level| |
71 s << content_tag('tr', | 81 s << content_tag('tr', |
72 content_tag('td', check_box_tag("ids[]", child.id, false, :id => nil), :class => 'checkbox') + | 82 content_tag('td', check_box_tag("ids[]", child.id, false, :id => nil), :class => 'checkbox') + |
73 content_tag('td', link_to_issue(child, :truncate => 60), :class => 'subject') + | 83 content_tag('td', link_to_issue(child, :truncate => 60), :class => 'subject') + |
74 content_tag('td', h(child.status)) + | 84 content_tag('td', h(child.status)) + |
75 content_tag('td', link_to_user(child.assigned_to)) + | 85 content_tag('td', link_to_user(child.assigned_to)) + |
77 :class => "issue issue-#{child.id} hascontextmenu #{level > 0 ? "idnt idnt-#{level}" : nil}") | 87 :class => "issue issue-#{child.id} hascontextmenu #{level > 0 ? "idnt idnt-#{level}" : nil}") |
78 end | 88 end |
79 s << '</form></table>' | 89 s << '</form></table>' |
80 s | 90 s |
81 end | 91 end |
82 | 92 |
83 def render_custom_fields_rows(issue) | 93 def render_custom_fields_rows(issue) |
84 return if issue.custom_field_values.empty? | 94 return if issue.custom_field_values.empty? |
85 ordered_values = [] | 95 ordered_values = [] |
86 half = (issue.custom_field_values.size / 2.0).ceil | 96 half = (issue.custom_field_values.size / 2.0).ceil |
87 half.times do |i| | 97 half.times do |i| |
96 n += 1 | 106 n += 1 |
97 end | 107 end |
98 s << "</tr>\n" | 108 s << "</tr>\n" |
99 s | 109 s |
100 end | 110 end |
101 | 111 |
112 def issues_destroy_confirmation_message(issues) | |
113 issues = [issues] unless issues.is_a?(Array) | |
114 message = l(:text_issues_destroy_confirmation) | |
115 descendant_count = issues.inject(0) {|memo, i| memo += (i.right - i.left - 1)/2} | |
116 if descendant_count > 0 | |
117 issues.each do |issue| | |
118 next if issue.root? | |
119 issues.each do |other_issue| | |
120 descendant_count -= 1 if issue.is_descendant_of?(other_issue) | |
121 end | |
122 end | |
123 if descendant_count > 0 | |
124 message << "\n" + l(:text_issues_destroy_descendants_confirmation, :count => descendant_count) | |
125 end | |
126 end | |
127 message | |
128 end | |
129 | |
102 def sidebar_queries | 130 def sidebar_queries |
103 unless @sidebar_queries | 131 unless @sidebar_queries |
104 # User can see public queries and his own queries | 132 # User can see public queries and his own queries |
105 visible = ARCondition.new(["is_public = ? OR user_id = ?", true, (User.current.logged? ? User.current.id : 0)]) | 133 visible = ARCondition.new(["is_public = ? OR user_id = ?", true, (User.current.logged? ? User.current.id : 0)]) |
106 # Project specific queries and global queries | 134 # Project specific queries and global queries |
107 visible << (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id]) | 135 visible << (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id]) |
108 @sidebar_queries = Query.find(:all, | 136 @sidebar_queries = Query.find(:all, |
109 :select => 'id, name', | 137 :select => 'id, name, is_public', |
110 :order => "name ASC", | 138 :order => "name ASC", |
111 :conditions => visible.conditions) | 139 :conditions => visible.conditions) |
112 end | 140 end |
113 @sidebar_queries | 141 @sidebar_queries |
142 end | |
143 | |
144 def query_links(title, queries) | |
145 # links to #index on issues/show | |
146 url_params = controller_name == 'issues' ? {:controller => 'issues', :action => 'index', :project_id => @project} : params | |
147 | |
148 content_tag('h3', title) + | |
149 queries.collect {|query| | |
150 link_to(h(query.name), url_params.merge(:query_id => query)) | |
151 }.join('<br />') | |
152 end | |
153 | |
154 def render_sidebar_queries | |
155 out = '' | |
156 queries = sidebar_queries.select {|q| !q.is_public?} | |
157 out << query_links(l(:label_my_queries), queries) if queries.any? | |
158 queries = sidebar_queries.select {|q| q.is_public?} | |
159 out << query_links(l(:label_query_plural), queries) if queries.any? | |
160 out | |
114 end | 161 end |
115 | 162 |
116 def show_detail(detail, no_html=false) | 163 def show_detail(detail, no_html=false) |
117 case detail.property | 164 case detail.property |
118 when 'attr' | 165 when 'attr' |
133 | 180 |
134 when detail.prop_key == 'parent_id' | 181 when detail.prop_key == 'parent_id' |
135 label = l(:field_parent_issue) | 182 label = l(:field_parent_issue) |
136 value = "##{detail.value}" unless detail.value.blank? | 183 value = "##{detail.value}" unless detail.value.blank? |
137 old_value = "##{detail.old_value}" unless detail.old_value.blank? | 184 old_value = "##{detail.old_value}" unless detail.old_value.blank? |
185 | |
186 when detail.prop_key == 'is_private' | |
187 value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank? | |
188 old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank? | |
138 end | 189 end |
139 when 'cf' | 190 when 'cf' |
140 custom_field = CustomField.find_by_id(detail.prop_key) | 191 custom_field = CustomField.find_by_id(detail.prop_key) |
141 if custom_field | 192 if custom_field |
142 label = custom_field.name | 193 label = custom_field.name |
149 call_hook(:helper_issues_show_detail_after_setting, {:detail => detail, :label => label, :value => value, :old_value => old_value }) | 200 call_hook(:helper_issues_show_detail_after_setting, {:detail => detail, :label => label, :value => value, :old_value => old_value }) |
150 | 201 |
151 label ||= detail.prop_key | 202 label ||= detail.prop_key |
152 value ||= detail.value | 203 value ||= detail.value |
153 old_value ||= detail.old_value | 204 old_value ||= detail.old_value |
154 | 205 |
155 unless no_html | 206 unless no_html |
156 label = content_tag('strong', label) | 207 label = content_tag('strong', label) |
157 old_value = content_tag("i", h(old_value)) if detail.old_value | 208 old_value = content_tag("i", h(old_value)) if detail.old_value |
158 old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?) | 209 old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?) |
159 if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key) | 210 if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key) |
161 value = link_to_attachment(a) | 212 value = link_to_attachment(a) |
162 else | 213 else |
163 value = content_tag("i", h(value)) if value | 214 value = content_tag("i", h(value)) if value |
164 end | 215 end |
165 end | 216 end |
166 | 217 |
167 if !detail.value.blank? | 218 if detail.property == 'attr' && detail.prop_key == 'description' |
219 s = l(:text_journal_changed_no_detail, :label => label) | |
220 unless no_html | |
221 diff_link = link_to 'diff', | |
222 {:controller => 'journals', :action => 'diff', :id => detail.journal_id, :detail_id => detail.id}, | |
223 :title => l(:label_view_diff) | |
224 s << " (#{ diff_link })" | |
225 end | |
226 s | |
227 elsif !detail.value.blank? | |
168 case detail.property | 228 case detail.property |
169 when 'attr', 'cf' | 229 when 'attr', 'cf' |
170 if !detail.old_value.blank? | 230 if !detail.old_value.blank? |
171 l(:text_journal_changed, :label => label, :old => old_value, :new => value) | 231 l(:text_journal_changed, :label => label, :old => old_value, :new => value) |
172 else | 232 else |
186 if association | 246 if association |
187 record = association.class_name.constantize.find_by_id(id) | 247 record = association.class_name.constantize.find_by_id(id) |
188 return record.name if record | 248 return record.name if record |
189 end | 249 end |
190 end | 250 end |
191 | 251 |
252 # Renders issue children recursively | |
253 def render_api_issue_children(issue, api) | |
254 return if issue.leaf? | |
255 api.array :children do | |
256 issue.children.each do |child| | |
257 api.issue(:id => child.id) do | |
258 api.tracker(:id => child.tracker_id, :name => child.tracker.name) unless child.tracker.nil? | |
259 api.subject child.subject | |
260 render_api_issue_children(child, api) | |
261 end | |
262 end | |
263 end | |
264 end | |
265 | |
192 def issues_to_csv(issues, project = nil) | 266 def issues_to_csv(issues, project = nil) |
193 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8') | 267 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8') |
194 decimal_separator = l(:general_csv_decimal_separator) | 268 decimal_separator = l(:general_csv_decimal_separator) |
195 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| | 269 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| |
196 # csv header fields | 270 # csv header fields |
197 headers = [ "#", | 271 headers = [ "#", |
198 l(:field_status), | 272 l(:field_status), |
199 l(:field_project), | 273 l(:field_project), |
200 l(:field_tracker), | 274 l(:field_tracker), |
201 l(:field_priority), | 275 l(:field_priority), |
202 l(:field_subject), | 276 l(:field_subject), |
203 l(:field_assigned_to), | 277 l(:field_assigned_to), |
220 headers << l(:field_description) | 294 headers << l(:field_description) |
221 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } | 295 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } |
222 # csv lines | 296 # csv lines |
223 issues.each do |issue| | 297 issues.each do |issue| |
224 fields = [issue.id, | 298 fields = [issue.id, |
225 issue.status.name, | 299 issue.status.name, |
226 issue.project.name, | 300 issue.project.name, |
227 issue.tracker.name, | 301 issue.tracker.name, |
228 issue.priority.name, | 302 issue.priority.name, |
229 issue.subject, | 303 issue.subject, |
230 issue.assigned_to, | 304 issue.assigned_to, |
231 issue.category, | 305 issue.category, |
232 issue.fixed_version, | 306 issue.fixed_version, |
234 format_date(issue.start_date), | 308 format_date(issue.start_date), |
235 format_date(issue.due_date), | 309 format_date(issue.due_date), |
236 issue.done_ratio, | 310 issue.done_ratio, |
237 issue.estimated_hours.to_s.gsub('.', decimal_separator), | 311 issue.estimated_hours.to_s.gsub('.', decimal_separator), |
238 issue.parent_id, | 312 issue.parent_id, |
239 format_time(issue.created_on), | 313 format_time(issue.created_on), |
240 format_time(issue.updated_on) | 314 format_time(issue.updated_on) |
241 ] | 315 ] |
242 custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) } | 316 custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) } |
243 fields << issue.description | 317 fields << issue.description |
244 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } | 318 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } |