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 ...@@ -45,6 +45,9 @@ module Boards
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def filter(issues) 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 = without_board_labels(issues) unless list&.movable? || list&.closed?
issues = with_list_label(issues) if list&.label? issues = with_list_label(issues) if list&.label?
issues issues
......
...@@ -30,7 +30,6 @@ class EpicsFinder < IssuableFinder ...@@ -30,7 +30,6 @@ class EpicsFinder < IssuableFinder
def self.scalar_params def self.scalar_params
@scalar_params ||= %i[ @scalar_params ||= %i[
board
parent_id parent_id
author_id author_id
author_username author_username
...@@ -44,7 +43,7 @@ class EpicsFinder < IssuableFinder ...@@ -44,7 +43,7 @@ class EpicsFinder < IssuableFinder
end end
def self.array_params def self.array_params
@array_params ||= { label_name: [] } @array_params ||= { issues: [], label_name: [] }
end end
def self.valid_iid_query?(query) def self.valid_iid_query?(query)
...@@ -109,7 +108,7 @@ class EpicsFinder < IssuableFinder ...@@ -109,7 +108,7 @@ class EpicsFinder < IssuableFinder
end end
def filter_items(items) def filter_items(items)
items = in_board(items) items = in_issues(items)
items = by_created_at(items) items = by_created_at(items)
items = by_updated_at(items) items = by_updated_at(items)
items = by_author(items) items = by_author(items)
...@@ -156,14 +155,13 @@ class EpicsFinder < IssuableFinder ...@@ -156,14 +155,13 @@ class EpicsFinder < IssuableFinder
items.iid_starts_with(query) items.iid_starts_with(query)
end end
def in_board(items) def in_issues(items)
board = params[:board] issues = params[:issues]
return items unless board.present? # 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 }) items.in_issues(issues.select(: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"))
end end
def related_groups def related_groups
......
...@@ -21,7 +21,7 @@ module EE ...@@ -21,7 +21,7 @@ module EE
field :weight, type: GraphQL::INT_TYPE, null: true, field :weight, type: GraphQL::INT_TYPE, null: true,
description: 'Weight of the board.' 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.', description: 'Epics associated with board issues.',
resolver: ::Resolvers::BoardGroupings::EpicsResolver resolver: ::Resolvers::BoardGroupings::EpicsResolver
end end
......
...@@ -4,20 +4,32 @@ module Resolvers ...@@ -4,20 +4,32 @@ module Resolvers
module BoardGroupings module BoardGroupings
class EpicsResolver < BaseResolver class EpicsResolver < BaseResolver
type Types::EpicType, null: true type Types::EpicType, null: true
def resolve(**args) 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 Epic.none unless board.present?
return [] unless epic_feature_enabled? 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 end
private private
attr_reader :resolver_object attr_accessor :board
def group
board.project_board? ? board.project.group : board.group
end
def epic_feature_enabled? def epic_feature_enabled?
group.feature_available?(:epics) 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