Commit f8f2c905 authored by Alexandru Croitor's avatar Alexandru Croitor Committed by Jan Provaznik

Change EpicsFinder to get epics related to a given issue list

* Lookup epics that are related to a given issue list.
* Update Board/Issues/ListService to fetch all issues related to a board
parent b2e31786
......@@ -45,6 +45,9 @@ module Boards
# rubocop: enable CodeReuse/ActiveRecord
def filter(issues)
# sometimes we want to just fetch all issues that a board can display
return issues if params[:all]
issues = without_board_labels(issues) unless list&.movable? || list&.closed?
issues = with_list_label(issues) if list&.label?
issues
......
......@@ -30,7 +30,6 @@ class EpicsFinder < IssuableFinder
def self.scalar_params
@scalar_params ||= %i[
board
parent_id
author_id
author_username
......@@ -44,7 +43,7 @@ class EpicsFinder < IssuableFinder
end
def self.array_params
@array_params ||= { label_name: [] }
@array_params ||= { issues: [], label_name: [] }
end
def self.valid_iid_query?(query)
......@@ -109,7 +108,7 @@ class EpicsFinder < IssuableFinder
end
def filter_items(items)
items = in_board(items)
items = in_issues(items)
items = by_created_at(items)
items = by_updated_at(items)
items = by_author(items)
......@@ -156,14 +155,13 @@ class EpicsFinder < IssuableFinder
items.iid_starts_with(query)
end
def in_board(items)
board = params[:board]
return items unless board.present?
def in_issues(items)
issues = params[:issues]
# ActiveRecord::Relation.empty? would run a SELECT 1 AS one FROM "issues" LIMIT $1
# ActiveRecord::Relation.blank? or ActiveRecord::Relation.present? would run SELECT "issues".* FROM "issues"
return items if issues.nil? || issues.empty?
list_service = Boards::Issues::ListService.new(board.resource_parent, current_user, { board_id: board.id })
issues = list_service.execute.except(:order).pluck_primary_key
epics_in_boards = EpicIssue.where(issue: issues)
items.id_in(epics_in_boards.select("epic_id as id"))
items.in_issues(issues.select(:id))
end
def related_groups
......
......@@ -21,7 +21,7 @@ module EE
field :weight, type: GraphQL::INT_TYPE, null: true,
description: 'Weight of the board.'
field :epic_groups, ::Types::EpicType.connection_type, null: true,
field :epics, ::Types::EpicType.connection_type, null: true,
description: 'Epics associated with board issues.',
resolver: ::Resolvers::BoardGroupings::EpicsResolver
end
......
......@@ -4,20 +4,32 @@ module Resolvers
module BoardGroupings
class EpicsResolver < BaseResolver
type Types::EpicType, null: true
type Types::EpicType, null: true
def resolve(**args)
board = object.respond_to?(:sync) ? object.sync : object
@board = object.respond_to?(:sync) ? object.sync : object
return [] unless resolver_object.present?
return [] unless epic_feature_enabled?
return Epic.none unless board.present?
return Epic.none unless epic_feature_enabled?
EpicsFinder.new(context[:current_user], args.merge(board: board)).execute
list_service = Boards::Issues::ListService.new(board.resource_parent, current_user, { all: true, board_id: board.id })
# get bare issues by removing ordering, grouping and extra selected fields to get just the issues filtered by board scope.
issues = list_service.execute.except(:order).except(:group).except(:select).distinct
# Depending on which level the board is, user can see epics related to issues from various groups in the hierarchy,
# so we need to look-up epics from all groups in the hierarchy.
board_params = { group_id: group.id, include_ancestor_groups: true, include_descendant_groups: true, issues: issues }
EpicsFinder.new(context[:current_user], args.merge(board_params)).execute.limit(10)
end
private
attr_reader :resolver_object
attr_accessor :board
def group
board.project_board? ? board.project.group : board.group
end
def epic_feature_enabled?
group.feature_available?(:epics)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment