BigW Consortium Gitlab

issuable_finder.rb 3.33 KB
Newer Older
1
# IssuableFinder
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#
# Used to filter Issues and MergeRequests collections by set of params
#
# Arguments:
#   klass - actual class like Issue or MergeRequest
#   current_user - which user use
#   params:
#     scope: 'created-by-me' or 'assigned-to-me' or 'all'
#     state: 'open' or 'closed' or 'all'
#     group_id: integer
#     project_id: integer
#     milestone_id: integer
#     assignee_id: integer
#     search: string
#     label_name: string
#     sort: string
#
19 20 21
require_relative 'projects_finder'

class IssuableFinder
22
  attr_accessor :current_user, :params
23

24
  def execute(current_user, params)
25 26 27
    @current_user = current_user
    @params = params

28 29
    items = init_collection
    items = by_scope(items)
30 31
    items = by_state(items)
    items = by_group(items)
32
    items = by_project(items)
33 34 35 36 37 38 39 40 41
    items = by_search(items)
    items = by_milestone(items)
    items = by_assignee(items)
    items = by_label(items)
    items = sort(items)
  end

  private

42
  def init_collection
43 44
    table_name = klass.table_name

45
    if project
46
      if project.public? || (current_user && current_user.can?(:read_project, project))
47 48 49 50
        project.send(table_name)
      else
        []
      end
51
    elsif current_user && params[:authorized_only].presence && !current_user_related?
52
      klass.of_projects(current_user.authorized_projects).references(:project)
53
    else
54
      klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project)
55 56 57 58
    end
  end

  def by_scope(items)
59 60
    case params[:scope]
    when 'created-by-me', 'authored' then
61
      items.where(author_id: current_user.id)
62
    when 'all' then
63
      items
64
    when 'assigned-to-me' then
65
      items.where(assignee_id: current_user.id)
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
    else
      raise 'You must specify default scope'
    end
  end

  def by_state(items)
    case params[:state]
    when 'closed'
      items.closed
    when 'all'
      items
    when 'opened'
      items.opened
    else
      raise 'You must specify default state'
    end
  end

  def by_group(items)
    if params[:group_id].present?
      items = items.of_group(Group.find(params[:group_id]))
    end

    items
  end

  def by_project(items)
    if params[:project_id].present?
      items = items.of_projects(params[:project_id])
    end

    items
  end

  def by_search(items)
    if params[:search].present?
      items = items.search(params[:search])
    end

    items
  end

  def sort(items)
    items.sort(params[:sort])
  end

  def by_milestone(items)
    if params[:milestone_id].present?
      items = items.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
    end

    items
  end

  def by_assignee(items)
    if params[:assignee_id].present?
      items = items.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
    end

    items
  end

  def by_label(items)
    if params[:label_name].present?
130 131 132 133 134 135 136
      label_names = params[:label_name].split(",")

      item_ids = LabelLink.joins(:label).
        where('labels.title in (?)', label_names).
        where(target_type: klass.name).pluck(:target_id)

      items = items.where(id: item_ids)
137 138 139 140
    end

    items
  end
141 142 143 144

  def project
    Project.where(id: params[:project_id]).first if params[:project_id].present?
  end
145 146 147 148

  def current_user_related?
    params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
  end
149
end