diff options
Diffstat (limited to 'app/graphql/types')
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 |