@@ -209,10 +209,25 class IssuesController < ApplicationController | |||||
209 | # Bulk edit a set of issues |
|
209 | # Bulk edit a set of issues | |
210 | def bulk_edit |
|
210 | def bulk_edit | |
211 | @issues.sort! |
|
211 | @issues.sort! | |
212 | @available_statuses = @projects.map{|p|Workflow.available_statuses(p)}.inject{|memo,w|memo & w} |
|
212 | ||
213 | @custom_fields = @projects.map{|p|p.all_issue_custom_fields}.inject{|memo,c|memo & c} |
|
213 | if User.current.allowed_to?(:move_issues, @projects) | |
214 | @assignables = @projects.map(&:assignable_users).inject{|memo,a| memo & a} |
|
214 | @allowed_projects = Issue.allowed_target_projects_on_move | |
215 | @trackers = @projects.map(&:trackers).inject{|memo,t| memo & t} |
|
215 | if params[:issue] | |
|
216 | @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id]} | |||
|
217 | if @target_project | |||
|
218 | target_projects = [@target_project] | |||
|
219 | end | |||
|
220 | end | |||
|
221 | end | |||
|
222 | target_projects ||= @projects | |||
|
223 | ||||
|
224 | @available_statuses = target_projects.map{|p|Workflow.available_statuses(p)}.inject{|memo,w|memo & w} | |||
|
225 | @custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.inject{|memo,c|memo & c} | |||
|
226 | @assignables = target_projects.map(&:assignable_users).inject{|memo,a| memo & a} | |||
|
227 | @trackers = target_projects.map(&:trackers).inject{|memo,t| memo & t} | |||
|
228 | ||||
|
229 | @notes = params[:notes] | |||
|
230 | render :layout => false if request.xhr? | |||
216 | end |
|
231 | end | |
217 |
|
232 | |||
218 | def bulk_update |
|
233 | def bulk_update | |
@@ -220,19 +235,31 class IssuesController < ApplicationController | |||||
220 | attributes = parse_params_for_bulk_issue_attributes(params) |
|
235 | attributes = parse_params_for_bulk_issue_attributes(params) | |
221 |
|
236 | |||
222 | unsaved_issue_ids = [] |
|
237 | unsaved_issue_ids = [] | |
|
238 | moved_issues = [] | |||
223 | @issues.each do |issue| |
|
239 | @issues.each do |issue| | |
224 | issue.reload |
|
240 | issue.reload | |
225 | journal = issue.init_journal(User.current, params[:notes]) |
|
241 | journal = issue.init_journal(User.current, params[:notes]) | |
226 | issue.safe_attributes = attributes |
|
242 | issue.safe_attributes = attributes | |
227 | call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) |
|
243 | call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) | |
228 |
|
|
244 | if issue.save | |
|
245 | moved_issues << issue | |||
|
246 | else | |||
229 | # Keep unsaved issue ids to display them in flash error |
|
247 | # Keep unsaved issue ids to display them in flash error | |
230 | unsaved_issue_ids << issue.id |
|
248 | unsaved_issue_ids << issue.id | |
231 | end |
|
249 | end | |
232 | end |
|
250 | end | |
233 | set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) |
|
251 | set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) | |
|
252 | ||||
|
253 | if params[:follow] | |||
|
254 | if @issues.size == 1 && moved_issues.size == 1 | |||
|
255 | redirect_to :controller => 'issues', :action => 'show', :id => moved_issues.first | |||
|
256 | elsif moved_issues.map(&:project).uniq.size == 1 | |||
|
257 | redirect_to :controller => 'issues', :action => 'index', :project_id => moved_issues.map(&:project).first | |||
|
258 | end | |||
|
259 | else | |||
234 | redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project}) |
|
260 | redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project}) | |
235 | end |
|
261 | end | |
|
262 | end | |||
236 |
|
263 | |||
237 | verify :method => :delete, :only => :destroy, :render => { :nothing => true, :status => :method_not_allowed } |
|
264 | verify :method => :delete, :only => :destroy, :render => { :nothing => true, :status => :method_not_allowed } | |
238 | def destroy |
|
265 | def destroy |
@@ -7,13 +7,22 | |||||
7 | ) + h(": #{i.subject}")) |
|
7 | ) + h(": #{i.subject}")) | |
8 | }.join("\n").html_safe %></ul> |
|
8 | }.join("\n").html_safe %></ul> | |
9 |
|
9 | |||
10 | <% form_tag(:action => 'bulk_update') do %> |
|
10 | <% form_tag({:action => 'bulk_update'}, :id => 'bulk_edit_form') do %> | |
11 | <%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %> |
|
11 | <%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %> | |
12 | <div class="box tabular"> |
|
12 | <div class="box tabular"> | |
13 | <fieldset class="attributes"> |
|
13 | <fieldset class="attributes"> | |
14 | <legend><%= l(:label_change_properties) %></legend> |
|
14 | <legend><%= l(:label_change_properties) %></legend> | |
15 |
|
15 | |||
16 | <div class="splitcontentleft"> |
|
16 | <div class="splitcontentleft"> | |
|
17 | <% if @allowed_projects.present? %> | |||
|
18 | <p> | |||
|
19 | <label for="issue_project_id"><%= l(:field_project) %></label> | |||
|
20 | <%= select_tag('issue[project_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + project_tree_options_for_select(@allowed_projects, :selected => @target_project)) %> | |||
|
21 | </p> | |||
|
22 | <%= observe_field :issue_project_id, :url => {:action => 'bulk_edit'}, | |||
|
23 | :update => 'content', | |||
|
24 | :with => "Form.serialize('bulk_edit_form')" %> | |||
|
25 | <% end %> | |||
17 | <p> |
|
26 | <p> | |
18 | <label for="issue_tracker_id"><%= l(:field_tracker) %></label> |
|
27 | <label for="issue_tracker_id"><%= l(:field_tracker) %></label> | |
19 | <%= select_tag('issue[tracker_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@trackers, :id, :name)) %> |
|
28 | <%= select_tag('issue[tracker_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@trackers, :id, :name)) %> | |
@@ -92,5 +101,13 | |||||
92 | </fieldset> |
|
101 | </fieldset> | |
93 | </div> |
|
102 | </div> | |
94 |
|
103 | |||
95 | <p><%= submit_tag l(:button_submit) %></p> |
|
104 | <p> | |
|
105 | <% if @target_project %> | |||
|
106 | <%= submit_tag l(:button_move) %> | |||
|
107 | <%= submit_tag l(:button_move_and_follow), :name => 'follow' %> | |||
|
108 | <% else %> | |||
|
109 | <%= submit_tag l(:button_submit) %> | |||
|
110 | <% end %> | |||
|
111 | </p> | |||
|
112 | ||||
96 | <% end %> |
|
113 | <% end %> |
@@ -198,7 +198,7 ActionController::Routing::Routes.draw do |map| | |||||
198 |
|
198 | |||
199 | map.resources :queries, :except => [:show] |
|
199 | map.resources :queries, :except => [:show] | |
200 | map.resources :issues, |
|
200 | map.resources :issues, | |
201 | :collection => {:bulk_edit => :get, :bulk_update => :post} do |issues| |
|
201 | :collection => {:bulk_edit => [:get, :post], :bulk_update => :post} do |issues| | |
202 | issues.resources :time_entries, :controller => 'timelog', |
|
202 | issues.resources :time_entries, :controller => 'timelog', | |
203 | :collection => {:report => :get} |
|
203 | :collection => {:report => :get} | |
204 | issues.resources :relations, :shallow => true, |
|
204 | issues.resources :relations, :shallow => true, |
@@ -2033,6 +2033,7 class IssuesControllerTest < ActionController::TestCase | |||||
2033 | assert_response :success |
|
2033 | assert_response :success | |
2034 | assert_template 'bulk_edit' |
|
2034 | assert_template 'bulk_edit' | |
2035 |
|
2035 | |||
|
2036 | assert_tag :select, :attributes => {:name => 'issue[project_id]'} | |||
2036 | assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'} |
|
2037 | assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'} | |
2037 |
|
2038 | |||
2038 | # Project specific custom field, date type |
|
2039 | # Project specific custom field, date type | |
@@ -2185,6 +2186,38 class IssuesControllerTest < ActionController::TestCase | |||||
2185 | assert_equal 2, ActionMailer::Base.deliveries.size |
|
2186 | assert_equal 2, ActionMailer::Base.deliveries.size | |
2186 | end |
|
2187 | end | |
2187 |
|
2188 | |||
|
2189 | def test_bulk_update_project | |||
|
2190 | @request.session[:user_id] = 2 | |||
|
2191 | post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'} | |||
|
2192 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook' | |||
|
2193 | # Issues moved to project 2 | |||
|
2194 | assert_equal 2, Issue.find(1).project_id | |||
|
2195 | assert_equal 2, Issue.find(2).project_id | |||
|
2196 | # No tracker change | |||
|
2197 | assert_equal 1, Issue.find(1).tracker_id | |||
|
2198 | assert_equal 2, Issue.find(2).tracker_id | |||
|
2199 | end | |||
|
2200 | ||||
|
2201 | def test_bulk_update_project_on_single_issue_should_follow_when_needed | |||
|
2202 | @request.session[:user_id] = 2 | |||
|
2203 | post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1' | |||
|
2204 | assert_redirected_to '/issues/1' | |||
|
2205 | end | |||
|
2206 | ||||
|
2207 | def test_bulk_update_project_on_multiple_issues_should_follow_when_needed | |||
|
2208 | @request.session[:user_id] = 2 | |||
|
2209 | post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1' | |||
|
2210 | assert_redirected_to '/projects/onlinestore/issues' | |||
|
2211 | end | |||
|
2212 | ||||
|
2213 | def test_bulk_update_tracker | |||
|
2214 | @request.session[:user_id] = 2 | |||
|
2215 | post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'} | |||
|
2216 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook' | |||
|
2217 | assert_equal 2, Issue.find(1).tracker_id | |||
|
2218 | assert_equal 2, Issue.find(2).tracker_id | |||
|
2219 | end | |||
|
2220 | ||||
2188 | def test_bulk_update_status |
|
2221 | def test_bulk_update_status | |
2189 | @request.session[:user_id] = 2 |
|
2222 | @request.session[:user_id] = 2 | |
2190 | # update issues priority |
|
2223 | # update issues priority | |
@@ -2198,6 +2231,24 class IssuesControllerTest < ActionController::TestCase | |||||
2198 | assert issue.closed? |
|
2231 | assert issue.closed? | |
2199 | end |
|
2232 | end | |
2200 |
|
2233 | |||
|
2234 | def test_bulk_update_priority | |||
|
2235 | @request.session[:user_id] = 2 | |||
|
2236 | post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6} | |||
|
2237 | ||||
|
2238 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook' | |||
|
2239 | assert_equal 6, Issue.find(1).priority_id | |||
|
2240 | assert_equal 6, Issue.find(2).priority_id | |||
|
2241 | end | |||
|
2242 | ||||
|
2243 | def test_bulk_update_with_notes | |||
|
2244 | @request.session[:user_id] = 2 | |||
|
2245 | post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues' | |||
|
2246 | ||||
|
2247 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook' | |||
|
2248 | assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes | |||
|
2249 | assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes | |||
|
2250 | end | |||
|
2251 | ||||
2201 | def test_bulk_update_parent_id |
|
2252 | def test_bulk_update_parent_id | |
2202 | @request.session[:user_id] = 2 |
|
2253 | @request.session[:user_id] = 2 | |
2203 | post :bulk_update, :ids => [1, 3], |
|
2254 | post :bulk_update, :ids => [1, 3], |
@@ -123,6 +123,11 class RoutingIssuesTest < ActionController::IntegrationTest | |||||
123 | { :method => 'get', :path => "/issues/bulk_edit" }, |
|
123 | { :method => 'get', :path => "/issues/bulk_edit" }, | |
124 | { :controller => 'issues', :action => 'bulk_edit' } |
|
124 | { :controller => 'issues', :action => 'bulk_edit' } | |
125 | ) |
|
125 | ) | |
|
126 | # For updating the bulk edit form | |||
|
127 | assert_routing( | |||
|
128 | { :method => 'post', :path => "/issues/bulk_edit" }, | |||
|
129 | { :controller => 'issues', :action => 'bulk_edit' } | |||
|
130 | ) | |||
126 | assert_routing( |
|
131 | assert_routing( | |
127 | { :method => 'post', :path => "/issues/bulk_update" }, |
|
132 | { :method => 'post', :path => "/issues/bulk_update" }, | |
128 | { :controller => 'issues', :action => 'bulk_update' } |
|
133 | { :controller => 'issues', :action => 'bulk_update' } |
General Comments 0
You need to be logged in to leave comments.
Login now