Commit d66db372 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch '247930-graphql-remove-use-of-resolve-procs-from-type-definitions' into 'master'

Remove resolve procs in type defs (Part 3) [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!48043
parents 13772a61 c60e793b
...@@ -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