129 lines
3.1 KiB
Ruby
129 lines
3.1 KiB
Ruby
|
# 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
|
||
|
|
||
|
private
|
||
|
|
||
|
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
|