You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bulk_edit.html.erb 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <h2><%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %></h2>
  2. <% if @saved_issues && @unsaved_issues.present? %>
  3. <div id="errorExplanation">
  4. <span>
  5. <%= l(:notice_failed_to_save_issues,
  6. :count => @unsaved_issues.size,
  7. :total => @saved_issues.size,
  8. :ids => @unsaved_issues.map {|i| "##{i.id}"}.join(', ')) %>
  9. </span>
  10. <ul>
  11. <% bulk_edit_error_messages(@unsaved_issues).each do |message| %>
  12. <li><%= message %></li>
  13. <% end %>
  14. </ul>
  15. </div>
  16. <% end %>
  17. <ul id="bulk-selection">
  18. <% @issues.each do |issue| %>
  19. <%= content_tag 'li', link_to_issue(issue) %>
  20. <% end %>
  21. </ul>
  22. <%= form_tag(bulk_update_issues_path, :id => 'bulk_edit_form') do %>
  23. <%= @issues.collect {|i| hidden_field_tag('ids[]', i.id, :id => nil)}.join("\n").html_safe %>
  24. <div class="box tabular">
  25. <fieldset class="attributes">
  26. <legend><%= l(:label_change_properties) %></legend>
  27. <div class="splitcontent">
  28. <div class="splitcontentleft">
  29. <% if @allowed_projects.present? %>
  30. <p>
  31. <label for="issue_project_id"><%= l(:field_project) %></label>
  32. <%= select_tag('issue[project_id]',
  33. project_tree_options_for_select(@allowed_projects,
  34. :include_blank => ((!@copy || (@projects & @allowed_projects == @projects)) ? l(:label_no_change_option) : false),
  35. :selected => @target_project),
  36. :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %>
  37. </p>
  38. <% end %>
  39. <p>
  40. <label for="issue_tracker_id"><%= l(:field_tracker) %></label>
  41. <%= select_tag('issue[tracker_id]',
  42. content_tag('option', l(:label_no_change_option), :value => '') +
  43. options_from_collection_for_select(@trackers, :id, :name, @issue_params[:tracker_id]),
  44. :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %>
  45. </p>
  46. <% if @available_statuses.any? %>
  47. <p>
  48. <label for='issue_status_id'><%= l(:field_status) %></label>
  49. <%= select_tag('issue[status_id]',
  50. content_tag('option', l(:label_no_change_option), :value => '') +
  51. options_from_collection_for_select(@available_statuses, :id, :name, @issue_params[:status_id]),
  52. :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %>
  53. </p>
  54. <% end %>
  55. <% if @safe_attributes.include?('priority_id') -%>
  56. <p>
  57. <label for='issue_priority_id'><%= l(:field_priority) %></label>
  58. <%= select_tag('issue[priority_id]',
  59. content_tag('option', l(:label_no_change_option), :value => '') +
  60. options_from_collection_for_select(IssuePriority.active, :id, :name, @issue_params[:priority_id])) %>
  61. </p>
  62. <% end %>
  63. <% if @safe_attributes.include?('assigned_to_id') -%>
  64. <p>
  65. <label for='issue_assigned_to_id'><%= l(:field_assigned_to) %></label>
  66. <%= select_tag('issue[assigned_to_id]',
  67. content_tag('option', l(:label_no_change_option), :value => '') +
  68. content_tag('option', l(:label_nobody), :value => 'none', :selected => (@issue_params[:assigned_to_id] == 'none')) +
  69. principals_options_for_select(@assignables, @issue_params[:assigned_to_id])) %>
  70. </p>
  71. <% end %>
  72. <% if @safe_attributes.include?('category_id') -%>
  73. <p>
  74. <label for='issue_category_id'><%= l(:field_category) %></label>
  75. <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') +
  76. content_tag('option', l(:label_none), :value => 'none', :selected => (@issue_params[:category_id] == 'none')) +
  77. options_from_collection_for_select(@categories, :id, :name, @issue_params[:category_id])) %>
  78. </p>
  79. <% end %>
  80. <% if @safe_attributes.include?('fixed_version_id') -%>
  81. <p>
  82. <label for='issue_fixed_version_id'><%= l(:field_fixed_version) %></label>
  83. <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') +
  84. content_tag('option', l(:label_none), :value => 'none', :selected => (@issue_params[:fixed_version_id] == 'none')) +
  85. version_options_for_select(@versions.sort, @issue_params[:fixed_version_id])) %>
  86. </p>
  87. <% end %>
  88. <% if @copy && Setting.link_copied_issue == 'ask' %>
  89. <p>
  90. <label for='link_copy'><%= l(:label_link_copied_issue) %></label>
  91. <%= hidden_field_tag 'link_copy', '0' %>
  92. <%= check_box_tag 'link_copy', '1', params[:link_copy] != 0 %>
  93. </p>
  94. <% end %>
  95. <% if @copy && (@attachments_present || @subtasks_present || @watchers_present) %>
  96. <p>
  97. <label><%= l(:button_copy) %></label>
  98. <% if @attachments_present %>
  99. <label class="block">
  100. <%= hidden_field_tag 'copy_attachments', '0' %>
  101. <%= check_box_tag 'copy_attachments', '1', params[:copy_attachments] != '0' %>
  102. <%= l(:label_attachment_plural) %>
  103. </label>
  104. <% end %>
  105. <% if @subtasks_present %>
  106. <label class="block">
  107. <%= hidden_field_tag 'copy_subtasks', '0' %>
  108. <%= check_box_tag 'copy_subtasks', '1', params[:copy_subtasks] != '0' %>
  109. <%= l(:label_subtask_plural) %>
  110. </label>
  111. <% end %>
  112. <% if @watchers_present %>
  113. <label class="block">
  114. <%= hidden_field_tag 'copy_watchers', '0' %>
  115. <%= check_box_tag 'copy_watchers', '1', params[:copy_watchers] != '0' %>
  116. <%= l(:label_issue_watchers) %>
  117. </label>
  118. <% end %>
  119. </p>
  120. <% end %>
  121. <%= call_hook(:view_issues_bulk_edit_details_bottom, { :issues => @issues }) %>
  122. </div>
  123. <div class="splitcontentright">
  124. <% if @safe_attributes.include?('is_private') %>
  125. <p>
  126. <label for='issue_is_private'><%= l(:field_is_private) %></label>
  127. <%= select_tag('issue[is_private]', content_tag('option', l(:label_no_change_option), :value => '') +
  128. content_tag('option', l(:general_text_Yes), :value => '1', :selected => (@issue_params[:is_private] == '1')) +
  129. content_tag('option', l(:general_text_No), :value => '0', :selected => (@issue_params[:is_private] == '0'))) %>
  130. </p>
  131. <% end %>
  132. <% if @safe_attributes.include?('parent_issue_id') && @project %>
  133. <p>
  134. <label for='issue_parent_issue_id'><%= l(:field_parent_issue) %></label>
  135. <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10, :value => @issue_params[:parent_issue_id] %>
  136. <label class="inline"><%= check_box_tag 'issue[parent_issue_id]', 'none', (@issue_params[:parent_issue_id] == 'none'), :id => nil, :data => {:disables => '#issue_parent_issue_id'} %><%= l(:button_clear) %></label>
  137. </p>
  138. <%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => Setting.cross_project_subtasks)}')" %>
  139. <% end %>
  140. <% if @safe_attributes.include?('start_date') %>
  141. <p>
  142. <label for='issue_start_date'><%= l(:field_start_date) %></label>
  143. <%= date_field_tag 'issue[start_date]', '', :value => @issue_params[:start_date], :size => 10 %><%= calendar_for('issue_start_date') %>
  144. <label class="inline"><%= check_box_tag 'issue[start_date]', 'none', (@issue_params[:start_date] == 'none'), :id => nil, :data => {:disables => '#issue_start_date'} %><%= l(:button_clear) %></label>
  145. </p>
  146. <% end %>
  147. <% if @safe_attributes.include?('due_date') %>
  148. <p>
  149. <label for='issue_due_date'><%= l(:field_due_date) %></label>
  150. <%= date_field_tag 'issue[due_date]', '', :value => @issue_params[:due_date], :size => 10 %><%= calendar_for('issue_due_date') %>
  151. <label class="inline"><%= check_box_tag 'issue[due_date]', 'none', (@issue_params[:due_date] == 'none'), :id => nil, :data => {:disables => '#issue_due_date'} %><%= l(:button_clear) %></label>
  152. </p>
  153. <% end %>
  154. <% if @safe_attributes.include?('estimated_hours') %>
  155. <p>
  156. <label for='issue_estimated_hours'><%= l(:field_estimated_hours) %></label>
  157. <%= text_field_tag 'issue[estimated_hours]', '', :value => @issue_params[:estimated_hours], :size => 10 %>
  158. <label class="inline"><%= check_box_tag 'issue[estimated_hours]', 'none', (@issue_params[:estimated_hours] == 'none'), :id => nil, :data => {:disables => '#issue_estimated_hours'} %><%= l(:button_clear) %></label>
  159. </p>
  160. <% end %>
  161. <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
  162. <p>
  163. <label for='issue_done_ratio'><%= l(:field_done_ratio) %></label>
  164. <%= 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]) %>
  165. </p>
  166. <% end %>
  167. </div>
  168. </div>
  169. <% custom_fields = @custom_fields %>
  170. <% custom_fields_full_width = custom_fields.select { |value| value.full_width_layout? } %>
  171. <% custom_fields -= custom_fields_full_width %>
  172. <% if custom_fields.present? %>
  173. <div class="splitcontent">
  174. <div class="splitcontentleft">
  175. <% i = 0 %>
  176. <% split_on = (custom_fields.size / 2.0).ceil - 1 %>
  177. <% custom_fields.each do |custom_field| %>
  178. <p>
  179. <label><%= custom_field.name %></label>
  180. <%= custom_field_tag_for_bulk_edit('issue', custom_field, @issues, @issue_params[:custom_field_values][custom_field.id.to_s]) %>
  181. </p>
  182. <% if i == split_on %>
  183. </div><div class="splitcontentright">
  184. <% end %>
  185. <% i += 1 %>
  186. <% end %>
  187. </div>
  188. </div>
  189. <% end %>
  190. <% custom_fields_full_width.each do |custom_field| %>
  191. <p>
  192. <label><%= custom_field.name %></label>
  193. <%= custom_field_tag_for_bulk_edit('issue', custom_field, @issues, @issue_params[:custom_field_values][custom_field.id.to_s]) %>
  194. </p>
  195. <%= wikitoolbar_for "issue_custom_field_values_#{custom_field.id}", preview_issue_path(:project_id => @project, :issue_id => nil) if custom_field.full_text_formatting? %>
  196. <% end %>
  197. </fieldset>
  198. <fieldset>
  199. <legend><%= l(:field_notes) %></legend>
  200. <%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit',
  201. :data => {
  202. :auto_complete => true
  203. }
  204. %>
  205. <%= wikitoolbar_for 'notes' %>
  206. <% if @safe_attributes.include?('private_notes') %>
  207. <label class="inline">
  208. <%= check_box_tag 'issue[private_notes]', 1, false %>
  209. <%= l(:field_private_notes) %>
  210. </label>
  211. <% end %>
  212. </fieldset>
  213. </div>
  214. <% if @values_by_custom_field.present? %>
  215. <div class="flash warning">
  216. <%= l(:warning_fields_cleared_on_bulk_edit) %>:<br />
  217. <%= safe_join(@values_by_custom_field.map {|field, ids| content_tag "span", "#{field.name} (#{ids.size})"}, ', ') %>
  218. </div>
  219. <% end %>
  220. <p>
  221. <% if @copy %>
  222. <%= hidden_field_tag 'copy', '1' %>
  223. <%= submit_tag l(:button_copy) %>
  224. <%= submit_tag l(:button_copy_and_follow), :name => 'follow' %>
  225. <% elsif @target_project %>
  226. <%= submit_tag l(:button_move) %>
  227. <%= submit_tag l(:button_move_and_follow), :name => 'follow' %>
  228. <% else %>
  229. <%= submit_tag l(:button_submit) %>
  230. <% end %>
  231. </p>
  232. <% end %>
  233. <%= javascript_tag do %>
  234. $(window).on('load', function(){
  235. $(document).on('change', 'input[data-disables]', function(){
  236. if ($(this).prop('checked')){
  237. $($(this).data('disables')).attr('disabled', true).val('');
  238. } else {
  239. $($(this).data('disables')).attr('disabled', false);
  240. }
  241. });
  242. });
  243. $(document).ready(function(){
  244. $('input[data-disables]').trigger('change');
  245. });
  246. <% end %>