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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
# frozen_string_literal: true
module IssuableCollections
extend ActiveSupport::Concern
include PaginatedCollection
include SearchRateLimitable
include SortingHelper
include SortingPreference
include Gitlab::Utils::StrongMemoize
included do
helper_method :finder
end
private
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def set_issuables_index
@issuables = issuables_collection
set_pagination
nil if redirect_out_of_range(@issuables, @total_pages)
end
def set_pagination
row_count = request.format.atom? ? -1 : finder.row_count
@issuables = @issuables.page(params[:page])
@issuables = per_page_for_relative_position if params[:sort] == 'relative_position'
@issuables = @issuables.without_count if row_count == -1
@issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @issuables).data
@total_pages = page_count_for_relation(@issuables, row_count)
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
# rubocop: disable CodeReuse/ActiveRecord
def issuables_collection
finder.execute.preload(preload_for_collection)
end
# rubocop: enable CodeReuse/ActiveRecord
def page_count_for_relation(relation, row_count)
limit = relation.limit_value.to_f
return 1 if limit == 0
return (params[:page] || 1).to_i + 1 if row_count == -1
(row_count.to_f / limit).ceil
end
# manual / relative_position sorting allows for 100 items on the page
def per_page_for_relative_position
@issuables.per(100) # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
def issuable_finder_for(finder_class)
finder_class.new(current_user, finder_options)
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def finder_options
params[:state] = default_state if params[:state].blank?
options = {
scope: params[:scope],
state: params[:state],
confidential: Gitlab::Utils.to_boolean(params[:confidential]),
sort: set_sort_order
}
# Used by view to highlight active option
@sort = options[:sort]
# When a user looks for an exact iid, we do not filter by search but only by iid
if params[:search] =~ /^#(?<iid>\d+)\z/
options[:iids] = Regexp.last_match[:iid]
params[:search] = nil
end
if @project
options[:project_id] = @project.id
options[:attempt_project_search_optimizations] = true
elsif @group
options[:group_id] = @group.id
options[:include_subgroups] = true
options[:attempt_group_search_optimizations] = true
end
params.permit(finder_type.valid_params).merge(options)
end
strong_memoize_attr :finder_options
# rubocop:enable Gitlab/ModuleWithInstanceVariables
def default_state
'opened'
end
def legacy_sort_cookie_name
'issuable_sort'
end
def default_sort_order
case params[:state]
when 'opened', 'all' then sort_value_created_date
when 'merged', 'closed' then sort_value_recently_updated
else sort_value_created_date
end
end
def finder
@finder ||= issuable_finder_for(finder_type)
end
def collection_type
@collection_type ||= if finder_type <= IssuesFinder
'Issue'
elsif finder_type <= MergeRequestsFinder
'MergeRequest'
end
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def preload_for_collection
common_attributes = [:author, :assignees, :labels, :milestone]
@preload_for_collection ||= case collection_type
when 'Issue'
common_attributes + [
::Gitlab::Issues::TypeAssociationGetter.call,
:project, { project: :namespace }
]
when 'MergeRequest'
common_attributes + [
:target_project, :latest_merge_request_diff, :approvals, :approved_by_users, :reviewers,
{ source_project: :route, head_pipeline: :project, target_project: :namespace }
]
end
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
end
IssuableCollections.prepend_mod_with('IssuableCollections')
|