@@ -213,6 +213,16 class IssuesController < ApplicationController | |||||
213 |
|
213 | |||
214 | edited_issues = Issue.where(:id => @issues.map(&:id)).to_a |
|
214 | edited_issues = Issue.where(:id => @issues.map(&:id)).to_a | |
215 |
|
215 | |||
|
216 | @values_by_custom_field = {} | |||
|
217 | edited_issues.each do |issue| | |||
|
218 | issue.custom_field_values.each do |c| | |||
|
219 | if c.value_present? | |||
|
220 | @values_by_custom_field[c.custom_field] ||= [] | |||
|
221 | @values_by_custom_field[c.custom_field] << issue.id | |||
|
222 | end | |||
|
223 | end | |||
|
224 | end | |||
|
225 | ||||
216 | @allowed_projects = Issue.allowed_target_projects |
|
226 | @allowed_projects = Issue.allowed_target_projects | |
217 | if params[:issue] |
|
227 | if params[:issue] | |
218 | @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s} |
|
228 | @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s} | |
@@ -244,6 +254,15 class IssuesController < ApplicationController | |||||
244 | end |
|
254 | end | |
245 | end |
|
255 | end | |
246 |
|
256 | |||
|
257 | edited_issues.each do |issue| | |||
|
258 | issue.custom_field_values.each do |c| | |||
|
259 | if c.value_present? && @values_by_custom_field[c.custom_field] | |||
|
260 | @values_by_custom_field[c.custom_field].delete(issue.id) | |||
|
261 | end | |||
|
262 | end | |||
|
263 | end | |||
|
264 | @values_by_custom_field.delete_if {|k,v| v.blank?} | |||
|
265 | ||||
247 | @custom_fields = edited_issues.map{|i|i.editable_custom_fields}.reduce(:&).select {|field| field.format.bulk_edit_supported} |
|
266 | @custom_fields = edited_issues.map{|i|i.editable_custom_fields}.reduce(:&).select {|field| field.format.bulk_edit_supported} | |
248 | @assignables = target_projects.map(&:assignable_users).reduce(:&) |
|
267 | @assignables = target_projects.map(&:assignable_users).reduce(:&) | |
249 | @versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&) |
|
268 | @versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&) |
@@ -52,6 +52,14 class CustomFieldValue | |||||
52 | @value = custom_field.set_custom_field_value(self, v) |
|
52 | @value = custom_field.set_custom_field_value(self, v) | |
53 | end |
|
53 | end | |
54 |
|
54 | |||
|
55 | def value_present? | |||
|
56 | if value.is_a?(Array) | |||
|
57 | value.any?(&:present?) | |||
|
58 | else | |||
|
59 | value.present? | |||
|
60 | end | |||
|
61 | end | |||
|
62 | ||||
55 | def validate_value |
|
63 | def validate_value | |
56 | custom_field.validate_custom_value(self).each do |message| |
|
64 | custom_field.validate_custom_value(self).each do |message| | |
57 | customized.errors.add(:base, custom_field.name + ' ' + message) |
|
65 | customized.errors.add(:base, custom_field.name + ' ' + message) |
@@ -186,6 +186,13 | |||||
186 | </fieldset> |
|
186 | </fieldset> | |
187 | </div> |
|
187 | </div> | |
188 |
|
188 | |||
|
189 | <% if @values_by_custom_field.present? %> | |||
|
190 | <div class="flash warning"> | |||
|
191 | <%= l(:warning_fields_cleared_on_bulk_edit) %>:<br /> | |||
|
192 | <%= safe_join(@values_by_custom_field.map {|field, ids| content_tag "span", "#{field.name} (#{ids.size})"}, ', ') %> | |||
|
193 | </div> | |||
|
194 | <% end %> | |||
|
195 | ||||
189 | <p> |
|
196 | <p> | |
190 | <% if @copy %> |
|
197 | <% if @copy %> | |
191 | <%= hidden_field_tag 'copy', '1' %> |
|
198 | <%= hidden_field_tag 'copy', '1' %> |
@@ -219,6 +219,7 en: | |||||
219 | error_no_projects_with_tracker_allowed_for_new_issue: "There are no projects with trackers for which you can create an issue" |
|
219 | error_no_projects_with_tracker_allowed_for_new_issue: "There are no projects with trackers for which you can create an issue" | |
220 | error_move_of_child_not_possible: "Subtask %{child} could not be moved to the new project: %{errors}" |
|
220 | error_move_of_child_not_possible: "Subtask %{child} could not be moved to the new project: %{errors}" | |
221 | error_cannot_reassign_time_entries_to_an_issue_about_to_be_deleted: "Spent time cannot be reassigned to an issue that is about to be deleted" |
|
221 | error_cannot_reassign_time_entries_to_an_issue_about_to_be_deleted: "Spent time cannot be reassigned to an issue that is about to be deleted" | |
|
222 | warning_fields_cleared_on_bulk_edit: "Changes will result in the automatic deletion of values from one or more fields on the selected objects" | |||
222 |
|
223 | |||
223 | mail_subject_lost_password: "Your %{value} password" |
|
224 | mail_subject_lost_password: "Your %{value} password" | |
224 | mail_body_lost_password: 'To change your password, click on the following link:' |
|
225 | mail_body_lost_password: 'To change your password, click on the following link:' |
@@ -239,6 +239,7 fr: | |||||
239 | error_no_projects_with_tracker_allowed_for_new_issue: "Aucun projet ne dispose d'un tracker sur lequel vous pouvez créer une demande" |
|
239 | error_no_projects_with_tracker_allowed_for_new_issue: "Aucun projet ne dispose d'un tracker sur lequel vous pouvez créer une demande" | |
240 | error_move_of_child_not_possible: "La sous-tâche %{child} n'a pas pu être déplacée dans le nouveau projet : %{errors}" |
|
240 | error_move_of_child_not_possible: "La sous-tâche %{child} n'a pas pu être déplacée dans le nouveau projet : %{errors}" | |
241 | error_cannot_reassign_time_entries_to_an_issue_about_to_be_deleted: "Le temps passé ne peut pas être réaffecté à une demande qui va être supprimée" |
|
241 | error_cannot_reassign_time_entries_to_an_issue_about_to_be_deleted: "Le temps passé ne peut pas être réaffecté à une demande qui va être supprimée" | |
|
242 | warning_fields_cleared_on_bulk_edit: "Les changements apportés entraîneront la suppression automatique des valeurs d'un ou plusieurs champs sur les objets sélectionnés" | |||
242 |
|
243 | |||
243 | mail_subject_lost_password: "Votre mot de passe %{value}" |
|
244 | mail_subject_lost_password: "Votre mot de passe %{value}" | |
244 | mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :' |
|
245 | mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :' |
@@ -4067,6 +4067,23 class IssuesControllerTest < Redmine::ControllerTest | |||||
4067 | assert_select 'input[name=?]', "issue[custom_field_values][#{field2.id}]" |
|
4067 | assert_select 'input[name=?]', "issue[custom_field_values][#{field2.id}]" | |
4068 | end |
|
4068 | end | |
4069 |
|
4069 | |||
|
4070 | def test_bulk_edit_should_warn_about_custom_field_values_about_to_be_cleared | |||
|
4071 | CustomField.delete_all | |||
|
4072 | ||||
|
4073 | cleared = IssueCustomField.generate!(:name => 'Cleared', :tracker_ids => [2], :is_for_all => true) | |||
|
4074 | CustomValue.create!(:customized => Issue.find(2), :custom_field => cleared, :value => 'foo') | |||
|
4075 | ||||
|
4076 | not_cleared = IssueCustomField.generate!(:name => 'Not cleared', :tracker_ids => [2, 3], :is_for_all => true) | |||
|
4077 | CustomValue.create!(:customized => Issue.find(2), :custom_field => not_cleared, :value => 'bar') | |||
|
4078 | @request.session[:user_id] = 2 | |||
|
4079 | ||||
|
4080 | get :bulk_edit, :ids => [1, 2], :issue => {:tracker_id => 3} | |||
|
4081 | assert_response :success | |||
|
4082 | assert_select '.warning', :text => /automatic deletion of values/ | |||
|
4083 | assert_select '.warning span', :text => 'Cleared (1)' | |||
|
4084 | assert_select '.warning span', :text => /Not cleared/, :count => 0 | |||
|
4085 | end | |||
|
4086 | ||||
4070 | def test_bulk_update |
|
4087 | def test_bulk_update | |
4071 | @request.session[:user_id] = 2 |
|
4088 | @request.session[:user_id] = 2 | |
4072 | # update issues priority |
|
4089 | # update issues priority |
General Comments 0
You need to be logged in to leave comments.
Login now