- <%= check_box_tag "issue_ids[]", issue.id, false, :id => "issue_#{issue.id}" %> |
+ <%= check_box_tag("issue_ids[]", issue.id, false, :id => "issue_#{issue.id}", :disabled => (!@project || @project != issue.project)) %> |
<%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %> |
<% query.columns.each do |column| %>
<%= content_tag 'td', column_content(column, issue), :class => column.name %>
diff --git a/app/views/projects/list_issues.rhtml b/app/views/projects/list_issues.rhtml
index 60e8f7be..9f2ff870 100644
--- a/app/views/projects/list_issues.rhtml
+++ b/app/views/projects/list_issues.rhtml
@@ -4,7 +4,6 @@
<% form_tag({ :controller => 'queries', :action => 'new', :project_id => @project }, :id => 'query_form') do %>
<%= render :partial => 'queries/filters', :locals => {:query => @query} %>
- <% end %>
<%= link_to_remote l(:button_apply),
{ :url => { :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 },
@@ -22,6 +21,8 @@
<% end %>
+
+ <% end %>
<% else %>
<% if @query.editable_by?(User.current) %>
@@ -31,6 +32,7 @@
<%= @query.name %>
+
<% set_html_title @query.name %>
<% end %>
<%= error_messages_for 'query' %>
@@ -38,15 +40,14 @@
<% if @issues.empty? %>
<%= l(:label_no_data) %>
<% else %>
-
-<% form_tag({:controller => 'projects', :action => 'move_issues', :id => @project}, :id => 'issues_form' ) do %>
+<% form_tag({:controller => 'projects', :action => 'bulk_edit_issues', :id => @project}, :id => 'issues_form', :onsubmit => "if (!checkBulkEdit(this)) {alert('#{l(:notice_no_issue_selected)}'); return false;}" ) do %>
<%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
<%= l(:label_export_to) %>
<%= link_to 'CSV', {:action => 'export_issues_csv', :id => @project}, :class => 'icon icon-csv' %>,
<%= link_to 'PDF', {:action => 'export_issues_pdf', :id => @project}, :class => 'icon icon-pdf' %>
-<%= submit_tag(l(:button_move), :class => "button-small") if authorize_for('projects', 'move_issues') %>
+
<%= pagination_links_full @issue_pages %>
[ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
@@ -57,3 +58,10 @@
<% content_for :sidebar do %>
<%= render :partial => 'issues/sidebar' %>
<% end %>
+
+<% content_for :header_tags do %>
+ <%= javascript_include_tag 'calendar/calendar' %>
+ <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
+ <%= javascript_include_tag 'calendar/calendar-setup' %>
+ <%= stylesheet_link_tag 'calendar' %>
+<% end %>
diff --git a/lang/bg.yml b/lang/bg.yml
index 12a5378d..e987e1ad 100644
--- a/lang/bg.yml
+++ b/lang/bg.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/cs.yml b/lang/cs.yml
index 078f824f..7b5c1a65 100644
--- a/lang/cs.yml
+++ b/lang/cs.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/de.yml b/lang/de.yml
index 47078557..23dd6518 100644
--- a/lang/de.yml
+++ b/lang/de.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/en.yml b/lang/en.yml
index 79e8f61d..af3faf49 100644
--- a/lang/en.yml
+++ b/lang/en.yml
@@ -73,6 +73,8 @@ notice_not_authorized: You are not authorized to access this page.
notice_email_sent: An email was sent to %s
notice_email_error: An error occurred while sending mail (%s)
notice_feeds_access_key_reseted: Your RSS access key was reseted.
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
mail_subject_lost_password: Your redMine password
mail_subject_register: redMine account activation
@@ -427,6 +429,8 @@ label_jump_to_a_project: Jump to a project...
label_file_plural: Files
label_changeset_plural: Changesets
label_default_columns: Default columns
+label_no_change_option: (No change)
+label_bulk_edit_selected_issues: Bulk edit selected issues
button_login: Login
button_submit: Submit
diff --git a/lang/es.yml b/lang/es.yml
index 2e8e6efb..40929e46 100644
--- a/lang/es.yml
+++ b/lang/es.yml
@@ -519,3 +519,7 @@ label_added_time_by: Added by %s %s ago
field_estimated_hours: Estimated time
label_changeset_plural: Changesets
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/fr.yml b/lang/fr.yml
index bb875288..a42ead91 100644
--- a/lang/fr.yml
+++ b/lang/fr.yml
@@ -73,6 +73,8 @@ notice_not_authorized: "Vous n'êtes pas autorisés à accéder à cette page."
notice_email_sent: "Un email a été envoyé à %s"
notice_email_error: "Erreur lors de l'envoi de l'email (%s)"
notice_feeds_access_key_reseted: Votre clé d'accès aux flux RSS a été réinitialisée.
+notice_failed_to_save_issues: "%d demande(s) sur les %d sélectionnées n'ont pas pu être mise(s) à jour: %s."
+notice_no_issue_selected: "Aucune demande sélectionnée ! Cochez les demandes que vous voulez mettre à jour."
mail_subject_lost_password: Votre mot de passe redMine
mail_subject_register: Activation de votre compte redMine
@@ -427,6 +429,8 @@ label_jump_to_a_project: Aller à un projet...
label_file_plural: Fichiers
label_changeset_plural: Révisions
label_default_columns: Colonnes par défaut
+label_no_change_option: (Pas de changement)
+label_bulk_edit_selected_issues: Modifier les demandes sélectionnées
button_login: Connexion
button_submit: Soumettre
diff --git a/lang/it.yml b/lang/it.yml
index 4d114b15..207a5e64 100644
--- a/lang/it.yml
+++ b/lang/it.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/ja.yml b/lang/ja.yml
index 433320aa..41c1ba5d 100644
--- a/lang/ja.yml
+++ b/lang/ja.yml
@@ -517,3 +517,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: 問題の一覧で表示する項目
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/nl.yml b/lang/nl.yml
index 7e252d9d..716618d7 100644
--- a/lang/nl.yml
+++ b/lang/nl.yml
@@ -517,3 +517,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/pl.yml b/lang/pl.yml
index 4db0d676..f883e2d2 100644
--- a/lang/pl.yml
+++ b/lang/pl.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/pt-br.yml b/lang/pt-br.yml
index 59a5e1cc..91d487e5 100644
--- a/lang/pt-br.yml
+++ b/lang/pt-br.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/pt.yml b/lang/pt.yml
index b4e4a0cb..3c6cec37 100644
--- a/lang/pt.yml
+++ b/lang/pt.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/ro.yml b/lang/ro.yml
index 25c48870..042b596f 100644
--- a/lang/ro.yml
+++ b/lang/ro.yml
@@ -516,3 +516,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/sv.yml b/lang/sv.yml
index e59e9233..02ecc6e1 100644
--- a/lang/sv.yml
+++ b/lang/sv.yml
@@ -517,3 +517,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lang/zh.yml b/lang/zh.yml
index b881ee4d..bbd08877 100644
--- a/lang/zh.yml
+++ b/lang/zh.yml
@@ -519,3 +519,7 @@ field_column_names: Columns
label_default_columns: Default columns
setting_issue_list_default_columns: Default columns displayed on the issue list
setting_repositories_encodings: Repositories encodings
+notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+label_bulk_edit_selected_issues: Bulk edit selected issues
+label_no_change_option: (No change)
+notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
diff --git a/lib/redmine.rb b/lib/redmine.rb
index f5682a95..cb6af8ae 100644
--- a/lib/redmine.rb
+++ b/lib/redmine.rb
@@ -29,7 +29,8 @@ Redmine::AccessControl.map do |map|
:queries => :index,
:reports => :issue_report}, :public => true
map.permission :add_issues, {:projects => :add_issue}, :require => :loggedin
- map.permission :edit_issues, {:issues => [:edit, :destroy_attachment]}, :require => :loggedin
+ map.permission :edit_issues, {:projects => :bulk_edit_issues,
+ :issues => [:edit, :destroy_attachment]}, :require => :loggedin
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}, :require => :loggedin
map.permission :add_issue_notes, {:issues => :add_note}, :require => :loggedin
map.permission :change_issue_status, {:issues => :change_status}, :require => :loggedin
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 6a30e42e..bf86f398 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -49,6 +49,16 @@ function promptToRemote(text, param, url) {
}
}
+/* checks that at least one checkbox is checked (used when submitting bulk edit form) */
+function checkBulkEdit(form) {
+ for (var i = 0; i < form.elements.length; i++) {
+ if (form.elements[i].checked) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* shows and hides ajax indicator */
Ajax.Responders.register({
onCreate: function(){
diff --git a/test/functional/projects_controller_test.rb b/test/functional/projects_controller_test.rb
index b065d82b..e9ffa302 100644
--- a/test/functional/projects_controller_test.rb
+++ b/test/functional/projects_controller_test.rb
@@ -83,6 +83,16 @@ class ProjectsControllerTest < Test::Unit::TestCase
assert_response :success
assert_not_nil assigns(:issues)
end
+
+ def test_bulk_edit_issues
+ @request.session[:user_id] = 2
+ # update issues priority
+ post :bulk_edit_issues, :id => 1, :issue_ids => [1, 2], :priority_id => 7, :notes => "Bulk editing"
+ assert_response 302
+ # check that the issues were updated
+ assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
+ assert_equal "Bulk editing", Issue.find(1).journals.last.notes
+ end
def test_list_news
get :list_news, :id => 1