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