BigW Consortium Gitlab

issuable_finder.rb 4.45 KB
Newer Older
1
# IssuableFinder
2 3 4 5 6 7 8 9 10 11 12
#
# 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
13
#     milestone_title: string
14 15 16 17 18
#     assignee_id: integer
#     search: string
#     label_name: string
#     sort: string
#
19 20 21
require_relative 'projects_finder'

class IssuableFinder
22
  NONE = '0'
23

24
  attr_accessor :current_user, :params
25

26
  def initialize(current_user, params)
27 28
    @current_user = current_user
    @params = params
29
  end
30

31
  def execute
32 33
    items = init_collection
    items = by_scope(items)
34 35
    items = by_state(items)
    items = by_group(items)
36
    items = by_project(items)
37 38 39
    items = by_search(items)
    items = by_milestone(items)
    items = by_assignee(items)
40
    items = by_author(items)
41 42 43 44
    items = by_label(items)
    items = sort(items)
  end

45 46 47
  def group
    return @group if defined?(@group)

48
    @group =
49 50
      if params[:group_id].present?
        Group.find(params[:group_id])
51
      else
52 53 54 55 56 57 58
        nil
      end
  end

  def project
    return @project if defined?(@project)

59
    @project =
60 61
      if params[:project_id].present?
        Project.find(params[:project_id])
62
      else
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
        nil
      end
  end

  def search
    params[:search].presence
  end

  def milestones?
    params[:milestone_title].present?
  end

  def milestones
    return @milestones if defined?(@milestones)

    @milestones =
79
      if milestones? && params[:milestone_title] != Milestone::None.title
80 81 82 83 84 85 86 87 88 89 90 91 92
        Milestone.where(title: params[:milestone_title])
      else
        nil
      end
  end

  def assignee?
    params[:assignee_id].present?
  end

  def assignee
    return @assignee if defined?(@assignee)

93
    @assignee =
94 95 96 97 98 99 100 101 102 103 104 105 106 107
      if assignee? && params[:assignee_id] != NONE
        User.find(params[:assignee_id])
      else
        nil
      end
  end

  def author?
    params[:author_id].present?
  end

  def author
    return @author if defined?(@author)

108
    @author =
109 110 111 112 113 114 115
      if author? && params[:author_id] != NONE
        User.find(params[:author_id])
      else
        nil
      end
  end

116 117
  private

118
  def init_collection
119 120
    table_name = klass.table_name

121
    if project
122
      if Ability.abilities.allowed?(current_user, :read_project, project)
123 124 125 126
        project.send(table_name)
      else
        []
      end
127
    elsif current_user && params[:authorized_only].presence && !current_user_related?
128
      klass.of_projects(current_user.authorized_projects).references(:project)
129
    else
130
      klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project)
131 132 133 134
    end
  end

  def by_scope(items)
135 136
    case params[:scope]
    when 'created-by-me', 'authored' then
137
      items.where(author_id: current_user.id)
138
    when 'all' then
139
      items
140
    when 'assigned-to-me' then
141
      items.where(assignee_id: current_user.id)
142 143 144 145 146 147 148 149 150
    else
      raise 'You must specify default scope'
    end
  end

  def by_state(items)
    case params[:state]
    when 'closed'
      items.closed
151 152
    when 'merged'
      items.respond_to?(:merged) ? items.merged : items.closed
153 154 155 156 157 158 159 160 161 162
    when 'all'
      items
    when 'opened'
      items.opened
    else
      raise 'You must specify default state'
    end
  end

  def by_group(items)
163
    items = items.of_group(group) if group
164 165 166 167 168

    items
  end

  def by_project(items)
169
    items = items.of_projects(project.id) if project
170 171 172 173 174

    items
  end

  def by_search(items)
175
    items = items.search(search) if search
176 177 178 179 180 181 182 183 184

    items
  end

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

  def by_milestone(items)
185
    if milestones?
186
      items = items.where(milestone_id: milestones.try(:pluck, :id))
187 188 189 190 191 192
    end

    items
  end

  def by_assignee(items)
193 194
    if assignee?
      items = items.where(assignee_id: assignee.try(:id))
195 196 197 198 199
    end

    items
  end

200
  def by_author(items)
201 202
    if author?
      items = items.where(author_id: author.try(:id))
203 204 205 206 207
    end

    items
  end

208 209
  def by_label(items)
    if params[:label_name].present?
210 211 212 213 214 215 216
      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)
217 218 219 220
    end

    items
  end
221

222 223 224
  def current_user_related?
    params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
  end
225
end