blob: ab9d11abe98ca8648a31e21aa36369ba8996b8f9 (
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
# frozen_string_literal: true
module Boards
module Issues
class ListService < Boards::BaseService
include Gitlab::Utils::StrongMemoize
def self.valid_params
IssuesFinder.valid_params
end
def execute
return fetch_issues.order_closed_date_desc if list&.closed?
fetch_issues.order_by_position_and_priority(with_cte: params[:search].present?)
end
# rubocop: disable CodeReuse/ActiveRecord
def metadata
issues = Issue.arel_table
keys = metadata_fields.keys
# TODO: eliminate need for SQL literal fragment
columns = Arel.sql(metadata_fields.values_at(*keys).join(', '))
results = Issue.where(id: fetch_issues.select(issues[:id])).pluck(columns)
Hash[keys.zip(results.flatten)]
end
# rubocop: enable CodeReuse/ActiveRecord
private
def metadata_fields
{ size: 'COUNT(*)' }
end
# We memoize the query here since the finder methods we use are quite complex. This does not memoize the result of the query.
# rubocop: disable CodeReuse/ActiveRecord
def fetch_issues
strong_memoize(:fetch_issues) do
issues = IssuesFinder.new(current_user, filter_params).execute
filter(issues).reorder(nil)
end
end
# rubocop: enable CodeReuse/ActiveRecord
def filter(issues)
# when grouping board issues by epics (used in board swimlanes)
# we need to get all issues in the board
# TODO: ignore hidden columns -
# https://gitlab.com/gitlab-org/gitlab/-/issues/233870
return issues if params[:all_lists]
issues = without_board_labels(issues) unless list&.movable? || list&.closed?
issues = with_list_label(issues) if list&.label?
issues
end
def board
@board ||= parent.boards.find(params[:board_id])
end
def list
return unless params.key?(:id)
strong_memoize(:list) do
id = params[:id]
if board.lists.loaded?
board.lists.find { |l| l.id == id }
else
board.lists.find(id)
end
end
end
def filter_params
set_parent
set_state
set_scope
set_non_archived
set_attempt_search_optimizations
set_issue_types
params
end
def set_parent
if parent.is_a?(Group)
params[:group_id] = parent.id
else
params[:project_id] = parent.id
end
end
def set_state
return if params[:all_lists]
params[:state] = list && list.closed? ? 'closed' : 'opened'
end
def set_scope
params[:include_subgroups] = board.group_board?
end
def set_non_archived
params[:non_archived] = parent.is_a?(Group)
end
def set_attempt_search_optimizations
return unless params[:search].present?
if board.group_board?
params[:attempt_group_search_optimizations] = true
else
params[:attempt_project_search_optimizations] = true
end
end
def set_issue_types
params[:issue_types] = Issue::TYPES_FOR_LIST
end
# rubocop: disable CodeReuse/ActiveRecord
def board_label_ids
@board_label_ids ||= board.lists.movable.pluck(:label_id)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def without_board_labels(issues)
return issues unless board_label_ids.any?
issues.where.not('EXISTS (?)', issues_label_links.limit(1))
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def issues_label_links
LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id").where(label_id: board_label_ids)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def with_list_label(issues)
issues.where('EXISTS (?)', LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id")
.where("label_links.label_id = ?", list.label_id).limit(1))
end
# rubocop: enable CodeReuse/ActiveRecord
def board_group
board.group_board? ? parent : parent.group
end
end
end
end
Boards::Issues::ListService.prepend_if_ee('EE::Boards::Issues::ListService')
|