Enable tracker update on issue edit form (#2405).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3108 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
3d317a435b
commit
88fcf484d4
|
@ -22,7 +22,7 @@ class IssuesController < ApplicationController
|
||||||
before_filter :find_issue, :only => [:show, :edit, :reply]
|
before_filter :find_issue, :only => [:show, :edit, :reply]
|
||||||
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
|
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
|
||||||
before_filter :find_project, :only => [:new, :update_form, :preview]
|
before_filter :find_project, :only => [:new, :update_form, :preview]
|
||||||
before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu]
|
before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :context_menu]
|
||||||
before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
|
before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
|
||||||
accept_key_auth :index, :show, :changes
|
accept_key_auth :index, :show, :changes
|
||||||
|
|
||||||
|
@ -429,8 +429,17 @@ class IssuesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_form
|
def update_form
|
||||||
@issue = Issue.new(params[:issue])
|
if params[:id]
|
||||||
render :action => :new, :layout => false
|
@issue = @project.issues.visible.find(params[:id])
|
||||||
|
else
|
||||||
|
@issue = Issue.new
|
||||||
|
@issue.project = @project
|
||||||
|
end
|
||||||
|
@issue.attributes = params[:issue]
|
||||||
|
@allowed_statuses = ([@issue.status] + @issue.status.find_new_statuses_allowed_to(User.current.roles_for_project(@project), @issue.tracker)).uniq
|
||||||
|
@priorities = IssuePriority.all
|
||||||
|
|
||||||
|
render :partial => 'attributes'
|
||||||
end
|
end
|
||||||
|
|
||||||
def preview
|
def preview
|
||||||
|
|
|
@ -127,6 +127,11 @@ class Issue < ActiveRecord::Base
|
||||||
self.priority = nil
|
self.priority = nil
|
||||||
write_attribute(:priority_id, pid)
|
write_attribute(:priority_id, pid)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tracker_id=(tid)
|
||||||
|
self.tracker = nil
|
||||||
|
write_attribute(:tracker_id, tid)
|
||||||
|
end
|
||||||
|
|
||||||
def estimated_hours=(h)
|
def estimated_hours=(h)
|
||||||
write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
|
write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
|
||||||
|
@ -152,6 +157,13 @@ class Issue < ActiveRecord::Base
|
||||||
errors.add_to_base I18n.t(:error_can_not_reopen_issue_on_closed_version)
|
errors.add_to_base I18n.t(:error_can_not_reopen_issue_on_closed_version)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Checks that the issue can not be added/moved to a disabled tracker
|
||||||
|
if project && (tracker_id_changed? || project_id_changed?)
|
||||||
|
unless project.trackers.include?(tracker)
|
||||||
|
errors.add :tracker_id, :inclusion
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_on_create
|
def validate_on_create
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<% fields_for :issue, @issue, :builder => TabularFormBuilder do |f| %>
|
||||||
|
|
||||||
|
<div class="splitcontentleft">
|
||||||
|
<% if @issue.new_record? || @allowed_statuses.any? %>
|
||||||
|
<p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
|
||||||
|
<% else %>
|
||||||
|
<p><label><%= l(:field_status) %></label> <%= @issue.status.name %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
|
||||||
|
<p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
|
||||||
|
<% unless @project.issue_categories.empty? %>
|
||||||
|
<p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
|
||||||
|
<%= prompt_to_remote(l(:label_issue_category_new),
|
||||||
|
l(:label_issue_category_new), 'category[name]',
|
||||||
|
{:controller => 'projects', :action => 'add_issue_category', :id => @project},
|
||||||
|
:class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
|
||||||
|
<% end %>
|
||||||
|
<% unless @issue.assignable_versions.empty? %>
|
||||||
|
<p><%= f.select :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true %></p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="splitcontentright">
|
||||||
|
<p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
|
||||||
|
<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
|
||||||
|
<p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
|
||||||
|
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="clear:both;"> </div>
|
||||||
|
<%= render :partial => 'form_custom_fields' %>
|
||||||
|
|
||||||
|
<% end %>
|
|
@ -1,12 +1,9 @@
|
||||||
<% if @issue.new_record? %>
|
|
||||||
<p><%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p>
|
|
||||||
<%= observe_field :issue_tracker_id, :url => { :action => :new },
|
|
||||||
:update => :content,
|
|
||||||
:with => "Form.serialize('issue-form')" %>
|
|
||||||
<hr />
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div id="issue_descr_fields" <%= 'style="display:none"' unless @issue.new_record? || @issue.errors.any? %>>
|
<div id="issue_descr_fields" <%= 'style="display:none"' unless @issue.new_record? || @issue.errors.any? %>>
|
||||||
|
<p><%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p>
|
||||||
|
<%= observe_field :issue_tracker_id, :url => { :action => :update_form, :project_id => @project, :id => @issue },
|
||||||
|
:update => :attributes,
|
||||||
|
:with => "Form.serialize('issue-form')" %>
|
||||||
|
|
||||||
<p><%= f.text_field :subject, :size => 80, :required => true %></p>
|
<p><%= f.text_field :subject, :size => 80, :required => true %></p>
|
||||||
<p><%= f.text_area :description,
|
<p><%= f.text_area :description,
|
||||||
:cols => 60,
|
:cols => 60,
|
||||||
|
@ -15,37 +12,8 @@
|
||||||
:class => 'wiki-edit' %></p>
|
:class => 'wiki-edit' %></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="attributes">
|
<div id="attributes" class="attributes">
|
||||||
<div class="splitcontentleft">
|
<%= render :partial => 'attributes' %>
|
||||||
<% if @issue.new_record? || @allowed_statuses.any? %>
|
|
||||||
<p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
|
|
||||||
<% else %>
|
|
||||||
<p><label><%= l(:field_status) %></label> <%= @issue.status.name %></p>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
|
|
||||||
<p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
|
|
||||||
<% unless @project.issue_categories.empty? %>
|
|
||||||
<p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
|
|
||||||
<%= prompt_to_remote(l(:label_issue_category_new),
|
|
||||||
l(:label_issue_category_new), 'category[name]',
|
|
||||||
{:controller => 'projects', :action => 'add_issue_category', :id => @project},
|
|
||||||
:class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
|
|
||||||
<% end %>
|
|
||||||
<% unless @issue.assignable_versions.empty? %>
|
|
||||||
<p><%= f.select :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true %></p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="splitcontentright">
|
|
||||||
<p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
|
|
||||||
<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
|
|
||||||
<p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
|
|
||||||
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="clear:both;"> </div>
|
|
||||||
<%= render :partial => 'form_custom_fields' %>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if @issue.new_record? %>
|
<% if @issue.new_record? %>
|
||||||
|
|
|
@ -42,8 +42,8 @@ Redmine::AccessControl.map do |map|
|
||||||
:versions => [:show, :status_by],
|
:versions => [:show, :status_by],
|
||||||
:queries => :index,
|
:queries => :index,
|
||||||
:reports => :issue_report}
|
:reports => :issue_report}
|
||||||
map.permission :add_issues, {:issues => :new}
|
map.permission :add_issues, {:issues => [:new, :update_form]}
|
||||||
map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit]}
|
map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit, :update_form]}
|
||||||
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
|
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
|
||||||
map.permission :add_issue_notes, {:issues => [:edit, :reply]}
|
map.permission :add_issue_notes, {:issues => [:edit, :reply]}
|
||||||
map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
|
map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
|
||||||
|
|
|
@ -501,14 +501,20 @@ class IssuesControllerTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_update_new_form
|
def test_update_new_form
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
xhr :post, :new, :project_id => 1,
|
xhr :post, :update_form, :project_id => 1,
|
||||||
:issue => {:tracker_id => 2,
|
:issue => {:tracker_id => 2,
|
||||||
:subject => 'This is the test_new issue',
|
:subject => 'This is the test_new issue',
|
||||||
:description => 'This is the description',
|
:description => 'This is the description',
|
||||||
:priority_id => 5}
|
:priority_id => 5}
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template 'new'
|
assert_template 'attributes'
|
||||||
end
|
|
||||||
|
issue = assigns(:issue)
|
||||||
|
assert_kind_of Issue, issue
|
||||||
|
assert_equal 1, issue.project_id
|
||||||
|
assert_equal 2, issue.tracker_id
|
||||||
|
assert_equal 'This is the test_new issue', issue.subject
|
||||||
|
end
|
||||||
|
|
||||||
def test_post_new
|
def test_post_new
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
|
@ -698,6 +704,25 @@ class IssuesControllerTest < ActionController::TestCase
|
||||||
:content => 'Urgent',
|
:content => 'Urgent',
|
||||||
:attributes => { :selected => 'selected' } }
|
:attributes => { :selected => 'selected' } }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_update_edit_form
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
xhr :post, :update_form, :project_id => 1,
|
||||||
|
:id => 1,
|
||||||
|
:issue => {:tracker_id => 2,
|
||||||
|
:subject => 'This is the test_new issue',
|
||||||
|
:description => 'This is the description',
|
||||||
|
:priority_id => 5}
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'attributes'
|
||||||
|
|
||||||
|
issue = assigns(:issue)
|
||||||
|
assert_kind_of Issue, issue
|
||||||
|
assert_equal 1, issue.id
|
||||||
|
assert_equal 1, issue.project_id
|
||||||
|
assert_equal 2, issue.tracker_id
|
||||||
|
assert_equal 'This is the test_new issue', issue.subject
|
||||||
|
end
|
||||||
|
|
||||||
def test_reply_routing
|
def test_reply_routing
|
||||||
assert_routing(
|
assert_routing(
|
||||||
|
|
|
@ -164,6 +164,29 @@ class IssueTest < ActiveSupport::TestCase
|
||||||
assert_equal custom_value.id, issue.custom_value_for(field).id
|
assert_equal custom_value.id, issue.custom_value_for(field).id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_should_update_issue_with_disabled_tracker
|
||||||
|
p = Project.find(1)
|
||||||
|
issue = Issue.find(1)
|
||||||
|
|
||||||
|
p.trackers.delete(issue.tracker)
|
||||||
|
assert !p.trackers.include?(issue.tracker)
|
||||||
|
|
||||||
|
issue.reload
|
||||||
|
issue.subject = 'New subject'
|
||||||
|
assert issue.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_should_not_set_a_disabled_tracker
|
||||||
|
p = Project.find(1)
|
||||||
|
p.trackers.delete(Tracker.find(2))
|
||||||
|
|
||||||
|
issue = Issue.find(1)
|
||||||
|
issue.tracker_id = 2
|
||||||
|
issue.subject = 'New subject'
|
||||||
|
assert !issue.save
|
||||||
|
assert_not_nil issue.errors.on(:tracker_id)
|
||||||
|
end
|
||||||
|
|
||||||
def test_category_based_assignment
|
def test_category_based_assignment
|
||||||
issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
|
issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
|
||||||
assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
|
assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
|
||||||
|
|
Loading…
Reference in New Issue