@@ -27,44 +27,38 module QueriesHelper | |||
|
27 | 27 | content_tag('th', column.caption) |
|
28 | 28 | end |
|
29 | 29 | |
|
30 | def column_value(column, issue) | |
|
31 | if column.is_a?(QueryCustomFieldColumn) | |
|
32 | cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id} | |
|
33 | show_value(cv) | |
|
34 | else | |
|
35 | value = issue.send(column.name) | |
|
36 | end | |
|
37 | end | |
|
38 | ||
|
39 | 30 | def column_content(column, issue) |
|
40 | if column.is_a?(QueryCustomFieldColumn) | |
|
41 | cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id} | |
|
42 | show_value(cv) | |
|
43 | else | |
|
44 | value = issue.send(column.name) | |
|
45 | if value.is_a?(Date) | |
|
46 | format_date(value) | |
|
47 | elsif value.is_a?(Time) | |
|
48 | format_time(value) | |
|
31 | value = column.value(issue) | |
|
32 | ||
|
33 | case value.class.name | |
|
34 | when 'String' | |
|
35 | if column.name == :subject | |
|
36 | link_to(h(value), :controller => 'issues', :action => 'show', :id => issue) | |
|
37 | else | |
|
38 | h(value) | |
|
39 | end | |
|
40 | when 'Time' | |
|
41 | format_time(value) | |
|
42 | when 'Date' | |
|
43 | format_date(value) | |
|
44 | when 'Fixnum', 'Float' | |
|
45 | if column.name == :done_ratio | |
|
46 | progress_bar(value, :width => '80px') | |
|
49 | 47 | else |
|
50 | case column.name | |
|
51 | when :subject | |
|
52 | h((!@project.nil? && @project != issue.project) ? "#{issue.project.name} - " : '') + | |
|
53 | link_to(h(value), :controller => 'issues', :action => 'show', :id => issue) | |
|
54 | when :project | |
|
55 | link_to(h(value), :controller => 'projects', :action => 'show', :id => value) | |
|
56 | when :assigned_to | |
|
57 | link_to_user value | |
|
58 | when :author | |
|
59 | link_to_user value | |
|
60 | when :done_ratio | |
|
61 | progress_bar(value, :width => '80px') | |
|
62 | when :fixed_version | |
|
63 | link_to(h(value), { :controller => 'versions', :action => 'show', :id => issue.fixed_version_id }) | |
|
64 | else | |
|
65 | h(value) | |
|
66 | end | |
|
48 | value.to_s | |
|
67 | 49 | end |
|
50 | when 'User' | |
|
51 | link_to_user value | |
|
52 | when 'Project' | |
|
53 | link_to(h(value), :controller => 'projects', :action => 'show', :id => value) | |
|
54 | when 'Version' | |
|
55 | link_to(h(value), :controller => 'versions', :action => 'show', :id => value) | |
|
56 | when 'TrueClass' | |
|
57 | l(:general_text_Yes) | |
|
58 | when 'FalseClass' | |
|
59 | l(:general_text_No) | |
|
60 | else | |
|
61 | h(value) | |
|
68 | 62 | end |
|
69 | 63 | end |
|
70 | 64 | end |
@@ -67,6 +67,25 class CustomField < ActiveRecord::Base | |||
|
67 | 67 | end |
|
68 | 68 | end |
|
69 | 69 | |
|
70 | def cast_value(value) | |
|
71 | casted = nil | |
|
72 | unless value.blank? | |
|
73 | case field_format | |
|
74 | when 'string', 'text', 'list' | |
|
75 | casted = value | |
|
76 | when 'date' | |
|
77 | casted = begin; value.to_date; rescue; nil end | |
|
78 | when 'bool' | |
|
79 | casted = (value == '1' ? true : false) | |
|
80 | when 'int' | |
|
81 | casted = value.to_i | |
|
82 | when 'float' | |
|
83 | casted = value.to_f | |
|
84 | end | |
|
85 | end | |
|
86 | casted | |
|
87 | end | |
|
88 | ||
|
70 | 89 | # Returns a ORDER BY clause that can used to sort customized |
|
71 | 90 | # objects by their value of the custom field. |
|
72 | 91 | # Returns false, if the custom field can not be used for sorting. |
@@ -37,6 +37,10 class QueryColumn | |||
|
37 | 37 | def sortable? |
|
38 | 38 | !sortable.nil? |
|
39 | 39 | end |
|
40 | ||
|
41 | def value(issue) | |
|
42 | issue.send name | |
|
43 | end | |
|
40 | 44 | end |
|
41 | 45 | |
|
42 | 46 | class QueryCustomFieldColumn < QueryColumn |
@@ -58,6 +62,11 class QueryCustomFieldColumn < QueryColumn | |||
|
58 | 62 | def custom_field |
|
59 | 63 | @cf |
|
60 | 64 | end |
|
65 | ||
|
66 | def value(issue) | |
|
67 | cv = issue.custom_values.detect {|v| v.custom_field_id == @cf.id} | |
|
68 | cv && @cf.cast_value(cv.value) | |
|
69 | end | |
|
61 | 70 | end |
|
62 | 71 | |
|
63 | 72 | class Query < ActiveRecord::Base |
@@ -407,16 +416,20 class Query < ActiveRecord::Base | |||
|
407 | 416 | |
|
408 | 417 | # Returns the issue count by group or nil if query is not grouped |
|
409 | 418 | def issue_count_by_group |
|
419 | r = nil | |
|
410 | 420 | if grouped? |
|
411 | 421 | begin |
|
412 | 422 | # Rails will raise an (unexpected) RecordNotFound if there's only a nil group value |
|
413 | Issue.count(:group => group_by_statement, :include => [:status, :project], :conditions => statement) | |
|
423 | r = Issue.count(:group => group_by_statement, :include => [:status, :project], :conditions => statement) | |
|
414 | 424 | rescue ActiveRecord::RecordNotFound |
|
415 | {nil => issue_count} | |
|
425 | r = {nil => issue_count} | |
|
426 | end | |
|
427 | c = group_by_column | |
|
428 | if c.is_a?(QueryCustomFieldColumn) | |
|
429 | r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h} | |
|
416 | 430 | end |
|
417 | else | |
|
418 | nil | |
|
419 | 431 | end |
|
432 | r | |
|
420 | 433 | rescue ::ActiveRecord::StatementInvalid => e |
|
421 | 434 | raise StatementInvalid.new(e.message) |
|
422 | 435 | end |
@@ -13,12 +13,12 | |||
|
13 | 13 | <% previous_group = false %> |
|
14 | 14 | <tbody> |
|
15 | 15 | <% issues.each do |issue| -%> |
|
16 |
<% if @query.grouped? && (group = |
|
|
16 | <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %> | |
|
17 | 17 | <% reset_cycle %> |
|
18 | 18 | <tr class="group open"> |
|
19 | 19 | <td colspan="<%= query.columns.size + 2 %>"> |
|
20 | 20 | <span class="expander" onclick="toggleRowGroup(this); return false;"> </span> |
|
21 | <%= group.blank? ? 'None' : group %> <span class="count">(<%= @issue_count_by_group[group] %>)</span> | |
|
21 | <%= group.blank? ? 'None' : column_content(@query.group_by_column, issue) %> <span class="count">(<%= @issue_count_by_group[group] %>)</span> | |
|
22 | 22 | </td> |
|
23 | 23 | </tr> |
|
24 | 24 | <% previous_group = group %> |
@@ -101,3 +101,17 custom_fields_007: | |||
|
101 | 101 | field_format: bool |
|
102 | 102 | default_value: "" |
|
103 | 103 | editable: true |
|
104 | custom_fields_008: | |
|
105 | name: Custom date | |
|
106 | min_length: 0 | |
|
107 | regexp: "" | |
|
108 | is_for_all: true | |
|
109 | is_filter: false | |
|
110 | type: IssueCustomField | |
|
111 | max_length: 0 | |
|
112 | possible_values: "" | |
|
113 | id: 8 | |
|
114 | is_required: false | |
|
115 | field_format: date | |
|
116 | default_value: "" | |
|
117 | editable: true |
@@ -95,3 +95,9 custom_values_016: | |||
|
95 | 95 | customized_id: 11 |
|
96 | 96 | id: 16 |
|
97 | 97 | value: '1' |
|
98 | custom_values_017: | |
|
99 | customized_type: Issue | |
|
100 | custom_field_id: 8 | |
|
101 | customized_id: 1 | |
|
102 | id: 17 | |
|
103 | value: '2009-12-01' |
@@ -177,10 +177,7 class IssuesControllerTest < ActionController::TestCase | |||
|
177 | 177 | assert_response :success |
|
178 | 178 | assert_template 'index.rhtml' |
|
179 | 179 | assert_not_nil assigns(:issues) |
|
180 |
|
|
|
181 | assert_kind_of Hash, count_by_group | |
|
182 | assert_kind_of Tracker, count_by_group.keys.first | |
|
183 | assert_not_nil count_by_group[Tracker.find(1)] | |
|
180 | assert_not_nil assigns(:issue_count_by_group) | |
|
184 | 181 | end |
|
185 | 182 | |
|
186 | 183 | def test_index_with_query_grouped_by_list_custom_field |
@@ -188,10 +185,7 class IssuesControllerTest < ActionController::TestCase | |||
|
188 | 185 | assert_response :success |
|
189 | 186 | assert_template 'index.rhtml' |
|
190 | 187 | assert_not_nil assigns(:issues) |
|
191 |
|
|
|
192 | assert_kind_of Hash, count_by_group | |
|
193 | assert_kind_of String, count_by_group.keys.first | |
|
194 | assert_not_nil count_by_group['MySQL'] | |
|
188 | assert_not_nil assigns(:issue_count_by_group) | |
|
195 | 189 | end |
|
196 | 190 | |
|
197 | 191 | def test_index_sort_by_field_not_included_in_columns |
@@ -276,6 +276,32 class QueryTest < ActiveSupport::TestCase | |||
|
276 | 276 | end |
|
277 | 277 | end |
|
278 | 278 | |
|
279 | def test_issue_count_by_association_group | |
|
280 | q = Query.new(:name => '_', :group_by => 'assigned_to') | |
|
281 | count_by_group = q.issue_count_by_group | |
|
282 | assert_kind_of Hash, count_by_group | |
|
283 | assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort | |
|
284 | assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq | |
|
285 | assert count_by_group.has_key?(User.find(3)) | |
|
286 | end | |
|
287 | ||
|
288 | def test_issue_count_by_list_custom_field_group | |
|
289 | q = Query.new(:name => '_', :group_by => 'cf_1') | |
|
290 | count_by_group = q.issue_count_by_group | |
|
291 | assert_kind_of Hash, count_by_group | |
|
292 | assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort | |
|
293 | assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq | |
|
294 | assert count_by_group.has_key?('MySQL') | |
|
295 | end | |
|
296 | ||
|
297 | def test_issue_count_by_date_custom_field_group | |
|
298 | q = Query.new(:name => '_', :group_by => 'cf_8') | |
|
299 | count_by_group = q.issue_count_by_group | |
|
300 | assert_kind_of Hash, count_by_group | |
|
301 | assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort | |
|
302 | assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq | |
|
303 | end | |
|
304 | ||
|
279 | 305 | def test_label_for |
|
280 | 306 | q = Query.new |
|
281 | 307 | assert_equal 'assigned_to', q.label_for('assigned_to_id') |
General Comments 0
You need to be logged in to leave comments.
Login now