]> source.dussan.org Git - redmine.git/commitdiff
Enable tracker update on issue edit form (#2405).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 29 Nov 2009 19:46:40 +0000 (19:46 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 29 Nov 2009 19:46:40 +0000 (19:46 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3108 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/issues_controller.rb
app/models/issue.rb
app/views/issues/_attributes.rhtml [new file with mode: 0644]
app/views/issues/_form.rhtml
lib/redmine.rb
test/functional/issues_controller_test.rb
test/unit/issue_test.rb

index d0a34d7bfd9ecd5386b5c606e382c9c32e466f2f..02be772a2a39242bf3899018f5f3a0bdb81020bf 100644 (file)
@@ -22,7 +22,7 @@ class IssuesController < ApplicationController
   before_filter :find_issue, :only => [:show, :edit, :reply]
   before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
   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]
   accept_key_auth :index, :show, :changes
 
@@ -429,8 +429,17 @@ class IssuesController < ApplicationController
   end
 
   def update_form
-    @issue = Issue.new(params[:issue])
-    render :action => :new, :layout => false
+    if params[:id]
+      @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
   
   def preview
index cfc2a1bc0aada884a6f130ca790025f9c44e3e40..658c8efbf58e0af802b411a65c3ae074f41197f5 100644 (file)
@@ -127,6 +127,11 @@ class Issue < ActiveRecord::Base
     self.priority = nil
     write_attribute(:priority_id, pid)
   end
+
+  def tracker_id=(tid)
+    self.tracker = nil
+    write_attribute(:tracker_id, tid)
+  end
   
   def estimated_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)
       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
   
   def validate_on_create
diff --git a/app/views/issues/_attributes.rhtml b/app/views/issues/_attributes.rhtml
new file mode 100644 (file)
index 0000000..cfa14d5
--- /dev/null
@@ -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 %>
index c61c79d6084e1ea165225bbf4507e68c5b74e83f..5337b51be38e314c97d9dc17a35599fcf988452c 100644 (file)
@@ -1,12 +1,9 @@
-<% if @issue.new_record? %>
+<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 => :new },
-                                     :update => :content,
+<%= observe_field :issue_tracker_id, :url => { :action => :update_form, :project_id => @project, :id => @issue },
+                                     :update => :attributes,
                                      :with => "Form.serialize('issue-form')" %>
-<hr />
-<% end %>
 
-<div id="issue_descr_fields" <%= 'style="display:none"' unless @issue.new_record? || @issue.errors.any? %>>
 <p><%= f.text_field :subject, :size => 80, :required => true %></p>
 <p><%= f.text_area :description,
                    :cols => 60,
                    :class => 'wiki-edit' %></p>
 </div>
 
-<div class="attributes">
-<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' %>
+<div id="attributes" class="attributes">
+       <%= render :partial => 'attributes' %>
 </div>
 
 <% if @issue.new_record? %>
index 1b88ee10fcf79d54d9be509cec6dbda8718988c4..8dbe5d0ef57b9a96f418c6d181457801befc1881 100644 (file)
@@ -42,8 +42,8 @@ Redmine::AccessControl.map do |map|
                                   :versions => [:show, :status_by],
                                   :queries => :index,
                                   :reports => :issue_report}
-    map.permission :add_issues, {:issues => :new}
-    map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit]}
+    map.permission :add_issues, {:issues => [:new, :update_form]}
+    map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit, :update_form]}
     map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
     map.permission :add_issue_notes, {:issues => [:edit, :reply]}
     map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
index 9555db4ea7fd485446afb86e363950f4c44ccd8b..4c6b25358ae2746fd7f67dce1569ad62cfe80d1e 100644 (file)
@@ -501,14 +501,20 @@ class IssuesControllerTest < ActionController::TestCase
   
   def test_update_new_form
     @request.session[:user_id] = 2
-    xhr :post, :new, :project_id => 1,
+    xhr :post, :update_form, :project_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 'new'
-  end 
+    assert_template 'attributes'
+    
+    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
     @request.session[:user_id] = 2
@@ -698,6 +704,25 @@ class IssuesControllerTest < ActionController::TestCase
                                     :content => 'Urgent',
                                     :attributes => { :selected => 'selected' } }
   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
     assert_routing(
index 3b0dd2697ce7d0091c3a426faa210060306ef181..afde6c72056bba8ed9394e10f82e07962c407d25 100644 (file)
@@ -164,6 +164,29 @@ class IssueTest < ActiveSupport::TestCase
     assert_equal custom_value.id, issue.custom_value_for(field).id
   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
     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