group_children_finder.rb 2.36 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class GroupChildrenFinder
  include Gitlab::Allowable

  attr_reader :current_user, :parent_group, :params

  def initialize(current_user = nil, parent_group:, params: {})
    @current_user = current_user
    @parent_group = parent_group
    @params = params
  end

  def execute
    Kaminari.paginate_array(children)
  end

  # This allows us to fetch only the count without loading the objects. Unless
  # the objects were already loaded.
  def total_count
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
    @total_count ||= subgroup_count + project_count
  end

  def subgroup_count
    @subgroup_count ||= if defined?(@children)
                          children.count { |child| child.is_a?(Group) }
                        else
                          subgroups.count
                        end
  end

  def project_count
    @project_count ||= if defined?(@children)
                         children.count { |child| child.is_a?(Project) }
                       else
                         projects.count
                       end
36 37 38 39 40
  end

  private

  def children
41
    @children ||= subgroups.with_route.includes(:route, :parent) + projects.with_route.includes(:route, :namespace)
42 43
  end

44 45 46 47 48 49 50 51 52 53 54
  def base_groups
    GroupsFinder.new(current_user,
                     parent: parent_group,
                     all_available: true).execute
  end

  def all_subgroups
    Gitlab::GroupHierarchy.new(Group.where(id: parent_group)).all_groups
  end

  def subgroups_matching_filter
55
    all_subgroups.where.not(id: parent_group).search(params[:filter])
56 57
  end

58
  def subgroups
59 60 61
    return Group.none unless Group.supports_nested_groups?
    return Group.none unless can?(current_user, :read_group, parent_group)

62 63 64 65 66
    groups = if params[:filter]
               subgroups_matching_filter
             else
               base_groups
             end
67
    groups.sort(params[:sort])
68 69
  end

70 71 72 73 74 75 76 77 78 79
  def base_projects
    GroupProjectsFinder.new(group: parent_group, params: params, current_user: current_user).execute
  end

  def projects_matching_filter
    ProjectsFinder.new(current_user: current_user).execute
      .search(params[:filter])
      .where(namespace: all_subgroups)
  end

80 81 82
  def projects
    return Project.none unless can?(current_user, :read_group, parent_group)

83 84 85 86 87
    projects = if params[:filter]
                 projects_matching_filter
               else
                 base_projects
               end
88
    projects.sort(params[:sort])
89 90
  end
end