@@ -555,21 +555,6 class ApplicationController < ActionController::Base | |||
|
555 | 555 | flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present? |
|
556 | 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 | 558 | # Rescues an invalid query statement. Just in case... |
|
574 | 559 | def query_statement_invalid(exception) |
|
575 | 560 | logger.error "Query::StatementInvalid: #{exception.message}" if logger |
@@ -241,7 +241,6 class IssuesController < ApplicationController | |||
|
241 | 241 | end |
|
242 | 242 | |
|
243 | 243 | @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&) |
|
244 | render :layout => false if request.xhr? | |
|
245 | 244 | end |
|
246 | 245 | |
|
247 | 246 | def bulk_update |
@@ -249,8 +248,8 class IssuesController < ApplicationController | |||
|
249 | 248 | @copy = params[:copy].present? |
|
250 | 249 | attributes = parse_params_for_bulk_issue_attributes(params) |
|
251 | 250 | |
|
252 |
unsaved_issue |
|
|
253 |
|
|
|
251 | unsaved_issues = [] | |
|
252 | saved_issues = [] | |
|
254 | 253 | |
|
255 | 254 | if @copy && params[:copy_subtasks].present? |
|
256 | 255 | # Descendant issues will be copied with the parent task |
@@ -270,23 +269,29 class IssuesController < ApplicationController | |||
|
270 | 269 | issue.safe_attributes = attributes |
|
271 | 270 | call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) |
|
272 | 271 | if issue.save |
|
273 |
|
|
|
272 | saved_issues << issue | |
|
274 | 273 | else |
|
275 | logger.info "issue could not be updated or copied: #{issue.errors.full_messages}" if logger && logger.info | |
|
276 | # Keep unsaved issue ids to display them in flash error | |
|
277 | unsaved_issue_ids << issue.id | |
|
274 | unsaved_issues << issue | |
|
278 | 275 | end |
|
279 | 276 | end |
|
280 | set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) | |
|
281 | 277 | |
|
282 | if params[:follow] | |
|
283 | if @issues.size == 1 && moved_issues.size == 1 | |
|
284 | redirect_to issue_path(moved_issues.first) | |
|
285 | elsif moved_issues.map(&:project).uniq.size == 1 | |
|
286 |
redirect_to |
|
|
278 | if unsaved_issues.empty? | |
|
279 | flash[:notice] = l(:notice_successful_update) unless saved_issues.empty? | |
|
280 | if params[:follow] | |
|
281 | if @issues.size == 1 && saved_issues.size == 1 | |
|
282 | redirect_to issue_path(saved_issues.first) | |
|
283 | elsif saved_issues.map(&:project).uniq.size == 1 | |
|
284 | redirect_to project_issues_path(saved_issues.map(&:project).first) | |
|
285 | end | |
|
286 | else | |
|
287 | redirect_back_or_default _project_issues_path(@project) | |
|
287 | 288 | end |
|
288 | 289 | else |
|
289 | redirect_back_or_default _project_issues_path(@project) | |
|
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' | |
|
290 | 295 | end |
|
291 | 296 | end |
|
292 | 297 |
@@ -94,6 +94,20 module IssuesHelper | |||
|
94 | 94 | s.html_safe |
|
95 | 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 | 111 | # Returns a link for adding a new subtask to the given issue |
|
98 | 112 | def link_to_new_subtask(issue) |
|
99 | 113 | attrs = { |
@@ -1,5 +1,21 | |||
|
1 | 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 | 19 | <ul id="bulk-selection"> |
|
4 | 20 | <% @issues.each do |issue| %> |
|
5 | 21 | <%= content_tag 'li', link_to_issue(issue) %> |
@@ -3588,13 +3588,32 class IssuesControllerTest < ActionController::TestCase | |||
|
3588 | 3588 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier |
|
3589 | 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 | 3592 | @request.session[:user_id] = 2 |
|
3593 | Issue.update_all("subject = ''", "id = 2") # Make it invalid | |
|
3594 | post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6} | |
|
3593 | post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'} | |
|
3595 | 3594 | |
|
3596 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook' | |
|
3597 | assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error] | |
|
3595 | assert_response :success | |
|
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 | 3617 | end |
|
3599 | 3618 | |
|
3600 | 3619 | def test_get_bulk_copy |
General Comments 0
You need to be logged in to leave comments.
Login now