]> source.dussan.org Git - redmine.git/commitdiff
Allow issue grouping by custom field (#2679).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Mon, 16 Nov 2009 18:07:30 +0000 (18:07 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Mon, 16 Nov 2009 18:07:30 +0000 (18:07 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3071 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/issues_controller.rb
app/helpers/queries_helper.rb
app/models/query.rb
app/views/issues/_list.rhtml
test/fixtures/queries.yml
test/functional/issues_controller_test.rb
test/unit/query_test.rb

index 2fa465f4ea3b61d810cf90e063676db89c214edc..2578b784b6dbbdc53fbfe8447189cc43580a280c 100644 (file)
@@ -64,7 +64,7 @@ class IssuesController < ApplicationController
       @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
       @issue_pages = Paginator.new self, @issue_count, limit, params['page']
       @issues = Issue.find :all, :order => [@query.group_by_sort_order, sort_clause].compact.join(','),
-                           :include => [ :assigned_to, :status, :tracker, :project, :priority, :category, :fixed_version ],
+      :include => [ :assigned_to, :status, :tracker, :project, :priority, :category, :fixed_version ],
                            :conditions => @query.statement,
                            :limit  =>  limit,
                            :offset =>  @issue_pages.current.offset
@@ -73,7 +73,7 @@ class IssuesController < ApplicationController
           if @query.grouped?
             # Retrieve the issue count by group
             @issue_count_by_group = begin
-              Issue.count(:group => @query.group_by, :include => [:status, :project], :conditions => @query.statement)
+              Issue.count(:group => @query.group_by_statement, :include => [:status, :project], :conditions => @query.statement)
             # Rails will raise an (unexpected) error if there's only a nil group value
             rescue ActiveRecord::RecordNotFound
               {nil => @issue_count}
index 165308efdab9deba9e5079a4821c3b6220b920b5..518226c8fea9dfd355e507f29213e7a051b43fa4 100644 (file)
@@ -27,6 +27,15 @@ module QueriesHelper
                       content_tag('th', column.caption)
   end
   
+  def column_value(column, issue)
+    if column.is_a?(QueryCustomFieldColumn)
+      cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
+      show_value(cv)
+    else
+      value = issue.send(column.name)
+    end
+  end
+  
   def column_content(column, issue)
     if column.is_a?(QueryCustomFieldColumn)
       cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
index 7ce95f0ea348f0cd91e7aea82c2602079384a8d7..816c5c5a05758301941b74486be80e649ec38801 100644 (file)
@@ -23,6 +23,9 @@ class QueryColumn
     self.name = name
     self.sortable = options[:sortable]
     self.groupable = options[:groupable] || false
+    if groupable == true
+      self.groupable = name.to_s
+    end
     self.default_order = options[:default_order]
   end
   
@@ -41,6 +44,10 @@ class QueryCustomFieldColumn < QueryColumn
   def initialize(custom_field)
     self.name = "cf_#{custom_field.id}".to_sym
     self.sortable = custom_field.order_statement || false
+    if %w(list date bool int).include?(custom_field.field_format)
+      self.groupable = custom_field.order_statement
+    end
+    self.groupable ||= false
     @cf = custom_field
   end
   
@@ -312,6 +319,10 @@ class Query < ActiveRecord::Base
     groupable_columns.detect {|c| c.name.to_s == group_by}
   end
   
+  def group_by_statement
+    group_by_column.groupable
+  end
+  
   def project_statement
     project_clauses = []
     if project && !@project.descendants.active.empty?
index 9d4ef7dd809fc0d91eae586fb3c84539fd2fbbcd..f51a70883c3f58e82106be33797931588e259c44 100644 (file)
           <%= column_header(column) %>
         <% end %>
        </tr></thead>
-       <% group = false %>
+       <% previous_group = false %>
        <tbody>
        <% issues.each do |issue| -%>
-  <% if @query.grouped? && issue.send(@query.group_by) != group %>
-    <% group = issue.send(@query.group_by) %>
+  <% if @query.grouped? && (group = column_value(@query.group_by_column, issue) || '') != previous_group %>
     <% reset_cycle %>
     <tr class="group open">
        <td colspan="<%= query.columns.size + 2 %>">
@@ -22,6 +21,7 @@
        <%= group.blank? ? 'None' : group %> <span class="count">(<%= @issue_count_by_group[group] %>)</span>
        </td>
                </tr>
+               <% previous_group = group %>
   <% end %>
        <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>">
            <td class="checkbox"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
index 3299f96f7efdd6a9e87e8dfff7693630fda9636c..a49f82fbbc91331574f12f27e85ea00e9a1e7012 100644 (file)
@@ -134,4 +134,23 @@ queries_008:
 
   user_id: 2
   column_names: 
+queries_009: 
+  id: 9
+  project_id: 
+  is_public: true
+  name: Open issues grouped by list custom field
+  filters: |
+    --- 
+    status_id: 
+      :values: 
+      - "1"
+      :operator: o
+
+  user_id: 1
+  column_names: 
+  group_by: cf_1
+  sort_criteria: |
+    --- 
+    - - priority
+      - desc
 
index 75da3c0c3d0ffe2a7cb0a9c59c30f4ff9f8ef5c0..7356b130bb7b43e8ee3acfbfa3feaaf63492ba89 100644 (file)
@@ -171,12 +171,26 @@ class IssuesControllerTest < ActionController::TestCase
     assert_nil assigns(:issue_count_by_group)
   end
   
-  def test_index_with_grouped_query
+  def test_index_with_query_grouped_by_tracker
     get :index, :project_id => 1, :query_id => 6
     assert_response :success
     assert_template 'index.rhtml'
     assert_not_nil assigns(:issues)
-    assert_not_nil assigns(:issue_count_by_group)
+    count_by_group = assigns(:issue_count_by_group)
+    assert_kind_of Hash, count_by_group
+    assert_kind_of Tracker, count_by_group.keys.first
+    assert_not_nil count_by_group[Tracker.find(1)]
+  end
+  
+  def test_index_with_query_grouped_by_list_custom_field
+    get :index, :project_id => 1, :query_id => 9
+    assert_response :success
+    assert_template 'index.rhtml'
+    assert_not_nil assigns(:issues)
+    count_by_group = assigns(:issue_count_by_group)
+    assert_kind_of Hash, count_by_group
+    assert_kind_of String, count_by_group.keys.first
+    assert_not_nil count_by_group['MySQL']
   end
   
   def test_index_csv_with_project
index f1f9397c6fb7feca1b53f64e1657569361b1e1a2..27aed0ce884d36059b5550175882a16a4135d9e5 100644 (file)
@@ -197,6 +197,11 @@ class QueryTest < ActiveSupport::TestCase
     assert q.has_column?(c)
   end
   
+  def test_groupable_columns_should_include_custom_fields
+    q = Query.new
+    assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn}
+  end
+  
   def test_default_sort
     q = Query.new
     assert_equal [], q.sort_criteria