diff options
Diffstat (limited to 'app/graphql/resolvers')
-rw-r--r-- | app/graphql/resolvers/base_resolver.rb | 10 | ||||
-rw-r--r-- | app/graphql/resolvers/concerns/resolves_snippets.rb | 57 | ||||
-rw-r--r-- | app/graphql/resolvers/echo_resolver.rb | 4 | ||||
-rw-r--r-- | app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb | 28 | ||||
-rw-r--r-- | app/graphql/resolvers/issues_resolver.rb | 14 | ||||
-rw-r--r-- | app/graphql/resolvers/projects/snippets_resolver.rb | 23 | ||||
-rw-r--r-- | app/graphql/resolvers/snippets_resolver.rb | 45 | ||||
-rw-r--r-- | app/graphql/resolvers/todo_resolver.rb | 50 | ||||
-rw-r--r-- | app/graphql/resolvers/users/snippets_resolver.rb | 21 |
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 |