Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/types')
-rw-r--r--app/graphql/types/abuse_report_type.rb2
-rw-r--r--app/graphql/types/analytics/cycle_analytics/value_stream_type.rb5
-rw-r--r--app/graphql/types/analytics/cycle_analytics/value_streams/stage_event_enum.rb18
-rw-r--r--app/graphql/types/analytics/cycle_analytics/value_streams/stage_type.rb54
-rw-r--r--app/graphql/types/ci/catalog/resource_scope_enum.rb1
-rw-r--r--app/graphql/types/ci/catalog/resource_type.rb51
-rw-r--r--app/graphql/types/ci/catalog/resources/component_type.rb41
-rw-r--r--app/graphql/types/ci/catalog/resources/components/input_type.rb29
-rw-r--r--app/graphql/types/ci/catalog/resources/version_sort_enum.rb14
-rw-r--r--app/graphql/types/ci/catalog/resources/version_type.rb54
-rw-r--r--app/graphql/types/container_registry/protection/rule_type.rb4
-rw-r--r--app/graphql/types/container_repository_tag_type.rb10
-rw-r--r--app/graphql/types/container_repository_type.rb10
-rw-r--r--app/graphql/types/current_user_type.rb12
-rw-r--r--app/graphql/types/group_connection.rb22
-rw-r--r--app/graphql/types/group_type.rb15
-rw-r--r--app/graphql/types/issue_connection.rb22
-rw-r--r--app/graphql/types/issue_type.rb10
-rw-r--r--app/graphql/types/issue_type_enum.rb16
-rw-r--r--app/graphql/types/merge_requests/detailed_merge_status_enum.rb3
-rw-r--r--app/graphql/types/merge_requests/mergeability_check_identifier_enum.rb2
-rw-r--r--app/graphql/types/ml/candidate_links_type.rb20
-rw-r--r--app/graphql/types/ml/candidate_type.rb23
-rw-r--r--app/graphql/types/ml/model_type.rb22
-rw-r--r--app/graphql/types/ml/model_version_links_type.rb17
-rw-r--r--app/graphql/types/ml/model_version_type.rb22
-rw-r--r--app/graphql/types/mutation_type.rb9
-rw-r--r--app/graphql/types/namespace/package_settings_type.rb6
-rw-r--r--app/graphql/types/organizations/organization_type.rb19
-rw-r--r--app/graphql/types/permission_types/abuse_report.rb11
-rw-r--r--app/graphql/types/permission_types/container_repository.rb13
-rw-r--r--app/graphql/types/permission_types/container_repository_tag.rb13
-rw-r--r--app/graphql/types/project_feature_access_level_enum.rb12
-rw-r--r--app/graphql/types/project_feature_access_level_type.rb18
-rw-r--r--app/graphql/types/project_type.rb35
-rw-r--r--app/graphql/types/query_type.rb21
-rw-r--r--app/graphql/types/security/codequality_reports_comparer/degradation_type.rb2
-rw-r--r--app/graphql/types/user_interface.rb4
-rw-r--r--app/graphql/types/user_preferences_type.rb4
-rw-r--r--app/graphql/types/user_type.rb2
-rw-r--r--app/graphql/types/work_item_state_counts_type.rb25
-rw-r--r--app/graphql/types/work_item_type.rb6
-rw-r--r--app/graphql/types/work_items/deleted_task_input_type.rb19
-rw-r--r--app/graphql/types/work_items/type_type.rb20
-rw-r--r--app/graphql/types/work_items/widget_definition_interface.rb39
-rw-r--r--app/graphql/types/work_items/widget_definitions/assignees_type.rb32
-rw-r--r--app/graphql/types/work_items/widget_definitions/generic_type.rb16
-rw-r--r--app/graphql/types/work_items/widget_definitions/hierarchy_type.rb26
-rw-r--r--app/graphql/types/work_items/widgets/assignees_type.rb14
-rw-r--r--app/graphql/types/work_items/widgets/labels_type.rb7
50 files changed, 709 insertions, 163 deletions
diff --git a/app/graphql/types/abuse_report_type.rb b/app/graphql/types/abuse_report_type.rb
index 2532530cfa9..dc40800af94 100644
--- a/app/graphql/types/abuse_report_type.rb
+++ b/app/graphql/types/abuse_report_type.rb
@@ -10,8 +10,6 @@ module Types
authorize :read_abuse_report
- expose_permissions Types::PermissionTypes::AbuseReport
-
field :id, Types::GlobalIDType[::AbuseReport],
null: false, description: 'Global ID of the abuse report.'
diff --git a/app/graphql/types/analytics/cycle_analytics/value_stream_type.rb b/app/graphql/types/analytics/cycle_analytics/value_stream_type.rb
index 16ce9b82718..900d2873789 100644
--- a/app/graphql/types/analytics/cycle_analytics/value_stream_type.rb
+++ b/app/graphql/types/analytics/cycle_analytics/value_stream_type.rb
@@ -26,6 +26,11 @@ module Types
null: true,
description: 'Project the value stream belongs to, returns empty if it belongs to a group.',
alpha: { milestone: '15.6' }
+
+ field :stages,
+ null: true,
+ resolver: Resolvers::Analytics::CycleAnalytics::StagesResolver,
+ description: 'Value Stream stages.'
end
end
end
diff --git a/app/graphql/types/analytics/cycle_analytics/value_streams/stage_event_enum.rb b/app/graphql/types/analytics/cycle_analytics/value_streams/stage_event_enum.rb
new file mode 100644
index 00000000000..f7fd1121e4a
--- /dev/null
+++ b/app/graphql/types/analytics/cycle_analytics/value_streams/stage_event_enum.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Types
+ module Analytics
+ module CycleAnalytics
+ module ValueStreams
+ class StageEventEnum < BaseEnum
+ graphql_name 'ValueStreamStageEvent'
+ description 'Stage event identifiers'
+
+ Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum.each do |key, value|
+ value(key.to_s.upcase, description: "#{key.to_s.humanize} event.", value: value)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/analytics/cycle_analytics/value_streams/stage_type.rb b/app/graphql/types/analytics/cycle_analytics/value_streams/stage_type.rb
new file mode 100644
index 00000000000..c8fdf8513be
--- /dev/null
+++ b/app/graphql/types/analytics/cycle_analytics/value_streams/stage_type.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Types
+ module Analytics
+ module CycleAnalytics
+ module ValueStreams
+ # rubocop: disable Graphql/AuthorizeTypes -- # Already authorized in parent value stream type.
+ class StageType < BaseObject
+ graphql_name 'ValueStreamStage'
+
+ field :name,
+ GraphQL::Types::String,
+ null: false,
+ description: 'Name of the stage.'
+
+ field :hidden,
+ GraphQL::Types::Boolean,
+ null: false,
+ description: 'Whether the stage is hidden.'
+
+ field :custom,
+ GraphQL::Types::Boolean,
+ null: false,
+ description: 'Whether the stage is customized.'
+
+ field :start_event_identifier,
+ StageEventEnum,
+ null: false,
+ description: 'Start event identifier.'
+
+ field :end_event_identifier,
+ StageEventEnum,
+ null: false,
+ description: 'End event identifier.'
+
+ def start_event_identifier
+ events_enum[object.start_event_identifier]
+ end
+
+ def end_event_identifier
+ events_enum[object.end_event_identifier]
+ end
+
+ def events_enum
+ Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum.with_indifferent_access
+ end
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+ end
+ end
+end
+
+Types::Analytics::CycleAnalytics::ValueStreams::StageType.prepend_mod
diff --git a/app/graphql/types/ci/catalog/resource_scope_enum.rb b/app/graphql/types/ci/catalog/resource_scope_enum.rb
index b825c3a7925..728670ba913 100644
--- a/app/graphql/types/ci/catalog/resource_scope_enum.rb
+++ b/app/graphql/types/ci/catalog/resource_scope_enum.rb
@@ -8,6 +8,7 @@ module Types
description 'Values for scoping catalog resources'
value 'ALL', 'All catalog resources visible to the current user.', value: :all
+ value 'NAMESPACES', 'Catalog resources belonging to authorized namespaces of the user.', value: :namespaces
end
end
end
diff --git a/app/graphql/types/ci/catalog/resource_type.rb b/app/graphql/types/ci/catalog/resource_type.rb
index 119313ae52b..44dec23b347 100644
--- a/app/graphql/types/ci/catalog/resource_type.rb
+++ b/app/graphql/types/ci/catalog/resource_type.rb
@@ -32,13 +32,14 @@ module Types
field :web_path, GraphQL::Types::String, null: true, description: 'Web path of the catalog resource.',
alpha: { milestone: '16.1' }
- field :versions, Types::ReleaseType.connection_type, null: true,
+ field :versions, Types::Ci::Catalog::Resources::VersionType.connection_type, null: true,
description: 'Versions of the catalog resource. This field can only be ' \
'resolved for one catalog resource in any single request.',
- resolver: Resolvers::Ci::Catalog::VersionsResolver,
+ resolver: Resolvers::Ci::Catalog::Resources::VersionsResolver,
alpha: { milestone: '16.2' }
- field :latest_version, Types::ReleaseType, null: true, description: 'Latest version of the catalog resource.',
+ field :latest_version, Types::Ci::Catalog::Resources::VersionType, null: true,
+ description: 'Latest version of the catalog resource.',
alpha: { milestone: '16.1' }
field :latest_released_at, Types::TimeType, null: true,
@@ -49,14 +50,6 @@ module Types
description: 'Number of times the catalog resource has been starred.',
alpha: { milestone: '16.1' }
- field :forks_count, GraphQL::Types::Int, null: false, calls_gitaly: true,
- description: 'Number of times the catalog resource has been forked.',
- alpha: { milestone: '16.1' }
-
- field :root_namespace, Types::NamespaceType, null: true,
- description: 'Root namespace of the catalog resource.',
- alpha: { milestone: '16.1' }
-
markdown_field :readme_html, null: false,
alpha: { milestone: '16.1' }
@@ -73,42 +66,16 @@ module Types
end
def latest_version
- BatchLoader::GraphQL.for(object.project).batch do |projects, loader|
- latest_releases = ReleasesFinder.new(projects, current_user, latest: true).execute
+ BatchLoader::GraphQL.for(object).batch do |catalog_resources, loader|
+ latest_versions = ::Ci::Catalog::Resources::VersionsFinder.new(
+ catalog_resources, current_user, latest: true).execute
- latest_releases.index_by(&:project).each do |project, latest_release|
- loader.call(project, latest_release)
+ latest_versions.index_by(&:catalog_resource).each do |catalog_resource, latest_version|
+ loader.call(catalog_resource, latest_version)
end
end
end
- def forks_count
- BatchLoader::GraphQL.wrap(object.forks_count)
- end
-
- def root_namespace
- BatchLoader::GraphQL.for(object.project_id).batch do |project_ids, loader|
- projects = Project.id_in(project_ids)
-
- # This preloader uses traversal_ids to obtain Group-type root namespaces.
- # It also preloads each project's immediate parent namespace, which effectively
- # preloads the User-type root namespaces since they cannot be nested (parent == root).
- Preloaders::ProjectRootAncestorPreloader.new(projects, :group).execute
- root_namespaces = projects.map(&:root_ancestor)
-
- # NamespaceType requires the `:read_namespace` ability. We must preload the policy for
- # Group-type namespaces to avoid N+1 queries caused by the authorization requests.
- group_root_namespaces = root_namespaces.select { |n| n.type == ::Group.sti_name }
- Preloaders::GroupPolicyPreloader.new(group_root_namespaces, current_user).execute
-
- # For User-type namespaces, the authorization request requires preloading the owner objects.
- user_root_namespaces = root_namespaces.select { |n| n.type == ::Namespaces::UserNamespace.sti_name }
- ActiveRecord::Associations::Preloader.new(records: user_root_namespaces, associations: :owner).call
-
- projects.each { |project| loader.call(project.id, project.root_ancestor) }
- end
- end
-
def readme_html_resolver
markdown_context = context.to_h.dup.merge(project: object.project)
::MarkupHelper.markdown(object.project.repository.readme&.data, markdown_context)
diff --git a/app/graphql/types/ci/catalog/resources/component_type.rb b/app/graphql/types/ci/catalog/resources/component_type.rb
new file mode 100644
index 00000000000..3b4771446cb
--- /dev/null
+++ b/app/graphql/types/ci/catalog/resources/component_type.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ module Catalog
+ module Resources
+ # rubocop: disable Graphql/AuthorizeTypes -- Authorization is handled by VersionType
+ class ComponentType < BaseObject
+ graphql_name 'CiCatalogResourceComponent'
+
+ field :id, ::Types::GlobalIDType[::Ci::Catalog::Resources::Component], null: false,
+ description: 'ID of the component.',
+ alpha: { milestone: '16.7' }
+
+ field :name, GraphQL::Types::String, null: true,
+ description: 'Name of the component.',
+ alpha: { milestone: '16.7' }
+
+ field :path, GraphQL::Types::String, null: true,
+ description: 'Path used to include the component.',
+ alpha: { milestone: '16.7' }
+
+ field :inputs, [Types::Ci::Catalog::Resources::Components::InputType], null: true,
+ description: 'Inputs for the component.',
+ alpha: { milestone: '16.7' }
+
+ def inputs
+ object.inputs.map do |key, value|
+ {
+ name: key,
+ required: !value&.key?('default'),
+ default: value&.dig('default')
+ }
+ end
+ end
+ end
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+ end
+end
diff --git a/app/graphql/types/ci/catalog/resources/components/input_type.rb b/app/graphql/types/ci/catalog/resources/components/input_type.rb
new file mode 100644
index 00000000000..4b20c564ea7
--- /dev/null
+++ b/app/graphql/types/ci/catalog/resources/components/input_type.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ module Catalog
+ module Resources
+ module Components
+ # rubocop: disable Graphql/AuthorizeTypes -- Authorization hanlded by ComponentType -> VersionType
+ class InputType < BaseObject
+ graphql_name 'CiCatalogResourceComponentInput'
+
+ field :name, GraphQL::Types::String, null: true,
+ description: 'Name of the input.',
+ alpha: { milestone: '16.7' }
+
+ field :default, GraphQL::Types::String, null: true,
+ description: 'Default value for the input.',
+ alpha: { milestone: '16.7' }
+
+ field :required, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if an input is required.',
+ alpha: { milestone: '16.7' }
+ end
+ end
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+ end
+end
diff --git a/app/graphql/types/ci/catalog/resources/version_sort_enum.rb b/app/graphql/types/ci/catalog/resources/version_sort_enum.rb
new file mode 100644
index 00000000000..c5a5f46605a
--- /dev/null
+++ b/app/graphql/types/ci/catalog/resources/version_sort_enum.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ module Catalog
+ module Resources
+ class VersionSortEnum < Types::ReleaseSortEnum
+ graphql_name 'CiCatalogResourceVersionSort'
+ description 'Values for sorting catalog resource versions'
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/catalog/resources/version_type.rb b/app/graphql/types/ci/catalog/resources/version_type.rb
new file mode 100644
index 00000000000..689f649afc5
--- /dev/null
+++ b/app/graphql/types/ci/catalog/resources/version_type.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ module Catalog
+ module Resources
+ # rubocop: disable Graphql/AuthorizeTypes -- Authorization is handled by Ci::Catalog::Resources::VersionsFinder in the resolver.
+ class VersionType < BaseObject
+ graphql_name 'CiCatalogResourceVersion'
+
+ connection_type_class Types::CountableConnectionType
+
+ field :id, ::Types::GlobalIDType[::Ci::Catalog::Resources::Version], null: false,
+ description: 'Global ID of the version.',
+ alpha: { milestone: '16.7' }
+
+ field :created_at, Types::TimeType, null: true, description: 'Timestamp of when the version was created.',
+ alpha: { milestone: '16.7' }
+
+ field :released_at, Types::TimeType, null: true, description: 'Timestamp of when the version was released.',
+ alpha: { milestone: '16.7' }
+
+ field :tag_name, GraphQL::Types::String, null: true, method: :name,
+ description: 'Name of the tag associated with the version.',
+ alpha: { milestone: '16.7' }
+
+ field :tag_path, GraphQL::Types::String, null: true,
+ description: 'Relative web path to the tag associated with the version.',
+ alpha: { milestone: '16.7' }
+
+ field :author, Types::UserType, null: true, description: 'User that created the version.',
+ alpha: { milestone: '16.7' }
+
+ field :commit, Types::CommitType, null: true, complexity: 10, calls_gitaly: true,
+ description: 'Commit associated with the version.',
+ alpha: { milestone: '16.7' }
+
+ field :components, Types::Ci::Catalog::Resources::ComponentType.connection_type, null: true,
+ description: 'Components belonging to the catalog resource.',
+ alpha: { milestone: '16.7' }
+
+ def author
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
+ end
+
+ def tag_path
+ Gitlab::Routing.url_helpers.project_tag_path(object.project, object.name)
+ end
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/container_registry/protection/rule_type.rb b/app/graphql/types/container_registry/protection/rule_type.rb
index 387f0202d2d..b80439b4de2 100644
--- a/app/graphql/types/container_registry/protection/rule_type.rb
+++ b/app/graphql/types/container_registry/protection/rule_type.rb
@@ -15,12 +15,12 @@ module Types
null: false,
description: 'ID of the container registry protection rule.'
- field :container_path_pattern,
+ field :repository_path_pattern,
GraphQL::Types::String,
null: false,
description:
'Container repository path pattern protected by the protection rule. ' \
- 'For example `@my-scope/my-container-*`. Wildcard character `*` allowed.'
+ 'For example `my-project/my-container-*`. Wildcard character `*` allowed.'
field :push_protected_up_to_access_level,
Types::ContainerRegistry::Protection::RuleAccessLevelEnum,
diff --git a/app/graphql/types/container_repository_tag_type.rb b/app/graphql/types/container_repository_tag_type.rb
index d9665175449..cf8796410d3 100644
--- a/app/graphql/types/container_repository_tag_type.rb
+++ b/app/graphql/types/container_repository_tag_type.rb
@@ -8,7 +8,15 @@ module Types
authorize :read_container_image
- field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete this tag.'
+ expose_permissions Types::PermissionTypes::ContainerRepositoryTag
+
+ field :can_delete, GraphQL::Types::Boolean,
+ null: false,
+ deprecated: {
+ reason: 'Use `userPermissions` field. See `ContainerRepositoryTagPermissions` type',
+ milestone: '16.7'
+ },
+ description: 'Can the current user delete this tag.'
field :created_at, Types::TimeType, null: true, description: 'Timestamp when the tag was created.'
field :digest, GraphQL::Types::String, null: true, description: 'Digest of the tag.'
field :location, GraphQL::Types::String, null: false, description: 'URL of the tag.'
diff --git a/app/graphql/types/container_repository_type.rb b/app/graphql/types/container_repository_type.rb
index dfa599e798c..c2a7eae5f94 100644
--- a/app/graphql/types/container_repository_type.rb
+++ b/app/graphql/types/container_repository_type.rb
@@ -8,7 +8,15 @@ module Types
authorize :read_container_image
- field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete the container repository.'
+ expose_permissions Types::PermissionTypes::ContainerRepository
+
+ field :can_delete, GraphQL::Types::Boolean,
+ null: false,
+ deprecated: {
+ reason: 'Use `userPermissions` field. See `ContainerRepositoryPermissions` type',
+ milestone: '16.7'
+ },
+ description: 'Can the current user delete the container repository.'
field :created_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was created.'
field :expiration_policy_cleanup_status, Types::ContainerRepositoryCleanupStatusEnum, null: true, description: 'Tags cleanup status for the container repository.'
field :expiration_policy_started_at, Types::TimeType, null: true, description: 'Timestamp when the cleanup done by the expiration policy was started on the container repository.'
diff --git a/app/graphql/types/current_user_type.rb b/app/graphql/types/current_user_type.rb
new file mode 100644
index 00000000000..d5ecdeba9e2
--- /dev/null
+++ b/app/graphql/types/current_user_type.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop:disable Graphql/AuthorizeTypes -- This is not necessary because the superclass declares the authorization
+ class CurrentUserType < ::Types::UserType
+ graphql_name 'CurrentUser'
+ description 'The currently authenticated GitLab user.'
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+end
+
+::Types::CurrentUserType.prepend_mod
diff --git a/app/graphql/types/group_connection.rb b/app/graphql/types/group_connection.rb
deleted file mode 100644
index e4332e24302..00000000000
--- a/app/graphql/types/group_connection.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-# Normally this wouldn't be needed and we could use
-#
-# type Types::GroupType.connection_type, null: true
-#
-# in a resolver. However we can end up with cyclic definitions.
-# Running the spec locally can result in errors like
-#
-# NameError: uninitialized constant Types::GroupType
-#
-# or other errors. To fix this, we created this file and use
-#
-# type "Types::GroupConnection", null: true
-#
-# which gives a delayed resolution, and the proper connection type.
-#
-# See gitlab/app/graphql/types/ci/runner_type.rb
-# Reference: https://github.com/rmosolgo/graphql-ruby/issues/3974#issuecomment-1084444214
-# and https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#testing-tips-and-tricks
-#
-Types::GroupConnection = Types::GroupType.connection_type
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 74e7f256b44..7234948033b 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -21,7 +21,8 @@ module Types
field :custom_emoji,
type: Types::CustomEmojiType.connection_type,
null: true,
- description: 'Custom emoji within this namespace.',
+ resolver: Resolvers::CustomEmojiResolver,
+ description: 'Custom emoji in this namespace.',
alpha: { milestone: '13.6' }
field :share_with_group_lock,
@@ -274,6 +275,14 @@ module Types
description: 'Find a work item by IID directly associated with the group. Returns `null` if the ' \
'`namespace_level_work_items` feature flag is disabled.'
+ field :work_item_state_counts,
+ Types::WorkItemStateCountsType,
+ null: true,
+ alpha: { milestone: '16.7' },
+ description: 'Counts of work items by state for the namespace. Returns `null` if the ' \
+ '`namespace_level_work_items` feature flag is disabled.',
+ resolver: Resolvers::Namespaces::WorkItemStateCountsResolver
+
field :autocomplete_users,
null: true,
resolver: Resolvers::AutocompleteUsersResolver,
@@ -330,10 +339,6 @@ module Types
group.dependency_proxy_setting || group.create_dependency_proxy_setting
end
- def custom_emoji
- object.custom_emoji if Feature.enabled?(:custom_emoji)
- end
-
private
def group
diff --git a/app/graphql/types/issue_connection.rb b/app/graphql/types/issue_connection.rb
deleted file mode 100644
index 2f07888b43e..00000000000
--- a/app/graphql/types/issue_connection.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-# Normally this wouldn't be needed and we could use
-#
-# type Types::IssueType.connection_type, null: true
-#
-# in a resolver. However we can end up with cyclic definitions.
-# Running the spec locally can result in errors like
-#
-# NameError: uninitialized constant Resolvers::GroupIssuesResolver
-#
-# or other errors. To fix this, we created this file and use
-#
-# type "Types::IssueConnection", null: true
-#
-# which gives a delayed resolution, and the proper connection type.
-#
-# See app/graphql/resolvers/base_issues_resolver.rb
-# Reference: https://github.com/rmosolgo/graphql-ruby/issues/3974#issuecomment-1084444214
-# and https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#testing-tips-and-tricks
-#
-Types::IssueConnection = Types::IssueType.connection_type
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 7c7d559e05d..76590f95687 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -91,13 +91,13 @@ module Types
description: 'Web URL of the issue.'
field :emails_disabled, GraphQL::Types::Boolean, null: false,
- method: :project_emails_disabled?,
- description: 'Indicates if a project has email notifications disabled: `true` if email notifications are disabled.',
+ method: :parent_emails_disabled?,
+ description: 'Indicates if the parent project or group has email notifications disabled: `true` if email notifications are disabled.',
deprecated: { reason: 'Use `emails_enabled`', milestone: '16.3' }
field :emails_enabled, GraphQL::Types::Boolean, null: false,
- method: :project_emails_enabled?,
- description: 'Indicates if a project has email notifications disabled: `false` if email notifications are disabled.'
+ method: :parent_emails_enabled?,
+ description: 'Indicates if the parent project or group has email notifications disabled: `false` if email notifications are disabled.'
field :human_time_estimate, GraphQL::Types::String, null: true,
description: 'Human-readable time estimate of the issue.'
@@ -162,7 +162,7 @@ module Types
field :timelogs, Types::TimelogType.connection_type, null: false,
description: 'Timelogs on the issue.'
- field :project_id, GraphQL::Types::Int, null: false, method: :project_id,
+ field :project_id, GraphQL::Types::Int, null: true, method: :project_id,
description: 'ID of the issue project.'
field :customer_relations_contacts, Types::CustomerRelations::ContactType.connection_type, null: true,
diff --git a/app/graphql/types/issue_type_enum.rb b/app/graphql/types/issue_type_enum.rb
index d7f587ff03d..491fc3d7fac 100644
--- a/app/graphql/types/issue_type_enum.rb
+++ b/app/graphql/types/issue_type_enum.rb
@@ -9,16 +9,16 @@ module Types
value issue_type.upcase, value: issue_type, description: "#{issue_type.titleize} issue type"
end
- value 'TASK', value: 'task',
- description: 'Task issue type.',
- alpha: { milestone: '15.2' }
-
value 'OBJECTIVE', value: 'objective',
- description: 'Objective issue type. Available only when feature flag `okrs_mvc` is enabled.',
- alpha: { milestone: '15.6' }
+ description: 'Objective issue type. Available only when feature flag `okrs_mvc` is enabled.',
+ alpha: { milestone: '15.6' }
value 'KEY_RESULT', value: 'key_result',
- description: 'Key Result issue type. Available only when feature flag `okrs_mvc` is enabled.',
- alpha: { milestone: '15.7' }
+ description: 'Key Result issue type. Available only when feature flag `okrs_mvc` is enabled.',
+ alpha: { milestone: '15.7' }
+ value 'EPIC', value: 'epic',
+ description: 'Epic issue type. ' \
+ 'Available only when feature flag `namespace_level_work_items` is enabled.',
+ alpha: { milestone: '16.7' }
end
end
diff --git a/app/graphql/types/merge_requests/detailed_merge_status_enum.rb b/app/graphql/types/merge_requests/detailed_merge_status_enum.rb
index e7246068a05..d2d0cfd23a4 100644
--- a/app/graphql/types/merge_requests/detailed_merge_status_enum.rb
+++ b/app/graphql/types/merge_requests/detailed_merge_status_enum.rb
@@ -48,6 +48,9 @@ module Types
value 'PREPARING',
value: :preparing,
description: 'Merge request diff is being created.'
+ value 'JIRA_ASSOCIATION',
+ value: :jira_association_missing,
+ description: 'Either the title or description must reference a Jira issue.'
end
end
end
diff --git a/app/graphql/types/merge_requests/mergeability_check_identifier_enum.rb b/app/graphql/types/merge_requests/mergeability_check_identifier_enum.rb
index ac25c98941c..d5e63d9c9ca 100644
--- a/app/graphql/types/merge_requests/mergeability_check_identifier_enum.rb
+++ b/app/graphql/types/merge_requests/mergeability_check_identifier_enum.rb
@@ -11,7 +11,7 @@ module Types
value identifier.upcase,
value: identifier,
- description: "Mergeability check identifier is #{identifier}."
+ description: check_class.description
end
end
end
diff --git a/app/graphql/types/ml/candidate_links_type.rb b/app/graphql/types/ml/candidate_links_type.rb
new file mode 100644
index 00000000000..f14ab6bbc4a
--- /dev/null
+++ b/app/graphql/types/ml/candidate_links_type.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Types
+ module Ml
+ # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+ class CandidateLinksType < BaseObject
+ graphql_name 'MLCandidateLinks'
+ description 'Represents links to perform actions on the candidate'
+
+ present_using ::Ml::CandidatePresenter
+
+ field :show_path, GraphQL::Types::String,
+ null: true, description: 'Path to the details page of the candidate.', method: :path
+
+ field :artifact_path, GraphQL::Types::String,
+ null: true, description: 'Path to the artifact.', method: :artifact_path
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+end
diff --git a/app/graphql/types/ml/candidate_type.rb b/app/graphql/types/ml/candidate_type.rb
new file mode 100644
index 00000000000..bee045c47bf
--- /dev/null
+++ b/app/graphql/types/ml/candidate_type.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Types
+ module Ml
+ # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+ class CandidateType < ::Types::BaseObject
+ graphql_name 'MlCandidate'
+ description 'Candidate for a model version in the model registry'
+
+ connection_type_class Types::LimitedCountableConnectionType
+
+ field :id, ::Types::GlobalIDType[::Ml::Candidate], null: false, description: 'ID of the candidate.'
+
+ field :name, ::GraphQL::Types::String, null: false, description: 'Name of the candidate.'
+
+ field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
+
+ field :_links, ::Types::Ml::CandidateLinksType, null: false, method: :itself,
+ description: 'Map of links to perform actions on the candidate.'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+end
diff --git a/app/graphql/types/ml/model_type.rb b/app/graphql/types/ml/model_type.rb
new file mode 100644
index 00000000000..ca63918b370
--- /dev/null
+++ b/app/graphql/types/ml/model_type.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Types
+ module Ml
+ # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+ class ModelType < ::Types::BaseObject
+ graphql_name 'MlModel'
+ description 'Machine learning model in the model registry'
+
+ field :id, ::Types::GlobalIDType[::Ml::Model], null: false, description: 'ID of the model.'
+
+ field :name, ::GraphQL::Types::String, null: false, description: 'Name of the model.'
+
+ field :versions, ::Types::Ml::ModelVersionType.connection_type, null: true,
+ description: 'Versions of the model.'
+
+ field :candidates, ::Types::Ml::CandidateType.connection_type, null: true,
+ description: 'Version candidates of the model.'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+end
diff --git a/app/graphql/types/ml/model_version_links_type.rb b/app/graphql/types/ml/model_version_links_type.rb
new file mode 100644
index 00000000000..142f62bfad2
--- /dev/null
+++ b/app/graphql/types/ml/model_version_links_type.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Types
+ module Ml
+ # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+ class ModelVersionLinksType < BaseObject
+ graphql_name 'MLModelVersionLinks'
+ description 'Represents links to perform actions on the model version'
+
+ present_using ::Ml::ModelVersionPresenter
+
+ field :show_path, GraphQL::Types::String,
+ null: true, description: 'Path to the details page of the model version.', method: :path
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+end
diff --git a/app/graphql/types/ml/model_version_type.rb b/app/graphql/types/ml/model_version_type.rb
new file mode 100644
index 00000000000..15c36a7a0d8
--- /dev/null
+++ b/app/graphql/types/ml/model_version_type.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Types
+ module Ml
+ # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+ class ModelVersionType < ::Types::BaseObject
+ graphql_name 'MlModelVersion'
+ description 'Version of a machine learning model'
+
+ connection_type_class Types::LimitedCountableConnectionType
+
+ field :id, ::Types::GlobalIDType[::Ml::ModelVersion], null: false, description: 'ID of the model version.'
+
+ field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
+ field :version, ::GraphQL::Types::String, null: false, description: 'Name of the version.'
+
+ field :_links, ::Types::Ml::ModelVersionLinksType, null: false, method: :itself,
+ description: 'Map of links to perform actions on the model version.'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+ end
+end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index e1bd1f603ad..590bc0ed282 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -107,7 +107,10 @@ module Types
mount_mutation Mutations::Notes::RepositionImageDiffNote
mount_mutation Mutations::Notes::Destroy
mount_mutation Mutations::Organizations::Create, alpha: { milestone: '16.6' }
+ mount_mutation Mutations::Organizations::Update, alpha: { milestone: '16.7' }
mount_mutation Mutations::Projects::SyncFork, calls_gitaly: true, alpha: { milestone: '15.9' }
+ mount_mutation Mutations::Projects::Star, alpha: { milestone: '16.7' }
+ mount_mutation Mutations::BranchRules::Update, alpha: { milestone: '16.7' }
mount_mutation Mutations::Releases::Create
mount_mutation Mutations::Releases::Update
mount_mutation Mutations::Releases::Delete
@@ -136,10 +139,12 @@ module Types
mount_mutation Mutations::DesignManagement::Update
mount_mutation Mutations::ContainerExpirationPolicies::Update
mount_mutation Mutations::ContainerRegistry::Protection::Rule::Create, alpha: { milestone: '16.6' }
+ mount_mutation Mutations::ContainerRegistry::Protection::Rule::Delete, alpha: { milestone: '16.7' }
+ mount_mutation Mutations::ContainerRegistry::Protection::Rule::Update, alpha: { milestone: '16.7' }
mount_mutation Mutations::ContainerRepositories::Destroy
mount_mutation Mutations::ContainerRepositories::DestroyTags
mount_mutation Mutations::Ci::Catalog::Resources::Create, alpha: { milestone: '15.11' }
- mount_mutation Mutations::Ci::Catalog::Resources::Unpublish, alpha: { milestone: '16.6' }
+ mount_mutation Mutations::Ci::Catalog::Resources::Destroy, alpha: { milestone: '16.6' }
mount_mutation Mutations::Ci::Job::Cancel
mount_mutation Mutations::Ci::Job::Play
mount_mutation Mutations::Ci::Job::Retry
@@ -176,13 +181,13 @@ module Types
mount_mutation Mutations::Packages::DestroyFile
mount_mutation Mutations::Packages::Protection::Rule::Create, alpha: { milestone: '16.5' }
mount_mutation Mutations::Packages::Protection::Rule::Delete, alpha: { milestone: '16.6' }
+ mount_mutation Mutations::Packages::Protection::Rule::Update, alpha: { milestone: '16.6' }
mount_mutation Mutations::Packages::DestroyFiles
mount_mutation Mutations::Packages::Cleanup::Policy::Update
mount_mutation Mutations::Echo
mount_mutation Mutations::WorkItems::Create, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::CreateFromTask, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::Delete, alpha: { milestone: '15.1' }
- mount_mutation Mutations::WorkItems::DeleteTask, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::Update, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::UpdateTask, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::Export, alpha: { milestone: '15.10' }
diff --git a/app/graphql/types/namespace/package_settings_type.rb b/app/graphql/types/namespace/package_settings_type.rb
index 6c6144f2357..7bf76ae7de5 100644
--- a/app/graphql/types/namespace/package_settings_type.rb
+++ b/app/graphql/types/namespace/package_settings_type.rb
@@ -31,7 +31,7 @@ module Types
description: 'When nuget_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. '
field :nuget_duplicates_allowed, GraphQL::Types::Boolean,
null: false,
- description: 'Indicates whether duplicate NuGet packages are allowed for this namespace. '
+ description: 'Indicates whether duplicate NuGet packages are allowed for this namespace.'
field :pypi_package_requests_forwarding, GraphQL::Types::Boolean,
null: true,
description: 'Indicates whether PyPI package forwarding is allowed for this namespace.'
@@ -58,5 +58,9 @@ module Types
null: false,
method: :pypi_package_requests_forwarding_locked?,
description: 'Indicates whether PyPI package forwarding settings are locked by a parent namespace.'
+
+ field :nuget_symbol_server_enabled, GraphQL::Types::Boolean,
+ null: false,
+ description: 'Indicates wheather the NuGet symbol server is enabled for this namespace.'
end
end
diff --git a/app/graphql/types/organizations/organization_type.rb b/app/graphql/types/organizations/organization_type.rb
index e7ba8de527c..379bf9956a3 100644
--- a/app/graphql/types/organizations/organization_type.rb
+++ b/app/graphql/types/organizations/organization_type.rb
@@ -7,6 +7,16 @@ module Types
authorize :read_organization
+ field :avatar_url,
+ type: GraphQL::Types::String,
+ null: true,
+ description: 'Avatar URL of the organization.',
+ alpha: { milestone: '16.7' }
+ field :description,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Description of the organization.',
+ alpha: { milestone: '16.7' }
field :groups,
Types::GroupType.connection_type,
null: false,
@@ -33,10 +43,17 @@ module Types
null: false,
description: 'Path of the organization.',
alpha: { milestone: '16.4' }
- field :web_url, GraphQL::Types::String,
+ field :web_url,
+ GraphQL::Types::String,
null: false,
description: 'Web URL of the organization.',
alpha: { milestone: '16.6' }
+
+ markdown_field :description_html, null: true, alpha: { milestone: '16.7' }, &:organization_detail
+
+ def avatar_url
+ object.avatar_url(only_path: false)
+ end
end
end
end
diff --git a/app/graphql/types/permission_types/abuse_report.rb b/app/graphql/types/permission_types/abuse_report.rb
deleted file mode 100644
index abd5d545d02..00000000000
--- a/app/graphql/types/permission_types/abuse_report.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-module Types
- module PermissionTypes
- class AbuseReport < BasePermissionType
- graphql_name 'AbuseReportPermissions'
-
- abilities :read_abuse_report, :create_note
- end
- end
-end
diff --git a/app/graphql/types/permission_types/container_repository.rb b/app/graphql/types/permission_types/container_repository.rb
new file mode 100644
index 00000000000..f6a76fb4d94
--- /dev/null
+++ b/app/graphql/types/permission_types/container_repository.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+ module PermissionTypes
+ class ContainerRepository < BasePermissionType
+ graphql_name 'ContainerRepositoryPermissions'
+
+ ability_field :destroy_container_image,
+ name: 'destroy_container_repository',
+ resolver_method: :destroy_container_image
+ end
+ end
+end
diff --git a/app/graphql/types/permission_types/container_repository_tag.rb b/app/graphql/types/permission_types/container_repository_tag.rb
new file mode 100644
index 00000000000..e2317ccd7d7
--- /dev/null
+++ b/app/graphql/types/permission_types/container_repository_tag.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+ module PermissionTypes
+ class ContainerRepositoryTag < BasePermissionType
+ graphql_name 'ContainerRepositoryTagPermissions'
+
+ ability_field :destroy_container_image,
+ name: 'destroy_container_repository_tag',
+ resolver_method: :destroy_container_image
+ end
+ end
+end
diff --git a/app/graphql/types/project_feature_access_level_enum.rb b/app/graphql/types/project_feature_access_level_enum.rb
new file mode 100644
index 00000000000..a107dbedc52
--- /dev/null
+++ b/app/graphql/types/project_feature_access_level_enum.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class ProjectFeatureAccessLevelEnum < BaseEnum
+ graphql_name 'ProjectFeatureAccessLevel'
+ description 'Access level of a project feature'
+
+ value 'DISABLED', value: ProjectFeature::DISABLED, description: 'Not enabled for anyone.'
+ value 'PRIVATE', value: ProjectFeature::PRIVATE, description: 'Enabled only for team members.'
+ value 'ENABLED', value: ProjectFeature::ENABLED, description: 'Enabled for everyone able to access the project.'
+ end
+end
diff --git a/app/graphql/types/project_feature_access_level_type.rb b/app/graphql/types/project_feature_access_level_type.rb
new file mode 100644
index 00000000000..d6d9fdefa70
--- /dev/null
+++ b/app/graphql/types/project_feature_access_level_type.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+# rubocop:disable Graphql/AuthorizeTypes -- It just returns the value of an enum as an integer and a string
+module Types
+ class ProjectFeatureAccessLevelType < Types::BaseObject
+ graphql_name 'ProjectFeatureAccess'
+ description 'Represents the access level required by the user to access a project feature'
+
+ field :integer_value, GraphQL::Types::Int, null: true,
+ description: 'Integer representation of access level.',
+ method: :to_i
+
+ field :string_value, Types::ProjectFeatureAccessLevelEnum, null: true,
+ description: 'String representation of access level.',
+ method: :to_i
+ end
+end
+# rubocop:enable Graphql/AuthorizeTypes
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index ec87f133843..8e84605cb05 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -151,6 +151,10 @@ module Types
null: true,
description: 'Number of open issues for the project.'
+ field :open_merge_requests_count, GraphQL::Types::Int,
+ null: true,
+ description: 'Number of open merge requests for the project.'
+
field :allow_merge_on_skipped_pipeline, GraphQL::Types::Boolean,
null: true,
description: 'If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of ' \
@@ -250,6 +254,13 @@ module Types
extras: [:lookahead],
resolver: Resolvers::WorkItemsResolver
+ field :work_item_state_counts,
+ Types::WorkItemStateCountsType,
+ null: true,
+ alpha: { milestone: '16.7' },
+ description: 'Counts of work items by state for the project.',
+ resolver: Resolvers::WorkItemStateCountsResolver
+
field :issue_status_counts,
Types::IssueStatusCountsType,
null: true,
@@ -647,6 +658,11 @@ module Types
description: 'Detailed import status of the project.',
method: :import_state
+ field :value_streams,
+ description: 'Value streams available to the project.',
+ null: true,
+ resolver: Resolvers::Analytics::CycleAnalytics::ValueStreamsResolver
+
def timelog_categories
object.project_namespace.timelog_categories if Feature.enabled?(:timelog_categories)
end
@@ -675,6 +691,19 @@ module Types
end
end
+ [:issues, :forking, :merge_requests].each do |feature|
+ field_name = "#{feature}_access_level"
+ feature_name = feature.to_s.tr("_", " ")
+
+ field field_name, Types::ProjectFeatureAccessLevelType,
+ null: true,
+ description: "Access level required for #{feature_name} access."
+
+ define_method field_name do
+ project.project_feature&.access_level(feature)
+ end
+ end
+
markdown_field :description_html, null: true
def avatar_url
@@ -689,6 +718,12 @@ module Types
BatchLoader::GraphQL.wrap(object.open_issues_count) if object.feature_available?(:issues, context[:current_user])
end
+ def open_merge_requests_count
+ return unless object.feature_available?(:merge_requests, context[:current_user])
+
+ BatchLoader::GraphQL.wrap(object.open_merge_requests_count)
+ end
+
def forks_count
BatchLoader::GraphQL.wrap(object.forks_count)
end
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index 173e877d86c..0e39ff2c030 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -48,7 +48,7 @@ module Types
required: true,
description: 'Global ID of the container repository.'
end
- field :current_user, Types::UserType,
+ field :current_user, Types::CurrentUserType,
null: true,
description: "Get information about current user."
field :design_management, Types::DesignManagementType,
@@ -57,12 +57,10 @@ module Types
field :echo, resolver: Resolvers::EchoResolver
field :frecent_groups, [Types::GroupType],
resolver: Resolvers::Users::FrecentGroupsResolver,
- description: "A user's frecently visited groups. Requires the `frecent_namespaces_suggestions` feature flag to be enabled.",
- alpha: { milestone: '16.6' }
+ description: "A user's frecently visited groups"
field :frecent_projects, [Types::ProjectType],
resolver: Resolvers::Users::FrecentProjectsResolver,
- description: "A user's frecently visited projects. Requires the `frecent_namespaces_suggestions` feature flag to be enabled.",
- alpha: { milestone: '16.6' }
+ description: "A user's frecently visited projects"
field :gitpod_enabled, GraphQL::Types::Boolean,
null: true,
description: "Whether Gitpod is enabled in application settings."
@@ -212,6 +210,19 @@ module Types
description: 'Abuse report labels.',
resolver: Resolvers::AbuseReportLabelsResolver
+ field :ml_model, ::Types::Ml::ModelType,
+ null: true,
+ alpha: { milestone: '16.7' },
+ description: 'Find machine learning models.',
+ resolver: Resolvers::Ml::ModelDetailResolver
+
+ field :work_items_by_reference,
+ null: true,
+ alpha: { milestone: '16.7' },
+ description: 'Find work items by their reference.',
+ extras: [:lookahead],
+ resolver: Resolvers::WorkItemReferencesResolver
+
def design_management
DesignManagementObject.new(nil)
end
diff --git a/app/graphql/types/security/codequality_reports_comparer/degradation_type.rb b/app/graphql/types/security/codequality_reports_comparer/degradation_type.rb
index 7dd47611a2e..d4aca0a3792 100644
--- a/app/graphql/types/security/codequality_reports_comparer/degradation_type.rb
+++ b/app/graphql/types/security/codequality_reports_comparer/degradation_type.rb
@@ -35,7 +35,7 @@ module Types
description: 'URL to the file along with line number.'
field :engine_name, GraphQL::Types::String,
- null: false,
+ null: true,
description: 'Code quality plugin that reported the degradation.'
end
# rubocop: enable Graphql/AuthorizeTypes
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 040711b5f58..7687da35baa 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -178,7 +178,7 @@ module Types
field :twitter,
type: ::GraphQL::Types::String,
null: true,
- description: 'Twitter username of the user.'
+ description: 'X (formerly Twitter) username of the user.'
field :discord,
type: ::GraphQL::Types::String,
@@ -229,5 +229,3 @@ module Types
end
end
end
-
-Types::UserInterface.prepend_mod
diff --git a/app/graphql/types/user_preferences_type.rb b/app/graphql/types/user_preferences_type.rb
index 094c7352c96..e9ac3a28a53 100644
--- a/app/graphql/types/user_preferences_type.rb
+++ b/app/graphql/types/user_preferences_type.rb
@@ -14,6 +14,10 @@ module Types
description: 'Determines whether the pipeline list shows ID or IID.',
null: true
+ field :use_web_ide_extension_marketplace, GraphQL::Types::Boolean,
+ description: 'Whether Web IDE Extension Marketplace is enabled for the user.',
+ null: false
+
def issues_sort
object.issues_sort.to_sym
end
diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb
index 87ca5fddf14..c5910236d51 100644
--- a/app/graphql/types/user_type.rb
+++ b/app/graphql/types/user_type.rb
@@ -14,3 +14,5 @@ module Types
present_using UserPresenter
end
end
+
+Types::UserType.prepend_mod
diff --git a/app/graphql/types/work_item_state_counts_type.rb b/app/graphql/types/work_item_state_counts_type.rb
new file mode 100644
index 00000000000..a5fdf542464
--- /dev/null
+++ b/app/graphql/types/work_item_state_counts_type.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop: disable Graphql/AuthorizeTypes -- Parent node applies authorization
+ class WorkItemStateCountsType < BaseObject
+ graphql_name 'WorkItemStateCountsType'
+ description 'Represents total number of work items for the represented states'
+
+ field :all,
+ GraphQL::Types::Int,
+ null: true,
+ description: 'Number of work items for the project or group.'
+
+ field :closed,
+ GraphQL::Types::Int,
+ null: true,
+ description: 'Number of work items with state CLOSED for the project or group.'
+
+ field :opened,
+ GraphQL::Types::Int,
+ null: true,
+ description: 'Number of work items with state OPENED for the project or group.'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+end
diff --git a/app/graphql/types/work_item_type.rb b/app/graphql/types/work_item_type.rb
index 103a1c0ec9b..b42684e650b 100644
--- a/app/graphql/types/work_item_type.rb
+++ b/app/graphql/types/work_item_type.rb
@@ -67,6 +67,12 @@ module Types
expose_permissions Types::PermissionTypes::WorkItem
+ def work_item_type
+ context.scoped_set!(:resource_parent, object.resource_parent)
+
+ object.work_item_type
+ end
+
def web_url
Gitlab::UrlBuilder.build(object)
end
diff --git a/app/graphql/types/work_items/deleted_task_input_type.rb b/app/graphql/types/work_items/deleted_task_input_type.rb
deleted file mode 100644
index 92297876c89..00000000000
--- a/app/graphql/types/work_items/deleted_task_input_type.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-module Types
- module WorkItems
- class DeletedTaskInputType < BaseInputObject
- graphql_name 'WorkItemDeletedTaskInput'
-
- argument :id, ::Types::GlobalIDType[::WorkItem],
- required: true,
- description: 'Global ID of the task referenced in the work item\'s description.'
- argument :line_number_end, GraphQL::Types::Int,
- required: true,
- description: 'Last line in the Markdown source that defines the list item task.'
- argument :line_number_start, GraphQL::Types::Int,
- required: true,
- description: 'First line in the Markdown source that defines the list item task.'
- end
- end
-end
diff --git a/app/graphql/types/work_items/type_type.rb b/app/graphql/types/work_items/type_type.rb
index 4d008a21b9c..b42d73544dc 100644
--- a/app/graphql/types/work_items/type_type.rb
+++ b/app/graphql/types/work_items/type_type.rb
@@ -7,12 +7,20 @@ module Types
authorize :read_work_item_type
- field :icon_name, GraphQL::Types::String, null: true,
- description: 'Icon name of the work item type.'
- field :id, Types::GlobalIDType[::WorkItems::Type], null: false,
- description: 'Global ID of the work item type.'
- field :name, GraphQL::Types::String, null: false,
- description: 'Name of the work item type.'
+ field :icon_name, GraphQL::Types::String,
+ null: true,
+ description: 'Icon name of the work item type.'
+ field :id, Types::GlobalIDType[::WorkItems::Type],
+ null: false,
+ description: 'Global ID of the work item type.'
+ field :name, GraphQL::Types::String,
+ null: false,
+ description: 'Name of the work item type.'
+ field :widget_definitions, [Types::WorkItems::WidgetDefinitionInterface],
+ null: true,
+ description: 'Available widgets for the work item type.',
+ method: :widgets,
+ alpha: { milestone: '16.7' }
end
end
end
diff --git a/app/graphql/types/work_items/widget_definition_interface.rb b/app/graphql/types/work_items/widget_definition_interface.rb
new file mode 100644
index 00000000000..032e78779e7
--- /dev/null
+++ b/app/graphql/types/work_items/widget_definition_interface.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module WidgetDefinitionInterface
+ include Types::BaseInterface
+
+ graphql_name 'WorkItemWidgetDefinition'
+
+ field :type, ::Types::WorkItems::WidgetTypeEnum,
+ null: false,
+ description: 'Widget type.'
+
+ ORPHAN_TYPES = [
+ ::Types::WorkItems::WidgetDefinitions::AssigneesType,
+ ::Types::WorkItems::WidgetDefinitions::GenericType,
+ ::Types::WorkItems::WidgetDefinitions::HierarchyType
+ ].freeze
+
+ def self.ce_orphan_types
+ ORPHAN_TYPES
+ end
+
+ def self.resolve_type(object, _context)
+ if object == ::WorkItems::Widgets::Assignees
+ ::Types::WorkItems::WidgetDefinitions::AssigneesType
+ elsif object == ::WorkItems::Widgets::Hierarchy
+ ::Types::WorkItems::WidgetDefinitions::HierarchyType
+ else
+ ::Types::WorkItems::WidgetDefinitions::GenericType
+ end
+ end
+
+ orphan_types(*ce_orphan_types)
+ end
+ end
+end
+
+Types::WorkItems::WidgetDefinitionInterface.prepend_mod
diff --git a/app/graphql/types/work_items/widget_definitions/assignees_type.rb b/app/graphql/types/work_items/widget_definitions/assignees_type.rb
new file mode 100644
index 00000000000..6f30148e9aa
--- /dev/null
+++ b/app/graphql/types/work_items/widget_definitions/assignees_type.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module WidgetDefinitions
+ # rubocop:disable Graphql/AuthorizeTypes -- Authorization too granular, parent type is authorized
+ class AssigneesType < BaseObject
+ graphql_name 'WorkItemWidgetDefinitionAssignees'
+ description 'Represents an assignees widget definition'
+
+ implements Types::WorkItems::WidgetDefinitionInterface
+
+ field :can_invite_members, GraphQL::Types::Boolean,
+ null: false,
+ description: 'Indicates whether the current user can invite members to the work item\'s parent.'
+
+ def can_invite_members
+ object.can_invite_members?(current_user, resource_parent)
+ end
+
+ private
+
+ def resource_parent
+ context[:resource_parent]
+ end
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+ end
+end
+
+Types::WorkItems::WidgetDefinitions::AssigneesType.prepend_mod
diff --git a/app/graphql/types/work_items/widget_definitions/generic_type.rb b/app/graphql/types/work_items/widget_definitions/generic_type.rb
new file mode 100644
index 00000000000..f3817ade654
--- /dev/null
+++ b/app/graphql/types/work_items/widget_definitions/generic_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module WidgetDefinitions
+ # rubocop:disable Graphql/AuthorizeTypes -- Authorization too granular, parent type is authorized
+ class GenericType < BaseObject
+ graphql_name 'WorkItemWidgetDefinitionGeneric'
+ description 'Represents a generic widget definition'
+
+ implements Types::WorkItems::WidgetDefinitionInterface
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+ end
+end
diff --git a/app/graphql/types/work_items/widget_definitions/hierarchy_type.rb b/app/graphql/types/work_items/widget_definitions/hierarchy_type.rb
new file mode 100644
index 00000000000..8bd70050c7c
--- /dev/null
+++ b/app/graphql/types/work_items/widget_definitions/hierarchy_type.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module WidgetDefinitions
+ # rubocop:disable Graphql/AuthorizeTypes -- authorized in work item type entity
+ class HierarchyType < BaseObject
+ graphql_name 'WorkItemWidgetDefinitionHierarchy'
+ description 'Represents a hierarchy widget definition'
+
+ implements Types::WorkItems::WidgetDefinitionInterface
+
+ field :allowed_child_types, Types::WorkItems::TypeType.connection_type,
+ null: true,
+ complexity: 5,
+ extras: [:parent],
+ description: 'Allowed child types for the work item type.'
+
+ def allowed_child_types(parent:)
+ parent.allowed_child_types(cache: true)
+ end
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+ end
+end
diff --git a/app/graphql/types/work_items/widgets/assignees_type.rb b/app/graphql/types/work_items/widgets/assignees_type.rb
index 74da3264567..ecc0bc390d3 100644
--- a/app/graphql/types/work_items/widgets/assignees_type.rb
+++ b/app/graphql/types/work_items/widgets/assignees_type.rb
@@ -18,11 +18,21 @@ module Types
field :allows_multiple_assignees, GraphQL::Types::Boolean,
null: true, method: :allows_multiple_assignees?,
- description: 'Indicates whether multiple assignees are allowed.'
+ description: 'Indicates whether multiple assignees are allowed.',
+ deprecated: {
+ milestone: '16.7',
+ replacement: 'workitemWidgetDefinitionAssignees.allowsMultipleAssignees',
+ reason: 'Field moved to workItemType widget definition interface'
+ }
field :can_invite_members, GraphQL::Types::Boolean,
null: false, resolver_method: :can_invite_members?,
- description: 'Indicates whether the current user can invite members to the work item\'s project.'
+ description: 'Indicates whether the current user can invite members to the work item\'s project.',
+ deprecated: {
+ milestone: '16.7',
+ replacement: 'workitemWidgetDefinitionAssignees.canInviteMembers',
+ reason: 'Field moved to workItemType widget definition interface'
+ }
def can_invite_members?
Ability.allowed?(current_user, :admin_project_member, object.work_item.project)
diff --git a/app/graphql/types/work_items/widgets/labels_type.rb b/app/graphql/types/work_items/widgets/labels_type.rb
index 20574b3e3bc..5e5d324341d 100644
--- a/app/graphql/types/work_items/widgets/labels_type.rb
+++ b/app/graphql/types/work_items/widgets/labels_type.rb
@@ -19,7 +19,12 @@ module Types
field :allows_scoped_labels, GraphQL::Types::Boolean,
null: true,
method: :allows_scoped_labels?,
- description: 'Indicates whether a scoped label is allowed.'
+ description: 'Indicates whether a scoped label is allowed.',
+ deprecated: {
+ milestone: '16.7',
+ replacement: 'WorkItemWidgetDefinitionLabels.allowsScopedLabels',
+ reason: 'Field moved to workItemType widget definition interface'
+ }
end
# rubocop:enable Graphql/AuthorizeTypes
end