Browse Source

Show only valid projects on issue form when the issue is a subtask (#33419).

Patch by Marius BALTEANU.


git-svn-id: http://svn.redmine.org/redmine/trunk@20701 e93f8b46-1217-0410-a6f0-8f06a7374b81
tags/4.2.0
Go MAEDA 3 years ago
parent
commit
3f3514d8b1

+ 10
- 0
app/helpers/issues_helper.rb View File

@@ -696,4 +696,14 @@ module IssuesHelper
user_default_tab
end
end

def projects_for_select(issue)
if issue.parent_issue_id.present?
issue.allowed_target_projects_for_subtask(User.current)
elsif issue.new_record? && !issue.copy?
issue.allowed_target_projects(User.current, 'descendants')
else
issue.allowed_target_projects(User.current)
end
end
end

+ 39
- 13
app/models/issue.rb View File

@@ -1596,29 +1596,38 @@ class Issue < ActiveRecord::Base
end
end

# Returns a scope of projects that user can assign the subtask
def allowed_target_projects_for_subtask(user=User.current)
if parent_issue_id.present?
scope = filter_projects_scope(Setting.cross_project_subtasks)
end

self.class.allowed_target_projects(user, project, scope)
end

# Returns a scope of projects that user can assign the issue to
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
def allowed_target_projects(user=User.current, scope=nil)
current_project = new_record? ? nil : project
if scope
scope = filter_projects_scope(scope)
end

self.class.allowed_target_projects(user, current_project)
self.class.allowed_target_projects(user, current_project, scope)
end

# Returns a scope of projects that user can assign issues to
# If current_project is given, it will be included in the scope
def self.allowed_target_projects(user=User.current, current_project=nil)
def self.allowed_target_projects(user=User.current, current_project=nil, scope=nil)
condition = Project.allowed_to_condition(user, :add_issues)
if current_project.is_a?(Project)
if current_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

if scope.nil?
scope = Project
end

scope.where(condition).having_trackers
end

# Returns a scope of trackers that user can assign the issue to
@@ -1988,4 +1997,21 @@ class Issue < ActiveRecord::Base
self.done_ratio ||= 0
end
end

def filter_projects_scope(scope=nil)
case scope
when 'system'
Project
when 'tree'
project.root.self_and_descendants
when 'hierarchy'
project.hierarchy
when 'descendants'
project.self_and_descendants
when ''
Project.where(:id => project.id)
else
Project
end
end
end

+ 2
- 1
app/views/issues/_attributes.html.erb View File

@@ -61,7 +61,8 @@
<div class="splitcontentright">
<% if @issue.safe_attribute? 'parent_issue_id' %>
<p id="parent_issue"><%= f.text_field :parent_issue_id, :size => 10,
:required => @issue.required_attribute?('parent_issue_id') %></p>
:required => @issue.required_attribute?('parent_issue_id'),
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %></p>
<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript(auto_complete_issues_path(:project_id => @issue.project, :scope => Setting.cross_project_subtasks, :status => @issue.closed? ? 'c' : 'o', :issue_id => @issue.id))}')" %>
<% end %>


+ 1
- 1
app/views/issues/_form.html.erb View File

@@ -9,7 +9,7 @@
</p>
<% end %>

<% projects = @issue.allowed_target_projects(User.current, @project) %>
<% projects = projects_for_select(@issue) %>
<% 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>

+ 24
- 0
test/functional/issues_controller_test.rb View File

@@ -3141,6 +3141,30 @@ class IssuesControllerTest < Redmine::ControllerTest
assert_select 'select[name="issue[project_id]"]', 0
end

def test_get_new_should_not_show_invalid_projects_when_issue_is_a_subtask
@request.session[:user_id] = 2
issue = Issue.find(1)
issue.parent_id = 3
issue.save

with_settings :cross_project_subtasks => 'tree' do
get(
:new,
:params => {
:project_id => 1,
:parent_issue_id => 1
}
)
end
assert_response :success
assert_select 'select[name="issue[project_id]"]' do
assert_select 'option', 3

# Onlinestore project should not be included
assert_select 'option[value=?]', '2', 0
end
end

def test_get_new_with_minimal_permissions
Role.find(1).update_attribute :permissions, [:add_issues]
WorkflowTransition.where(:role_id => 1).delete_all

+ 34
- 0
test/unit/issue_test.rb View File

@@ -1708,6 +1708,17 @@ class IssueTest < ActiveSupport::TestCase
assert_not_include project, Issue.allowed_target_projects(User.find(1))
end

def test_allowed_target_projects_for_subtask_should_not_include_invalid_projects
User.current = User.find(1)
issue = Issue.find(1)
issue.parent_id = 3

with_settings :cross_project_subtasks => 'tree' do
# Should include only the project tree
assert_equal [1, 3, 5], issue.allowed_target_projects_for_subtask.ids.sort
end
end

def test_allowed_target_trackers_with_one_role_allowed_on_all_trackers
user = User.generate!
role = Role.generate!
@@ -3343,4 +3354,27 @@ class IssueTest < ActiveSupport::TestCase
assert !child.reopenable?
assert_equal l(:notice_issue_not_reopenable_by_closed_parent_issue), child.transition_warning
end

def test_filter_projects_scope
Issue.send(:public, :filter_projects_scope)
# Project eCookbook
issue = Issue.find(1)

assert_equal Project, issue.filter_projects_scope
assert_equal Project, issue.filter_projects_scope('system')

# Project Onlinestore (id 2) is not part of the tree
assert_equal [1, 3, 4, 5, 6], Issue.find(5).filter_projects_scope('tree').ids.sort

# Project "Private child of eCookbook"
issue2 = Issue.find(9)

# Projects "eCookbook Subproject 1" (id 3) and "eCookbook Subproject 1" (id 4) are not part of hierarchy
assert_equal [1, 5, 6], issue2.filter_projects_scope('hierarchy').ids.sort

# Project "Child of private child" is descendant of "Private child of eCookbook"
assert_equal [5, 6], issue2.filter_projects_scope('descendants').ids.sort

assert_equal [5], issue2.filter_projects_scope('').ids.sort
end
end

Loading…
Cancel
Save