blob: cbc7a332cbe5366de28b3ffaad3808567d781f59 (
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
|
# frozen_string_literal: true
module Boards
class BaseItemsListService < Boards::BaseService
include Gitlab::Utils::StrongMemoize
include ActiveRecord::ConnectionAdapters::Quoting
def execute
return items.order_closed_date_desc if list&.closed?
ordered_items
end
# rubocop: disable CodeReuse/ActiveRecord
def metadata
issuables = item_model.arel_table
keys = metadata_fields.keys
# TODO: eliminate need for SQL literal fragment
columns = Arel.sql(metadata_fields.values_at(*keys).join(', '))
results = item_model.where(id: items.select(issuables[:id])).pluck(columns)
Hash[keys.zip(results.flatten)]
end
# rubocop: enable CodeReuse/ActiveRecord
private
def metadata_fields
{ size: 'COUNT(*)' }
end
def ordered_items
raise NotImplementedError
end
def finder
raise NotImplementedError
end
def board
raise NotImplementedError
end
def item_model
raise NotImplementedError
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 items
strong_memoize(:items) do
filter(finder.execute).reorder(nil)
end
end
# rubocop: enable CodeReuse/ActiveRecord
def filter(items)
# 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 items if params[:all_lists]
items = without_board_labels(items) unless list&.movable? || list&.closed?
items = with_list_label(items) if list&.label?
items
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_attempt_search_optimizations
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_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
# 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(items)
return items unless board_label_ids.any?
items.where.not('EXISTS (?)', label_links(board_label_ids).limit(1))
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def label_links(label_ids)
LabelLink
.where(label_links: { target_type: item_model })
.where(item_model.arel_table[:id].eq(LabelLink.arel_table[:target_id]).to_sql)
.where(label_id: label_ids)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def with_list_label(items)
items.where('EXISTS (?)', label_links(list.label_id).limit(1))
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
|