Added 'Bulk edit' functionality.
This can be done by clicking on the edit link (little pen icon) at the upper-left corner of the issue list. Most properties can be set (priority, assignee, category, fixed version, start and due dates, done ratio) and a note can be entered. Only issues of the current project can be selected for bulk edit (subproject issues can't). git-svn-id: http://redmine.rubyforge.org/svn/trunk@817 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
1 parent
df631e8c06
commit
2c4647f8c6
24 files changed
+167
-8
No files matched your search
@@ -336,6 +336,36 @@ class ProjectsController < ApplicationController
|
||||
@options_for_rfpdf[:file_name] = "export.pdf"
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
# Bulk edit issues
|
||||
def bulk_edit_issues
|
||||
if request.post?
|
||||
priority = Enumeration.find_by_id(params[:priority_id])
|
||||
assigned_to = User.find_by_id(params[:assigned_to_id])
|
||||
issues = @project.issues.find_all_by_id(params[:issue_ids])
|
||||
unsaved_issue_ids = []
|
||||
issues.each do |issue|
|
||||
issue.init_journal(User.current, params[:notes])
|
||||
issue.priority = priority if priority
|
||||
issue.assigned_to = assigned_to if assigned_to
|
||||
issue.start_date = params[:start_date] unless params[:start_date].blank?
|
||||
issue.due_date = params[:due_date] unless params[:due_date].blank?
|
||||
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
|
||||
unsaved_issue_ids << issue.id unless issue.save
|
||||
end
|
||||
if unsaved_issue_ids.empty?
|
||||
flash[:notice] = l(:notice_successful_update) unless issues.empty?
|
||||
else
|
||||
flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, issues.size, '#' + unsaved_issue_ids.join(', #'))
|
||||
end
|
||||
redirect_to :action => 'list_issues', :id => @project
|
||||
return
|
||||
end
|
||||
render :update do |page|
|
||||
page.hide 'query_form'
|
||||
page.replace_html 'bulk-edit', :partial => 'issues/bulk_edit_form'
|
||||
end
|
||||
end
|
||||
|
||||
def move_issues
|
||||
@issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ class Issue < ActiveRecord::Base
|
||||
|
||||
# Users the issue can be assigned to
|
||||
def assignable_users
|
||||
project.members.select {|m| m.role.assignable?}.collect {|m| m.user}
|
||||
project.assignable_users
|
||||
end
|
||||
|
||||
def spent_hours
|
||||
|
||||
@@ -113,6 +113,11 @@ class Project < ActiveRecord::Base
|
||||
children.select {|child| child.active?}
|
||||
end
|
||||
|
||||
# Users issues can be assigned to
|
||||
def assignable_users
|
||||
members.select {|m| m.role.assignable?}.collect {|m| m.user}
|
||||
end
|
||||
|
||||
# Returns an array of all custom fields enabled for project issues
|
||||
# (explictly associated custom fields and custom fields enabled for all projects)
|
||||
def custom_fields_for_issues(tracker)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<div id="bulk-edit-fields">
|
||||
<fieldset class="box"><legend><%= l(:label_bulk_edit_selected_issues) %></legend>
|
||||
|
||||
<p>
|
||||
<label><%= l(:field_priority) %>:
|
||||
<%= select_tag('priority_id', "<option>#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(Enumeration.get_values('IPRI'), :id, :name)) %></label>
|
||||
<label><%= l(:field_assigned_to) %>:
|
||||
<%= select_tag('assigned_to_id', "<option>#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@project.assignable_users, :id, :name)) %></label>
|
||||
<label><%= l(:field_category) %>:
|
||||
<%= select_tag('category_id', "<option>#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@project.issue_categories, :id, :name)) %></label>
|
||||
<label><%= l(:field_fixed_version) %>:
|
||||
<%= select_tag('fixed_version_id', "<option>#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@project.versions, :id, :name)) %></label>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label><%= l(:field_start_date) %>:
|
||||
<%= text_field_tag 'start_date', '', :size => 10 %><%= calendar_for('start_date') %></label>
|
||||
<label><%= l(:field_due_date) %>:
|
||||
<%= text_field_tag 'due_date', '', :size => 10 %><%= calendar_for('due_date') %></label>
|
||||
<label><%= l(:field_done_ratio) %>:
|
||||
<%= select_tag 'done_ratio', options_for_select([l(:label_no_change_option)] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></label>
|
||||
</p>
|
||||
|
||||
<label for="notes"><%= l(:field_notes) %></label><br />
|
||||
<%= text_area_tag 'notes', '', :cols => 80, :rows => 5 %>
|
||||
|
||||
</fieldset>
|
||||
<p><%= submit_tag l(:button_apply) %>
|
||||
<%= link_to l(:button_cancel), {}, :onclick => 'Element.hide("bulk-edit-fields"); if ($("query_form")) {Element.show("query_form")}; return false;' %></p>
|
||||
</div>
|
||||
@@ -1,6 +1,11 @@
|
||||
<div id="bulk-edit"></div>
|
||||
<table class="list">
|
||||
<thead><tr>
|
||||
<th></th>
|
||||
<th><%= link_to_remote(image_tag('edit.png'),
|
||||
{:url => { :controller => 'projects', :action => 'bulk_edit_issues', :id => @project },
|
||||
:method => :get},
|
||||
{:title => l(:label_bulk_edit_selected_issues)}) if @project && User.current.allowed_to?(:edit_issues, @project) %>
|
||||
</th>
|
||||
<%= sort_header_tag("#{Issue.table_name}.id", :caption => '#') %>
|
||||
<% query.columns.each do |column| %>
|
||||
<%= column_header(column) %>
|
||||
@@ -9,7 +14,7 @@
|
||||
<tbody>
|
||||
<% issues.each do |issue| %>
|
||||
<tr class="issue <%= cycle('odd', 'even') %>">
|
||||
<td class="checkbox"><%= check_box_tag "issue_ids[]", issue.id, false, :id => "issue_#{issue.id}" %></td>
|
||||
<td class="checkbox"><%= check_box_tag("issue_ids[]", issue.id, false, :id => "issue_#{issue.id}", :disabled => (!@project || @project != issue.project)) %></td>
|
||||
<td><%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %></td>
|
||||
<% query.columns.each do |column| %>
|
||||
<%= content_tag 'td', column_content(column, issue), :class => column.name %>
|
||||
|
||||
@@ -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 %>
|
||||
<div class="contextual">
|
||||
<%= link_to_remote l(:button_apply),
|
||||
{ :url => { :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 },
|
||||
@@ -22,6 +21,8 @@
|
||||
<% end %>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="contextual">
|
||||
<% if @query.editable_by?(User.current) %>
|
||||
@@ -31,6 +32,7 @@
|
||||
</div>
|
||||
|
||||
<h2><%= @query.name %></h2>
|
||||
<div id="query_form"></div>
|
||||
<% set_html_title @query.name %>
|
||||
<% end %>
|
||||
<%= error_messages_for 'query' %>
|
||||
@@ -38,15 +40,14 @@
|
||||
<% if @issues.empty? %>
|
||||
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||
<% 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} %>
|
||||
<div class="contextual">
|
||||
<%= 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' %>
|
||||
</div>
|
||||
<p><%= submit_tag(l(:button_move), :class => "button-small") if authorize_for('projects', 'move_issues') %>
|
||||
<p>
|
||||
<%= pagination_links_full @issue_pages %>
|
||||
[ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
|
||||
</p>
|
||||
@@ -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 %>
|
||||
Reference in new issue
Block a user