summaryrefslogtreecommitdiff
path: root/app/graphql/resolvers
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/resolvers')
-rw-r--r--app/graphql/resolvers/base_resolver.rb10
-rw-r--r--app/graphql/resolvers/concerns/resolves_snippets.rb57
-rw-r--r--app/graphql/resolvers/echo_resolver.rb4
-rw-r--r--app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb28
-rw-r--r--app/graphql/resolvers/issues_resolver.rb14
-rw-r--r--app/graphql/resolvers/projects/snippets_resolver.rb23
-rw-r--r--app/graphql/resolvers/snippets_resolver.rb45
-rw-r--r--app/graphql/resolvers/todo_resolver.rb50
-rw-r--r--app/graphql/resolvers/users/snippets_resolver.rb21
9 files changed, 201 insertions, 51 deletions
diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb
index 85d6b377934..62dcc41dd9c 100644
--- a/app/graphql/resolvers/base_resolver.rb
+++ b/app/graphql/resolvers/base_resolver.rb
@@ -2,6 +2,8 @@
module Resolvers
class BaseResolver < GraphQL::Schema::Resolver
+ extend ::Gitlab::Utils::Override
+
def self.single
@single ||= Class.new(self) do
def resolve(**args)
@@ -36,5 +38,13 @@ module Resolvers
# complexity difference is minimal in this case.
[args[:iid], args[:iids]].any? ? 0 : 0.01
end
+
+ override :object
+ def object
+ super.tap do |obj|
+ # If the field this resolver is used in is wrapped in a presenter, go back to it's subject
+ break obj.subject if obj.is_a?(Gitlab::View::Presenter::Base)
+ end
+ end
end
end
diff --git a/app/graphql/resolvers/concerns/resolves_snippets.rb b/app/graphql/resolvers/concerns/resolves_snippets.rb
new file mode 100644
index 00000000000..483372bbf63
--- /dev/null
+++ b/app/graphql/resolvers/concerns/resolves_snippets.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module ResolvesSnippets
+ extend ActiveSupport::Concern
+
+ included do
+ type Types::SnippetType, null: false
+
+ argument :ids, [GraphQL::ID_TYPE],
+ required: false,
+ description: 'Array of global snippet ids, e.g., "gid://gitlab/ProjectSnippet/1"'
+
+ argument :visibility, Types::Snippets::VisibilityScopesEnum,
+ required: false,
+ description: 'The visibility of the snippet'
+ end
+
+ def resolve(**args)
+ resolve_snippets(args)
+ end
+
+ private
+
+ def resolve_snippets(args)
+ SnippetsFinder.new(context[:current_user], snippet_finder_params(args)).execute
+ end
+
+ def snippet_finder_params(args)
+ {
+ ids: resolve_ids(args[:ids]),
+ scope: args[:visibility]
+ }.merge(options_by_type(args[:type]))
+ end
+
+ def resolve_ids(ids)
+ Array.wrap(ids).map { |id| resolve_gid(id, :id) }
+ end
+
+ def resolve_gid(gid, argument)
+ return unless gid.present?
+
+ GlobalID.parse(gid)&.model_id.tap do |id|
+ raise Gitlab::Graphql::Errors::ArgumentError, "Invalid global id format for param #{argument}" if id.nil?
+ end
+ end
+
+ def options_by_type(type)
+ case type
+ when 'personal'
+ { only_personal: true }
+ when 'project'
+ { only_project: true }
+ else
+ {}
+ end
+ end
+end
diff --git a/app/graphql/resolvers/echo_resolver.rb b/app/graphql/resolvers/echo_resolver.rb
index 2ce55544254..fe0b1893a23 100644
--- a/app/graphql/resolvers/echo_resolver.rb
+++ b/app/graphql/resolvers/echo_resolver.rb
@@ -2,9 +2,11 @@
module Resolvers
class EchoResolver < BaseResolver
- argument :text, GraphQL::STRING_TYPE, required: true # rubocop:disable Graphql/Descriptions
description 'Testing endpoint to validate the API with'
+ argument :text, GraphQL::STRING_TYPE, required: true,
+ description: 'Text to echo back'
+
def resolve(**args)
username = context[:current_user]&.username
diff --git a/app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb b/app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb
new file mode 100644
index 00000000000..63455ff3acb
--- /dev/null
+++ b/app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module ErrorTracking
+ class SentryDetailedErrorResolver < BaseResolver
+ argument :id, GraphQL::ID_TYPE,
+ required: true,
+ description: 'ID of the Sentry issue'
+
+ def resolve(**args)
+ project = object
+ current_user = context[:current_user]
+ issue_id = GlobalID.parse(args[:id]).model_id
+
+ # Get data from Sentry
+ response = ::ErrorTracking::IssueDetailsService.new(
+ project,
+ current_user,
+ { issue_id: issue_id }
+ ).execute
+ issue = response[:issue]
+ issue.gitlab_project = project if issue
+
+ issue
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/issues_resolver.rb b/app/graphql/resolvers/issues_resolver.rb
index 1fbc61cd950..664e0955535 100644
--- a/app/graphql/resolvers/issues_resolver.rb
+++ b/app/graphql/resolvers/issues_resolver.rb
@@ -4,17 +4,17 @@ module Resolvers
class IssuesResolver < BaseResolver
argument :iid, GraphQL::STRING_TYPE,
required: false,
- description: 'The IID of the issue, e.g., "1"'
+ description: 'IID of the issue. For example, "1"'
argument :iids, [GraphQL::STRING_TYPE],
required: false,
- description: 'The list of IIDs of issues, e.g., [1, 2]'
+ description: 'List of IIDs of issues. For example, [1, 2]'
argument :state, Types::IssuableStateEnum,
required: false,
- description: 'Current state of Issue'
+ description: 'Current state of this issue'
argument :label_name, GraphQL::STRING_TYPE.to_list_type,
required: false,
- description: 'Labels applied to the Issue'
+ description: 'Labels applied to this issue'
argument :created_before, Types::TimeType,
required: false,
description: 'Issues created before this date'
@@ -33,8 +33,9 @@ module Resolvers
argument :closed_after, Types::TimeType,
required: false,
description: 'Issues closed after this date'
- argument :search, GraphQL::STRING_TYPE, # rubocop:disable Graphql/Descriptions
- required: false
+ argument :search, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Search query for finding issues by title or description'
argument :sort, Types::IssueSortEnum,
description: 'Sort issues by this criteria',
required: false,
@@ -53,6 +54,7 @@ module Resolvers
# https://gitlab.com/gitlab-org/gitlab-foss/issues/54520
args[:project_id] = project.id
args[:iids] ||= [args[:iid]].compact
+ args[:attempt_project_search_optimizations] = args[:search].present?
IssuesFinder.new(context[:current_user], args).execute
end
diff --git a/app/graphql/resolvers/projects/snippets_resolver.rb b/app/graphql/resolvers/projects/snippets_resolver.rb
new file mode 100644
index 00000000000..bf9aa45349f
--- /dev/null
+++ b/app/graphql/resolvers/projects/snippets_resolver.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Projects
+ class SnippetsResolver < BaseResolver
+ include ResolvesSnippets
+
+ alias_method :project, :object
+
+ def resolve(**args)
+ return Snippet.none if project.nil?
+
+ super
+ end
+
+ private
+
+ def snippet_finder_params(args)
+ super.merge(project: project)
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/snippets_resolver.rb b/app/graphql/resolvers/snippets_resolver.rb
new file mode 100644
index 00000000000..530a288a25b
--- /dev/null
+++ b/app/graphql/resolvers/snippets_resolver.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class SnippetsResolver < BaseResolver
+ include ResolvesSnippets
+
+ ERROR_MESSAGE = 'Filtering by both an author and a project is not supported'
+
+ alias_method :user, :object
+
+ argument :author_id, GraphQL::ID_TYPE,
+ required: false,
+ description: 'The ID of an author'
+
+ argument :project_id, GraphQL::ID_TYPE,
+ required: false,
+ description: 'The ID of a project'
+
+ argument :type, Types::Snippets::TypeEnum,
+ required: false,
+ description: 'The type of snippet'
+
+ argument :explore,
+ GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: 'Explore personal snippets'
+
+ def resolve(**args)
+ if args[:author_id].present? && args[:project_id].present?
+ raise Gitlab::Graphql::Errors::ArgumentError, ERROR_MESSAGE
+ end
+
+ super
+ end
+
+ private
+
+ def snippet_finder_params(args)
+ super
+ .merge(author: resolve_gid(args[:author_id], :author),
+ project: resolve_gid(args[:project_id], :project),
+ explore: args[:explore])
+ end
+ end
+end
diff --git a/app/graphql/resolvers/todo_resolver.rb b/app/graphql/resolvers/todo_resolver.rb
index 38a4539f34a..cff65321dc0 100644
--- a/app/graphql/resolvers/todo_resolver.rb
+++ b/app/graphql/resolvers/todo_resolver.rb
@@ -38,53 +38,15 @@ module Resolvers
private
- # TODO: Support multiple queries for e.g. state and type on TodosFinder:
- #
- # https://gitlab.com/gitlab-org/gitlab/merge_requests/18487
- # https://gitlab.com/gitlab-org/gitlab/merge_requests/18518
- #
- # As soon as these MR's are merged, we can refactor this to query by
- # multiple contents.
- #
def todo_finder_params(args)
{
- state: first_state(args),
- type: first_type(args),
- group_id: first_group_id(args),
- author_id: first_author_id(args),
- action_id: first_action(args),
- project_id: first_project(args)
+ state: args[:state],
+ type: args[:type],
+ group_id: args[:group_id],
+ author_id: args[:author_id],
+ action_id: args[:action],
+ project_id: args[:project_id]
}
end
-
- def first_project(args)
- first_query_field(args, :project_id)
- end
-
- def first_action(args)
- first_query_field(args, :action)
- end
-
- def first_author_id(args)
- first_query_field(args, :author_id)
- end
-
- def first_group_id(args)
- first_query_field(args, :group_id)
- end
-
- def first_state(args)
- first_query_field(args, :state)
- end
-
- def first_type(args)
- first_query_field(args, :type)
- end
-
- def first_query_field(query, field)
- return unless query.key?(field)
-
- query[field].first if query[field].respond_to?(:first)
- end
end
end
diff --git a/app/graphql/resolvers/users/snippets_resolver.rb b/app/graphql/resolvers/users/snippets_resolver.rb
new file mode 100644
index 00000000000..d757640b5ff
--- /dev/null
+++ b/app/graphql/resolvers/users/snippets_resolver.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Users
+ class SnippetsResolver < BaseResolver
+ include ResolvesSnippets
+
+ alias_method :user, :object
+
+ argument :type, Types::Snippets::TypeEnum,
+ required: false,
+ description: 'The type of snippet'
+
+ private
+
+ def snippet_finder_params(args)
+ super.merge(author: user)
+ end
+ end
+ end
+end