diff options
author | Jean-Baptiste Barth <jeanbaptiste.barth@gmail.com> | 2010-10-08 03:09:51 +0000 |
---|---|---|
committer | Jean-Baptiste Barth <jeanbaptiste.barth@gmail.com> | 2010-10-08 03:09:51 +0000 |
commit | 156eca4d223efce4abd67c9ef7b129a3d07d83e6 (patch) | |
tree | dc61c3fa752872267c3b964c1716374720bb10ba | |
parent | 73f12765a99b6d78c5d23a58fe887c79a4012e99 (diff) | |
download | redmine-156eca4d223efce4abd67c9ef7b129a3d07d83e6.tar.gz redmine-156eca4d223efce4abd67c9ef7b129a3d07d83e6.zip |
Added ability to edit issues from different project through contextual menu (#5332)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4242 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r-- | app/controllers/context_menus_controller.rb | 8 | ||||
-rw-r--r-- | app/controllers/issues_controller.rb | 8 | ||||
-rw-r--r-- | app/views/context_menus/issues.html.erb | 5 | ||||
-rw-r--r-- | app/views/issues/bulk_edit.rhtml | 9 | ||||
-rw-r--r-- | test/functional/context_menus_controller_test.rb | 12 | ||||
-rw-r--r-- | test/functional/issues_controller_test.rb | 46 |
6 files changed, 78 insertions, 10 deletions
diff --git a/app/controllers/context_menus_controller.rb b/app/controllers/context_menus_controller.rb index ae8517243..3e1438306 100644 --- a/app/controllers/context_menus_controller.rb +++ b/app/controllers/context_menus_controller.rb @@ -16,9 +16,9 @@ class ContextMenusController < ApplicationController @projects = @issues.collect(&:project).compact.uniq @project = @projects.first if @projects.size == 1 - @can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)), + @can = {:edit => User.current.allowed_to?(:edit_issues, @projects), :log_time => (@project && User.current.allowed_to?(:log_time, @project)), - :update => (@project && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && @allowed_statuses && !@allowed_statuses.empty?))), + :update => (User.current.allowed_to?(:edit_issues, @projects) || (User.current.allowed_to?(:change_status, @projects) && !@allowed_statuses.blank?)), :move => (@project && User.current.allowed_to?(:move_issues, @project)), :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)), :delete => User.current.allowed_to?(:delete_issues, @projects) @@ -27,6 +27,10 @@ class ContextMenusController < ApplicationController @assignables = @project.assignable_users @assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to) @trackers = @project.trackers + else + #when multiple projects, we only keep the intersection of each set + @assignables = @projects.map(&:assignable_users).inject{|memo,a| memo & a} + @trackers = @projects.map(&:trackers).inject{|memo,t| memo & t} end @priorities = IssuePriority.all.reverse diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 2221db871..67488b753 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -21,7 +21,7 @@ class IssuesController < ApplicationController before_filter :find_issue, :only => [:show, :edit, :update] before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :move, :perform_move, :destroy] - before_filter :check_project_uniqueness, :only => [:bulk_edit, :bulk_update, :move, :perform_move] + before_filter :check_project_uniqueness, :only => [:move, :perform_move] before_filter :find_project, :only => [:new, :create] before_filter :authorize, :except => [:index] before_filter :find_optional_project, :only => [:index] @@ -194,8 +194,10 @@ class IssuesController < ApplicationController # Bulk edit a set of issues def bulk_edit @issues.sort! - @available_statuses = Workflow.available_statuses(@project) - @custom_fields = @project.all_issue_custom_fields + @available_statuses = @projects.map{|p|Workflow.available_statuses(p)}.inject{|memo,w|memo & w} + @custom_fields = @projects.map{|p|p.all_issue_custom_fields}.inject{|memo,c|memo & c} + @assignables = @projects.map(&:assignable_users).inject{|memo,a| memo & a} + @trackers = @projects.map(&:trackers).inject{|memo,t| memo & t} end def bulk_update diff --git a/app/views/context_menus/issues.html.erb b/app/views/context_menus/issues.html.erb index 3f45f4ea2..3109ac4dd 100644 --- a/app/views/context_menus/issues.html.erb +++ b/app/views/context_menus/issues.html.erb @@ -33,7 +33,6 @@ </li> <% end %> - <% if @projects.size == 1 %> <li class="folder"> <a href="#" class="submenu"><%= l(:field_priority) %></a> <ul> @@ -43,8 +42,8 @@ <% end -%> </ul> </li> - <% end %> + <% #TODO: allow editing versions when multiple projects %> <% unless @project.nil? || @project.shared_versions.open.empty? -%> <li class="folder"> <a href="#" class="submenu"><%= l(:field_fixed_version) %></a> @@ -85,7 +84,7 @@ </li> <% end -%> - <% if Issue.use_field_for_done_ratio? && @projects.size == 1 %> + <% if Issue.use_field_for_done_ratio? %> <li class="folder"> <a href="#" class="submenu"><%= l(:field_done_ratio) %></a> <ul> diff --git a/app/views/issues/bulk_edit.rhtml b/app/views/issues/bulk_edit.rhtml index 5fdfd58a6..7091e358b 100644 --- a/app/views/issues/bulk_edit.rhtml +++ b/app/views/issues/bulk_edit.rhtml @@ -11,7 +11,7 @@ <div class="splitcontentleft"> <p> <label><%= l(:field_tracker) %></label> - <%= select_tag('issue[tracker_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@project.trackers, :id, :name)) %> + <%= select_tag('issue[tracker_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@trackers, :id, :name)) %> </p> <% if @available_statuses.any? %> <p> @@ -27,20 +27,25 @@ <label><%= l(:field_assigned_to) %></label> <%= select_tag('issue[assigned_to_id]', content_tag('option', l(:label_no_change_option), :value => '') + content_tag('option', l(:label_nobody), :value => 'none') + - options_from_collection_for_select(@project.assignable_users, :id, :name)) %> + options_from_collection_for_select(@assignables, :id, :name)) %> </p> +<% if @project %> <p> <label><%= l(:field_category) %></label> <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') + content_tag('option', l(:label_none), :value => 'none') + options_from_collection_for_select(@project.issue_categories, :id, :name)) %> </p> +<% end %> +<% #TODO: allow editing versions when multiple projects %> +<% if @project %> <p> <label><%= l(:field_fixed_version) %></label> <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') + content_tag('option', l(:label_none), :value => 'none') + version_options_for_select(@project.shared_versions.open)) %> </p> +<% end %> <% @custom_fields.each do |custom_field| %> <p><label><%= h(custom_field.name) %></label> <%= custom_field_tag_for_bulk_edit('issue', custom_field) %></p> diff --git a/test/functional/context_menus_controller_test.rb b/test/functional/context_menus_controller_test.rb index 0202cf2c7..6d2b45bad 100644 --- a/test/functional/context_menus_controller_test.rb +++ b/test/functional/context_menus_controller_test.rb @@ -85,6 +85,18 @@ class ContextMenusControllerTest < ActionController::TestCase assert_response :success assert_template 'context_menu' ids = "ids%5B%5D=1&ids%5B%5D=2&ids%5B%5D=6" + assert_tag :tag => 'a', :content => 'Edit', + :attributes => { :href => "/issues/bulk_edit?#{ids}", + :class => 'icon-edit' } + assert_tag :tag => 'a', :content => 'Closed', + :attributes => { :href => "/issues/bulk_edit?#{ids}&issue%5Bstatus_id%5D=5", + :class => '' } + assert_tag :tag => 'a', :content => 'Immediate', + :attributes => { :href => "/issues/bulk_edit?#{ids}&issue%5Bpriority_id%5D=8", + :class => '' } + assert_tag :tag => 'a', :content => 'John Smith', + :attributes => { :href => "/issues/bulk_edit?#{ids}&issue%5Bassigned_to_id%5D=2", + :class => '' } assert_tag :tag => 'a', :content => 'Delete', :attributes => { :href => "/issues/destroy?#{ids}", :class => 'icon-del' } diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 4db2dae86..59b16c32c 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -911,6 +911,19 @@ class IssuesControllerTest < ActionController::TestCase assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'} end + def test_get_bulk_edit_on_different_projects + @request.session[:user_id] = 2 + get :bulk_edit, :ids => [1, 2, 6] + assert_response :success + assert_template 'bulk_edit' + + # Project specific custom field, date type + field = CustomField.find(9) + assert !field.is_for_all? + assert !field.project_ids.include?(Issue.find(6).project_id) + assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'} + end + def test_bulk_update @request.session[:user_id] = 2 # update issues priority @@ -930,6 +943,39 @@ class IssuesControllerTest < ActionController::TestCase assert_equal 1, journal.details.size end + def test_bulk_update_on_different_projects + @request.session[:user_id] = 2 + # update issues priority + post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing', + :issue => {:priority_id => 7, + :assigned_to_id => '', + :custom_field_values => {'2' => ''}} + + assert_response 302 + # check that the issues were updated + assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id) + + issue = Issue.find(1) + journal = issue.journals.find(:first, :order => 'created_on DESC') + assert_equal '125', issue.custom_value_for(2).value + assert_equal 'Bulk editing', journal.notes + assert_equal 1, journal.details.size + end + + def test_bulk_update_on_different_projects_without_rights + @request.session[:user_id] = 3 + user = User.find(3) + action = { :controller => "issues", :action => "bulk_update" } + assert user.allowed_to?(action, Issue.find(1).project) + assert ! user.allowed_to?(action, Issue.find(6).project) + post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail', + :issue => {:priority_id => 7, + :assigned_to_id => '', + :custom_field_values => {'2' => ''}} + assert_response 403 + assert_not_equal "Bulk should fail", Journal.last.notes + end + def test_bullk_update_should_send_a_notification @request.session[:user_id] = 2 ActionMailer::Base.deliveries.clear |