]> source.dussan.org Git - redmine.git/commitdiff
Display the bulk edit form with error messages when some issues can not be saved...
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 4 May 2013 08:52:51 +0000 (08:52 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 4 May 2013 08:52:51 +0000 (08:52 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@11786 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/application_controller.rb
app/controllers/issues_controller.rb
app/helpers/issues_helper.rb
app/views/issues/bulk_edit.html.erb
test/functional/issues_controller_test.rb

index 6bbc4d1fcc492d38d0786dc3d10a07f8425b496c..a3fbae5aa89e76ab20db216bcedb0284b491bd1a 100644 (file)
@@ -555,21 +555,6 @@ class ApplicationController < ActionController::Base
     flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
   end
 
-  # Sets the `flash` notice or error based the number of issues that did not save
-  #
-  # @param [Array, Issue] issues all of the saved and unsaved Issues
-  # @param [Array, Integer] unsaved_issue_ids the issue ids that were not saved
-  def set_flash_from_bulk_issue_save(issues, unsaved_issue_ids)
-    if unsaved_issue_ids.empty?
-      flash[:notice] = l(:notice_successful_update) unless issues.empty?
-    else
-      flash[:error] = l(:notice_failed_to_save_issues,
-                        :count => unsaved_issue_ids.size,
-                        :total => issues.size,
-                        :ids => '#' + unsaved_issue_ids.join(', #'))
-    end
-  end
-
   # Rescues an invalid query statement. Just in case...
   def query_statement_invalid(exception)
     logger.error "Query::StatementInvalid: #{exception.message}" if logger
index 3f3966abab9daefe2c62be11009621fec71c0d46..c95e25b12669d287e673bd1c1131b8314811fc2a 100644 (file)
@@ -241,7 +241,6 @@ class IssuesController < ApplicationController
     end
 
     @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
-    render :layout => false if request.xhr?
   end
 
   def bulk_update
@@ -249,8 +248,8 @@ class IssuesController < ApplicationController
     @copy = params[:copy].present?
     attributes = parse_params_for_bulk_issue_attributes(params)
 
-    unsaved_issue_ids = []
-    moved_issues = []
+    unsaved_issues = []
+    saved_issues = []
 
     if @copy && params[:copy_subtasks].present?
       # Descendant issues will be copied with the parent task
@@ -270,23 +269,29 @@ class IssuesController < ApplicationController
       issue.safe_attributes = attributes
       call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
       if issue.save
-        moved_issues << issue
+        saved_issues << issue
       else
-        logger.info "issue could not be updated or copied: #{issue.errors.full_messages}" if logger && logger.info
-        # Keep unsaved issue ids to display them in flash error
-        unsaved_issue_ids << issue.id
+        unsaved_issues << issue
       end
     end
-    set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids)
 
-    if params[:follow]
-      if @issues.size == 1 && moved_issues.size == 1
-        redirect_to issue_path(moved_issues.first)
-      elsif moved_issues.map(&:project).uniq.size == 1
-        redirect_to project_issues_path(moved_issues.map(&:project).first)
+    if unsaved_issues.empty?
+      flash[:notice] = l(:notice_successful_update) unless saved_issues.empty?
+      if params[:follow]
+        if @issues.size == 1 && saved_issues.size == 1
+          redirect_to issue_path(saved_issues.first)
+        elsif saved_issues.map(&:project).uniq.size == 1
+          redirect_to project_issues_path(saved_issues.map(&:project).first)
+        end
+      else
+        redirect_back_or_default _project_issues_path(@project)
       end
     else
-      redirect_back_or_default _project_issues_path(@project)
+      @saved_issues = @issues
+      @unsaved_issues = unsaved_issues
+      @issues = Issue.visible.find_all_by_id(@unsaved_issues.map(&:id))
+      bulk_edit
+      render :action => 'bulk_edit'
     end
   end
 
index 7d54bf22eaa18e5ab826936199b2d2aeaf84bf3f..39b24fe04d295802b7d562b1f5d71af178b7d8b1 100644 (file)
@@ -94,6 +94,20 @@ module IssuesHelper
     s.html_safe
   end
 
+  # Returns an array of error messages for bulk edited issues
+  def bulk_edit_error_messages(issues)
+    messages = {}
+    issues.each do |issue|
+      issue.errors.full_messages.each do |message|
+        messages[message] ||= []
+        messages[message] << issue
+      end
+    end
+    messages.map { |message, issues|
+      "#{message}: " + issues.map {|i| "##{i.id}"}.join(', ')
+    }
+ end
+
   # Returns a link for adding a new subtask to the given issue
   def link_to_new_subtask(issue)
     attrs = {
index 903a0daf8619a5f156561db970718f6429af6ab3..cfcc5705a6a4e6fef0068bea000c5359c43f2a67 100644 (file)
@@ -1,5 +1,21 @@
 <h2><%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %></h2>
 
+<% if @saved_issues && @unsaved_issues.present? %>
+<div id="errorExplanation">
+  <span>
+    <%= l(:notice_failed_to_save_issues,
+        :count => @unsaved_issues.size,
+        :total => @saved_issues.size,
+        :ids => @unsaved_issues.map {|i| "##{i.id}"}.join(', ')) %>
+  </span>
+  <ul>
+  <% bulk_edit_error_messages(@unsaved_issues).each do |message| %>
+    <li><%= message %></li>
+  <% end %>
+  </ul>
+</div>
+<% end %>
+
 <ul id="bulk-selection">
 <% @issues.each do |issue| %>
   <%= content_tag 'li', link_to_issue(issue) %>
index 59f7a858a9c75a163d773454a4f73f5d0abe65c6..3e206db95eacc9b03bc6974bf2096f4da5d1298a 100644 (file)
@@ -3588,13 +3588,32 @@ class IssuesControllerTest < ActionController::TestCase
     assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
   end
 
-  def test_bulk_update_with_failure_should_set_flash
+  def test_bulk_update_with_all_failures_should_show_errors
     @request.session[:user_id] = 2
-    Issue.update_all("subject = ''", "id = 2") # Make it invalid
-    post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
+    post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'}
 
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
-    assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
+    assert_response :success
+    assert_template 'bulk_edit'
+    assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
+    assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
+
+    assert_equal [1, 2], assigns[:issues].map(&:id)
+  end
+
+  def test_bulk_update_with_some_failures_should_show_errors
+    issue1 = Issue.generate!(:start_date => '2013-05-12')
+    issue2 = Issue.generate!(:start_date => '2013-05-15')
+    issue3 = Issue.generate!
+
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id], :issue => {:due_date => '2013-05-01'}
+
+    assert_response :success
+    assert_template 'bulk_edit'
+    assert_select '#errorExplanation span', :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
+    assert_select '#errorExplanation ul li', :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
+
+    assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
   end
 
   def test_get_bulk_copy