@@ -555,21 +555,6 class ApplicationController < ActionController::Base | |||||
555 | flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present? |
|
555 | flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present? | |
556 | end |
|
556 | end | |
557 |
|
557 | |||
558 | # Sets the `flash` notice or error based the number of issues that did not save |
|
|||
559 | # |
|
|||
560 | # @param [Array, Issue] issues all of the saved and unsaved Issues |
|
|||
561 | # @param [Array, Integer] unsaved_issue_ids the issue ids that were not saved |
|
|||
562 | def set_flash_from_bulk_issue_save(issues, unsaved_issue_ids) |
|
|||
563 | if unsaved_issue_ids.empty? |
|
|||
564 | flash[:notice] = l(:notice_successful_update) unless issues.empty? |
|
|||
565 | else |
|
|||
566 | flash[:error] = l(:notice_failed_to_save_issues, |
|
|||
567 | :count => unsaved_issue_ids.size, |
|
|||
568 | :total => issues.size, |
|
|||
569 | :ids => '#' + unsaved_issue_ids.join(', #')) |
|
|||
570 | end |
|
|||
571 | end |
|
|||
572 |
|
||||
573 | # Rescues an invalid query statement. Just in case... |
|
558 | # Rescues an invalid query statement. Just in case... | |
574 | def query_statement_invalid(exception) |
|
559 | def query_statement_invalid(exception) | |
575 | logger.error "Query::StatementInvalid: #{exception.message}" if logger |
|
560 | logger.error "Query::StatementInvalid: #{exception.message}" if logger |
@@ -241,7 +241,6 class IssuesController < ApplicationController | |||||
241 | end |
|
241 | end | |
242 |
|
242 | |||
243 | @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&) |
|
243 | @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&) | |
244 | render :layout => false if request.xhr? |
|
|||
245 | end |
|
244 | end | |
246 |
|
245 | |||
247 | def bulk_update |
|
246 | def bulk_update | |
@@ -249,8 +248,8 class IssuesController < ApplicationController | |||||
249 | @copy = params[:copy].present? |
|
248 | @copy = params[:copy].present? | |
250 | attributes = parse_params_for_bulk_issue_attributes(params) |
|
249 | attributes = parse_params_for_bulk_issue_attributes(params) | |
251 |
|
250 | |||
252 |
unsaved_issue |
|
251 | unsaved_issues = [] | |
253 |
|
|
252 | saved_issues = [] | |
254 |
|
253 | |||
255 | if @copy && params[:copy_subtasks].present? |
|
254 | if @copy && params[:copy_subtasks].present? | |
256 | # Descendant issues will be copied with the parent task |
|
255 | # Descendant issues will be copied with the parent task | |
@@ -270,24 +269,30 class IssuesController < ApplicationController | |||||
270 | issue.safe_attributes = attributes |
|
269 | issue.safe_attributes = attributes | |
271 | call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) |
|
270 | call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) | |
272 | if issue.save |
|
271 | if issue.save | |
273 |
|
|
272 | saved_issues << issue | |
274 | else |
|
273 | else | |
275 | logger.info "issue could not be updated or copied: #{issue.errors.full_messages}" if logger && logger.info |
|
274 | unsaved_issues << issue | |
276 | # Keep unsaved issue ids to display them in flash error |
|
|||
277 | unsaved_issue_ids << issue.id |
|
|||
278 | end |
|
275 | end | |
279 | end |
|
276 | end | |
280 | set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) |
|
|||
281 |
|
277 | |||
|
278 | if unsaved_issues.empty? | |||
|
279 | flash[:notice] = l(:notice_successful_update) unless saved_issues.empty? | |||
282 | if params[:follow] |
|
280 | if params[:follow] | |
283 |
if @issues.size == 1 && |
|
281 | if @issues.size == 1 && saved_issues.size == 1 | |
284 |
redirect_to issue_path( |
|
282 | redirect_to issue_path(saved_issues.first) | |
285 |
elsif |
|
283 | elsif saved_issues.map(&:project).uniq.size == 1 | |
286 |
redirect_to project_issues_path( |
|
284 | redirect_to project_issues_path(saved_issues.map(&:project).first) | |
287 | end |
|
285 | end | |
288 | else |
|
286 | else | |
289 | redirect_back_or_default _project_issues_path(@project) |
|
287 | redirect_back_or_default _project_issues_path(@project) | |
290 | end |
|
288 | end | |
|
289 | else | |||
|
290 | @saved_issues = @issues | |||
|
291 | @unsaved_issues = unsaved_issues | |||
|
292 | @issues = Issue.visible.find_all_by_id(@unsaved_issues.map(&:id)) | |||
|
293 | bulk_edit | |||
|
294 | render :action => 'bulk_edit' | |||
|
295 | end | |||
291 | end |
|
296 | end | |
292 |
|
297 | |||
293 | def destroy |
|
298 | def destroy |
@@ -94,6 +94,20 module IssuesHelper | |||||
94 | s.html_safe |
|
94 | s.html_safe | |
95 | end |
|
95 | end | |
96 |
|
96 | |||
|
97 | # Returns an array of error messages for bulk edited issues | |||
|
98 | def bulk_edit_error_messages(issues) | |||
|
99 | messages = {} | |||
|
100 | issues.each do |issue| | |||
|
101 | issue.errors.full_messages.each do |message| | |||
|
102 | messages[message] ||= [] | |||
|
103 | messages[message] << issue | |||
|
104 | end | |||
|
105 | end | |||
|
106 | messages.map { |message, issues| | |||
|
107 | "#{message}: " + issues.map {|i| "##{i.id}"}.join(', ') | |||
|
108 | } | |||
|
109 | end | |||
|
110 | ||||
97 | # Returns a link for adding a new subtask to the given issue |
|
111 | # Returns a link for adding a new subtask to the given issue | |
98 | def link_to_new_subtask(issue) |
|
112 | def link_to_new_subtask(issue) | |
99 | attrs = { |
|
113 | attrs = { |
@@ -1,5 +1,21 | |||||
1 | <h2><%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %></h2> |
|
1 | <h2><%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %></h2> | |
2 |
|
2 | |||
|
3 | <% if @saved_issues && @unsaved_issues.present? %> | |||
|
4 | <div id="errorExplanation"> | |||
|
5 | <span> | |||
|
6 | <%= l(:notice_failed_to_save_issues, | |||
|
7 | :count => @unsaved_issues.size, | |||
|
8 | :total => @saved_issues.size, | |||
|
9 | :ids => @unsaved_issues.map {|i| "##{i.id}"}.join(', ')) %> | |||
|
10 | </span> | |||
|
11 | <ul> | |||
|
12 | <% bulk_edit_error_messages(@unsaved_issues).each do |message| %> | |||
|
13 | <li><%= message %></li> | |||
|
14 | <% end %> | |||
|
15 | </ul> | |||
|
16 | </div> | |||
|
17 | <% end %> | |||
|
18 | ||||
3 | <ul id="bulk-selection"> |
|
19 | <ul id="bulk-selection"> | |
4 | <% @issues.each do |issue| %> |
|
20 | <% @issues.each do |issue| %> | |
5 | <%= content_tag 'li', link_to_issue(issue) %> |
|
21 | <%= content_tag 'li', link_to_issue(issue) %> |
@@ -3588,13 +3588,32 class IssuesControllerTest < ActionController::TestCase | |||||
3588 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier |
|
3588 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier | |
3589 | end |
|
3589 | end | |
3590 |
|
3590 | |||
3591 |
def test_bulk_update_with_failure_should_s |
|
3591 | def test_bulk_update_with_all_failures_should_show_errors | |
3592 | @request.session[:user_id] = 2 |
|
3592 | @request.session[:user_id] = 2 | |
3593 | Issue.update_all("subject = ''", "id = 2") # Make it invalid |
|
3593 | post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'} | |
3594 | post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6} |
|
|||
3595 |
|
3594 | |||
3596 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook' |
|
3595 | assert_response :success | |
3597 | assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error] |
|
3596 | assert_template 'bulk_edit' | |
|
3597 | assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.' | |||
|
3598 | assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2' | |||
|
3599 | ||||
|
3600 | assert_equal [1, 2], assigns[:issues].map(&:id) | |||
|
3601 | end | |||
|
3602 | ||||
|
3603 | def test_bulk_update_with_some_failures_should_show_errors | |||
|
3604 | issue1 = Issue.generate!(:start_date => '2013-05-12') | |||
|
3605 | issue2 = Issue.generate!(:start_date => '2013-05-15') | |||
|
3606 | issue3 = Issue.generate! | |||
|
3607 | ||||
|
3608 | @request.session[:user_id] = 2 | |||
|
3609 | post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id], :issue => {:due_date => '2013-05-01'} | |||
|
3610 | ||||
|
3611 | assert_response :success | |||
|
3612 | assert_template 'bulk_edit' | |||
|
3613 | assert_select '#errorExplanation span', :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}." | |||
|
3614 | assert_select '#errorExplanation ul li', :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}" | |||
|
3615 | ||||
|
3616 | assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id) | |||
3598 | end |
|
3617 | end | |
3599 |
|
3618 | |||
3600 | def test_get_bulk_copy |
|
3619 | def test_get_bulk_copy |
General Comments 0
You need to be logged in to leave comments.
Login now