]> source.dussan.org Git - redmine.git/commitdiff
Bulk-edit custom fields through context menu (#6296).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 9 Feb 2012 18:22:11 +0000 (18:22 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 9 Feb 2012 18:22:11 +0000 (18:22 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@8824 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/context_menus_controller.rb
app/helpers/context_menus_helper.rb
app/models/custom_field.rb
app/views/context_menus/issues.html.erb
public/stylesheets/context_menu.css
test/functional/context_menus_controller_test.rb

index defadb230b8d602c971f2406b44d99d34a37eaea..007cc38e6e47af11025b188e945f5f7436d6b7df 100644 (file)
@@ -42,6 +42,19 @@ class ContextMenusController < ApplicationController
     @statuses = IssueStatus.find(:all, :order => 'position')
     @back = back_url
 
+    @options_by_custom_field = {}
+    if @can[:edit]
+      custom_fields = @issues.map(&:available_custom_fields).inject {|memo, f| memo & f}.select do |f|
+        %w(bool list user version).include?(f.field_format) && !f.multiple?
+      end
+      custom_fields.each do |field|
+        values = field.possible_values_options(@projects)
+        if values.any?
+          @options_by_custom_field[field] = values
+        end
+      end
+    end
+
     render :layout => false
   end
 
index 93ec40af9aeff15f8f25d6b143c65fb06c4f28fa..f2575c913482c5f0456807ea7b58ac84a0342c45 100644 (file)
@@ -33,4 +33,11 @@ module ContextMenusHelper
     end
     link_to h(name), url, options
   end
+
+  def bulk_update_custom_field_context_menu_link(field, text, value)
+    context_menu_link h(text),
+      {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back},
+      :method => :post,
+      :selected => (@issue && @issue.custom_field_value(field) == value)
+  end
 end
index b8005fea1278958c7a94bba5021947b224378fdf..8011320b3202ed34b24844a93b8ec5548988b5b1 100644 (file)
@@ -77,8 +77,10 @@ class CustomField < ActiveRecord::Base
       else
         []
       end
+    when 'bool'
+      [[l(:general_text_Yes), '1'], [l(:general_text_No), '0']]
     else
-      read_attribute :possible_values
+      read_attribute(:possible_values) || []
     end
   end
 
@@ -86,6 +88,8 @@ class CustomField < ActiveRecord::Base
     case field_format
     when 'user', 'version'
       possible_values_options(obj).collect(&:last)
+    when 'bool'
+      ['1', '0']
     else
       read_attribute :possible_values
     end
index 135edba99797b54418a80f046cc36451484c5de2..3757584841374f9a0519901adb4b1ec928cbcf42 100644 (file)
   </li>
   <% end %>
 
+  <% @options_by_custom_field.each do |field, options| %>
+    <li class="folder">
+      <a href="#" class="submenu"><%= h(field.name) %></a>
+      <ul>
+      <% options.each do |text, value| %>
+        <li><%= bulk_update_custom_field_context_menu_link(field, text, value || text) %></li>
+      <% end %>
+      <% unless field.is_required? %>
+        <li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '') %></li>
+      <% end %>
+      </ul>
+    </li>
+  <% end %>
+
 <% if !@issue.nil? %>
   <% if @can[:log_time] -%>
   <li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue},
index fd5a974c054d2e612a4ee1f6c6f033a7eb4ccf0e..df00f067e41ed33a0cdefb15bf9785706cfafcab 100644 (file)
@@ -39,7 +39,7 @@
 }
 #context-menu li>a { width:auto; } /* others */
 #context-menu a.disabled, #context-menu a.disabled:hover {color: #ccc;}
-#context-menu li a.submenu { background:url("../images/bullet_arrow_right.png") right no-repeat; }
+#context-menu li a.submenu { padding-right:16px; background:url("../images/bullet_arrow_right.png") right no-repeat; }
 #context-menu li:hover { border:1px solid gray; background-color:#eee; }
 #context-menu a:hover {color:#2A5685;}
 #context-menu li.folder:hover { z-index:40; }
index 353f31d9d2ef2c246fa7d2f193a43b3ff3d27b77..5546c5c6b74cbf2fb1b0216475255271e382f8f2 100644 (file)
@@ -117,6 +117,102 @@ class ContextMenusControllerTest < ActionController::TestCase
                                              :class => 'icon-del' }
   end
 
+  def test_context_menu_should_include_list_custom_fields
+    field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
+      :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2]
+
+    assert_tag 'a',
+      :content => 'List',
+      :attributes => {:href => '#'},
+      :sibling => {:tag => 'ul', :children => {:count => 3}}
+
+    assert_tag 'a',
+      :content => 'Foo',
+      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=Foo"}
+    assert_tag 'a',
+      :content => 'none',
+      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D="}
+  end
+
+  def test_context_menu_should_not_include_null_value_for_required_custom_fields
+    field = IssueCustomField.create!(:name => 'List', :is_required => true, :field_format => 'list',
+      :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2]
+
+    assert_tag 'a',
+      :content => 'List',
+      :attributes => {:href => '#'},
+      :sibling => {:tag => 'ul', :children => {:count => 2}}
+  end
+
+  def test_context_menu_on_single_issue_should_select_current_custom_field_value
+    field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
+      :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
+    issue = Issue.find(1)
+    issue.custom_field_values = {field.id => 'Bar'}
+    issue.save!
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+
+    assert_tag 'a',
+      :content => 'List',
+      :attributes => {:href => '#'},
+      :sibling => {:tag => 'ul', :children => {:count => 3}}
+    assert_tag 'a',
+      :content => 'Bar',
+      :attributes => {:class => /icon-checked/}
+  end
+
+  def test_context_menu_should_include_bool_custom_fields
+    field = IssueCustomField.create!(:name => 'Bool', :field_format => 'bool',
+      :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2]
+
+    assert_tag 'a',
+      :content => 'Bool',
+      :attributes => {:href => '#'},
+      :sibling => {:tag => 'ul', :children => {:count => 3}}
+
+    assert_tag 'a',
+      :content => 'Yes',
+      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=1"}
+  end
+
+  def test_context_menu_should_include_user_custom_fields
+    field = IssueCustomField.create!(:name => 'User', :field_format => 'user',
+      :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2]
+
+    assert_tag 'a',
+      :content => 'User',
+      :attributes => {:href => '#'},
+      :sibling => {:tag => 'ul', :children => {:count => Project.find(1).members.count + 1}}
+
+    assert_tag 'a',
+      :content => 'John Smith',
+      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=2"}
+  end
+
+  def test_context_menu_should_include_version_custom_fields
+    field = IssueCustomField.create!(:name => 'Version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2]
+
+    assert_tag 'a',
+      :content => 'Version',
+      :attributes => {:href => '#'},
+      :sibling => {:tag => 'ul', :children => {:count => Project.find(1).shared_versions.count + 1}}
+
+    assert_tag 'a',
+      :content => '2.0',
+      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=3"}
+  end
+
   def test_context_menu_by_assignable_user_should_include_assigned_to_me_link
     @request.session[:user_id] = 2
     get :issues, :ids => [1]