summaryrefslogtreecommitdiff
path: root/app/controllers/concerns/issuable_collections.rb
blob: 23909bd2d39aafa58f57f3a3831afaae04aa12e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
module IssuableCollections
  extend ActiveSupport::Concern
  include SortingHelper
  include Gitlab::IssuableMetadata

  included do
    helper_method :issues_finder
    helper_method :merge_requests_finder
  end

  private

  def issues_collection
    issues_finder.execute.preload(:project, :author, :assignees, :labels, :milestone, project: :namespace)
  end

  def merge_requests_collection
    merge_requests_finder.execute.preload(
      :source_project,
      :target_project,
      :author,
      :assignee,
      :labels,
      :milestone,
      head_pipeline: :project,
      target_project: :namespace,
      merge_request_diff: :merge_request_diff_commits
    )
  end

  def issues_finder
    @issues_finder ||= issuable_finder_for(IssuesFinder)
  end

  def merge_requests_finder
    @merge_requests_finder ||= issuable_finder_for(MergeRequestsFinder)
  end

  def redirect_out_of_range(relation, total_pages)
    return false if total_pages.zero?

    out_of_range = relation.current_page > total_pages

    if out_of_range
      redirect_to(url_for(params.merge(page: total_pages, only_path: true)))
    end

    out_of_range
  end

  def issues_page_count(relation)
    page_count_for_relation(relation, issues_finder.row_count)
  end

  def merge_requests_page_count(relation)
    page_count_for_relation(relation, merge_requests_finder.row_count)
  end

  def page_count_for_relation(relation, row_count)
    limit = relation.limit_value.to_f

    return 1 if limit.zero?

    (row_count.to_f / limit).ceil
  end

  def issuable_finder_for(finder_class)
    finder_class.new(current_user, filter_params)
  end

  def filter_params
    set_sort_order_from_cookie
    set_default_state

    # Skip irrelevant Rails routing params
    @filter_params = params.dup.except(:controller, :action, :namespace_id)
    @filter_params[:sort] ||= default_sort_order

    @sort = @filter_params[:sort]

    if @project
      @filter_params[:project_id] = @project.id
    elsif @group
      @filter_params[:group_id] = @group.id
    else
      # TODO: this filter ignore issues/mr created in public or
      # internal repos where you are not a member. Enable this filter
      # or improve current implementation to filter only issues you
      # created or assigned or mentioned
      # @filter_params[:authorized_only] = true
    end

    @filter_params
  end

  def set_default_state
    params[:state] = 'opened' if params[:state].blank?
  end

  def set_sort_order_from_cookie
    key = 'issuable_sort'

    cookies[key] = params[:sort] if params[:sort].present?

    # id_desc and id_asc are old values for these two.
    cookies[key] = sort_value_recently_created if cookies[key] == 'id_desc'
    cookies[key] = sort_value_oldest_created if cookies[key] == 'id_asc'

    params[:sort] = cookies[key]
  end

  def default_sort_order
    case params[:state]
    when 'opened', 'all' then sort_value_recently_created
    when 'merged', 'closed' then sort_value_recently_updated
    else sort_value_recently_created
    end
  end
end