##// END OF EJS Templates
Preserve field values on bulk edit failure (#13943)....
Jean-Philippe Lang -
r11557:70bdb86c534f
parent child
Show More
@@ -241,6 +241,9 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
245 @issue_params = params[:issue] || {}
246 @issue_params[:custom_field_values] ||= {}
244 end
247 end
245
248
246 def bulk_update
249 def bulk_update
@@ -330,7 +330,7 module ApplicationHelper
330 end
330 end
331 groups = ''
331 groups = ''
332 collection.sort.each do |element|
332 collection.sort.each do |element|
333 selected_attribute = ' selected="selected"' if option_value_selected?(element, selected)
333 selected_attribute = ' selected="selected"' if option_value_selected?(element, selected) || element.id.to_s == selected
334 (element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.name}</option>)
334 (element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.name}</option>)
335 end
335 end
336 unless groups.empty?
336 unless groups.empty?
@@ -348,6 +348,10 module ApplicationHelper
348 options
348 options
349 end
349 end
350
350
351 def option_tag(name, text, value, selected=nil, options={})
352 content_tag 'option', value, options.merge(:value => value, :selected => (value == selected))
353 end
354
351 # Truncates and returns the string as a single line
355 # Truncates and returns the string as a single line
352 def truncate_single_line(string, *args)
356 def truncate_single_line(string, *args)
353 truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ')
357 truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ')
@@ -77,7 +77,7 module CustomFieldsHelper
77 custom_field_label_tag(name, custom_value, options) + custom_field_tag(name, custom_value)
77 custom_field_label_tag(name, custom_value, options) + custom_field_tag(name, custom_value)
78 end
78 end
79
79
80 def custom_field_tag_for_bulk_edit(name, custom_field, projects=nil)
80 def custom_field_tag_for_bulk_edit(name, custom_field, projects=nil, value=nil)
81 field_name = "#{name}[custom_field_values][#{custom_field.id}]"
81 field_name = "#{name}[custom_field_values][#{custom_field.id}]"
82 field_name << "[]" if custom_field.multiple?
82 field_name << "[]" if custom_field.multiple?
83 field_id = "#{name}_custom_field_values_#{custom_field.id}"
83 field_id = "#{name}_custom_field_values_#{custom_field.id}"
@@ -87,22 +87,22 module CustomFieldsHelper
87 field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
87 field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
88 case field_format.try(:edit_as)
88 case field_format.try(:edit_as)
89 when "date"
89 when "date"
90 text_field_tag(field_name, '', tag_options.merge(:size => 10)) +
90 text_field_tag(field_name, value, tag_options.merge(:size => 10)) +
91 calendar_for(field_id)
91 calendar_for(field_id)
92 when "text"
92 when "text"
93 text_area_tag(field_name, '', tag_options.merge(:rows => 3))
93 text_area_tag(field_name, value, tag_options.merge(:rows => 3))
94 when "bool"
94 when "bool"
95 select_tag(field_name, options_for_select([[l(:label_no_change_option), ''],
95 select_tag(field_name, options_for_select([[l(:label_no_change_option), ''],
96 [l(:general_text_yes), '1'],
96 [l(:general_text_yes), '1'],
97 [l(:general_text_no), '0']]), tag_options)
97 [l(:general_text_no), '0']], value), tag_options)
98 when "list"
98 when "list"
99 options = []
99 options = []
100 options << [l(:label_no_change_option), ''] unless custom_field.multiple?
100 options << [l(:label_no_change_option), ''] unless custom_field.multiple?
101 options << [l(:label_none), '__none__'] unless custom_field.is_required?
101 options << [l(:label_none), '__none__'] unless custom_field.is_required?
102 options += custom_field.possible_values_options(projects)
102 options += custom_field.possible_values_options(projects)
103 select_tag(field_name, options_for_select(options), tag_options.merge(:multiple => custom_field.multiple?))
103 select_tag(field_name, options_for_select(options, value), tag_options.merge(:multiple => custom_field.multiple?))
104 else
104 else
105 text_field_tag(field_name, '', tag_options)
105 text_field_tag(field_name, value, tag_options)
106 end
106 end
107 end
107 end
108
108
@@ -69,10 +69,11 module ProjectsHelper
69 grouped[version.project.name] << [version.name, version.id]
69 grouped[version.project.name] << [version.name, version.id]
70 end
70 end
71
71
72 selected = selected.is_a?(Version) ? selected.id : selected
72 if grouped.keys.size > 1
73 if grouped.keys.size > 1
73 grouped_options_for_select(grouped, selected && selected.id)
74 grouped_options_for_select(grouped, selected)
74 else
75 else
75 options_for_select((grouped.values.first || []), selected && selected.id)
76 options_for_select((grouped.values.first || []), selected)
76 end
77 end
77 end
78 end
78
79
@@ -32,34 +32,43
32 <% if @allowed_projects.present? %>
32 <% if @allowed_projects.present? %>
33 <p>
33 <p>
34 <label for="issue_project_id"><%= l(:field_project) %></label>
34 <label for="issue_project_id"><%= l(:field_project) %></label>
35 <%= select_tag('issue[project_id]', content_tag('option', l(:label_no_change_option), :value => '') + project_tree_options_for_select(@allowed_projects, :selected => @target_project),
35 <%= select_tag('issue[project_id]',
36 content_tag('option', l(:label_no_change_option), :value => '') +
37 project_tree_options_for_select(@allowed_projects, :selected => @target_project),
36 :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %>
38 :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %>
37 </p>
39 </p>
38 <% end %>
40 <% end %>
39 <p>
41 <p>
40 <label for="issue_tracker_id"><%= l(:field_tracker) %></label>
42 <label for="issue_tracker_id"><%= l(:field_tracker) %></label>
41 <%= select_tag('issue[tracker_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@trackers, :id, :name)) %>
43 <%= select_tag('issue[tracker_id]',
44 content_tag('option', l(:label_no_change_option), :value => '') +
45 options_from_collection_for_select(@trackers, :id, :name, @issue_params[:tracker_id])) %>
42 </p>
46 </p>
43 <% if @available_statuses.any? %>
47 <% if @available_statuses.any? %>
44 <p>
48 <p>
45 <label for='issue_status_id'><%= l(:field_status) %></label>
49 <label for='issue_status_id'><%= l(:field_status) %></label>
46 <%= select_tag('issue[status_id]',content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_statuses, :id, :name)) %>
50 <%= select_tag('issue[status_id]',
51 content_tag('option', l(:label_no_change_option), :value => '') +
52 options_from_collection_for_select(@available_statuses, :id, :name, @issue_params[:status_id])) %>
47 </p>
53 </p>
48 <% end %>
54 <% end %>
49
55
50 <% if @safe_attributes.include?('priority_id') -%>
56 <% if @safe_attributes.include?('priority_id') -%>
51 <p>
57 <p>
52 <label for='issue_priority_id'><%= l(:field_priority) %></label>
58 <label for='issue_priority_id'><%= l(:field_priority) %></label>
53 <%= select_tag('issue[priority_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(IssuePriority.active, :id, :name)) %>
59 <%= select_tag('issue[priority_id]',
60 content_tag('option', l(:label_no_change_option), :value => '') +
61 options_from_collection_for_select(IssuePriority.active, :id, :name, @issue_params[:priority_id])) %>
54 </p>
62 </p>
55 <% end %>
63 <% end %>
56
64
57 <% if @safe_attributes.include?('assigned_to_id') -%>
65 <% if @safe_attributes.include?('assigned_to_id') -%>
58 <p>
66 <p>
59 <label for='issue_assigned_to_id'><%= l(:field_assigned_to) %></label>
67 <label for='issue_assigned_to_id'><%= l(:field_assigned_to) %></label>
60 <%= select_tag('issue[assigned_to_id]', content_tag('option', l(:label_no_change_option), :value => '') +
68 <%= select_tag('issue[assigned_to_id]',
61 content_tag('option', l(:label_nobody), :value => 'none') +
69 content_tag('option', l(:label_no_change_option), :value => '') +
62 principals_options_for_select(@assignables)) %>
70 content_tag('option', l(:label_nobody), :value => 'none', :selected => (@issue_params[:assigned_to_id] == 'none')) +
71 principals_options_for_select(@assignables, @issue_params[:assigned_to_id])) %>
63 </p>
72 </p>
64 <% end %>
73 <% end %>
65
74
@@ -67,8 +76,8
67 <p>
76 <p>
68 <label for='issue_category_id'><%= l(:field_category) %></label>
77 <label for='issue_category_id'><%= l(:field_category) %></label>
69 <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') +
78 <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') +
70 content_tag('option', l(:label_none), :value => 'none') +
79 content_tag('option', l(:label_none), :value => 'none', :selected => (@issue_params[:category_id] == 'none')) +
71 options_from_collection_for_select(@categories, :id, :name)) %>
80 options_from_collection_for_select(@categories, :id, :name, @issue_params[:category_id])) %>
72 </p>
81 </p>
73 <% end %>
82 <% end %>
74
83
@@ -76,26 +85,31
76 <p>
85 <p>
77 <label for='issue_fixed_version_id'><%= l(:field_fixed_version) %></label>
86 <label for='issue_fixed_version_id'><%= l(:field_fixed_version) %></label>
78 <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') +
87 <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') +
79 content_tag('option', l(:label_none), :value => 'none') +
88 content_tag('option', l(:label_none), :value => 'none', :selected => (@issue_params[:fixed_version_id] == 'none')) +
80 version_options_for_select(@versions.sort)) %>
89 version_options_for_select(@versions.sort, @issue_params[:fixed_version_id])) %>
81 </p>
90 </p>
82 <% end %>
91 <% end %>
83
92
84 <% @custom_fields.each do |custom_field| %>
93 <% @custom_fields.each do |custom_field| %>
85 <p><label><%= h(custom_field.name) %></label> <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects) %></p>
94 <p>
95 <label><%= h(custom_field.name) %></label>
96 <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects, @issue_params[:custom_field_values][custom_field.id.to_s]) %>
97 </p>
86 <% end %>
98 <% end %>
87
99
88 <% if @copy && @attachments_present %>
100 <% if @copy && @attachments_present %>
101 <%= hidden_field_tag 'copy_attachments', '0' %>
89 <p>
102 <p>
90 <label for='copy_attachments'><%= l(:label_copy_attachments) %></label>
103 <label for='copy_attachments'><%= l(:label_copy_attachments) %></label>
91 <%= check_box_tag 'copy_attachments', '1', true %>
104 <%= check_box_tag 'copy_attachments', '1', params[:copy_attachments] != '0' %>
92 </p>
105 </p>
93 <% end %>
106 <% end %>
94
107
95 <% if @copy && @subtasks_present %>
108 <% if @copy && @subtasks_present %>
109 <%= hidden_field_tag 'copy_subtasks', '0' %>
96 <p>
110 <p>
97 <label for='copy_subtasks'><%= l(:label_copy_subtasks) %></label>
111 <label for='copy_subtasks'><%= l(:label_copy_subtasks) %></label>
98 <%= check_box_tag 'copy_subtasks', '1', true %>
112 <%= check_box_tag 'copy_subtasks', '1', params[:copy_subtasks] != '0' %>
99 </p>
113 </p>
100 <% end %>
114 <% end %>
101
115
@@ -107,15 +121,15
107 <p>
121 <p>
108 <label for='issue_is_private'><%= l(:field_is_private) %></label>
122 <label for='issue_is_private'><%= l(:field_is_private) %></label>
109 <%= select_tag('issue[is_private]', content_tag('option', l(:label_no_change_option), :value => '') +
123 <%= select_tag('issue[is_private]', content_tag('option', l(:label_no_change_option), :value => '') +
110 content_tag('option', l(:general_text_Yes), :value => '1') +
124 content_tag('option', l(:general_text_Yes), :value => '1', :selected => (@issue_params[:is_private] == '1')) +
111 content_tag('option', l(:general_text_No), :value => '0')) %>
125 content_tag('option', l(:general_text_No), :value => '0', :selected => (@issue_params[:is_private] == '0'))) %>
112 </p>
126 </p>
113 <% end %>
127 <% end %>
114
128
115 <% if @safe_attributes.include?('parent_issue_id') && @project %>
129 <% if @safe_attributes.include?('parent_issue_id') && @project %>
116 <p>
130 <p>
117 <label for='issue_parent_issue_id'><%= l(:field_parent_issue) %></label>
131 <label for='issue_parent_issue_id'><%= l(:field_parent_issue) %></label>
118 <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10 %>
132 <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10, :value => @issue_params[:parent_issue_id] %>
119 </p>
133 </p>
120 <%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %>
134 <%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %>
121 <% end %>
135 <% end %>
@@ -123,21 +137,21
123 <% if @safe_attributes.include?('start_date') %>
137 <% if @safe_attributes.include?('start_date') %>
124 <p>
138 <p>
125 <label for='issue_start_date'><%= l(:field_start_date) %></label>
139 <label for='issue_start_date'><%= l(:field_start_date) %></label>
126 <%= text_field_tag 'issue[start_date]', '', :size => 10 %><%= calendar_for('issue_start_date') %>
140 <%= text_field_tag 'issue[start_date]', '', :value => @issue_params[:start_date], :size => 10 %><%= calendar_for('issue_start_date') %>
127 </p>
141 </p>
128 <% end %>
142 <% end %>
129
143
130 <% if @safe_attributes.include?('due_date') %>
144 <% if @safe_attributes.include?('due_date') %>
131 <p>
145 <p>
132 <label for='issue_due_date'><%= l(:field_due_date) %></label>
146 <label for='issue_due_date'><%= l(:field_due_date) %></label>
133 <%= text_field_tag 'issue[due_date]', '', :size => 10 %><%= calendar_for('issue_due_date') %>
147 <%= text_field_tag 'issue[due_date]', '', :value => @issue_params[:due_date], :size => 10 %><%= calendar_for('issue_due_date') %>
134 </p>
148 </p>
135 <% end %>
149 <% end %>
136
150
137 <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
151 <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
138 <p>
152 <p>
139 <label for='issue_done_ratio'><%= l(:field_done_ratio) %></label>
153 <label for='issue_done_ratio'><%= l(:field_done_ratio) %></label>
140 <%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %>
154 <%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }, @issue_params[:done_ratio]) %>
141 </p>
155 </p>
142 <% end %>
156 <% end %>
143 </div>
157 </div>
@@ -3616,6 +3616,18 class IssuesControllerTest < ActionController::TestCase
3616 assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
3616 assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
3617 end
3617 end
3618
3618
3619 def test_bulk_update_with_failure_should_preserved_form_values
3620 @request.session[:user_id] = 2
3621 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2', :start_date => 'foo'}
3622
3623 assert_response :success
3624 assert_template 'bulk_edit'
3625 assert_select 'select[name=?]', 'issue[tracker_id]' do
3626 assert_select 'option[value=2][selected=selected]'
3627 end
3628 assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
3629 end
3630
3619 def test_get_bulk_copy
3631 def test_get_bulk_copy
3620 @request.session[:user_id] = 2
3632 @request.session[:user_id] = 2
3621 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
3633 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
General Comments 0
You need to be logged in to leave comments. Login now