@@ -20,7 +20,7 class IssuesController < ApplicationController | |||||
20 | default_search_scope :issues |
|
20 | default_search_scope :issues | |
21 |
|
21 | |||
22 | before_filter :find_issue, :only => [:show, :edit, :update] |
|
22 | before_filter :find_issue, :only => [:show, :edit, :update] | |
23 | before_filter :find_issues, :only => [:bulk_edit, :move, :perform_move, :destroy] |
|
23 | before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :move, :perform_move, :destroy] | |
24 | before_filter :find_project, :only => [:new, :create] |
|
24 | before_filter :find_project, :only => [:new, :create] | |
25 | before_filter :authorize, :except => [:index] |
|
25 | before_filter :authorize, :except => [:index] | |
26 | before_filter :find_optional_project, :only => [:index] |
|
26 | before_filter :find_optional_project, :only => [:index] | |
@@ -54,6 +54,7 class IssuesController < ApplicationController | |||||
54 | :render => { :nothing => true, :status => :method_not_allowed } |
|
54 | :render => { :nothing => true, :status => :method_not_allowed } | |
55 |
|
55 | |||
56 | verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed } |
|
56 | verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed } | |
|
57 | verify :method => :post, :only => :bulk_update, :render => {:nothing => true, :status => :method_not_allowed } | |||
57 | verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed } |
|
58 | verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed } | |
58 |
|
59 | |||
59 | def index |
|
60 | def index | |
@@ -191,29 +192,31 class IssuesController < ApplicationController | |||||
191 | # Bulk edit a set of issues |
|
192 | # Bulk edit a set of issues | |
192 | def bulk_edit |
|
193 | def bulk_edit | |
193 | @issues.sort! |
|
194 | @issues.sort! | |
194 | if request.post? |
|
|||
195 | attributes = (params[:issue] || {}).reject {|k,v| v.blank?} |
|
|||
196 | attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} |
|
|||
197 | attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] |
|
|||
198 |
|
||||
199 | unsaved_issue_ids = [] |
|
|||
200 | @issues.each do |issue| |
|
|||
201 | issue.reload |
|
|||
202 | journal = issue.init_journal(User.current, params[:notes]) |
|
|||
203 | issue.safe_attributes = attributes |
|
|||
204 | call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) |
|
|||
205 | unless issue.save |
|
|||
206 | # Keep unsaved issue ids to display them in flash error |
|
|||
207 | unsaved_issue_ids << issue.id |
|
|||
208 | end |
|
|||
209 | end |
|
|||
210 | set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) |
|
|||
211 | redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project}) |
|
|||
212 | return |
|
|||
213 | end |
|
|||
214 | @available_statuses = Workflow.available_statuses(@project) |
|
195 | @available_statuses = Workflow.available_statuses(@project) | |
215 | @custom_fields = @project.all_issue_custom_fields |
|
196 | @custom_fields = @project.all_issue_custom_fields | |
216 | end |
|
197 | end | |
|
198 | ||||
|
199 | def bulk_update | |||
|
200 | @issues.sort! | |||
|
201 | ||||
|
202 | attributes = (params[:issue] || {}).reject {|k,v| v.blank?} | |||
|
203 | attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} | |||
|
204 | attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] | |||
|
205 | ||||
|
206 | unsaved_issue_ids = [] | |||
|
207 | @issues.each do |issue| | |||
|
208 | issue.reload | |||
|
209 | journal = issue.init_journal(User.current, params[:notes]) | |||
|
210 | issue.safe_attributes = attributes | |||
|
211 | call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) | |||
|
212 | unless issue.save | |||
|
213 | # Keep unsaved issue ids to display them in flash error | |||
|
214 | unsaved_issue_ids << issue.id | |||
|
215 | end | |||
|
216 | end | |||
|
217 | set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) | |||
|
218 | redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project}) | |||
|
219 | end | |||
217 |
|
220 | |||
218 | def destroy |
|
221 | def destroy | |
219 | @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f |
|
222 | @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f |
@@ -2,7 +2,7 | |||||
2 |
|
2 | |||
3 | <ul><%= @issues.collect {|i| content_tag('li', link_to(h("#{i.tracker} ##{i.id}"), { :action => 'show', :id => i }) + h(": #{i.subject}")) }.join("\n") %></ul> |
|
3 | <ul><%= @issues.collect {|i| content_tag('li', link_to(h("#{i.tracker} ##{i.id}"), { :action => 'show', :id => i }) + h(": #{i.subject}")) }.join("\n") %></ul> | |
4 |
|
4 | |||
5 | <% form_tag() do %> |
|
5 | <% form_tag(:action => 'bulk_update') do %> | |
6 | <%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join %> |
|
6 | <%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join %> | |
7 | <div class="box tabular"> |
|
7 | <div class="box tabular"> | |
8 | <fieldset class="attributes"> |
|
8 | <fieldset class="attributes"> |
@@ -132,6 +132,7 ActionController::Routing::Routes.draw do |map| | |||||
132 | issues_actions.connect 'issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/ |
|
132 | issues_actions.connect 'issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/ | |
133 | issues_actions.connect 'issues/:id/:action', :action => /edit|destroy/, :id => /\d+/ |
|
133 | issues_actions.connect 'issues/:id/:action', :action => /edit|destroy/, :id => /\d+/ | |
134 | issues_actions.connect 'issues.:format', :action => 'create', :format => /xml/ |
|
134 | issues_actions.connect 'issues.:format', :action => 'create', :format => /xml/ | |
|
135 | issues_actions.connect 'issues/bulk_edit', :action => 'bulk_update' | |||
135 | end |
|
136 | end | |
136 | issues_routes.with_options :conditions => {:method => :put} do |issues_actions| |
|
137 | issues_routes.with_options :conditions => {:method => :put} do |issues_actions| | |
137 | issues_actions.connect 'issues/:id/edit', :action => 'update', :id => /\d+/ |
|
138 | issues_actions.connect 'issues/:id/edit', :action => 'update', :id => /\d+/ |
@@ -66,7 +66,7 Redmine::AccessControl.map do |map| | |||||
66 | :queries => :index, |
|
66 | :queries => :index, | |
67 | :reports => [:issue_report, :issue_report_details]} |
|
67 | :reports => [:issue_report, :issue_report_details]} | |
68 | map.permission :add_issues, {:issues => [:new, :create, :update_form]} |
|
68 | map.permission :add_issues, {:issues => [:new, :create, :update_form]} | |
69 | map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :update_form], :journals => [:new]} |
|
69 | map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]} | |
70 | map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} |
|
70 | map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} | |
71 | map.permission :manage_subtasks, {} |
|
71 | map.permission :manage_subtasks, {} | |
72 | map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]} |
|
72 | map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]} |
@@ -910,10 +910,10 class IssuesControllerTest < ActionController::TestCase | |||||
910 | assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'} |
|
910 | assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'} | |
911 | end |
|
911 | end | |
912 |
|
912 | |||
913 |
def test_bulk_ |
|
913 | def test_bulk_update | |
914 | @request.session[:user_id] = 2 |
|
914 | @request.session[:user_id] = 2 | |
915 | # update issues priority |
|
915 | # update issues priority | |
916 |
post :bulk_ |
|
916 | post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing', | |
917 | :issue => {:priority_id => 7, |
|
917 | :issue => {:priority_id => 7, | |
918 | :assigned_to_id => '', |
|
918 | :assigned_to_id => '', | |
919 | :custom_field_values => {'2' => ''}} |
|
919 | :custom_field_values => {'2' => ''}} | |
@@ -929,10 +929,10 class IssuesControllerTest < ActionController::TestCase | |||||
929 | assert_equal 1, journal.details.size |
|
929 | assert_equal 1, journal.details.size | |
930 | end |
|
930 | end | |
931 |
|
931 | |||
932 |
def test_bullk_ |
|
932 | def test_bullk_update_should_send_a_notification | |
933 | @request.session[:user_id] = 2 |
|
933 | @request.session[:user_id] = 2 | |
934 | ActionMailer::Base.deliveries.clear |
|
934 | ActionMailer::Base.deliveries.clear | |
935 |
post(:bulk_ |
|
935 | post(:bulk_update, | |
936 | { |
|
936 | { | |
937 | :ids => [1, 2], |
|
937 | :ids => [1, 2], | |
938 | :notes => 'Bulk editing', |
|
938 | :notes => 'Bulk editing', | |
@@ -947,10 +947,10 class IssuesControllerTest < ActionController::TestCase | |||||
947 | assert_equal 2, ActionMailer::Base.deliveries.size |
|
947 | assert_equal 2, ActionMailer::Base.deliveries.size | |
948 | end |
|
948 | end | |
949 |
|
949 | |||
950 |
def test_bulk_ |
|
950 | def test_bulk_update_status | |
951 | @request.session[:user_id] = 2 |
|
951 | @request.session[:user_id] = 2 | |
952 | # update issues priority |
|
952 | # update issues priority | |
953 |
post :bulk_ |
|
953 | post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status', | |
954 | :issue => {:priority_id => '', |
|
954 | :issue => {:priority_id => '', | |
955 | :assigned_to_id => '', |
|
955 | :assigned_to_id => '', | |
956 | :status_id => '5'} |
|
956 | :status_id => '5'} | |
@@ -960,10 +960,10 class IssuesControllerTest < ActionController::TestCase | |||||
960 | assert issue.closed? |
|
960 | assert issue.closed? | |
961 | end |
|
961 | end | |
962 |
|
962 | |||
963 |
def test_bulk_ |
|
963 | def test_bulk_update_custom_field | |
964 | @request.session[:user_id] = 2 |
|
964 | @request.session[:user_id] = 2 | |
965 | # update issues priority |
|
965 | # update issues priority | |
966 |
post :bulk_ |
|
966 | post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field', | |
967 | :issue => {:priority_id => '', |
|
967 | :issue => {:priority_id => '', | |
968 | :assigned_to_id => '', |
|
968 | :assigned_to_id => '', | |
969 | :custom_field_values => {'2' => '777'}} |
|
969 | :custom_field_values => {'2' => '777'}} | |
@@ -978,20 +978,20 class IssuesControllerTest < ActionController::TestCase | |||||
978 | assert_equal '777', journal.details.first.value |
|
978 | assert_equal '777', journal.details.first.value | |
979 | end |
|
979 | end | |
980 |
|
980 | |||
981 | def test_bulk_unassign |
|
981 | def test_bulk_update_unassign | |
982 | assert_not_nil Issue.find(2).assigned_to |
|
982 | assert_not_nil Issue.find(2).assigned_to | |
983 | @request.session[:user_id] = 2 |
|
983 | @request.session[:user_id] = 2 | |
984 | # unassign issues |
|
984 | # unassign issues | |
985 |
post :bulk_ |
|
985 | post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'} | |
986 | assert_response 302 |
|
986 | assert_response 302 | |
987 | # check that the issues were updated |
|
987 | # check that the issues were updated | |
988 | assert_nil Issue.find(2).assigned_to |
|
988 | assert_nil Issue.find(2).assigned_to | |
989 | end |
|
989 | end | |
990 |
|
990 | |||
991 |
def test_post_bulk_ |
|
991 | def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject | |
992 | @request.session[:user_id] = 2 |
|
992 | @request.session[:user_id] = 2 | |
993 |
|
993 | |||
994 |
post :bulk_ |
|
994 | post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4} | |
995 |
|
995 | |||
996 | assert_response :redirect |
|
996 | assert_response :redirect | |
997 | issues = Issue.find([1,2]) |
|
997 | issues = Issue.find([1,2]) | |
@@ -1001,17 +1001,17 class IssuesControllerTest < ActionController::TestCase | |||||
1001 | end |
|
1001 | end | |
1002 | end |
|
1002 | end | |
1003 |
|
1003 | |||
1004 |
def test_post_bulk_ |
|
1004 | def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter | |
1005 | @request.session[:user_id] = 2 |
|
1005 | @request.session[:user_id] = 2 | |
1006 |
post :bulk_ |
|
1006 | post :bulk_update, :ids => [1,2], :back_url => '/issues' | |
1007 |
|
1007 | |||
1008 | assert_response :redirect |
|
1008 | assert_response :redirect | |
1009 | assert_redirected_to '/issues' |
|
1009 | assert_redirected_to '/issues' | |
1010 | end |
|
1010 | end | |
1011 |
|
1011 | |||
1012 |
def test_post_bulk_ |
|
1012 | def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host | |
1013 | @request.session[:user_id] = 2 |
|
1013 | @request.session[:user_id] = 2 | |
1014 |
post :bulk_ |
|
1014 | post :bulk_update, :ids => [1,2], :back_url => 'http://google.com' | |
1015 |
|
1015 | |||
1016 | assert_response :redirect |
|
1016 | assert_response :redirect | |
1017 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier |
|
1017 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier |
@@ -108,6 +108,9 class RoutingTest < ActionController::IntegrationTest | |||||
108 | should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues' |
|
108 | should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues' | |
109 |
|
109 | |||
110 | should_route :get, "/issues/changes", :controller => 'journals', :action => 'index' |
|
110 | should_route :get, "/issues/changes", :controller => 'journals', :action => 'index' | |
|
111 | ||||
|
112 | should_route :get, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_edit' | |||
|
113 | should_route :post, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_update' | |||
111 | end |
|
114 | end | |
112 |
|
115 | |||
113 | context "issue categories" do |
|
116 | context "issue categories" do |
General Comments 0
You need to be logged in to leave comments.
Login now