Merged nested projects branch. Removes limit on subproject nesting (#594).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2304 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -20,4 +20,12 @@ module AdminHelper
|
||||
options_for_select([[l(:label_all), ''],
|
||||
[l(:status_active), 1]], selected)
|
||||
end
|
||||
|
||||
def css_project_classes(project)
|
||||
s = 'project'
|
||||
s << ' root' if project.root?
|
||||
s << ' child' if project.child?
|
||||
s << (project.leaf? ? ' leaf' : ' parent')
|
||||
s
|
||||
end
|
||||
end
|
||||
|
||||
@@ -156,6 +156,45 @@ module ApplicationHelper
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
# Renders the project quick-jump box
|
||||
def render_project_jump_box
|
||||
# Retrieve them now to avoid a COUNT query
|
||||
projects = User.current.projects.all
|
||||
if projects.any?
|
||||
s = '<select onchange="if (this.value != \'\') { window.location = this.value; }">' +
|
||||
"<option selected='selected'>#{ l(:label_jump_to_a_project) }</option>" +
|
||||
'<option disabled="disabled">---</option>'
|
||||
s << project_tree_options_for_select(projects) do |p|
|
||||
{ :value => url_for(:controller => 'projects', :action => 'show', :id => p) }
|
||||
end
|
||||
s << '</select>'
|
||||
s
|
||||
end
|
||||
end
|
||||
|
||||
def project_tree_options_for_select(projects, options = {})
|
||||
s = ''
|
||||
project_tree(projects) do |project, level|
|
||||
name_prefix = (level > 0 ? (' ' * 2 * level + '» ') : '')
|
||||
tag_options = {:value => project.id, :selected => ((project == options[:selected]) ? 'selected' : nil)}
|
||||
tag_options.merge!(yield(project)) if block_given?
|
||||
s << content_tag('option', name_prefix + h(project), tag_options)
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
# Yields the given block for each project with its level in the tree
|
||||
def project_tree(projects, &block)
|
||||
ancestors = []
|
||||
projects.sort_by(&:lft).each do |project|
|
||||
while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
|
||||
ancestors.pop
|
||||
end
|
||||
yield project, ancestors.size
|
||||
ancestors << project
|
||||
end
|
||||
end
|
||||
|
||||
# Truncates and returns the string as a single line
|
||||
def truncate_single_line(string, *args)
|
||||
|
||||
@@ -33,4 +33,39 @@ module ProjectsHelper
|
||||
]
|
||||
tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
|
||||
end
|
||||
|
||||
def parent_project_select_tag(project)
|
||||
options = '<option></option>' + project_tree_options_for_select(project.possible_parents, :selected => project.parent)
|
||||
content_tag('select', options, :name => 'project[parent_id]')
|
||||
end
|
||||
|
||||
# Renders a tree of projects as a nested set of unordered lists
|
||||
# The given collection may be a subset of the whole project tree
|
||||
# (eg. some intermediate nodes are private and can not be seen)
|
||||
def render_project_hierarchy(projects)
|
||||
s = ''
|
||||
if projects.any?
|
||||
ancestors = []
|
||||
projects.each do |project|
|
||||
if (ancestors.empty? || project.is_descendant_of?(ancestors.last))
|
||||
s << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>\n"
|
||||
else
|
||||
ancestors.pop
|
||||
s << "</li>"
|
||||
while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
|
||||
ancestors.pop
|
||||
s << "</ul></li>\n"
|
||||
end
|
||||
end
|
||||
classes = (ancestors.empty? ? 'root' : 'child')
|
||||
s << "<li class='#{classes}'><div class='#{classes}'>" +
|
||||
link_to(h(project), {:controller => 'projects', :action => 'show', :id => project}, :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}")
|
||||
s << "<div class='wiki description'>#{textilizable(project.short_description, :project => project)}</div>" unless project.description.blank?
|
||||
s << "</div>\n"
|
||||
ancestors << project
|
||||
end
|
||||
s << ("</li></ul>\n" * ancestors.size)
|
||||
end
|
||||
s
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,7 +44,7 @@ module SearchHelper
|
||||
def project_select_tag
|
||||
options = [[l(:label_project_all), 'all']]
|
||||
options << [l(:label_my_projects), 'my_projects'] unless User.current.memberships.empty?
|
||||
options << [l(:label_and_its_subprojects, @project.name), 'subprojects'] unless @project.nil? || @project.active_children.empty?
|
||||
options << [l(:label_and_its_subprojects, @project.name), 'subprojects'] unless @project.nil? || @project.descendants.active.empty?
|
||||
options << [@project.name, ''] unless @project.nil?
|
||||
select_tag('scope', options_for_select(options, params[:scope].to_s)) if options.size > 1
|
||||
end
|
||||
|
||||
@@ -25,15 +25,10 @@ module UsersHelper
|
||||
end
|
||||
|
||||
# Options for the new membership projects combo-box
|
||||
def projects_options_for_select(projects)
|
||||
def options_for_membership_project_select(user, projects)
|
||||
options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
|
||||
projects_by_root = projects.group_by(&:root)
|
||||
projects_by_root.keys.sort.each do |root|
|
||||
options << content_tag('option', h(root.name), :value => root.id, :disabled => (!projects.include?(root)))
|
||||
projects_by_root[root].sort.each do |project|
|
||||
next if project == root
|
||||
options << content_tag('option', '» ' + h(project.name), :value => project.id)
|
||||
end
|
||||
options << project_tree_options_for_select(projects) do |p|
|
||||
{:disabled => (user.projects.include?(p))}
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user