blob: bf68aee2c1f23229525262ab1011f3fde67a1e31 (
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
|
# frozen_string_literal: true
module Boards
class BaseItemsListService < Boards::BaseService
include Gitlab::Utils::StrongMemoize
include ActiveRecord::ConnectionAdapters::Quoting
def execute
items = init_collection
order(items)
end
# rubocop: disable CodeReuse/ActiveRecord
def metadata(required_fields = [:issue_count, :total_issue_weight])
fields = metadata_fields(required_fields)
keys = fields.keys
# TODO: eliminate need for SQL literal fragment
columns = Arel.sql(fields.values_at(*keys).join(', '))
results = item_model.where(id: collection_ids)
results = results.select(columns)
Hash[keys.zip(results.pluck(columns).flatten)]
end
# rubocop: enable CodeReuse/ActiveRecord
private
def collection_ids
@collection_ids ||= init_collection.select(item_model.arel_table[:id])
end
def metadata_fields(required_fields)
required_fields&.include?(:issue_count) ? { size: 'COUNT(*)' } : {}
end
def order(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 init_collection
strong_memoize(:init_collection) 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) || params.key?(:list)
strong_memoize(:list) do
id = params[:id]
list = params[:list]
if list.present?
list
elsif 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
|