Commit c60e793b authored by Brett Walker's avatar Brett Walker Committed by Bob Van Landuyt

Removing resolve procs from GraphQL Types

so that we can start using the new GraphQL
interpreter (https://graphql-ruby.org/queries/interpreter.html#compatibility)

# Conflicts:
#	ee/app/graphql/ee/types/issue_type.rb

# Conflicts:
#	app/graphql/types/ci/job_type.rb
#	app/graphql/types/merge_request_type.rb
#	ee/app/graphql/ee/types/project_type.rb
parent 3c8a630c
...@@ -38,10 +38,11 @@ module Types ...@@ -38,10 +38,11 @@ module Types
field :user, field :user,
Types::UserType, Types::UserType,
null: false, null: false,
description: 'The user who awarded the emoji', description: 'The user who awarded the emoji'
resolve: -> (award_emoji, _args, _context) {
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, award_emoji.user_id).find def user
} Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
end
end end
end end
end end
...@@ -19,8 +19,7 @@ module Types ...@@ -19,8 +19,7 @@ module Types
field :label, Types::LabelType, null: true, field :label, Types::LabelType, null: true,
description: 'Label of the list' description: 'Label of the list'
field :collapsed, GraphQL::BOOLEAN_TYPE, null: true, field :collapsed, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if list is collapsed for this user', description: 'Indicates if list is collapsed for this user'
resolve: -> (list, _args, ctx) { list.collapsed?(ctx[:current_user]) }
field :issues_count, GraphQL::INT_TYPE, null: true, field :issues_count, GraphQL::INT_TYPE, null: true,
description: 'Count of issues in the list' description: 'Count of issues in the list'
...@@ -32,6 +31,10 @@ module Types ...@@ -32,6 +31,10 @@ module Types
metadata[:size] metadata[:size]
end end
def collapsed
object.collapsed?(context[:current_user])
end
def metadata def metadata
strong_memoize(:metadata) do strong_memoize(:metadata) do
list = self.object list = self.object
......
...@@ -25,20 +25,21 @@ module Types ...@@ -25,20 +25,21 @@ module Types
description: 'Tooltip associated with the status', description: 'Tooltip associated with the status',
method: :status_tooltip method: :status_tooltip
field :action, Types::Ci::StatusActionType, null: true, field :action, Types::Ci::StatusActionType, null: true,
description: 'Action information for the status. This includes method, button title, icon, path, and title', description: 'Action information for the status. This includes method, button title, icon, path, and title'
resolve: -> (obj, _args, _ctx) {
if obj.has_action? def action
if object.has_action?
{ {
button_title: obj.action_button_title, button_title: object.action_button_title,
icon: obj.action_icon, icon: object.action_icon,
method: obj.action_method, method: object.action_method,
path: obj.action_path, path: object.action_path,
title: obj.action_title title: object.action_title
} }
else else
nil nil
end end
} end
end end
# rubocop: enable Graphql/AuthorizeTypes # rubocop: enable Graphql/AuthorizeTypes
end end
......
...@@ -13,8 +13,11 @@ module Types ...@@ -13,8 +13,11 @@ module Types
field :jobs, Ci::JobType.connection_type, null: true, field :jobs, Ci::JobType.connection_type, null: true,
description: 'Jobs in group' description: 'Jobs in group'
field :detailed_status, Types::Ci::DetailedStatusType, null: true, field :detailed_status, Types::Ci::DetailedStatusType, null: true,
description: 'Detailed status of the group', description: 'Detailed status of the group'
resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
def detailed_status
object.detailed_status(context[:current_user])
end
end end
end end
end end
...@@ -7,25 +7,26 @@ module Types ...@@ -7,25 +7,26 @@ module Types
graphql_name 'CiJob' graphql_name 'CiJob'
field :pipeline, Types::Ci::PipelineType, null: false, field :pipeline, Types::Ci::PipelineType, null: false,
description: 'Pipeline the job belongs to', description: 'Pipeline the job belongs to'
resolve: -> (build, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, build.pipeline_id).find }
field :name, GraphQL::STRING_TYPE, null: true, field :name, GraphQL::STRING_TYPE, null: true,
description: 'Name of the job' description: 'Name of the job'
field :needs, JobType.connection_type, null: true, field :needs, JobType.connection_type, null: true,
description: 'Builds that must complete before the jobs run' description: 'Builds that must complete before the jobs run'
field :detailed_status, Types::Ci::DetailedStatusType, null: true, field :detailed_status, Types::Ci::DetailedStatusType, null: true,
description: 'Detailed status of the job', description: 'Detailed status of the job'
resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
field :scheduled_at, Types::TimeType, null: true, field :scheduled_at, Types::TimeType, null: true,
description: 'Schedule for the build' description: 'Schedule for the build'
field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true, field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true,
description: 'Artifacts generated by the job' description: 'Artifacts generated by the job'
def pipeline
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, object.pipeline_id).find
end
def detailed_status
object.detailed_status(context[:current_user])
end
def artifacts def artifacts
if object.is_a?(::Ci::Build) if object.is_a?(::Ci::Build)
object.job_artifacts object.job_artifacts
......
...@@ -27,8 +27,7 @@ module Types ...@@ -27,8 +27,7 @@ module Types
description: "Status of the pipeline (#{::Ci::Pipeline.all_state_names.compact.join(', ').upcase})" description: "Status of the pipeline (#{::Ci::Pipeline.all_state_names.compact.join(', ').upcase})"
field :detailed_status, Types::Ci::DetailedStatusType, null: false, field :detailed_status, Types::Ci::DetailedStatusType, null: false,
description: 'Detailed status of the pipeline', description: 'Detailed status of the pipeline'
resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
field :config_source, PipelineConfigSourceEnum, null: true, field :config_source, PipelineConfigSourceEnum, null: true,
description: "Config source of the pipeline (#{::Enums::Ci::Pipeline.config_sources.keys.join(', ').upcase})" description: "Config source of the pipeline (#{::Enums::Ci::Pipeline.config_sources.keys.join(', ').upcase})"
...@@ -60,8 +59,7 @@ module Types ...@@ -60,8 +59,7 @@ module Types
resolver: Resolvers::Ci::PipelineStagesResolver resolver: Resolvers::Ci::PipelineStagesResolver
field :user, Types::UserType, null: true, field :user, Types::UserType, null: true,
description: 'Pipeline user', description: 'Pipeline user'
resolve: -> (pipeline, _args, _context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, pipeline.user_id).find }
field :retryable, GraphQL::BOOLEAN_TYPE, field :retryable, GraphQL::BOOLEAN_TYPE,
description: 'Specifies if a pipeline can be retried', description: 'Specifies if a pipeline can be retried',
...@@ -91,11 +89,22 @@ module Types ...@@ -91,11 +89,22 @@ module Types
method: :triggered_by_pipeline method: :triggered_by_pipeline
field :path, GraphQL::STRING_TYPE, null: true, field :path, GraphQL::STRING_TYPE, null: true,
description: "Relative path to the pipeline's page", description: "Relative path to the pipeline's page"
resolve: -> (obj, _args, _ctx) { ::Gitlab::Routing.url_helpers.project_pipeline_path(obj.project, obj) }
field :project, Types::ProjectType, null: true, field :project, Types::ProjectType, null: true,
description: 'Project the pipeline belongs to' description: 'Project the pipeline belongs to'
def detailed_status
object.detailed_status(context[:current_user])
end
def user
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
end
def path
::Gitlab::Routing.url_helpers.project_pipeline_path(object.project, object)
end
end end
end end
end end
......
...@@ -11,8 +11,11 @@ module Types ...@@ -11,8 +11,11 @@ module Types
field :groups, Ci::GroupType.connection_type, null: true, field :groups, Ci::GroupType.connection_type, null: true,
description: 'Group of jobs for the stage' description: 'Group of jobs for the stage'
field :detailed_status, Types::Ci::DetailedStatusType, null: true, field :detailed_status, Types::Ci::DetailedStatusType, null: true,
description: 'Detailed status of the stage', description: 'Detailed status of the stage'
resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
def detailed_status
object.detailed_status(context[:current_user])
end
end end
end end
end end
...@@ -31,10 +31,7 @@ module Types ...@@ -31,10 +31,7 @@ module Types
field :author_name, type: GraphQL::STRING_TYPE, null: true, field :author_name, type: GraphQL::STRING_TYPE, null: true,
description: 'Commit authors name' description: 'Commit authors name'
field :author_gravatar, type: GraphQL::STRING_TYPE, null: true, field :author_gravatar, type: GraphQL::STRING_TYPE, null: true,
description: 'Commit authors gravatar', description: 'Commit authors gravatar'
resolve: -> (commit, args, context) do
GravatarService.new.execute(commit.author_email, 40)
end
# models/commit lazy loads the author by email # models/commit lazy loads the author by email
field :author, type: Types::UserType, null: true, field :author, type: Types::UserType, null: true,
...@@ -44,5 +41,9 @@ module Types ...@@ -44,5 +41,9 @@ module Types
null: true, null: true,
description: 'Pipelines of the commit ordered latest first', description: 'Pipelines of the commit ordered latest first',
resolver: Resolvers::CommitPipelinesResolver resolver: Resolvers::CommitPipelinesResolver
def author_gravatar
GravatarService.new.execute(object.author_email, 40)
end
end end
end end
...@@ -11,7 +11,10 @@ module Types ...@@ -11,7 +11,10 @@ module Types
description 'Represents a Group Invitation' description 'Represents a Group Invitation'
field :group, Types::GroupType, null: true, field :group, Types::GroupType, null: true,
description: 'Group that a User is invited to', description: 'Group that a User is invited to'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.source_id).find }
def group
Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find
end
end end
end end
...@@ -11,7 +11,10 @@ module Types ...@@ -11,7 +11,10 @@ module Types
description 'Represents a Group Membership' description 'Represents a Group Membership'
field :group, Types::GroupType, null: true, field :group, Types::GroupType, null: true,
description: 'Group that a User is a member of', description: 'Group that a User is a member of'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.source_id).find }
def group
Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find
end
end end
end end
...@@ -12,10 +12,7 @@ module Types ...@@ -12,10 +12,7 @@ module Types
description: 'Web URL of the group' description: 'Web URL of the group'
field :avatar_url, GraphQL::STRING_TYPE, null: true, field :avatar_url, GraphQL::STRING_TYPE, null: true,
description: 'Avatar URL of the group', description: 'Avatar URL of the group'
resolve: -> (group, args, ctx) do
group.avatar_url(only_path: false)
end
field :custom_emoji, Types::CustomEmojiType.connection_type, null: true, field :custom_emoji, Types::CustomEmojiType.connection_type, null: true,
description: 'Custom emoji within this namespace', description: 'Custom emoji within this namespace',
...@@ -44,8 +41,7 @@ module Types ...@@ -44,8 +41,7 @@ module Types
description: 'Indicates if a group is disabled from getting mentioned' description: 'Indicates if a group is disabled from getting mentioned'
field :parent, GroupType, null: true, field :parent, GroupType, null: true,
description: 'Parent group', description: 'Parent group'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.parent_id).find }
field :issues, field :issues,
Types::IssueType.connection_type, Types::IssueType.connection_type,
...@@ -120,6 +116,14 @@ module Types ...@@ -120,6 +116,14 @@ module Types
.execute .execute
end end
def avatar_url
object.avatar_url(only_path: false)
end
def parent
Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.parent_id).find
end
private private
def group def group
......
...@@ -132,8 +132,7 @@ module Types ...@@ -132,8 +132,7 @@ module Types
description: 'Labels of the merge request' description: 'Labels of the merge request'
field :discussion_locked, GraphQL::BOOLEAN_TYPE, field :discussion_locked, GraphQL::BOOLEAN_TYPE,
description: 'Indicates if comments on the merge request are locked to members only', description: 'Indicates if comments on the merge request are locked to members only',
null: false, null: false
resolve: -> (obj, _args, _ctx) { !!obj.discussion_locked }
field :time_estimate, GraphQL::INT_TYPE, null: false, field :time_estimate, GraphQL::INT_TYPE, null: false,
description: 'Time estimate of the merge request' description: 'Time estimate of the merge request'
field :total_time_spent, GraphQL::INT_TYPE, null: false, field :total_time_spent, GraphQL::INT_TYPE, null: false,
...@@ -200,6 +199,11 @@ module Types ...@@ -200,6 +199,11 @@ module Types
def source_branch_protected def source_branch_protected
object.source_project.present? && ProtectedBranch.protected?(object.source_project, object.source_branch) object.source_project.present? && ProtectedBranch.protected?(object.source_project, object.source_branch)
end end
def discussion_locked
!!object.discussion_locked
end
end end
end end
Types::MergeRequestType.prepend_if_ee('::EE::Types::MergeRequestType') Types::MergeRequestType.prepend_if_ee('::EE::Types::MergeRequestType')
...@@ -21,6 +21,7 @@ module Types ...@@ -21,6 +21,7 @@ module Types
field :description, GraphQL::STRING_TYPE, null: true, field :description, GraphQL::STRING_TYPE, null: true,
description: 'Description of the namespace' description: 'Description of the namespace'
markdown_field :description_html, null: true markdown_field :description_html, null: true
field :visibility, GraphQL::STRING_TYPE, null: true, field :visibility, GraphQL::STRING_TYPE, null: true,
description: 'Visibility of the namespace' description: 'Visibility of the namespace'
field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true, method: :lfs_enabled?, field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true, method: :lfs_enabled?,
...@@ -30,12 +31,15 @@ module Types ...@@ -30,12 +31,15 @@ module Types
field :root_storage_statistics, Types::RootStorageStatisticsType, field :root_storage_statistics, Types::RootStorageStatisticsType,
null: true, null: true,
description: 'Aggregated storage statistics of the namespace. Only available for root namespaces', description: 'Aggregated storage statistics of the namespace. Only available for root namespaces'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(obj.id).find }
field :projects, Types::ProjectType.connection_type, null: false, field :projects, Types::ProjectType.connection_type, null: false,
description: 'Projects within this namespace', description: 'Projects within this namespace',
resolver: ::Resolvers::NamespaceProjectsResolver resolver: ::Resolvers::NamespaceProjectsResolver
def root_storage_statistics
Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(object.id).find
end
end end
end end
......
...@@ -21,25 +21,43 @@ module Types ...@@ -21,25 +21,43 @@ module Types
# Fields for text positions # Fields for text positions
field :old_line, GraphQL::INT_TYPE, null: true, field :old_line, GraphQL::INT_TYPE, null: true,
description: 'Line on start SHA that was changed', description: 'Line on start SHA that was changed'
resolve: -> (position, _args, _ctx) { position.old_line if position.on_text? }
field :new_line, GraphQL::INT_TYPE, null: true, field :new_line, GraphQL::INT_TYPE, null: true,
description: 'Line on HEAD SHA that was changed', description: 'Line on HEAD SHA that was changed'
resolve: -> (position, _args, _ctx) { position.new_line if position.on_text? }
# Fields for image positions # Fields for image positions
field :x, GraphQL::INT_TYPE, null: true, field :x, GraphQL::INT_TYPE, null: true,
description: 'X position of the note', description: 'X position of the note'
resolve: -> (position, _args, _ctx) { position.x if position.on_image? }
field :y, GraphQL::INT_TYPE, null: true, field :y, GraphQL::INT_TYPE, null: true,
description: 'Y position of the note', description: 'Y position of the note'
resolve: -> (position, _args, _ctx) { position.y if position.on_image? }
field :width, GraphQL::INT_TYPE, null: true, field :width, GraphQL::INT_TYPE, null: true,
description: 'Total width of the image', description: 'Total width of the image'
resolve: -> (position, _args, _ctx) { position.width if position.on_image? }
field :height, GraphQL::INT_TYPE, null: true, field :height, GraphQL::INT_TYPE, null: true,
description: 'Total height of the image', description: 'Total height of the image'
resolve: -> (position, _args, _ctx) { position.height if position.on_image? }
def old_line
object.old_line if object.on_text?
end
def new_line
object.new_line if object.on_text?
end
def x
object.x if object.on_image?
end
def y
object.y if object.on_image?
end
def width
object.width if object.on_image?
end
def height
object.height if object.on_image?
end
end end
# rubocop: enable Graphql/AuthorizeTypes # rubocop: enable Graphql/AuthorizeTypes
end end
......
...@@ -16,13 +16,11 @@ module Types ...@@ -16,13 +16,11 @@ module Types
field :project, Types::ProjectType, field :project, Types::ProjectType,
null: true, null: true,
description: 'Project associated with the note', description: 'Project associated with the note'
resolve: -> (note, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, note.project_id).find }
field :author, Types::UserType, field :author, Types::UserType,
null: false, null: false,
description: 'User who wrote this note', description: 'User who wrote this note'
resolve: -> (note, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, note.author_id).find }
field :system, GraphQL::BOOLEAN_TYPE, field :system, GraphQL::BOOLEAN_TYPE,
null: false, null: false,
...@@ -52,6 +50,14 @@ module Types ...@@ -52,6 +50,14 @@ module Types
def system_note_icon_name def system_note_icon_name
SystemNoteHelper.system_note_icon_name(object) if object.system? SystemNoteHelper.system_note_icon_name(object) if object.system?
end end
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
end
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
end end
end end
end end
...@@ -19,7 +19,9 @@ module Types ...@@ -19,7 +19,9 @@ module Types
permission_field field_name, method: :"can_#{field_name}?", calls_gitaly: true permission_field field_name, method: :"can_#{field_name}?", calls_gitaly: true
end end
permission_field :can_merge, calls_gitaly: true, resolve: -> (object, args, context) do permission_field :can_merge, calls_gitaly: true
def can_merge
object.can_be_merged_by?(context[:current_user]) object.can_be_merged_by?(context[:current_user])
end end
end end
......
...@@ -67,33 +67,25 @@ module Types ...@@ -67,33 +67,25 @@ module Types
description: 'E-mail address of the service desk.' description: 'E-mail address of the service desk.'
field :avatar_url, GraphQL::STRING_TYPE, null: true, calls_gitaly: true, field :avatar_url, GraphQL::STRING_TYPE, null: true, calls_gitaly: true,
description: 'URL to avatar image file of the project', description: 'URL to avatar image file of the project'
resolve: -> (project, args, ctx) do
project.avatar_url(only_path: false)
end
%i[issues merge_requests wiki snippets].each do |feature| %i[issues merge_requests wiki snippets].each do |feature|
field "#{feature}_enabled", GraphQL::BOOLEAN_TYPE, null: true, field "#{feature}_enabled", GraphQL::BOOLEAN_TYPE, null: true,
description: "Indicates if #{feature.to_s.titleize.pluralize} are enabled for the current user", description: "Indicates if #{feature.to_s.titleize.pluralize} are enabled for the current user"
resolve: -> (project, args, ctx) do
project.feature_available?(feature, ctx[:current_user]) define_method "#{feature}_enabled" do
object.feature_available?(feature, context[:current_user])
end end
end end
field :jobs_enabled, GraphQL::BOOLEAN_TYPE, null: true, field :jobs_enabled, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if CI/CD pipeline jobs are enabled for the current user', description: 'Indicates if CI/CD pipeline jobs are enabled for the current user'
resolve: -> (project, args, ctx) do
project.feature_available?(:builds, ctx[:current_user])
end
field :public_jobs, GraphQL::BOOLEAN_TYPE, method: :public_builds, null: true, field :public_jobs, GraphQL::BOOLEAN_TYPE, method: :public_builds, null: true,
description: 'Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts' description: 'Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts'
field :open_issues_count, GraphQL::INT_TYPE, null: true, field :open_issues_count, GraphQL::INT_TYPE, null: true,
description: 'Number of open issues for the project', description: 'Number of open issues for the project'
resolve: -> (project, args, ctx) do
project.open_issues_count if project.feature_available?(:issues, ctx[:current_user])
end
field :import_status, GraphQL::STRING_TYPE, null: true, field :import_status, GraphQL::STRING_TYPE, null: true,
description: 'Status of import background job of the project' description: 'Status of import background job of the project'
...@@ -123,8 +115,7 @@ module Types ...@@ -123,8 +115,7 @@ module Types
field :statistics, Types::ProjectStatisticsType, field :statistics, Types::ProjectStatisticsType,
null: true, null: true,
description: 'Statistics of the project', description: 'Statistics of the project'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchProjectStatisticsLoader.new(obj.id).find }
field :repository, Types::RepositoryType, null: true, field :repository, Types::RepositoryType, null: true,
description: 'Git repository of the project' description: 'Git repository of the project'
...@@ -334,6 +325,22 @@ module Types ...@@ -334,6 +325,22 @@ module Types
.execute .execute
end end
def avatar_url
object.avatar_url(only_path: false)
end
def jobs_enabled
object.feature_available?(:builds, context[:current_user])
end
def open_issues_count
object.open_issues_count if object.feature_available?(:issues, context[:current_user])
end
def statistics
Gitlab::Graphql::Loaders::BatchProjectStatisticsLoader.new(object.id).find
end
private private
def project def project
......
...@@ -24,7 +24,6 @@ module Types ...@@ -24,7 +24,6 @@ module Types
field :current_user, Types::UserType, field :current_user, Types::UserType,
null: true, null: true,
resolve: -> (_obj, _args, context) { context[:current_user] },
description: "Get information about current user" description: "Get information about current user"
field :namespace, Types::NamespaceType, field :namespace, Types::NamespaceType,
...@@ -116,6 +115,10 @@ module Types ...@@ -116,6 +115,10 @@ module Types
id = ::Types::GlobalIDType[::ContainerRepository].coerce_isolated_input(id) id = ::Types::GlobalIDType[::ContainerRepository].coerce_isolated_input(id)
GitlabSchema.find_by_gid(id) GitlabSchema.find_by_gid(id)
end end
def current_user
context[:current_user]
end
end end
end end
......
...@@ -17,14 +17,12 @@ module Types ...@@ -17,14 +17,12 @@ module Types
field :collapsed, GraphQL::BOOLEAN_TYPE, field :collapsed, GraphQL::BOOLEAN_TYPE,
description: 'Shows whether the blob should be displayed collapsed', description: 'Shows whether the blob should be displayed collapsed',
method: :collapsed?, method: :collapsed?,
null: false, null: false
resolve: -> (viewer, _args, _ctx) { !!viewer&.collapsed? }
field :too_large, GraphQL::BOOLEAN_TYPE, field :too_large, GraphQL::BOOLEAN_TYPE,
description: 'Shows whether the blob too large to be displayed', description: 'Shows whether the blob too large to be displayed',
method: :too_large?, method: :too_large?,
null: false, null: false
resolve: -> (viewer, _args, _ctx) { !!viewer&.too_large? }
field :render_error, GraphQL::STRING_TYPE, field :render_error, GraphQL::STRING_TYPE,
description: 'Error rendering the blob content', description: 'Error rendering the blob content',
...@@ -38,6 +36,14 @@ module Types ...@@ -38,6 +36,14 @@ module Types
field :loading_partial_name, GraphQL::STRING_TYPE, field :loading_partial_name, GraphQL::STRING_TYPE,
description: 'Loading partial name', description: 'Loading partial name',
null: false null: false
def collapsed
!!object&.collapsed?
end
def too_large
!!object&.too_large?
end
end end
end end
end end
...@@ -20,8 +20,7 @@ module Types ...@@ -20,8 +20,7 @@ module Types
field :locked_by_user, Types::UserType, field :locked_by_user, Types::UserType,
null: true, null: true,
authorize: :read_user, authorize: :read_user,
description: 'The user currently holding a lock on the Terraform state', description: 'The user currently holding a lock on the Terraform state'
resolve: -> (state, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, state.locked_by_user_id).find }
field :locked_at, Types::TimeType, field :locked_at, Types::TimeType,
null: true, null: true,
...@@ -39,6 +38,10 @@ module Types ...@@ -39,6 +38,10 @@ module Types
field :updated_at, Types::TimeType, field :updated_at, Types::TimeType,
null: false, null: false,
description: 'Timestamp the Terraform state was updated' description: 'Timestamp the Terraform state was updated'
def locked_by_user
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.locked_by_user_id).find
end
end end
end end
end end
...@@ -14,14 +14,12 @@ module Types ...@@ -14,14 +14,12 @@ module Types
field :created_by_user, Types::UserType, field :created_by_user, Types::UserType,
null: true, null: true,
authorize: :read_user, authorize: :read_user,
description: 'The user that created this version', description: 'The user that created this version'
resolve: -> (version, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, version.created_by_user_id).find }
field :job, Types::Ci::JobType, field :job, Types::Ci::JobType,
null: true, null: true,
authorize: :read_build, authorize: :read_build,
description: 'The job that created this version', description: 'The job that created this version'
resolve: -> (version, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Build, version.ci_build_id).find }
field :created_at, Types::TimeType, field :created_at, Types::TimeType,
null: false, null: false,
...@@ -30,6 +28,14 @@ module Types ...@@ -30,6 +28,14 @@ module Types
field :updated_at, Types::TimeType, field :updated_at, Types::TimeType,
null: false, null: false,
description: 'Timestamp the version was updated' description: 'Timestamp the version was updated'
def created_by_user
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.created_by_user_id).find
end
def job
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Build, object.ci_build_id).find
end
end end
end end
end end
...@@ -16,19 +16,16 @@ module Types ...@@ -16,19 +16,16 @@ module Types
field :project, Types::ProjectType, field :project, Types::ProjectType,
description: 'The project this todo is associated with', description: 'The project this todo is associated with',
null: true, null: true,
authorize: :read_project, authorize: :read_project
resolve: -> (todo, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, todo.project_id).find }
field :group, Types::GroupType, field :group, Types::GroupType,
description: 'Group this todo is associated with', description: 'Group this todo is associated with',
null: true, null: true,
authorize: :read_group, authorize: :read_group
resolve: -> (todo, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, todo.group_id).find }
field :author, Types::UserType, field :author, Types::UserType,
description: 'The author of this todo', description: 'The author of this todo',
null: false, null: false
resolve: -> (todo, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, todo.author_id).find }
field :action, Types::TodoActionEnum, field :action, Types::TodoActionEnum,
description: 'Action of the todo', description: 'Action of the todo',
...@@ -50,5 +47,17 @@ module Types ...@@ -50,5 +47,17 @@ module Types
field :created_at, Types::TimeType, field :created_at, Types::TimeType,
description: 'Timestamp this todo was created', description: 'Timestamp this todo was created',
null: false null: false
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
end
def group
Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.group_id).find
end
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
end end
end end
...@@ -15,13 +15,14 @@ module Types ...@@ -15,13 +15,14 @@ module Types
field :web_path, GraphQL::STRING_TYPE, null: true, field :web_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path of the blob' description: 'Web path of the blob'
field :lfs_oid, GraphQL::STRING_TYPE, null: true, field :lfs_oid, GraphQL::STRING_TYPE, null: true,
description: 'LFS ID of the blob', description: 'LFS ID of the blob'
resolve: -> (blob, args, ctx) do
Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(blob.repository, blob.id).find
end
field :mode, GraphQL::STRING_TYPE, null: true, field :mode, GraphQL::STRING_TYPE, null: true,
description: 'Blob mode in numeric format' description: 'Blob mode in numeric format'
# rubocop: enable Graphql/AuthorizeTypes
def lfs_oid
Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(object.repository, object.id).find
end end
end end
# rubocop: enable Graphql/AuthorizeTypes
end
end end
...@@ -12,23 +12,28 @@ module Types ...@@ -12,23 +12,28 @@ module Types
description: 'Last commit for the tree' description: 'Last commit for the tree'
field :trees, Types::Tree::TreeEntryType.connection_type, null: false, field :trees, Types::Tree::TreeEntryType.connection_type, null: false,
description: 'Trees of the tree', description: 'Trees of the tree'
resolve: -> (obj, args, ctx) do
Gitlab::Graphql::Representation::TreeEntry.decorate(obj.trees, obj.repository)
end
field :submodules, Types::Tree::SubmoduleType.connection_type, null: false, field :submodules, Types::Tree::SubmoduleType.connection_type, null: false,
description: 'Sub-modules of the tree', description: 'Sub-modules of the tree',
calls_gitaly: true, resolve: -> (obj, args, ctx) do calls_gitaly: true
Gitlab::Graphql::Representation::SubmoduleTreeEntry.decorate(obj.submodules, obj)
end
field :blobs, Types::Tree::BlobType.connection_type, null: false, field :blobs, Types::Tree::BlobType.connection_type, null: false,
description: 'Blobs of the tree', description: 'Blobs of the tree',
calls_gitaly: true, resolve: -> (obj, args, ctx) do calls_gitaly: true
Gitlab::Graphql::Representation::TreeEntry.decorate(obj.blobs, obj.repository)
def trees
Gitlab::Graphql::Representation::TreeEntry.decorate(object.trees, object.repository)
end end
# rubocop: enable Graphql/AuthorizeTypes
def submodules
Gitlab::Graphql::Representation::SubmoduleTreeEntry.decorate(object.submodules, object)
end end
def blobs
Gitlab::Graphql::Representation::TreeEntry.decorate(object.blobs, object.repository)
end
end
# rubocop: enable Graphql/AuthorizeTypes
end end
end end
...@@ -5298,12 +5298,12 @@ Represents a DAST Site Validation ...@@ -5298,12 +5298,12 @@ Represents a DAST Site Validation
""" """
type DastSiteValidation { type DastSiteValidation {
""" """
ID of the site validation Global ID of the site validation
""" """
id: DastSiteValidationID! id: DastSiteValidationID!
""" """
The status of the validation Status of the site validation
""" """
status: DastSiteProfileValidationStatusEnum! status: DastSiteProfileValidationStatusEnum!
} }
...@@ -7803,12 +7803,12 @@ type EpicIssue implements CurrentUserTodos & Noteable { ...@@ -7803,12 +7803,12 @@ type EpicIssue implements CurrentUserTodos & Noteable {
author: User! author: User!
""" """
Indicates the issue is blocked Indicates the issue is blocked.
""" """
blocked: Boolean! blocked: Boolean!
""" """
Count of issues blocking this issue Count of issues blocking this issue.
""" """
blockedByCount: Int blockedByCount: Int
...@@ -7918,7 +7918,7 @@ type EpicIssue implements CurrentUserTodos & Noteable { ...@@ -7918,7 +7918,7 @@ type EpicIssue implements CurrentUserTodos & Noteable {
emailsDisabled: Boolean! emailsDisabled: Boolean!
""" """
Epic to which this issue belongs Epic to which this issue belongs.
""" """
epic: Epic epic: Epic
...@@ -7953,7 +7953,7 @@ type EpicIssue implements CurrentUserTodos & Noteable { ...@@ -7953,7 +7953,7 @@ type EpicIssue implements CurrentUserTodos & Noteable {
iid: ID! iid: ID!
""" """
Iteration of the issue Iteration of the issue.
""" """
iteration: Iteration iteration: Iteration
...@@ -8088,7 +8088,7 @@ type EpicIssue implements CurrentUserTodos & Noteable { ...@@ -8088,7 +8088,7 @@ type EpicIssue implements CurrentUserTodos & Noteable {
state: IssueState! state: IssueState!
""" """
Indicates whether an issue is published to the status page Indicates whether an issue is published to the status page.
""" """
statusPagePublishedIncident: Boolean statusPagePublishedIncident: Boolean
...@@ -8168,7 +8168,7 @@ type EpicIssue implements CurrentUserTodos & Noteable { ...@@ -8168,7 +8168,7 @@ type EpicIssue implements CurrentUserTodos & Noteable {
webUrl: String! webUrl: String!
""" """
Weight of the issue Weight of the issue.
""" """
weight: Int weight: Int
} }
...@@ -10484,12 +10484,12 @@ type Issue implements CurrentUserTodos & Noteable { ...@@ -10484,12 +10484,12 @@ type Issue implements CurrentUserTodos & Noteable {
author: User! author: User!
""" """
Indicates the issue is blocked Indicates the issue is blocked.
""" """
blocked: Boolean! blocked: Boolean!
""" """
Count of issues blocking this issue Count of issues blocking this issue.
""" """
blockedByCount: Int blockedByCount: Int
...@@ -10599,7 +10599,7 @@ type Issue implements CurrentUserTodos & Noteable { ...@@ -10599,7 +10599,7 @@ type Issue implements CurrentUserTodos & Noteable {
emailsDisabled: Boolean! emailsDisabled: Boolean!
""" """
Epic to which this issue belongs Epic to which this issue belongs.
""" """
epic: Epic epic: Epic
...@@ -10629,7 +10629,7 @@ type Issue implements CurrentUserTodos & Noteable { ...@@ -10629,7 +10629,7 @@ type Issue implements CurrentUserTodos & Noteable {
iid: ID! iid: ID!
""" """
Iteration of the issue Iteration of the issue.
""" """
iteration: Iteration iteration: Iteration
...@@ -10759,7 +10759,7 @@ type Issue implements CurrentUserTodos & Noteable { ...@@ -10759,7 +10759,7 @@ type Issue implements CurrentUserTodos & Noteable {
state: IssueState! state: IssueState!
""" """
Indicates whether an issue is published to the status page Indicates whether an issue is published to the status page.
""" """
statusPagePublishedIncident: Boolean statusPagePublishedIncident: Boolean
...@@ -10839,7 +10839,7 @@ type Issue implements CurrentUserTodos & Noteable { ...@@ -10839,7 +10839,7 @@ type Issue implements CurrentUserTodos & Noteable {
webUrl: String! webUrl: String!
""" """
Weight of the issue Weight of the issue.
""" """
weight: Int weight: Int
} }
......
...@@ -14507,7 +14507,7 @@ ...@@ -14507,7 +14507,7 @@
"fields": [ "fields": [
{ {
"name": "id", "name": "id",
"description": "ID of the site validation", "description": "Global ID of the site validation",
"args": [ "args": [
], ],
...@@ -14525,7 +14525,7 @@ ...@@ -14525,7 +14525,7 @@
}, },
{ {
"name": "status", "name": "status",
"description": "The status of the validation", "description": "Status of the site validation",
"args": [ "args": [
], ],
...@@ -21660,7 +21660,7 @@ ...@@ -21660,7 +21660,7 @@
}, },
{ {
"name": "blocked", "name": "blocked",
"description": "Indicates the issue is blocked", "description": "Indicates the issue is blocked.",
"args": [ "args": [
], ],
...@@ -21678,7 +21678,7 @@ ...@@ -21678,7 +21678,7 @@
}, },
{ {
"name": "blockedByCount", "name": "blockedByCount",
"description": "Count of issues blocking this issue", "description": "Count of issues blocking this issue.",
"args": [ "args": [
], ],
...@@ -21976,7 +21976,7 @@ ...@@ -21976,7 +21976,7 @@
}, },
{ {
"name": "epic", "name": "epic",
"description": "Epic to which this issue belongs", "description": "Epic to which this issue belongs.",
"args": [ "args": [
], ],
...@@ -22082,7 +22082,7 @@ ...@@ -22082,7 +22082,7 @@
}, },
{ {
"name": "iteration", "name": "iteration",
"description": "Iteration of the issue", "description": "Iteration of the issue.",
"args": [ "args": [
], ],
...@@ -22424,7 +22424,7 @@ ...@@ -22424,7 +22424,7 @@
}, },
{ {
"name": "statusPagePublishedIncident", "name": "statusPagePublishedIncident",
"description": "Indicates whether an issue is published to the status page", "description": "Indicates whether an issue is published to the status page.",
"args": [ "args": [
], ],
...@@ -22696,7 +22696,7 @@ ...@@ -22696,7 +22696,7 @@
}, },
{ {
"name": "weight", "name": "weight",
"description": "Weight of the issue", "description": "Weight of the issue.",
"args": [ "args": [
], ],
...@@ -28744,7 +28744,7 @@ ...@@ -28744,7 +28744,7 @@
}, },
{ {
"name": "blocked", "name": "blocked",
"description": "Indicates the issue is blocked", "description": "Indicates the issue is blocked.",
"args": [ "args": [
], ],
...@@ -28762,7 +28762,7 @@ ...@@ -28762,7 +28762,7 @@
}, },
{ {
"name": "blockedByCount", "name": "blockedByCount",
"description": "Count of issues blocking this issue", "description": "Count of issues blocking this issue.",
"args": [ "args": [
], ],
...@@ -29060,7 +29060,7 @@ ...@@ -29060,7 +29060,7 @@
}, },
{ {
"name": "epic", "name": "epic",
"description": "Epic to which this issue belongs", "description": "Epic to which this issue belongs.",
"args": [ "args": [
], ],
...@@ -29152,7 +29152,7 @@ ...@@ -29152,7 +29152,7 @@
}, },
{ {
"name": "iteration", "name": "iteration",
"description": "Iteration of the issue", "description": "Iteration of the issue.",
"args": [ "args": [
], ],
...@@ -29480,7 +29480,7 @@ ...@@ -29480,7 +29480,7 @@
}, },
{ {
"name": "statusPagePublishedIncident", "name": "statusPagePublishedIncident",
"description": "Indicates whether an issue is published to the status page", "description": "Indicates whether an issue is published to the status page.",
"args": [ "args": [
], ],
...@@ -29752,7 +29752,7 @@ ...@@ -29752,7 +29752,7 @@
}, },
{ {
"name": "weight", "name": "weight",
"description": "Weight of the issue", "description": "Weight of the issue.",
"args": [ "args": [
], ],
...@@ -887,8 +887,8 @@ Represents a DAST Site Validation. ...@@ -887,8 +887,8 @@ Represents a DAST Site Validation.
| Field | Type | Description | | Field | Type | Description |
| ----- | ---- | ----------- | | ----- | ---- | ----------- |
| `id` | DastSiteValidationID! | ID of the site validation | | `id` | DastSiteValidationID! | Global ID of the site validation |
| `status` | DastSiteProfileValidationStatusEnum! | The status of the validation | | `status` | DastSiteProfileValidationStatusEnum! | Status of the site validation |
### DastSiteValidationCreatePayload ### DastSiteValidationCreatePayload
...@@ -1309,8 +1309,8 @@ Relationship between an epic and an issue. ...@@ -1309,8 +1309,8 @@ Relationship between an epic and an issue.
| `alertManagementAlert` | AlertManagementAlert | Alert associated to this issue | | `alertManagementAlert` | AlertManagementAlert | Alert associated to this issue |
| `assignees` | UserConnection | Assignees of the issue | | `assignees` | UserConnection | Assignees of the issue |
| `author` | User! | User that created the issue | | `author` | User! | User that created the issue |
| `blocked` | Boolean! | Indicates the issue is blocked | | `blocked` | Boolean! | Indicates the issue is blocked. |
| `blockedByCount` | Int | Count of issues blocking this issue | | `blockedByCount` | Int | Count of issues blocking this issue. |
| `closedAt` | Time | Timestamp of when the issue was closed | | `closedAt` | Time | Timestamp of when the issue was closed |
| `confidential` | Boolean! | Indicates the issue is confidential | | `confidential` | Boolean! | Indicates the issue is confidential |
| `createdAt` | Time! | Timestamp of when the issue was created | | `createdAt` | Time! | Timestamp of when the issue was created |
...@@ -1323,14 +1323,14 @@ Relationship between an epic and an issue. ...@@ -1323,14 +1323,14 @@ Relationship between an epic and an issue.
| `downvotes` | Int! | Number of downvotes the issue has received | | `downvotes` | Int! | Number of downvotes the issue has received |
| `dueDate` | Time | Due date of the issue | | `dueDate` | Time | Due date of the issue |
| `emailsDisabled` | Boolean! | Indicates if a project has email notifications disabled: `true` if email notifications are disabled | | `emailsDisabled` | Boolean! | Indicates if a project has email notifications disabled: `true` if email notifications are disabled |
| `epic` | Epic | Epic to which this issue belongs | | `epic` | Epic | Epic to which this issue belongs. |
| `epicIssueId` | ID! | ID of the epic-issue relation | | `epicIssueId` | ID! | ID of the epic-issue relation |
| `healthStatus` | HealthStatus | Current health status. Returns null if `save_issuable_health_status` feature flag is disabled. | | `healthStatus` | HealthStatus | Current health status. Returns null if `save_issuable_health_status` feature flag is disabled. |
| `humanTimeEstimate` | String | Human-readable time estimate of the issue | | `humanTimeEstimate` | String | Human-readable time estimate of the issue |
| `humanTotalTimeSpent` | String | Human-readable total time reported as spent on the issue | | `humanTotalTimeSpent` | String | Human-readable total time reported as spent on the issue |
| `id` | ID | Global ID of the epic-issue relation | | `id` | ID | Global ID of the epic-issue relation |
| `iid` | ID! | Internal ID of the issue | | `iid` | ID! | Internal ID of the issue |
| `iteration` | Iteration | Iteration of the issue | | `iteration` | Iteration | Iteration of the issue. |
| `labels` | LabelConnection | Labels of the issue | | `labels` | LabelConnection | Labels of the issue |
| `metricImages` | MetricImage! => Array | Metric images associated to the issue. | | `metricImages` | MetricImage! => Array | Metric images associated to the issue. |
| `milestone` | Milestone | Milestone of the issue | | `milestone` | Milestone | Milestone of the issue |
...@@ -1344,7 +1344,7 @@ Relationship between an epic and an issue. ...@@ -1344,7 +1344,7 @@ Relationship between an epic and an issue.
| `severity` | IssuableSeverity | Severity level of the incident | | `severity` | IssuableSeverity | Severity level of the incident |
| `slaDueAt` | Time | Timestamp of when the issue SLA expires. | | `slaDueAt` | Time | Timestamp of when the issue SLA expires. |
| `state` | IssueState! | State of the issue | | `state` | IssueState! | State of the issue |
| `statusPagePublishedIncident` | Boolean | Indicates whether an issue is published to the status page | | `statusPagePublishedIncident` | Boolean | Indicates whether an issue is published to the status page. |
| `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue | | `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue |
| `taskCompletionStatus` | TaskCompletionStatus! | Task completion status of the issue | | `taskCompletionStatus` | TaskCompletionStatus! | Task completion status of the issue |
| `timeEstimate` | Int! | Time estimate of the issue | | `timeEstimate` | Int! | Time estimate of the issue |
...@@ -1360,7 +1360,7 @@ Relationship between an epic and an issue. ...@@ -1360,7 +1360,7 @@ Relationship between an epic and an issue.
| `userPermissions` | IssuePermissions! | Permissions for the current user on the resource | | `userPermissions` | IssuePermissions! | Permissions for the current user on the resource |
| `webPath` | String! | Web path of the issue | | `webPath` | String! | Web path of the issue |
| `webUrl` | String! | Web URL of the issue | | `webUrl` | String! | Web URL of the issue |
| `weight` | Int | Weight of the issue | | `weight` | Int | Weight of the issue. |
### EpicPermissions ### EpicPermissions
...@@ -1608,8 +1608,8 @@ Represents a recorded measurement (object count) for the Admins. ...@@ -1608,8 +1608,8 @@ Represents a recorded measurement (object count) for the Admins.
| `alertManagementAlert` | AlertManagementAlert | Alert associated to this issue | | `alertManagementAlert` | AlertManagementAlert | Alert associated to this issue |
| `assignees` | UserConnection | Assignees of the issue | | `assignees` | UserConnection | Assignees of the issue |
| `author` | User! | User that created the issue | | `author` | User! | User that created the issue |
| `blocked` | Boolean! | Indicates the issue is blocked | | `blocked` | Boolean! | Indicates the issue is blocked. |
| `blockedByCount` | Int | Count of issues blocking this issue | | `blockedByCount` | Int | Count of issues blocking this issue. |
| `closedAt` | Time | Timestamp of when the issue was closed | | `closedAt` | Time | Timestamp of when the issue was closed |
| `confidential` | Boolean! | Indicates the issue is confidential | | `confidential` | Boolean! | Indicates the issue is confidential |
| `createdAt` | Time! | Timestamp of when the issue was created | | `createdAt` | Time! | Timestamp of when the issue was created |
...@@ -1622,13 +1622,13 @@ Represents a recorded measurement (object count) for the Admins. ...@@ -1622,13 +1622,13 @@ Represents a recorded measurement (object count) for the Admins.
| `downvotes` | Int! | Number of downvotes the issue has received | | `downvotes` | Int! | Number of downvotes the issue has received |
| `dueDate` | Time | Due date of the issue | | `dueDate` | Time | Due date of the issue |
| `emailsDisabled` | Boolean! | Indicates if a project has email notifications disabled: `true` if email notifications are disabled | | `emailsDisabled` | Boolean! | Indicates if a project has email notifications disabled: `true` if email notifications are disabled |
| `epic` | Epic | Epic to which this issue belongs | | `epic` | Epic | Epic to which this issue belongs. |
| `healthStatus` | HealthStatus | Current health status. Returns null if `save_issuable_health_status` feature flag is disabled. | | `healthStatus` | HealthStatus | Current health status. Returns null if `save_issuable_health_status` feature flag is disabled. |
| `humanTimeEstimate` | String | Human-readable time estimate of the issue | | `humanTimeEstimate` | String | Human-readable time estimate of the issue |
| `humanTotalTimeSpent` | String | Human-readable total time reported as spent on the issue | | `humanTotalTimeSpent` | String | Human-readable total time reported as spent on the issue |
| `id` | ID! | ID of the issue | | `id` | ID! | ID of the issue |
| `iid` | ID! | Internal ID of the issue | | `iid` | ID! | Internal ID of the issue |
| `iteration` | Iteration | Iteration of the issue | | `iteration` | Iteration | Iteration of the issue. |
| `labels` | LabelConnection | Labels of the issue | | `labels` | LabelConnection | Labels of the issue |
| `metricImages` | MetricImage! => Array | Metric images associated to the issue. | | `metricImages` | MetricImage! => Array | Metric images associated to the issue. |
| `milestone` | Milestone | Milestone of the issue | | `milestone` | Milestone | Milestone of the issue |
...@@ -1641,7 +1641,7 @@ Represents a recorded measurement (object count) for the Admins. ...@@ -1641,7 +1641,7 @@ Represents a recorded measurement (object count) for the Admins.
| `severity` | IssuableSeverity | Severity level of the incident | | `severity` | IssuableSeverity | Severity level of the incident |
| `slaDueAt` | Time | Timestamp of when the issue SLA expires. | | `slaDueAt` | Time | Timestamp of when the issue SLA expires. |
| `state` | IssueState! | State of the issue | | `state` | IssueState! | State of the issue |
| `statusPagePublishedIncident` | Boolean | Indicates whether an issue is published to the status page | | `statusPagePublishedIncident` | Boolean | Indicates whether an issue is published to the status page. |
| `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue | | `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue |
| `taskCompletionStatus` | TaskCompletionStatus! | Task completion status of the issue | | `taskCompletionStatus` | TaskCompletionStatus! | Task completion status of the issue |
| `timeEstimate` | Int! | Time estimate of the issue | | `timeEstimate` | Int! | Time estimate of the issue |
...@@ -1657,7 +1657,7 @@ Represents a recorded measurement (object count) for the Admins. ...@@ -1657,7 +1657,7 @@ Represents a recorded measurement (object count) for the Admins.
| `userPermissions` | IssuePermissions! | Permissions for the current user on the resource | | `userPermissions` | IssuePermissions! | Permissions for the current user on the resource |
| `webPath` | String! | Web path of the issue | | `webPath` | String! | Web path of the issue |
| `webUrl` | String! | Web URL of the issue | | `webUrl` | String! | Web URL of the issue |
| `weight` | Int | Weight of the issue | | `weight` | Int | Weight of the issue. |
### IssueMoveListPayload ### IssueMoveListPayload
......
...@@ -7,9 +7,12 @@ module EE ...@@ -7,9 +7,12 @@ module EE
prepended do prepended do
%i[epics group_timelogs].each do |feature| %i[epics group_timelogs].each do |feature|
field "#{feature}_enabled", GraphQL::BOOLEAN_TYPE, null: true, resolve: -> (group, args, ctx) do field "#{feature}_enabled", GraphQL::BOOLEAN_TYPE, null: true,
group.feature_available?(feature) description: "Indicates if #{feature.to_s.humanize} are enabled for namespace"
end, description: "Indicates if #{feature.to_s.humanize} are enabled for namespace"
define_method "#{feature}_enabled" do
object.feature_available?(feature)
end
end end
field :epic, ::Types::EpicType, null: true, field :epic, ::Types::EpicType, null: true,
......
...@@ -7,44 +7,55 @@ module EE ...@@ -7,44 +7,55 @@ module EE
prepended do prepended do
field :epic, ::Types::EpicType, null: true, field :epic, ::Types::EpicType, null: true,
description: 'Epic to which this issue belongs' description: 'Epic to which this issue belongs.'
field :iteration, ::Types::IterationType, null: true, field :iteration, ::Types::IterationType, null: true,
description: 'Iteration of the issue', description: 'Iteration of the issue.'
resolve: -> (obj, _args, _ctx) { ::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Iteration, obj.sprint_id).find }
field :weight, GraphQL::INT_TYPE, null: true, field :weight, GraphQL::INT_TYPE, null: true,
description: 'Weight of the issue', description: 'Weight of the issue.'
resolve: -> (obj, _args, _ctx) { obj.weight_available? ? obj.weight : nil }
field :blocked, GraphQL::BOOLEAN_TYPE, null: false, field :blocked, GraphQL::BOOLEAN_TYPE, null: false,
description: 'Indicates the issue is blocked', description: 'Indicates the issue is blocked.'
resolve: -> (obj, _args, ctx) {
::Gitlab::Graphql::Aggregations::Issues::LazyBlockAggregate.new(ctx, obj.id) do |count|
(count || 0) > 0
end
}
field :blocked_by_count, GraphQL::INT_TYPE, null: true, field :blocked_by_count, GraphQL::INT_TYPE, null: true,
description: 'Count of issues blocking this issue', description: 'Count of issues blocking this issue.'
resolve: -> (obj, _args, ctx) {
::Gitlab::Graphql::Aggregations::Issues::LazyBlockAggregate.new(ctx, obj.id) do |count|
count || 0
end
}
field :health_status, ::Types::HealthStatusEnum, null: true, field :health_status, ::Types::HealthStatusEnum, null: true,
description: 'Current health status. Returns null if `save_issuable_health_status` feature flag is disabled.', description: 'Current health status. Returns null if `save_issuable_health_status` feature flag is disabled.'
resolve: -> (obj, _, _) { obj.supports_health_status? ? obj.health_status : nil }
field :status_page_published_incident, GraphQL::BOOLEAN_TYPE, null: true, field :status_page_published_incident, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates whether an issue is published to the status page' description: 'Indicates whether an issue is published to the status page.'
field :sla_due_at, ::Types::TimeType, null: true, field :sla_due_at, ::Types::TimeType, null: true,
description: 'Timestamp of when the issue SLA expires.' description: 'Timestamp of when the issue SLA expires.'
field :metric_images, [::Types::MetricImageType], null: true, field :metric_images, [::Types::MetricImageType], null: true,
description: 'Metric images associated to the issue.' description: 'Metric images associated to the issue.'
def iteration
::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Iteration, object.sprint_id).find
end
def weight
object.weight_available? ? object.weight : nil
end
def blocked
::Gitlab::Graphql::Aggregations::Issues::LazyBlockAggregate.new(context, object.id) do |count|
(count || 0) > 0
end
end
def blocked_by_count
::Gitlab::Graphql::Aggregations::Issues::LazyBlockAggregate.new(context, object.id) do |count|
count || 0
end
end
def health_status
object.supports_health_status? ? object.health_status : nil
end
end end
end end
end end
......
...@@ -9,8 +9,7 @@ module EE ...@@ -9,8 +9,7 @@ module EE
field :additional_purchased_storage_size, field :additional_purchased_storage_size,
GraphQL::FLOAT_TYPE, GraphQL::FLOAT_TYPE,
null: true, null: true,
description: 'Additional storage purchased for the root namespace in bytes', description: 'Additional storage purchased for the root namespace in bytes'
resolve: -> (obj, _args, _ctx) { obj.additional_purchased_storage_size.megabytes }
field :total_repository_size_excess, field :total_repository_size_excess,
GraphQL::FLOAT_TYPE, GraphQL::FLOAT_TYPE,
...@@ -26,7 +25,7 @@ module EE ...@@ -26,7 +25,7 @@ module EE
GraphQL::BOOLEAN_TYPE, GraphQL::BOOLEAN_TYPE,
null: false, null: false,
description: 'Includes at least one project where the repository size exceeds the limit', description: 'Includes at least one project where the repository size exceeds the limit',
resolve: -> (obj, _args, _ctx) { obj.contains_locked_projects? } method: :contains_locked_projects?
field :repository_size_excess_project_count, field :repository_size_excess_project_count,
GraphQL::INT_TYPE, GraphQL::INT_TYPE,
...@@ -37,24 +36,31 @@ module EE ...@@ -37,24 +36,31 @@ module EE
GraphQL::FLOAT_TYPE, GraphQL::FLOAT_TYPE,
null: true, null: true,
description: 'Size limit for repositories in the namespace in bytes', description: 'Size limit for repositories in the namespace in bytes',
resolve: -> (obj, _args, _ctx) { obj.actual_size_limit } method: :actual_size_limit
field :storage_size_limit, field :storage_size_limit,
GraphQL::FLOAT_TYPE, GraphQL::FLOAT_TYPE,
null: true, null: true,
description: 'Total storage limit of the root namespace in bytes', description: 'Total storage limit of the root namespace in bytes'
resolve: -> (obj, _args, _ctx) { obj.root_storage_size.limit }
field :is_temporary_storage_increase_enabled, field :is_temporary_storage_increase_enabled,
GraphQL::BOOLEAN_TYPE, GraphQL::BOOLEAN_TYPE,
null: false, null: false,
description: 'Status of the temporary storage increase', description: 'Status of the temporary storage increase',
resolve: -> (obj, _args, _ctx) { obj.temporary_storage_increase_enabled? } method: :temporary_storage_increase_enabled?
field :temporary_storage_increase_ends_on, field :temporary_storage_increase_ends_on,
::Types::TimeType, ::Types::TimeType,
null: true, null: true,
description: 'Date until the temporary storage increase is active' description: 'Date until the temporary storage increase is active'
def additional_purchased_storage_size
object.additional_purchased_storage_size.megabytes
end
def storage_size_limit
object.root_storage_size.limit
end
end end
end end
end end
......
...@@ -7,7 +7,8 @@ module EE ...@@ -7,7 +7,8 @@ module EE
prepended do prepended do
field :security_scanners, ::Types::SecurityScanners, null: true, field :security_scanners, ::Types::SecurityScanners, null: true,
description: 'Information about security analyzers used in the project' description: 'Information about security analyzers used in the project',
method: :itself
field :dast_scanner_profiles, field :dast_scanner_profiles,
::Types::DastScannerProfileType.connection_type, ::Types::DastScannerProfileType.connection_type,
...@@ -106,7 +107,8 @@ module EE ...@@ -106,7 +107,8 @@ module EE
field :actual_repository_size_limit, field :actual_repository_size_limit,
GraphQL::FLOAT_TYPE, GraphQL::FLOAT_TYPE,
null: true, null: true,
description: 'Size limit for the repository in bytes' description: 'Size limit for the repository in bytes',
method: :actual_size_limit
field :code_coverage_summary, field :code_coverage_summary,
::Types::Ci::CodeCoverageSummaryType, ::Types::Ci::CodeCoverageSummaryType,
...@@ -120,10 +122,6 @@ module EE ...@@ -120,10 +122,6 @@ module EE
description: 'Incident Management On-call schedules of the project', description: 'Incident Management On-call schedules of the project',
resolver: ::Resolvers::IncidentManagement::OncallScheduleResolver resolver: ::Resolvers::IncidentManagement::OncallScheduleResolver
def actual_repository_size_limit
object.actual_size_limit
end
def dast_scanner_profiles def dast_scanner_profiles
DastScannerProfilesFinder.new(project_ids: [object.id]).execute DastScannerProfilesFinder.new(project_ids: [object.id]).execute
end end
...@@ -143,10 +141,6 @@ module EE ...@@ -143,10 +141,6 @@ module EE
def security_dashboard_path def security_dashboard_path
Rails.application.routes.url_helpers.project_security_dashboard_index_path(object) Rails.application.routes.url_helpers.project_security_dashboard_index_path(object)
end end
def security_scanners
object
end
end end
end end
end end
......
...@@ -12,8 +12,7 @@ module Types ...@@ -12,8 +12,7 @@ module Types
field :cluster_agent, field :cluster_agent,
Types::Clusters::AgentType, Types::Clusters::AgentType,
description: 'Cluster agent this token is associated with', description: 'Cluster agent this token is associated with',
null: true, null: true
resolve: -> (token, _args, _context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(::Clusters::Agent, token.agent_id).find }
field :created_at, field :created_at,
Types::TimeType, Types::TimeType,
...@@ -24,6 +23,10 @@ module Types ...@@ -24,6 +23,10 @@ module Types
::Types::GlobalIDType[::Clusters::AgentToken], ::Types::GlobalIDType[::Clusters::AgentToken],
null: false, null: false,
description: 'Global ID of the token' description: 'Global ID of the token'
def cluster_agent
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Clusters::Agent, object.agent_id).find
end
end end
end end
end end
...@@ -26,8 +26,7 @@ module Types ...@@ -26,8 +26,7 @@ module Types
field :project, Types::ProjectType, field :project, Types::ProjectType,
description: 'The project this cluster agent is associated with', description: 'The project this cluster agent is associated with',
null: true, null: true,
authorize: :read_project, authorize: :read_project
resolve: -> (agent, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, agent.project_id).find }
field :tokens, Types::Clusters::AgentTokenType.connection_type, field :tokens, Types::Clusters::AgentTokenType.connection_type,
description: 'Tokens associated with the cluster agent', description: 'Tokens associated with the cluster agent',
...@@ -38,6 +37,10 @@ module Types ...@@ -38,6 +37,10 @@ module Types
Types::TimeType, Types::TimeType,
null: true, null: true,
description: 'Timestamp the cluster agent was updated' description: 'Timestamp the cluster agent was updated'
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
end
end end
end end
end end
...@@ -38,9 +38,10 @@ module Types ...@@ -38,9 +38,10 @@ module Types
'True to include the debug messages.' 'True to include the debug messages.'
field :edit_path, GraphQL::STRING_TYPE, null: true, field :edit_path, GraphQL::STRING_TYPE, null: true,
description: 'Relative web path to the edit page of a scanner profile', description: 'Relative web path to the edit page of a scanner profile'
resolve: -> (obj, _args, _ctx) do
Rails.application.routes.url_helpers.edit_project_security_configuration_dast_profiles_dast_scanner_profile_path(obj.project, obj) def edit_path
Rails.application.routes.url_helpers.edit_project_security_configuration_dast_profiles_dast_scanner_profile_path(object.project, object)
end end
end end
end end
...@@ -14,20 +14,24 @@ module Types ...@@ -14,20 +14,24 @@ module Types
field :profile_name, GraphQL::STRING_TYPE, null: true, field :profile_name, GraphQL::STRING_TYPE, null: true,
description: 'The name of the site profile', description: 'The name of the site profile',
resolve: -> (obj, _args, _ctx) { obj.name } method: :name
field :target_url, GraphQL::STRING_TYPE, null: true, field :target_url, GraphQL::STRING_TYPE, null: true,
description: 'The URL of the target to be scanned', description: 'The URL of the target to be scanned'
resolve: -> (obj, _args, _ctx) { obj.dast_site.url }
field :edit_path, GraphQL::STRING_TYPE, null: true, field :edit_path, GraphQL::STRING_TYPE, null: true,
description: 'Relative web path to the edit page of a site profile', description: 'Relative web path to the edit page of a site profile'
resolve: -> (obj, _args, _ctx) do
Rails.application.routes.url_helpers.edit_project_security_configuration_dast_profiles_dast_site_profile_path(obj.project, obj)
end
field :validation_status, Types::DastSiteProfileValidationStatusEnum, null: true, field :validation_status, Types::DastSiteProfileValidationStatusEnum, null: true,
description: 'The current validation status of the site profile', description: 'The current validation status of the site profile',
resolve: -> (obj, _args, _ctx) { obj.status } method: :status
def target_url
object.dast_site.url
end
def edit_path
Rails.application.routes.url_helpers.edit_project_security_configuration_dast_profiles_dast_site_profile_path(object.project, object)
end
end end
end end
...@@ -8,10 +8,10 @@ module Types ...@@ -8,10 +8,10 @@ module Types
authorize :create_on_demand_dast_scan authorize :create_on_demand_dast_scan
field :id, ::Types::GlobalIDType[::DastSiteValidation], null: false, field :id, ::Types::GlobalIDType[::DastSiteValidation], null: false,
description: 'ID of the site validation' description: 'Global ID of the site validation'
field :status, Types::DastSiteProfileValidationStatusEnum, null: false, field :status, Types::DastSiteProfileValidationStatusEnum, null: false,
description: 'The status of the validation', description: 'Status of the site validation',
resolve: -> (obj, _args, _ctx) { obj.state } method: :state
end end
end end
...@@ -13,18 +13,18 @@ module Types ...@@ -13,18 +13,18 @@ module Types
description: 'ID of the epic-issue relation' description: 'ID of the epic-issue relation'
field :relation_path, GraphQL::STRING_TYPE, null: true, field :relation_path, GraphQL::STRING_TYPE, null: true,
description: 'URI path of the epic-issue relation', description: 'URI path of the epic-issue relation'
resolve: -> (issue, args, ctx) do
issue.group_epic_issue_path(ctx[:current_user])
end
field :id, GraphQL::ID_TYPE, null: true, resolve: -> (issue, args, ctx) do field :id, GraphQL::ID_TYPE, null: true,
issue.to_global_id description: 'Global ID of the epic-issue relation'
end, description: 'Global ID of the epic-issue relation'
def epic_issue_id def epic_issue_id
"gid://gitlab/EpicIssue/#{object.epic_issue_id}" "gid://gitlab/EpicIssue/#{object.epic_issue_id}"
end end
# rubocop: enable Graphql/AuthorizeTypes
def relation_path
object.group_epic_issue_path(context[:current_user])
end end
end
# rubocop: enable Graphql/AuthorizeTypes
end end
...@@ -34,8 +34,7 @@ module Types ...@@ -34,8 +34,7 @@ module Types
field :parent, EpicType, null: true, field :parent, EpicType, null: true,
description: 'Parent epic of the epic' description: 'Parent epic of the epic'
field :author, Types::UserType, null: false, field :author, Types::UserType, null: false,
description: 'Author of the epic', description: 'Author of the epic'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.author_id).find }
field :start_date, Types::TimeType, null: true, field :start_date, Types::TimeType, null: true,
description: 'Start date of the epic' description: 'Start date of the epic'
...@@ -132,22 +131,13 @@ module Types ...@@ -132,22 +131,13 @@ module Types
resolver: Resolvers::EpicIssuesResolver resolver: Resolvers::EpicIssuesResolver
field :descendant_counts, Types::EpicDescendantCountType, null: true, field :descendant_counts, Types::EpicDescendantCountType, null: true,
description: 'Number of open and closed descendant epics and issues', description: 'Number of open and closed descendant epics and issues'
resolve: -> (epic, args, ctx) do
Gitlab::Graphql::Aggregations::Epics::LazyEpicAggregate.new(ctx, epic.id, COUNT)
end
field :descendant_weight_sum, Types::EpicDescendantWeightSumType, null: true, field :descendant_weight_sum, Types::EpicDescendantWeightSumType, null: true,
description: "Total weight of open and closed issues in the epic and its descendants", description: "Total weight of open and closed issues in the epic and its descendants"
resolve: -> (epic, args, ctx) do
Gitlab::Graphql::Aggregations::Epics::LazyEpicAggregate.new(ctx, epic.id, WEIGHT_SUM)
end
field :health_status, Types::EpicHealthStatusType, null: true, complexity: 10, field :health_status, Types::EpicHealthStatusType, null: true, complexity: 10,
description: 'Current health status of the epic', description: 'Current health status of the epic'
resolve: -> (epic, args, ctx) do
Epics::DescendantCountService.new(epic, ctx[:current_user])
end
def user_notes_count def user_notes_count
BatchLoader::GraphQL.for(object.id).batch(key: :epic_user_notes_count) do |ids, loader, args| BatchLoader::GraphQL.for(object.id).batch(key: :epic_user_notes_count) do |ids, loader, args|
...@@ -183,5 +173,21 @@ module Types ...@@ -183,5 +173,21 @@ module Types
alias_method :has_children, :has_children? alias_method :has_children, :has_children?
alias_method :has_issues, :has_issues? alias_method :has_issues, :has_issues?
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
def descendant_counts
Gitlab::Graphql::Aggregations::Epics::LazyEpicAggregate.new(context, object.id, COUNT)
end
def descendant_weight_sum
Gitlab::Graphql::Aggregations::Epics::LazyEpicAggregate.new(context, object.id, WEIGHT_SUM)
end
def health_status
Epics::DescendantCountService.new(object, context[:current_user])
end
end end
end end
...@@ -25,12 +25,13 @@ module Types ...@@ -25,12 +25,13 @@ module Types
field :vulnerability_grades, field :vulnerability_grades,
[Types::VulnerableProjectsByGradeType], [Types::VulnerableProjectsByGradeType],
null: false, null: false,
description: 'Represents vulnerable project counts for each grade', description: 'Represents vulnerable project counts for each grade'
resolve: -> (obj, _args, ctx) {
def vulnerability_grades
::Gitlab::Graphql::Aggregations::VulnerabilityStatistics::LazyAggregate.new( ::Gitlab::Graphql::Aggregations::VulnerabilityStatistics::LazyAggregate.new(
ctx, context,
::InstanceSecurityDashboard.new(ctx[:current_user]) ::InstanceSecurityDashboard.new(context[:current_user])
) )
} end
end end
end end
...@@ -37,12 +37,10 @@ module Types ...@@ -37,12 +37,10 @@ module Types
description: 'Indicates if latest test report was created by user' description: 'Indicates if latest test report was created by user'
field :project, ProjectType, null: false, field :project, ProjectType, null: false,
description: 'Project to which the requirement belongs', description: 'Project to which the requirement belongs'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, obj.project_id).find }
field :author, UserType, null: false, field :author, UserType, null: false,
description: 'Author of the requirement', description: 'Author of the requirement'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.author_id).find }
field :test_reports, TestReportType.connection_type, null: true, complexity: 5, field :test_reports, TestReportType.connection_type, null: true, complexity: 5,
description: 'Test reports of the requirement', description: 'Test reports of the requirement',
...@@ -53,6 +51,14 @@ module Types ...@@ -53,6 +51,14 @@ module Types
field :updated_at, Types::TimeType, null: false, field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of when the requirement was last updated' description: 'Timestamp of when the requirement was last updated'
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
end
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
end end
end end
end end
...@@ -15,11 +15,14 @@ module Types ...@@ -15,11 +15,14 @@ module Types
description: 'State of the test report' description: 'State of the test report'
field :author, UserType, null: true, field :author, UserType, null: true,
description: 'Author of the test report', description: 'Author of the test report'
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.author_id).find }
field :created_at, TimeType, null: false, field :created_at, TimeType, null: false,
description: 'Timestamp of when the test report was created' description: 'Timestamp of when the test report was created'
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
end end
end end
end end
...@@ -8,22 +8,16 @@ module Types ...@@ -8,22 +8,16 @@ module Types
field :enabled, [::Types::SecurityScannerTypeEnum], null: true, field :enabled, [::Types::SecurityScannerTypeEnum], null: true,
description: 'List of analyzers which are enabled for the project.', description: 'List of analyzers which are enabled for the project.',
calls_gitaly: true, method: :enabled_scanners,
resolve: -> (project, _args, ctx) do calls_gitaly: true
project.enabled_scanners
end
field :available, [::Types::SecurityScannerTypeEnum], null: true, field :available, [::Types::SecurityScannerTypeEnum], null: true,
description: 'List of analyzers which are available for the project.', description: 'List of analyzers which are available for the project.',
resolve: -> (project, _args, ctx) do method: :available_scanners
project.available_scanners
end
field :pipeline_run, [::Types::SecurityScannerTypeEnum], null: true, field :pipeline_run, [::Types::SecurityScannerTypeEnum], null: true,
description: 'List of analyzers which ran successfully in the latest pipeline.', description: 'List of analyzers which ran successfully in the latest pipeline.',
calls_gitaly: true, method: :scanners_run_in_last_pipeline,
resolve: -> (project, _args, ctx) do calls_gitaly: true
project.scanners_run_in_last_pipeline
end
end end
end end
...@@ -19,18 +19,24 @@ module Types ...@@ -19,18 +19,24 @@ module Types
field :user, field :user,
Types::UserType, Types::UserType,
null: false, null: false,
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.user_id).find },
description: 'The user that logged the time' description: 'The user that logged the time'
field :issue, field :issue,
Types::IssueType, Types::IssueType,
null: true, null: true,
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Issue, obj.issue_id).find },
description: 'The issue that logged time was added to' description: 'The issue that logged time was added to'
field :note, field :note,
Types::Notes::NoteType, Types::Notes::NoteType,
null: true, null: true,
description: 'The note where the quick action to add the logged time was executed' description: 'The note where the quick action to add the logged time was executed'
def user
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
end
def issue
Gitlab::Graphql::Loaders::BatchModelLoader.new(Issue, object.issue_id).find
end
end end
end end
...@@ -9,7 +9,7 @@ module Gitlab ...@@ -9,7 +9,7 @@ module Gitlab
field :user_permissions, permission_type, field :user_permissions, permission_type,
description: description, description: description,
null: false, null: false,
resolve: -> (obj, _, _) { obj } method: :itself
end end
end end
end end
......
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