summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGo MAEDA <maeda@farend.jp>2018-02-28 06:42:52 +0000
committerGo MAEDA <maeda@farend.jp>2018-02-28 06:42:52 +0000
commita175f9ded969c233dd8730d30d6a206105c355d7 (patch)
treee248db11fffa957d0e6931fd2c6313574be4f368
parentfd789630723adbf792832cd7de1b8ac94dc8fef2 (diff)
downloadredmine-a175f9ded969c233dd8730d30d6a206105c355d7.tar.gz
redmine-a175f9ded969c233dd8730d30d6a206105c355d7.zip
Allow selecting subprojects on new issue form (#12704).
Patch by Marius BALTEANU. git-svn-id: http://svn.redmine.org/redmine/trunk@17217 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r--app/models/issue.rb15
-rw-r--r--app/views/issues/_form.html.erb5
-rw-r--r--test/functional/issues_controller_test.rb34
3 files changed, 47 insertions, 7 deletions
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 7ab8ae9c9..8583d43e5 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -1514,8 +1514,15 @@ class Issue < ActiveRecord::Base
end
# Returns a scope of projects that user can assign the issue to
- def allowed_target_projects(user=User.current)
- current_project = new_record? ? nil : project
+ def allowed_target_projects(user=User.current, context=nil)
+ if new_record? && context.is_a?(Project) && !copy?
+ current_project = context.self_and_descendants
+ elsif new_record?
+ current_project = nil
+ else
+ current_project = project
+ end
+
self.class.allowed_target_projects(user, current_project)
end
@@ -1523,8 +1530,10 @@ class Issue < ActiveRecord::Base
# If current_project is given, it will be included in the scope
def self.allowed_target_projects(user=User.current, current_project=nil)
condition = Project.allowed_to_condition(user, :add_issues)
- if current_project
+ if current_project.is_a?(Project)
condition = ["(#{condition}) OR #{Project.table_name}.id = ?", current_project.id]
+ elsif current_project
+ condition = ["(#{condition}) AND #{Project.table_name}.id IN (?)", current_project.map(&:id)]
end
Project.where(condition).having_trackers
end
diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb
index ab19feef2..f25cb3b2b 100644
--- a/app/views/issues/_form.html.erb
+++ b/app/views/issues/_form.html.erb
@@ -9,8 +9,9 @@
</p>
<% end %>
-<% if (@issue.safe_attribute?('project_id') || @issue.project_id_changed?) && (!@issue.new_record? || @project.nil? || @issue.copy?) %>
-<p><%= f.select :project_id, project_tree_options_for_select(@issue.allowed_target_projects, :selected => @issue.project), {:required => true},
+<% projects = @issue.allowed_target_projects(User.current, @project) %>
+<% if (@issue.safe_attribute?('project_id') || @issue.project_id_changed?) && (@project.nil? || projects.length > 1 || @issue.copy?) %>
+<p><%= f.select :project_id, project_tree_options_for_select(projects, :selected => @issue.project), {:required => true},
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %></p>
<% end %>
diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb
index 5be84b9c7..9f62758e4 100644
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -2302,7 +2302,7 @@ class IssuesControllerTest < Redmine::ControllerTest
assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
assert_select 'form#issue-form' do
assert_select 'input[name=?]', 'issue[is_private]'
- assert_select 'select[name=?]', 'issue[project_id]', 0
+ assert_select 'select[name=?]', 'issue[project_id]'
assert_select 'select[name=?]', 'issue[tracker_id]'
assert_select 'input[name=?]', 'issue[subject]'
assert_select 'textarea[name=?]', 'issue[description]'
@@ -2326,6 +2326,36 @@ class IssuesControllerTest < Redmine::ControllerTest
end
end
+ def test_get_new_should_show_project_selector_for_project_with_subprojects
+ @request.session[:user_id] = 2
+ get :new, :params => {
+ :project_id => 1,
+ :tracker_id => 1
+ }
+ assert_response :success
+
+ assert_select 'select[name="issue[project_id]"]' do
+ assert_select 'option', 3
+ assert_select 'option[selected=selected]', :text => 'eCookbook'
+ assert_select 'option[value=?]', '5', :text => '  » Private child of eCookbook'
+ assert_select 'option[value=?]', '3', :text => '  » eCookbook Subproject 1'
+
+ # user_id 2 is not allowed to add issues on project_id 4 (it's not a member)
+ assert_select 'option[value=?]', '4', 0
+ end
+ end
+
+ def test_get_new_should_not_show_project_selector_for_project_without_subprojects
+ @request.session[:user_id] = 2
+ get :new, :params => {
+ :project_id => 2,
+ :tracker_id => 1
+ }
+ assert_response :success
+
+ assert_select 'select[name="issue[project_id]"]', 0
+ end
+
def test_get_new_with_minimal_permissions
Role.find(1).update_attribute :permissions, [:add_issues]
WorkflowTransition.where(:role_id => 1).delete_all
@@ -2339,7 +2369,7 @@ class IssuesControllerTest < Redmine::ControllerTest
assert_select 'form#issue-form' do
assert_select 'input[name=?]', 'issue[is_private]', 0
- assert_select 'select[name=?]', 'issue[project_id]', 0
+ assert_select 'select[name=?]', 'issue[project_id]'
assert_select 'select[name=?]', 'issue[tracker_id]'
assert_select 'input[name=?]', 'issue[subject]'
assert_select 'textarea[name=?]', 'issue[description]'