diff options
Diffstat (limited to 'app/graphql/types')
27 files changed, 453 insertions, 170 deletions
diff --git a/app/graphql/types/access_level_enum.rb b/app/graphql/types/access_level_enum.rb index 299952e4685..d58e7230a8e 100644 --- a/app/graphql/types/access_level_enum.rb +++ b/app/graphql/types/access_level_enum.rb @@ -14,3 +14,5 @@ module Types value 'OWNER', value: Gitlab::Access::OWNER, description: 'Owner access.' end end + +Types::AccessLevelEnum.prepend_mod_with('Types::AccessLevelEnum') diff --git a/app/graphql/types/achievements/achievement_type.rb b/app/graphql/types/achievements/achievement_type.rb new file mode 100644 index 00000000000..e2b9495c83d --- /dev/null +++ b/app/graphql/types/achievements/achievement_type.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module Types + module Achievements + class AchievementType < BaseObject + graphql_name 'Achievement' + + authorize :read_achievement + + field :id, + ::Types::GlobalIDType[::Achievements::Achievement], + null: false, + description: 'ID of the achievement.' + + field :namespace, + ::Types::NamespaceType, + null: false, + description: 'Namespace of the achievement.' + + field :name, + GraphQL::Types::String, + null: false, + description: 'Name of the achievement.' + + field :avatar_url, + GraphQL::Types::String, + null: true, + description: 'URL to avatar of the achievement.' + + field :description, + GraphQL::Types::String, + null: true, + description: 'Description or notes for the achievement.' + + field :revokeable, + GraphQL::Types::Boolean, + null: false, + description: 'Revokeability of the achievement.' + + field :created_at, + Types::TimeType, + null: false, + description: 'Timestamp the achievement was created.' + + field :updated_at, + Types::TimeType, + null: false, + description: 'Timestamp the achievement was last updated.' + + def avatar_url + object.avatar_url(only_path: false) + end + end + end +end diff --git a/app/graphql/types/ci/runner_countable_connection_type.rb b/app/graphql/types/ci/runner_countable_connection_type.rb new file mode 100644 index 00000000000..f5c3a2c1f5f --- /dev/null +++ b/app/graphql/types/ci/runner_countable_connection_type.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Types + module Ci + # rubocop: disable Graphql/AuthorizeTypes + class RunnerCountableConnectionType < ::Types::CountableConnectionType + end + # rubocop: enable Graphql/AuthorizeTypes + end +end + +Types::Ci::RunnerCountableConnectionType.prepend_mod diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb index 5d34906f7b8..35339624e37 100644 --- a/app/graphql/types/ci/runner_type.rb +++ b/app/graphql/types/ci/runner_type.rb @@ -6,7 +6,7 @@ module Types graphql_name 'CiRunner' edge_type_class(RunnerWebUrlEdge) - connection_type_class(Types::CountableConnectionType) + connection_type_class(RunnerCountableConnectionType) authorize :read_runner present_using ::Ci::RunnerPresenter @@ -38,10 +38,9 @@ module Types field :executor_name, GraphQL::Types::String, null: true, description: 'Executor last advertised by the runner.', method: :executor_name - field :groups, 'Types::GroupConnection', - null: true, - resolver: ::Resolvers::Ci::RunnerGroupsResolver, - description: 'Groups the runner is associated with. For group runners only.' + field :groups, null: true, + resolver: ::Resolvers::Ci::RunnerGroupsResolver, + description: 'Groups the runner is associated with. For group runners only.' field :id, ::Types::GlobalIDType[::Ci::Runner], null: false, description: 'ID of the runner.' field :ip_address, GraphQL::Types::String, null: true, diff --git a/app/graphql/types/description_version_type.rb b/app/graphql/types/description_version_type.rb new file mode 100644 index 00000000000..bee30597e4c --- /dev/null +++ b/app/graphql/types/description_version_type.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Types + class DescriptionVersionType < BaseObject + graphql_name 'DescriptionVersion' + + authorize :read_issuable + + field :id, ::Types::GlobalIDType[::DescriptionVersion], + null: false, + description: 'ID of the description version.' + + field :description, GraphQL::Types::String, + null: true, + description: 'Content of the given description version.' + end +end + +Types::DescriptionVersionType.prepend_mod diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb index dd2ad26ce49..4948063610a 100644 --- a/app/graphql/types/issue_type.rb +++ b/app/graphql/types/issue_type.rb @@ -117,7 +117,6 @@ module Types description: 'Collection of design images associated with this issue.' field :type, Types::IssueTypeEnum, null: true, - method: :issue_type, description: 'Type of the issue.' field :alert_management_alert, @@ -198,6 +197,14 @@ module Types def escalation_status object.supports_escalation? ? object.escalation_status&.status_name : nil end + + def type + if Feature.enabled?(:issue_type_uses_work_item_types_table) + object.work_item_type.base_type + else + object.issue_type + end + end end end diff --git a/app/graphql/types/issues/unioned_issue_filter_input_type.rb b/app/graphql/types/issues/unioned_issue_filter_input_type.rb index 9c7261279c7..a9c5b3c24ce 100644 --- a/app/graphql/types/issues/unioned_issue_filter_input_type.rb +++ b/app/graphql/types/issues/unioned_issue_filter_input_type.rb @@ -11,6 +11,9 @@ module Types argument :author_usernames, [GraphQL::Types::String], required: false, description: 'Filters issues that are authored by one of the given users.' + argument :label_names, [GraphQL::Types::String], + required: false, + description: 'Filters issues that have at least one of the given labels.' end end end diff --git a/app/graphql/types/member_access_level_enum.rb b/app/graphql/types/member_access_level_enum.rb new file mode 100644 index 00000000000..8f89b882641 --- /dev/null +++ b/app/graphql/types/member_access_level_enum.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + class MemberAccessLevelEnum < BaseEnum + graphql_name 'MemberAccessLevel' + description 'Access level of a group or project member' + + value 'GUEST', value: Gitlab::Access::GUEST, description: 'Guest access.' + value 'REPORTER', value: Gitlab::Access::REPORTER, description: 'Reporter access.' + value 'DEVELOPER', value: Gitlab::Access::DEVELOPER, description: 'Developer access.' + value 'MAINTAINER', value: Gitlab::Access::MAINTAINER, description: 'Maintainer access.' + value 'OWNER', value: Gitlab::Access::OWNER, description: 'Owner access.' + end +end + +Types::MemberAccessLevelEnum.prepend_mod_with('Types::MemberAccessLevelEnum') diff --git a/app/graphql/types/member_interface.rb b/app/graphql/types/member_interface.rb index edadbcddfb3..4c9ee6246a3 100644 --- a/app/graphql/types/member_interface.rb +++ b/app/graphql/types/member_interface.rb @@ -46,7 +46,7 @@ module Types def merge_request_interaction(id: nil) Gitlab::Graphql::Lazy.with_value(GitlabSchema.object_from_id(id, expected_class: ::MergeRequest)) do |merge_request| - Users::MergeRequestInteraction.new(user: object.user, merge_request: merge_request) if merge_request + ::Users::MergeRequestInteraction.new(user: object.user, merge_request: merge_request) if merge_request end end end diff --git a/app/graphql/types/merge_requests/interacts_with_merge_request.rb b/app/graphql/types/merge_requests/interacts_with_merge_request.rb index bef2d39dc5c..672a2a315d4 100644 --- a/app/graphql/types/merge_requests/interacts_with_merge_request.rb +++ b/app/graphql/types/merge_requests/interacts_with_merge_request.rb @@ -16,7 +16,7 @@ module Types def merge_request_interaction(parent:, id: nil) # need the connection parent if called from a connection node: parent = parent.parent if parent.try(:field)&.connection? - Users::MergeRequestInteraction.new(user: object, merge_request: parent) + ::Users::MergeRequestInteraction.new(user: object, merge_request: parent) end end end diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index b342e57804b..5a92ba754aa 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -6,6 +6,7 @@ module Types include Gitlab::Graphql::MountMutation + mount_mutation Mutations::Achievements::Create mount_mutation Mutations::Admin::SidekiqQueues::DeleteJobs mount_mutation Mutations::AlertManagement::CreateAlertIssue mount_mutation Mutations::AlertManagement::UpdateAlertStatus @@ -66,6 +67,7 @@ module Types mount_mutation Mutations::Issues::LinkAlerts mount_mutation Mutations::Issues::UnlinkAlert mount_mutation Mutations::Labels::Create + mount_mutation Mutations::Members::Groups::BulkUpdate mount_mutation Mutations::MergeRequests::Accept mount_mutation Mutations::MergeRequests::Create mount_mutation Mutations::MergeRequests::Update diff --git a/app/graphql/types/namespace/shared_runners_setting_enum.rb b/app/graphql/types/namespace/shared_runners_setting_enum.rb index 4773e414aeb..fd067c9d803 100644 --- a/app/graphql/types/namespace/shared_runners_setting_enum.rb +++ b/app/graphql/types/namespace/shared_runners_setting_enum.rb @@ -4,10 +4,21 @@ module Types class Namespace::SharedRunnersSettingEnum < BaseEnum graphql_name 'SharedRunnersSetting' - ::Namespace::SHARED_RUNNERS_SETTINGS.each do |type| + DEPRECATED_SETTINGS = [::Namespace::SR_DISABLED_WITH_OVERRIDE].freeze + + ::Namespace::SHARED_RUNNERS_SETTINGS.excluding(DEPRECATED_SETTINGS).each do |type| value type.upcase, description: "Sharing of runners is #{type.tr('_', ' ')}.", value: type end + + value ::Namespace::SR_DISABLED_WITH_OVERRIDE.upcase, + description: "Sharing of runners is disabled and overridable.", + value: ::Namespace::SR_DISABLED_WITH_OVERRIDE, + deprecated: { + reason: :renamed, + replacement: ::Namespace::SR_DISABLED_AND_OVERRIDABLE, + milestone: "17.0" + } end end diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb index 0f634e7c2d3..fc55ff512b6 100644 --- a/app/graphql/types/namespace_type.rb +++ b/app/graphql/types/namespace_type.rb @@ -63,6 +63,13 @@ module Types description: "Timelog categories for the namespace.", alpha: { milestone: '15.3' } + field :achievements, + Types::Achievements::AchievementType.connection_type, + null: true, + alpha: { milestone: '15.8' }, + description: "Achievements for the namespace. " \ + "Returns `null` if the `achievements` feature flag is disabled." + markdown_field :description_html, null: true def timelog_categories @@ -76,6 +83,10 @@ module Types def root_storage_statistics Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(object.id).find end + + def achievements + object.achievements if Feature.enabled?(:achievements, object) + end end end diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb index 05629ea9223..5055facb21b 100644 --- a/app/graphql/types/notes/note_type.rb +++ b/app/graphql/types/notes/note_type.rb @@ -11,54 +11,72 @@ module Types implements(Types::ResolvableInterface) - field :id, ::Types::GlobalIDType[::Note], null: false, - description: 'ID of the note.' + field :id, ::Types::GlobalIDType[::Note], + null: false, + description: 'ID of the note.' field :project, Types::ProjectType, - null: true, - description: 'Project associated with the note.' + null: true, + description: 'Project associated with the note.' field :author, Types::UserType, - null: false, - description: 'User who wrote this note.' + null: false, + description: 'User who wrote this note.' field :system, GraphQL::Types::Boolean, - null: false, - description: 'Indicates whether this note was created by the system or by a user.' + null: false, + description: 'Indicates whether this note was created by the system or by a user.' field :system_note_icon_name, - GraphQL::Types::String, - null: true, - description: 'Name of the icon corresponding to a system note.' + GraphQL::Types::String, + null: true, + description: 'Name of the icon corresponding to a system note.' field :body, GraphQL::Types::String, - null: false, - method: :note, - description: 'Content of the note.' - - field :confidential, GraphQL::Types::Boolean, null: true, - description: 'Indicates if this note is confidential.', - method: :confidential?, - deprecated: { - reason: :renamed, - replacement: 'internal', - milestone: '15.5' - } - - field :internal, GraphQL::Types::Boolean, null: true, - description: 'Indicates if this note is internal.', - method: :confidential? - - field :created_at, Types::TimeType, null: false, - description: 'Timestamp of the note creation.' - field :discussion, Types::Notes::DiscussionType, null: true, - description: 'Discussion this note is a part of.' - field :position, Types::Notes::DiffPositionType, null: true, - description: 'Position of this note on a diff.' - field :updated_at, Types::TimeType, null: false, - description: "Timestamp of the note's last activity." + null: false, + method: :note, + description: 'Content of the note.' + + field :confidential, GraphQL::Types::Boolean, + null: true, + description: 'Indicates if this note is confidential.', + method: :confidential?, + deprecated: { + reason: :renamed, + replacement: 'internal', + milestone: '15.5' + } + + field :internal, GraphQL::Types::Boolean, + null: true, + description: 'Indicates if this note is internal.', + method: :confidential? + + field :created_at, Types::TimeType, + null: false, + description: 'Timestamp of the note creation.' + field :discussion, Types::Notes::DiscussionType, + null: true, + description: 'Discussion this note is a part of.' + field :position, Types::Notes::DiffPositionType, + null: true, + description: 'Position of this note on a diff.' + field :updated_at, Types::TimeType, + null: false, + description: "Timestamp of the note's last activity." field :url, GraphQL::Types::String, - null: true, - description: 'URL to view this Note in the Web UI.' + null: true, + description: 'URL to view this Note in the Web UI.' + + field :last_edited_at, Types::TimeType, + null: true, + description: 'Timestamp when note was last edited.' + field :last_edited_by, Types::UserType, + null: true, + description: 'User who last edited the note.' + + field :system_note_metadata, Types::Notes::SystemNoteMetadataType, + null: true, + description: 'Metadata for the given note if it is a system note.' markdown_field :body_html, null: true, method: :note diff --git a/app/graphql/types/notes/noteable_interface.rb b/app/graphql/types/notes/noteable_interface.rb index bd22f12d6f0..537084dff62 100644 --- a/app/graphql/types/notes/noteable_interface.rb +++ b/app/graphql/types/notes/noteable_interface.rb @@ -7,6 +7,7 @@ module Types field :notes, Types::Notes::NoteType.connection_type, null: false, description: "All notes on this noteable." field :discussions, Types::Notes::DiscussionType.connection_type, null: false, description: "All discussions on this noteable." + field :commenters, Types::UserType.connection_type, null: false, description: "All commenters on this noteable." def self.resolve_type(object, context) case object @@ -24,6 +25,10 @@ module Types raise "Unknown GraphQL type for #{object}" end end + + def commenters + object.commenters(user: current_user) + end end end end diff --git a/app/graphql/types/notes/system_note_metadata_type.rb b/app/graphql/types/notes/system_note_metadata_type.rb new file mode 100644 index 00000000000..b3dd7e037f9 --- /dev/null +++ b/app/graphql/types/notes/system_note_metadata_type.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Types + module Notes + class SystemNoteMetadataType < BaseObject + graphql_name 'SystemNoteMetadata' + + authorize :read_note + + field :id, ::Types::GlobalIDType[::SystemNoteMetadata], + null: false, + description: 'Global ID of the specific system note metadata.' + + field :action, GraphQL::Types::String, + null: true, + description: 'System note metadata action.' + field :description_version, ::Types::DescriptionVersionType, + null: true, + description: 'Version of the changed description.' + end + end +end diff --git a/app/graphql/types/projects/branch_rule_type.rb b/app/graphql/types/projects/branch_rule_type.rb index 1afd2cc3fef..08b1203d4a3 100644 --- a/app/graphql/types/projects/branch_rule_type.rb +++ b/app/graphql/types/projects/branch_rule_type.rb @@ -5,7 +5,6 @@ module Types class BranchRuleType < BaseObject graphql_name 'BranchRule' description 'List of branch rules for a project, grouped by branch name.' - accepts ::ProtectedBranch authorize :read_protected_branch alias_method :branch_rule, :object @@ -22,6 +21,12 @@ module Types calls_gitaly: true, description: "Check if this branch rule protects the project's default branch." + field :is_protected, + type: GraphQL::Types::Boolean, + null: false, + method: :protected?, + description: "Check if this branch rule protects access for the branch." + field :matching_branches_count, type: GraphQL::Types::Int, null: false, @@ -30,9 +35,8 @@ module Types field :branch_protection, type: Types::BranchRules::BranchProtectionType, - null: false, - description: 'Branch protections configured for this branch rule.', - method: :itself + null: true, + description: 'Branch protections configured for this branch rule.' field :created_at, Types::TimeType, @@ -43,10 +47,6 @@ module Types Types::TimeType, null: false, description: 'Timestamp of when the branch rule was last updated.' - - def matching_branches_count - branch_rule.matching(branch_rule.project.repository.branch_names).count - end end end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 7263f792bae..990ba1fb7fc 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -7,56 +7,17 @@ module Types # The design management context object needs to implement #issue DesignManagementObject = Struct.new(:issue) - field :project, Types::ProjectType, - null: true, - resolver: Resolvers::ProjectResolver, - description: "Find a project." - - field :projects, Types::ProjectType.connection_type, - null: true, - resolver: Resolvers::ProjectsResolver, - description: "Find projects visible to the current user." - - field :group, Types::GroupType, - null: true, - resolver: Resolvers::GroupResolver, - description: "Find a group." - - field :current_user, Types::UserType, - null: true, - description: "Get information about current user." - - field :namespace, Types::NamespaceType, - null: true, - resolver: Resolvers::NamespaceResolver, - description: "Find a namespace." - - field :metadata, Types::MetadataType, - null: true, - resolver: Resolvers::MetadataResolver, - description: 'Metadata about GitLab.' - - field :query_complexity, Types::QueryComplexityType, + field :board_list, ::Types::BoardListType, null: true, - description: 'Information about the complexity of the GraphQL query.' - - field :snippets, - Types::SnippetType.connection_type, + resolver: Resolvers::BoardListResolver + field :ci_application_settings, Types::Ci::ApplicationSettingType, null: true, - resolver: Resolvers::SnippetsResolver, - description: 'Find Snippets visible to the current user.' - - field :design_management, Types::DesignManagementType, - null: false, - description: 'Fields related to design management.' - - field :milestone, ::Types::MilestoneType, + description: 'CI related settings that apply to the entire instance.' + field :ci_config, resolver: Resolvers::Ci::ConfigResolver, complexity: 126 # AUTHENTICATED_MAX_COMPLEXITY / 2 + 1 + field :ci_variables, + Types::Ci::InstanceVariableType.connection_type, null: true, - extras: [:lookahead], - description: 'Find a milestone.' do - argument :id, ::Types::GlobalIDType[Milestone], required: true, description: 'Find a milestone by its ID.' - end - + description: "List of the instance's CI/CD variables." field :container_repository, Types::ContainerRepositoryDetailsType, null: true, description: 'Find a container repository.' do @@ -65,107 +26,116 @@ module Types required: true, description: 'Global ID of the container repository.' end - - field :package, - description: 'Find a package. This field can only be resolved for one query in any single request. Returns `null` if a package has no `default` status.', - resolver: Resolvers::PackageDetailsResolver - - field :user, Types::UserType, - null: true, - description: 'Find a user.', - resolver: Resolvers::UserResolver - - field :users, Types::UserType.connection_type, + field :current_user, Types::UserType, null: true, - description: 'Find users.', - resolver: Resolvers::UsersResolver - + description: "Get information about current user." + field :design_management, Types::DesignManagementType, + null: false, + description: 'Fields related to design management.' field :echo, resolver: Resolvers::EchoResolver - - field :issues, + field :gitpod_enabled, GraphQL::Types::Boolean, null: true, - alpha: { milestone: '15.6' }, - resolver: Resolvers::IssuesResolver, - description: 'Issues visible by the current user.' \ - ' Returns null if the `root_level_issues_query` feature flag is disabled.' - + description: "Whether Gitpod is enabled in application settings." + field :group, Types::GroupType, + null: true, + resolver: Resolvers::GroupResolver, + description: "Find a group." field :issue, Types::IssueType, null: true, description: 'Find an issue.' do argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'Global ID of the issue.' end - - field :work_item, Types::WorkItemType, + field :issues, null: true, - resolver: Resolvers::WorkItemResolver, - alpha: { milestone: '15.1' }, - description: 'Find a work item.' - + alpha: { milestone: '15.6' }, + resolver: Resolvers::IssuesResolver, + description: 'Find issues visible to the current user.' \ + ' At least one filter must be provided.' \ + ' Returns `null` if the `root_level_issues_query` feature flag is disabled.' + field :jobs, + ::Types::Ci::JobType.connection_type, + null: true, + description: 'All jobs on this GitLab instance.', + resolver: ::Resolvers::Ci::AllJobsResolver field :merge_request, Types::MergeRequestType, null: true, description: 'Find a merge request.' do argument :id, ::Types::GlobalIDType[::MergeRequest], required: true, description: 'Global ID of the merge request.' end - - field :usage_trends_measurements, Types::Admin::Analytics::UsageTrends::MeasurementType.connection_type, + field :metadata, Types::MetadataType, null: true, - description: 'Get statistics on the instance.', - resolver: Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver - - field :ci_application_settings, Types::Ci::ApplicationSettingType, + resolver: Resolvers::MetadataResolver, + description: 'Metadata about GitLab.' + field :milestone, ::Types::MilestoneType, null: true, - description: 'CI related settings that apply to the entire instance.' - - field :runner_platforms, resolver: Resolvers::Ci::RunnerPlatformsResolver - field :runner_setup, resolver: Resolvers::Ci::RunnerSetupResolver - + extras: [:lookahead], + description: 'Find a milestone.' do + argument :id, ::Types::GlobalIDType[Milestone], required: true, description: 'Find a milestone by its ID.' + end + field :namespace, Types::NamespaceType, + null: true, + resolver: Resolvers::NamespaceResolver, + description: "Find a namespace." + field :package, + description: 'Find a package. This field can only be resolved for one query in any single request. Returns `null` if a package has no `default` status.', + resolver: Resolvers::PackageDetailsResolver + field :project, Types::ProjectType, + null: true, + resolver: Resolvers::ProjectResolver, + description: "Find a project." + field :projects, Types::ProjectType.connection_type, + null: true, + resolver: Resolvers::ProjectsResolver, + description: "Find projects visible to the current user." + field :query_complexity, Types::QueryComplexityType, + null: true, + description: 'Information about the complexity of the GraphQL query.' field :runner, Types::Ci::RunnerType, null: true, resolver: Resolvers::Ci::RunnerResolver, extras: [:lookahead], description: "Find a runner." - + field :runner_platforms, resolver: Resolvers::Ci::RunnerPlatformsResolver + field :runner_setup, resolver: Resolvers::Ci::RunnerSetupResolver field :runners, Types::Ci::RunnerType.connection_type, null: true, resolver: Resolvers::Ci::RunnersResolver, description: "Find runners visible to the current user." - - field :ci_variables, - Types::Ci::InstanceVariableType.connection_type, + field :snippets, + Types::SnippetType.connection_type, null: true, - description: "List of the instance's CI/CD variables." - - field :ci_config, resolver: Resolvers::Ci::ConfigResolver, complexity: 126 # AUTHENTICATED_MAX_COMPLEXITY / 2 + 1 - + resolver: Resolvers::SnippetsResolver, + description: 'Find Snippets visible to the current user.' field :timelogs, Types::TimelogType.connection_type, null: true, description: 'Find timelogs visible to the current user.', extras: [:lookahead], complexity: 5, resolver: ::Resolvers::TimelogResolver - - field :board_list, ::Types::BoardListType, - null: true, - resolver: Resolvers::BoardListResolver - field :todo, null: true, resolver: Resolvers::TodoResolver - field :topics, Types::Projects::TopicType.connection_type, null: true, resolver: Resolvers::TopicsResolver, description: "Find project topics." - - field :gitpod_enabled, GraphQL::Types::Boolean, + field :usage_trends_measurements, Types::Admin::Analytics::UsageTrends::MeasurementType.connection_type, null: true, - description: "Whether Gitpod is enabled in application settings." - - field :jobs, - ::Types::Ci::JobType.connection_type, + description: 'Get statistics on the instance.', + resolver: Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver + field :user, Types::UserType, null: true, - description: 'All jobs on this GitLab instance.', - resolver: ::Resolvers::Ci::AllJobsResolver + description: 'Find a user.', + resolver: Resolvers::UserResolver + field :users, Types::UserType.connection_type, + null: true, + description: 'Find users.', + resolver: Resolvers::UsersResolver + field :work_item, Types::WorkItemType, + null: true, + resolver: Resolvers::WorkItemResolver, + alpha: { milestone: '15.1' }, + description: 'Find a work item.' def design_management DesignManagementObject.new(nil) diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb index 8c90a8df611..c5d6e26e94b 100644 --- a/app/graphql/types/repository/blob_type.rb +++ b/app/graphql/types/repository/blob_type.rb @@ -44,11 +44,11 @@ module Types field :fork_and_view_path, GraphQL::Types::String, null: true, description: 'Web path to view this blob using a forked project.' - field :size, GraphQL::Types::Int, null: true, - description: 'Size (in bytes) of the blob.' + field :size, GraphQL::Types::BigInt, null: true, + description: 'Size (in bytes) of the blob.' - field :raw_size, GraphQL::Types::Int, null: true, - description: 'Size (in bytes) of the blob, or the blob target if stored externally.' + field :raw_size, GraphQL::Types::BigInt, null: true, + description: 'Size (in bytes) of the blob, or the blob target if stored externally.' field :raw_blob, GraphQL::Types::String, null: true, method: :data, description: 'Raw content of the blob.' diff --git a/app/graphql/types/time_tracking/timelog_connection_type.rb b/app/graphql/types/time_tracking/timelog_connection_type.rb new file mode 100644 index 00000000000..43e6955c2a3 --- /dev/null +++ b/app/graphql/types/time_tracking/timelog_connection_type.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Types + module TimeTracking + # rubocop: disable Graphql/AuthorizeTypes + class TimelogConnectionType < CountableConnectionType + field :total_spent_time, + GraphQL::Types::Int, + null: false, + description: 'Total time spent in seconds.' + + def total_spent_time + # rubocop: disable CodeReuse/ActiveRecord + relation = object.items + + # sometimes relation is an Array + relation = relation.reorder(nil) if relation.respond_to?(:reorder) + # rubocop: enable CodeReuse/ActiveRecord + + relation.sum(:time_spent) + end + end + # rubocop: enable Graphql/AuthorizeTypes + end +end diff --git a/app/graphql/types/time_tracking/timelog_sort_enum.rb b/app/graphql/types/time_tracking/timelog_sort_enum.rb new file mode 100644 index 00000000000..ad21c084d78 --- /dev/null +++ b/app/graphql/types/time_tracking/timelog_sort_enum.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Types + module TimeTracking + class TimelogSortEnum < SortEnum + graphql_name 'TimelogSort' + description 'Values for sorting timelogs' + + sortable_fields = ['Spent at', 'Time spent'] + + sortable_fields.each do |field| + value "#{field.upcase.tr(' ', '_')}_ASC", + value: { field: field.downcase.tr(' ', '_'), direction: :asc }, + description: "#{field} by ascending order." + value "#{field.upcase.tr(' ', '_')}_DESC", + value: { field: field.downcase.tr(' ', '_'), direction: :desc }, + description: "#{field} by descending order." + end + end + end +end diff --git a/app/graphql/types/timelog_type.rb b/app/graphql/types/timelog_type.rb index 3856e1aa3b3..3a060518cd9 100644 --- a/app/graphql/types/timelog_type.rb +++ b/app/graphql/types/timelog_type.rb @@ -4,6 +4,8 @@ module Types class TimelogType < BaseObject graphql_name 'Timelog' + connection_type_class(Types::TimeTracking::TimelogConnectionType) + authorize :read_issuable expose_permissions Types::PermissionTypes::Timelog diff --git a/app/graphql/types/todo_action_enum.rb b/app/graphql/types/todo_action_enum.rb index 33e1c4e98a4..fda96796c0f 100644 --- a/app/graphql/types/todo_action_enum.rb +++ b/app/graphql/types/todo_action_enum.rb @@ -11,6 +11,6 @@ module Types value 'directly_addressed', value: 7, description: 'User was directly addressed.' value 'merge_train_removed', value: 8, description: 'Merge request authored by the user was removed from the merge train.' value 'review_requested', value: 9, description: 'Review was requested from the user.' - value 'member_access_requested', value: 10, description: 'Group access requested from the user.' + value 'member_access_requested', value: 10, description: 'Group or project access requested from the user.' end end diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb index 51046d09f90..a5bed3b9e19 100644 --- a/app/graphql/types/user_interface.rb +++ b/app/graphql/types/user_interface.rb @@ -42,10 +42,23 @@ module Types null: true, description: 'User email.', method: :public_email, deprecated: { reason: :renamed, replacement: 'User.publicEmail', milestone: '13.7' } + field :emails, + type: Types::Users::EmailType.connection_type, + null: true, + description: "User's email addresses." field :public_email, type: GraphQL::Types::String, null: true, description: "User's public email." + field :commit_email, + type: GraphQL::Types::String, + null: true, + description: "User's default commit email.", + authorize: :read_user_email_address + field :namespace_commit_emails, + type: Types::Users::NamespaceCommitEmailType.connection_type, + null: true, + description: "User's custom namespace commit emails." field :avatar_url, type: GraphQL::Types::String, null: true, diff --git a/app/graphql/types/users/email_type.rb b/app/graphql/types/users/email_type.rb new file mode 100644 index 00000000000..5e0b9563f57 --- /dev/null +++ b/app/graphql/types/users/email_type.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Types + module Users + class EmailType < BaseObject + graphql_name 'Email' + + authorize :read_user_email_address + + field :id, + GraphQL::Types::ID, + null: false, + description: 'Internal ID of the email.' + + field :email, + GraphQL::Types::String, + null: false, + description: 'Email address.' + + field :confirmed_at, + Types::TimeType, + null: true, + description: 'Timestamp the email was confirmed.' + + field :created_at, + Types::TimeType, + null: false, + description: 'Timestamp the email was created.' + + field :updated_at, + Types::TimeType, + null: false, + description: 'Timestamp the email was last updated.' + end + end +end diff --git a/app/graphql/types/users/namespace_commit_email_type.rb b/app/graphql/types/users/namespace_commit_email_type.rb new file mode 100644 index 00000000000..a64423c7169 --- /dev/null +++ b/app/graphql/types/users/namespace_commit_email_type.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Types + module Users + class NamespaceCommitEmailType < BaseObject + graphql_name 'NamespaceCommitEmail' + + authorize :read_user_email_address + + field :id, + GraphQL::Types::ID, + null: false, + description: 'Internal ID of the namespace commit email.' + + field :email, + Types::Users::EmailType, + null: false, + description: 'Email.' + + field :namespace, + Types::NamespaceType, + null: false, + description: 'Namespace.' + + field :created_at, + Types::TimeType, + null: false, + description: 'Timestamp the namespace commit email was created.' + + field :updated_at, + Types::TimeType, + null: false, + description: 'Timestamp the namespace commit email was last updated.' + end + end +end diff --git a/app/graphql/types/work_items/widgets/description_type.rb b/app/graphql/types/work_items/widgets/description_type.rb index 4861f7f46d8..92dca965b59 100644 --- a/app/graphql/types/work_items/widgets/description_type.rb +++ b/app/graphql/types/work_items/widgets/description_type.rb @@ -26,9 +26,7 @@ module Types null: true, description: 'User that made the last edit to the work item\'s description.' - markdown_field :description_html, null: true do |resolved_object| - resolved_object.work_item - end + markdown_field :description_html, null: true, &:work_item end # rubocop:enable Graphql/AuthorizeTypes end |