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')
-rw-r--r--app/graphql/mutations/alert_management/alerts/set_assignees.rb12
-rw-r--r--app/graphql/mutations/alert_management/base.rb26
-rw-r--r--app/graphql/mutations/alert_management/http_integration/create.rb12
-rw-r--r--app/graphql/mutations/alert_management/http_integration/destroy.rb4
-rw-r--r--app/graphql/mutations/alert_management/http_integration/http_integration_base.rb6
-rw-r--r--app/graphql/mutations/alert_management/http_integration/reset_token.rb4
-rw-r--r--app/graphql/mutations/alert_management/http_integration/update.rb12
-rw-r--r--app/graphql/mutations/alert_management/prometheus_integration/create.rb12
-rw-r--r--app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb6
-rw-r--r--app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb4
-rw-r--r--app/graphql/mutations/alert_management/prometheus_integration/update.rb12
-rw-r--r--app/graphql/mutations/alert_management/update_alert_status.rb4
-rw-r--r--app/graphql/mutations/award_emojis/base.rb4
-rw-r--r--app/graphql/mutations/ci/pipeline_schedule/create.rb32
-rw-r--r--app/graphql/mutations/ci/pipeline_trigger/base.rb18
-rw-r--r--app/graphql/mutations/ci/pipeline_trigger/create.rb38
-rw-r--r--app/graphql/mutations/ci/pipeline_trigger/delete.rb19
-rw-r--r--app/graphql/mutations/ci/pipeline_trigger/update.rb32
-rw-r--r--app/graphql/mutations/concerns/mutations/validate_time_estimate.rb22
-rw-r--r--app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb2
-rw-r--r--app/graphql/mutations/environments/create.rb5
-rw-r--r--app/graphql/mutations/environments/update.rb5
-rw-r--r--app/graphql/mutations/issues/update.rb5
-rw-r--r--app/graphql/mutations/merge_requests/update.rb7
-rw-r--r--app/graphql/mutations/metrics/dashboard/annotations/create.rb10
-rw-r--r--app/graphql/mutations/metrics/dashboard/annotations/delete.rb14
-rw-r--r--app/graphql/mutations/namespace/package_settings/update.rb20
-rw-r--r--app/graphql/mutations/work_items/create.rb8
-rw-r--r--app/graphql/mutations/work_items/linked_items/add.rb32
-rw-r--r--app/graphql/mutations/work_items/linked_items/base.rb58
-rw-r--r--app/graphql/mutations/work_items/subscribe.rb41
-rw-r--r--app/graphql/queries/repository/blob_info.query.graphql3
-rw-r--r--app/graphql/queries/repository/files.query.graphql3
-rw-r--r--app/graphql/queries/repository/paginated_tree.query.graphql10
-rw-r--r--app/graphql/queries/repository/path_last_commit.query.graphql4
-rw-r--r--app/graphql/resolvers/abuse_report_labels_resolver.rb19
-rw-r--r--app/graphql/resolvers/abuse_report_resolver.rb21
-rw-r--r--app/graphql/resolvers/autocomplete_users_resolver.rb32
-rw-r--r--app/graphql/resolvers/ci/pipeline_triggers_resolver.rb23
-rw-r--r--app/graphql/resolvers/concerns/resolves_merge_requests.rb3
-rw-r--r--app/graphql/resolvers/concerns/work_items/look_ahead_preloads.rb57
-rw-r--r--app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb5
-rw-r--r--app/graphql/resolvers/namespaces/work_items_resolver.rb34
-rw-r--r--app/graphql/resolvers/work_items/linked_items_resolver.rb36
-rw-r--r--app/graphql/resolvers/work_items_resolver.rb46
-rw-r--r--app/graphql/types/abuse_report_type.rb12
-rw-r--r--app/graphql/types/access_levels/deploy_key_type.rb32
-rw-r--r--app/graphql/types/access_levels/user_type.rb61
-rw-r--r--app/graphql/types/achievements/achievement_type.rb2
-rw-r--r--app/graphql/types/achievements/user_achievement_type.rb2
-rw-r--r--app/graphql/types/alert_management/alert_type.rb14
-rw-r--r--app/graphql/types/alert_management/http_integration_type.rb2
-rw-r--r--app/graphql/types/alert_management/prometheus_integration_type.rb2
-rw-r--r--app/graphql/types/branch_protections/push_access_level_type.rb5
-rw-r--r--app/graphql/types/ci/ci_cd_setting_type.rb55
-rw-r--r--app/graphql/types/ci/detailed_status_type.rb20
-rw-r--r--app/graphql/types/ci/group_environment_scope_type.rb2
-rw-r--r--app/graphql/types/ci/group_variable_type.rb4
-rw-r--r--app/graphql/types/ci/instance_variable_type.rb2
-rw-r--r--app/graphql/types/ci/job_type.rb2
-rw-r--r--app/graphql/types/ci/manual_variable_type.rb2
-rw-r--r--app/graphql/types/ci/pipeline_schedule_type.rb2
-rw-r--r--app/graphql/types/ci/pipeline_schedule_variable_type.rb2
-rw-r--r--app/graphql/types/ci/pipeline_trigger_type.rb44
-rw-r--r--app/graphql/types/ci/pipeline_type.rb2
-rw-r--r--app/graphql/types/ci/project_variable_type.rb4
-rw-r--r--app/graphql/types/ci/recent_failures_type.rb2
-rw-r--r--app/graphql/types/ci/runner_manager_type.rb17
-rw-r--r--app/graphql/types/ci/runner_type.rb19
-rw-r--r--app/graphql/types/ci/test_case_type.rb2
-rw-r--r--app/graphql/types/ci/test_suite_summary_type.rb2
-rw-r--r--app/graphql/types/ci/test_suite_type.rb2
-rw-r--r--app/graphql/types/clusters/agent_activity_event_type.rb2
-rw-r--r--app/graphql/types/clusters/agent_token_type.rb2
-rw-r--r--app/graphql/types/clusters/agent_type.rb2
-rw-r--r--app/graphql/types/commit_type.rb23
-rw-r--r--app/graphql/types/custom_emoji_type.rb8
-rw-r--r--app/graphql/types/deployment_type.rb3
-rw-r--r--app/graphql/types/design_management/design_type.rb8
-rw-r--r--app/graphql/types/diff_type.rb26
-rw-r--r--app/graphql/types/environment_type.rb3
-rw-r--r--app/graphql/types/group_type.rb12
-rw-r--r--app/graphql/types/issue_type.rb16
-rw-r--r--app/graphql/types/label_type.rb2
-rw-r--r--app/graphql/types/merge_request_state_enum.rb3
-rw-r--r--app/graphql/types/merge_request_type.rb15
-rw-r--r--app/graphql/types/mutation_type.rb5
-rw-r--r--app/graphql/types/namespace/package_settings_type.rb8
-rw-r--r--app/graphql/types/notes/discussion_type.rb2
-rw-r--r--app/graphql/types/notes/note_type.rb4
-rw-r--r--app/graphql/types/notes/position_type_enum.rb1
-rw-r--r--app/graphql/types/packages/package_base_type.rb2
-rw-r--r--app/graphql/types/permission_types/group.rb2
-rw-r--r--app/graphql/types/project_type.rb774
-rw-r--r--app/graphql/types/projects/services/base_service_type.rb2
-rw-r--r--app/graphql/types/projects/services/jira_service_type.rb2
-rw-r--r--app/graphql/types/query_type.rb12
-rw-r--r--app/graphql/types/release_type.rb2
-rw-r--r--app/graphql/types/saved_reply_type.rb2
-rw-r--r--app/graphql/types/snippet_type.rb2
-rw-r--r--app/graphql/types/snippets/blob_type.rb2
-rw-r--r--app/graphql/types/terraform/state_type.rb2
-rw-r--r--app/graphql/types/timelog_type.rb2
-rw-r--r--app/graphql/types/todo_action_enum.rb1
-rw-r--r--app/graphql/types/users/autocompleted_user_type.rb24
-rw-r--r--app/graphql/types/work_item_type.rb2
-rw-r--r--app/graphql/types/work_items/linked_item_type.rb22
-rw-r--r--app/graphql/types/work_items/related_link_type_enum.rb14
-rw-r--r--app/graphql/types/work_items/widget_interface.rb5
-rw-r--r--app/graphql/types/work_items/widgets/award_emoji_type.rb4
-rw-r--r--app/graphql/types/work_items/widgets/linked_items_type.rb25
111 files changed, 1507 insertions, 640 deletions
diff --git a/app/graphql/mutations/alert_management/alerts/set_assignees.rb b/app/graphql/mutations/alert_management/alerts/set_assignees.rb
index 500e2b868b1..a8513417c1c 100644
--- a/app/graphql/mutations/alert_management/alerts/set_assignees.rb
+++ b/app/graphql/mutations/alert_management/alerts/set_assignees.rb
@@ -7,14 +7,14 @@ module Mutations
graphql_name 'AlertSetAssignees'
argument :assignee_usernames,
- [GraphQL::Types::String],
- required: true,
- description: 'Usernames to assign to the alert. Replaces existing assignees by default.'
+ [GraphQL::Types::String],
+ required: true,
+ description: 'Usernames to assign to the alert. Replaces existing assignees by default.'
argument :operation_mode,
- Types::MutationOperationModeEnum,
- required: false,
- description: 'Operation to perform. Defaults to REPLACE.'
+ Types::MutationOperationModeEnum,
+ required: false,
+ description: 'Operation to perform. Defaults to REPLACE.'
def resolve(args)
alert = authorized_find!(project_path: args[:project_path], iid: args[:iid])
diff --git a/app/graphql/mutations/alert_management/base.rb b/app/graphql/mutations/alert_management/base.rb
index 771ace5510f..615c0f43a15 100644
--- a/app/graphql/mutations/alert_management/base.rb
+++ b/app/graphql/mutations/alert_management/base.rb
@@ -6,27 +6,27 @@ module Mutations
include Gitlab::Utils::UsageData
argument :project_path, GraphQL::Types::ID,
- required: true,
- description: "Project the alert to mutate is in."
+ required: true,
+ description: "Project the alert to mutate is in."
argument :iid, GraphQL::Types::String,
- required: true,
- description: "IID of the alert to mutate."
+ required: true,
+ description: "IID of the alert to mutate."
field :alert,
- Types::AlertManagement::AlertType,
- null: true,
- description: "Alert after mutation."
+ Types::AlertManagement::AlertType,
+ null: true,
+ description: "Alert after mutation."
field :todo,
- Types::TodoType,
- null: true,
- description: "To-do item after mutation."
+ Types::TodoType,
+ null: true,
+ description: "To-do item after mutation."
field :issue,
- Types::IssueType,
- null: true,
- description: "Issue created after mutation."
+ Types::IssueType,
+ null: true,
+ description: "Issue created after mutation."
authorize :update_alert_management_alert
diff --git a/app/graphql/mutations/alert_management/http_integration/create.rb b/app/graphql/mutations/alert_management/http_integration/create.rb
index f8d1a383706..fccef8cd3ad 100644
--- a/app/graphql/mutations/alert_management/http_integration/create.rb
+++ b/app/graphql/mutations/alert_management/http_integration/create.rb
@@ -9,16 +9,16 @@ module Mutations
include FindsProject
argument :project_path, GraphQL::Types::ID,
- required: true,
- description: 'Project to create the integration in.'
+ required: true,
+ description: 'Project to create the integration in.'
argument :name, GraphQL::Types::String,
- required: true,
- description: 'Name of the integration.'
+ required: true,
+ description: 'Name of the integration.'
argument :active, GraphQL::Types::Boolean,
- required: true,
- description: 'Whether the integration is receiving alerts.'
+ required: true,
+ description: 'Whether the integration is receiving alerts.'
def resolve(args)
project = authorized_find!(args[:project_path])
diff --git a/app/graphql/mutations/alert_management/http_integration/destroy.rb b/app/graphql/mutations/alert_management/http_integration/destroy.rb
index dc5c73ecff6..9da50a4c4ce 100644
--- a/app/graphql/mutations/alert_management/http_integration/destroy.rb
+++ b/app/graphql/mutations/alert_management/http_integration/destroy.rb
@@ -7,8 +7,8 @@ module Mutations
graphql_name 'HttpIntegrationDestroy'
argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration],
- required: true,
- description: "ID of the integration to remove."
+ required: true,
+ description: "ID of the integration to remove."
def resolve(id:)
integration = authorized_find!(id: id)
diff --git a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb
index 2f25d315d2e..9434ac1637e 100644
--- a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb
+++ b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb
@@ -5,9 +5,9 @@ module Mutations
module HttpIntegration
class HttpIntegrationBase < BaseMutation
field :integration,
- Types::AlertManagement::HttpIntegrationType,
- null: true,
- description: "HTTP integration."
+ Types::AlertManagement::HttpIntegrationType,
+ null: true,
+ description: "HTTP integration."
authorize :admin_operations
diff --git a/app/graphql/mutations/alert_management/http_integration/reset_token.rb b/app/graphql/mutations/alert_management/http_integration/reset_token.rb
index 83ad7762408..bed3cf08674 100644
--- a/app/graphql/mutations/alert_management/http_integration/reset_token.rb
+++ b/app/graphql/mutations/alert_management/http_integration/reset_token.rb
@@ -7,8 +7,8 @@ module Mutations
graphql_name 'HttpIntegrationResetToken'
argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration],
- required: true,
- description: "ID of the integration to mutate."
+ required: true,
+ description: "ID of the integration to mutate."
def resolve(id:)
integration = authorized_find!(id: id)
diff --git a/app/graphql/mutations/alert_management/http_integration/update.rb b/app/graphql/mutations/alert_management/http_integration/update.rb
index 78424e317b8..06d0b7163b0 100644
--- a/app/graphql/mutations/alert_management/http_integration/update.rb
+++ b/app/graphql/mutations/alert_management/http_integration/update.rb
@@ -7,16 +7,16 @@ module Mutations
graphql_name 'HttpIntegrationUpdate'
argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration],
- required: true,
- description: "ID of the integration to mutate."
+ required: true,
+ description: "ID of the integration to mutate."
argument :name, GraphQL::Types::String,
- required: false,
- description: "Name of the integration."
+ required: false,
+ description: "Name of the integration."
argument :active, GraphQL::Types::Boolean,
- required: false,
- description: "Whether the integration is receiving alerts."
+ required: false,
+ description: "Whether the integration is receiving alerts."
def resolve(args)
integration = authorized_find!(id: args[:id])
diff --git a/app/graphql/mutations/alert_management/prometheus_integration/create.rb b/app/graphql/mutations/alert_management/prometheus_integration/create.rb
index b06a4f58df5..665ce96f0f9 100644
--- a/app/graphql/mutations/alert_management/prometheus_integration/create.rb
+++ b/app/graphql/mutations/alert_management/prometheus_integration/create.rb
@@ -9,16 +9,16 @@ module Mutations
include FindsProject
argument :project_path, GraphQL::Types::ID,
- required: true,
- description: 'Project to create the integration in.'
+ required: true,
+ description: 'Project to create the integration in.'
argument :active, GraphQL::Types::Boolean,
- required: true,
- description: 'Whether the integration is receiving alerts.'
+ required: true,
+ description: 'Whether the integration is receiving alerts.'
argument :api_url, GraphQL::Types::String,
- required: false,
- description: 'Endpoint at which Prometheus can be queried.'
+ required: false,
+ description: 'Endpoint at which Prometheus can be queried.'
def resolve(args)
project = authorized_find!(args[:project_path])
diff --git a/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb b/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb
index 29834d63f35..28729ec70cd 100644
--- a/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb
+++ b/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb
@@ -5,9 +5,9 @@ module Mutations
module PrometheusIntegration
class PrometheusIntegrationBase < BaseMutation
field :integration,
- Types::AlertManagement::PrometheusIntegrationType,
- null: true,
- description: "Newly created integration."
+ Types::AlertManagement::PrometheusIntegrationType,
+ null: true,
+ description: "Newly created integration."
authorize :admin_project
diff --git a/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb b/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb
index 71c02efdc03..15e6763b1ee 100644
--- a/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb
+++ b/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb
@@ -7,8 +7,8 @@ module Mutations
graphql_name 'PrometheusIntegrationResetToken'
argument :id, Types::GlobalIDType[::Integrations::Prometheus],
- required: true,
- description: "ID of the integration to mutate."
+ required: true,
+ description: "ID of the integration to mutate."
def resolve(id:)
integration = authorized_find!(id: id)
diff --git a/app/graphql/mutations/alert_management/prometheus_integration/update.rb b/app/graphql/mutations/alert_management/prometheus_integration/update.rb
index 50aafdc26a6..593624aaafd 100644
--- a/app/graphql/mutations/alert_management/prometheus_integration/update.rb
+++ b/app/graphql/mutations/alert_management/prometheus_integration/update.rb
@@ -7,16 +7,16 @@ module Mutations
graphql_name 'PrometheusIntegrationUpdate'
argument :id, Types::GlobalIDType[::Integrations::Prometheus],
- required: true,
- description: "ID of the integration to mutate."
+ required: true,
+ description: "ID of the integration to mutate."
argument :active, GraphQL::Types::Boolean,
- required: false,
- description: "Whether the integration is receiving alerts."
+ required: false,
+ description: "Whether the integration is receiving alerts."
argument :api_url, GraphQL::Types::String,
- required: false,
- description: "Endpoint at which Prometheus can be queried."
+ required: false,
+ description: "Endpoint at which Prometheus can be queried."
def resolve(args)
integration = authorized_find!(id: args[:id])
diff --git a/app/graphql/mutations/alert_management/update_alert_status.rb b/app/graphql/mutations/alert_management/update_alert_status.rb
index be271a7d795..a0d06ebf221 100644
--- a/app/graphql/mutations/alert_management/update_alert_status.rb
+++ b/app/graphql/mutations/alert_management/update_alert_status.rb
@@ -6,8 +6,8 @@ module Mutations
graphql_name 'UpdateAlertStatus'
argument :status, Types::AlertManagement::StatusEnum,
- required: true,
- description: 'Status to set the alert.'
+ required: true,
+ description: 'Status to set the alert.'
def resolve(project_path:, iid:, status:)
alert = authorized_find!(project_path: project_path, iid: iid)
diff --git a/app/graphql/mutations/award_emojis/base.rb b/app/graphql/mutations/award_emojis/base.rb
index 65065de0de4..0223c978cf9 100644
--- a/app/graphql/mutations/award_emojis/base.rb
+++ b/app/graphql/mutations/award_emojis/base.rb
@@ -3,7 +3,7 @@
module Mutations
module AwardEmojis
class Base < BaseMutation
- NOT_EMOJI_AWARDABLE = 'You cannot award emoji to this resource.'
+ NOT_EMOJI_AWARDABLE = 'You cannot add emoji reactions to this resource.'
authorize :award_emoji
@@ -20,7 +20,7 @@ module Mutations
field :award_emoji,
Types::AwardEmojis::AwardEmojiType,
null: true,
- description: 'Award emoji after mutation.'
+ description: 'Emoji reactions after mutation.'
private
diff --git a/app/graphql/mutations/ci/pipeline_schedule/create.rb b/app/graphql/mutations/ci/pipeline_schedule/create.rb
index 71a366ed342..d21ac6fd727 100644
--- a/app/graphql/mutations/ci/pipeline_schedule/create.rb
+++ b/app/graphql/mutations/ci/pipeline_schedule/create.rb
@@ -51,28 +51,16 @@ module Mutations
params = pipeline_schedule_attrs.merge(variables_attributes: variables.map(&:to_h))
- if ::Feature.enabled?(:ci_refactoring_pipeline_schedule_create_service, project)
- response = ::Ci::PipelineSchedules::CreateService
- .new(project, current_user, params)
- .execute
-
- schedule = response.payload
-
- unless response.success?
- return {
- pipeline_schedule: nil, errors: response.errors
- }
- end
- else
- schedule = ::Ci::CreatePipelineScheduleService
- .new(project, current_user, params)
- .execute
-
- unless schedule.persisted?
- return {
- pipeline_schedule: nil, errors: schedule.errors.full_messages
- }
- end
+ response = ::Ci::PipelineSchedules::CreateService
+ .new(project, current_user, params)
+ .execute
+
+ schedule = response.payload
+
+ unless response.success?
+ return {
+ pipeline_schedule: nil, errors: response.errors
+ }
end
{
diff --git a/app/graphql/mutations/ci/pipeline_trigger/base.rb b/app/graphql/mutations/ci/pipeline_trigger/base.rb
new file mode 100644
index 00000000000..23be70e7754
--- /dev/null
+++ b/app/graphql/mutations/ci/pipeline_trigger/base.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Ci
+ module PipelineTrigger
+ class Base < BaseMutation
+ authorize :admin_build
+ authorize :admin_trigger
+
+ PipelineTriggerID = ::Types::GlobalIDType[::Ci::Trigger]
+
+ argument :id, PipelineTriggerID,
+ required: true,
+ description: 'ID of the pipeline trigger token to mutate.'
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/ci/pipeline_trigger/create.rb b/app/graphql/mutations/ci/pipeline_trigger/create.rb
new file mode 100644
index 00000000000..042f9b26dd0
--- /dev/null
+++ b/app/graphql/mutations/ci/pipeline_trigger/create.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Ci
+ module PipelineTrigger
+ class Create < BaseMutation
+ graphql_name 'PipelineTriggerCreate'
+
+ include FindsProject
+
+ authorize :admin_build
+
+ argument :project_path, GraphQL::Types::ID,
+ required: true,
+ description: 'Full path of the project that the pipeline trigger token to mutate is in.'
+
+ argument :description, GraphQL::Types::String,
+ required: true,
+ description: 'Description of the pipeline trigger token.'
+
+ field :pipeline_trigger, Types::Ci::PipelineTriggerType,
+ null: true,
+ description: 'Mutated pipeline trigger token.'
+
+ def resolve(project_path:, description:)
+ project = authorized_find!(project_path)
+
+ trigger = project.triggers.create(owner: current_user, description: description)
+
+ {
+ pipeline_trigger: trigger,
+ errors: trigger.errors.full_messages
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/ci/pipeline_trigger/delete.rb b/app/graphql/mutations/ci/pipeline_trigger/delete.rb
new file mode 100644
index 00000000000..bc18f58ec43
--- /dev/null
+++ b/app/graphql/mutations/ci/pipeline_trigger/delete.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Ci
+ module PipelineTrigger
+ class Delete < Base
+ graphql_name 'PipelineTriggerDelete'
+
+ def resolve(id:)
+ trigger = authorized_find!(id: id)
+
+ errors = trigger.destroy ? [] : ['Could not remove the trigger']
+
+ { errors: errors }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/ci/pipeline_trigger/update.rb b/app/graphql/mutations/ci/pipeline_trigger/update.rb
new file mode 100644
index 00000000000..fa68593eb09
--- /dev/null
+++ b/app/graphql/mutations/ci/pipeline_trigger/update.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Ci
+ module PipelineTrigger
+ class Update < Base
+ graphql_name 'PipelineTriggerUpdate'
+
+ argument :description, GraphQL::Types::String,
+ required: true,
+ description: 'Description of the pipeline trigger token.'
+
+ field :pipeline_trigger, Types::Ci::PipelineTriggerType,
+ null: true,
+ description: 'Mutated pipeline trigger token.'
+
+ def resolve(id:, description:)
+ trigger = authorized_find!(id: id)
+
+ trigger.description = description
+
+ trigger.save
+
+ {
+ pipeline_trigger: trigger,
+ errors: trigger.errors.full_messages
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/concerns/mutations/validate_time_estimate.rb b/app/graphql/mutations/concerns/mutations/validate_time_estimate.rb
new file mode 100644
index 00000000000..82a56fd04f3
--- /dev/null
+++ b/app/graphql/mutations/concerns/mutations/validate_time_estimate.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Mutations
+ module ValidateTimeEstimate
+ private
+
+ def validate_time_estimate(time_estimate)
+ return unless time_estimate
+
+ parsed_time_estimate = Gitlab::TimeTrackingFormatter.parse(time_estimate, keep_zero: true)
+
+ if parsed_time_estimate.nil?
+ raise Gitlab::Graphql::Errors::ArgumentError,
+ 'timeEstimate must be formatted correctly, for example `1h 30m`'
+ elsif parsed_time_estimate < 0
+ raise Gitlab::Graphql::Errors::ArgumentError,
+ 'timeEstimate must be greater than or equal to zero. ' \
+ 'Remember that every new timeEstimate overwrites the previous value.'
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
index f009abdba70..7aa78509bea 100644
--- a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
+++ b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
@@ -47,7 +47,7 @@ module Mutations
argument :award_emoji_widget,
::Types::WorkItems::Widgets::AwardEmojiUpdateInputType,
required: false,
- description: 'Input for award emoji widget.'
+ description: 'Input for emoji reactions widget.'
end
end
end
diff --git a/app/graphql/mutations/environments/create.rb b/app/graphql/mutations/environments/create.rb
index f18ce0eba97..76a5bf2f551 100644
--- a/app/graphql/mutations/environments/create.rb
+++ b/app/graphql/mutations/environments/create.rb
@@ -40,6 +40,11 @@ module Mutations
required: false,
description: 'Kubernetes namespace of the environment.'
+ argument :flux_resource_path,
+ GraphQL::Types::String,
+ required: false,
+ description: 'Flux resource path of the environment.'
+
field :environment,
Types::EnvironmentType,
null: true,
diff --git a/app/graphql/mutations/environments/update.rb b/app/graphql/mutations/environments/update.rb
index 07ab22685cc..44b9398c233 100644
--- a/app/graphql/mutations/environments/update.rb
+++ b/app/graphql/mutations/environments/update.rb
@@ -33,6 +33,11 @@ module Mutations
required: false,
description: 'Kubernetes namespace of the environment.'
+ argument :flux_resource_path,
+ GraphQL::Types::String,
+ required: false,
+ description: 'Flux resource path of the environment.'
+
field :environment,
Types::EnvironmentType,
null: true,
diff --git a/app/graphql/mutations/issues/update.rb b/app/graphql/mutations/issues/update.rb
index 2a863893cf1..35deb9e0af8 100644
--- a/app/graphql/mutations/issues/update.rb
+++ b/app/graphql/mutations/issues/update.rb
@@ -6,6 +6,7 @@ module Mutations
graphql_name 'UpdateIssue'
include CommonMutationArguments
+ include ValidateTimeEstimate
argument :title, GraphQL::Types::String,
required: false,
@@ -54,9 +55,7 @@ module Mutations
raise Gitlab::Graphql::Errors::ArgumentError, 'labelIds is mutually exclusive with any of addLabelIds or removeLabelIds'
end
- if !time_estimate.nil? && Gitlab::TimeTrackingFormatter.parse(time_estimate, keep_zero: true).nil?
- raise Gitlab::Graphql::Errors::ArgumentError, 'timeEstimate must be formatted correctly, for example `1h 30m`'
- end
+ validate_time_estimate(time_estimate)
super
end
diff --git a/app/graphql/mutations/merge_requests/update.rb b/app/graphql/mutations/merge_requests/update.rb
index da4db7342a3..470292df86c 100644
--- a/app/graphql/mutations/merge_requests/update.rb
+++ b/app/graphql/mutations/merge_requests/update.rb
@@ -5,6 +5,8 @@ module Mutations
class Update < Base
graphql_name 'MergeRequestUpdate'
+ include ValidateTimeEstimate
+
description 'Update attributes of a merge request'
argument :title, GraphQL::Types::String,
@@ -45,10 +47,7 @@ module Mutations
end
def ready?(time_estimate: nil, **args)
- if !time_estimate.nil? && Gitlab::TimeTrackingFormatter.parse(time_estimate, keep_zero: true).nil?
- raise Gitlab::Graphql::Errors::ArgumentError,
- 'timeEstimate must be formatted correctly, for example `1h 30m`'
- end
+ validate_time_estimate(time_estimate)
super
end
diff --git a/app/graphql/mutations/metrics/dashboard/annotations/create.rb b/app/graphql/mutations/metrics/dashboard/annotations/create.rb
index 296efa19bb7..59ddffe3aad 100644
--- a/app/graphql/mutations/metrics/dashboard/annotations/create.rb
+++ b/app/graphql/mutations/metrics/dashboard/annotations/create.rb
@@ -61,14 +61,10 @@ module Mutations
end
end
- def resolve(args)
- annotation_response = ::Metrics::Dashboard::Annotations::CreateService.new(context[:current_user], annotation_create_params(args)).execute
-
- annotation = annotation_response[:annotation]
-
+ def resolve(_args)
{
- annotation: annotation.valid? ? annotation : nil,
- errors: errors_on_object(annotation)
+ annotation: nil,
+ errors: []
}
end
diff --git a/app/graphql/mutations/metrics/dashboard/annotations/delete.rb b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
index 32047cda213..61fcf8e0b13 100644
--- a/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
+++ b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
@@ -13,19 +13,11 @@ module Mutations
required: true,
description: 'Global ID of the annotation to delete.'
+ # rubocop:disable Lint/UnusedMethodArgument
def resolve(id:)
- raise_resource_not_available_error! if Feature.enabled?(:remove_monitor_metrics)
-
- annotation = authorized_find!(id: id)
-
- result = ::Metrics::Dashboard::Annotations::DeleteService.new(context[:current_user], annotation).execute
-
- errors = Array.wrap(result[:message])
-
- {
- errors: errors
- }
+ raise_resource_not_available_error!
end
+ # rubocop:enable Lint/UnusedMethodArgument
end
end
end
diff --git a/app/graphql/mutations/namespace/package_settings/update.rb b/app/graphql/mutations/namespace/package_settings/update.rb
index 96bee693a1e..4e71bed52c6 100644
--- a/app/graphql/mutations/namespace/package_settings/update.rb
+++ b/app/graphql/mutations/namespace/package_settings/update.rb
@@ -8,6 +8,8 @@ module Mutations
include Mutations::ResolvesNamespace
+ NUGET_DUPLICATES_FF_ERROR = '`nuget_duplicates_option` feature flag is disabled.'
+
description <<~DESC
These settings can be adjusted by the group Owner or Maintainer.
[Issue 370471](https://gitlab.com/gitlab-org/gitlab/-/issues/370471) proposes limiting
@@ -41,6 +43,16 @@ module Mutations
required: false,
description: copy_field_description(Types::Namespace::PackageSettingsType, :generic_duplicate_exception_regex)
+ argument :nuget_duplicates_allowed,
+ GraphQL::Types::Boolean,
+ required: false,
+ description: copy_field_description(Types::Namespace::PackageSettingsType, :nuget_duplicates_allowed)
+
+ argument :nuget_duplicate_exception_regex,
+ Types::UntrustedRegexp,
+ required: false,
+ description: copy_field_description(Types::Namespace::PackageSettingsType, :nuget_duplicate_exception_regex)
+
argument :maven_package_requests_forwarding,
GraphQL::Types::Boolean,
required: false,
@@ -79,6 +91,10 @@ module Mutations
def resolve(namespace_path:, **args)
namespace = authorized_find!(namespace_path: namespace_path)
+ if nuget_duplicate_settings_present?(args) && Feature.disabled?(:nuget_duplicates_option, namespace)
+ raise_resource_not_available_error! NUGET_DUPLICATES_FF_ERROR
+ end
+
result = ::Namespaces::PackageSettings::UpdateService
.new(container: namespace, current_user: current_user, params: args)
.execute
@@ -94,6 +110,10 @@ module Mutations
def find_object(namespace_path:)
resolve_namespace(full_path: namespace_path)
end
+
+ def nuget_duplicate_settings_present?(args)
+ args.key?(:nuget_duplicates_allowed) || args.key?(:nuget_duplicate_exception_regex)
+ end
end
end
end
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index 9f7b7b5db97..7ce508e5ef1 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -14,6 +14,7 @@ module Mutations
authorize :create_work_item
MUTUALLY_EXCLUSIVE_ARGUMENTS_ERROR = 'Please provide either projectPath or namespacePath argument, but not both.'
+ DISABLED_FF_ERROR = 'namespace_level_work_items feature flag is disabled. Only project paths allowed.'
argument :confidential, GraphQL::Types::Boolean,
required: false,
@@ -59,6 +60,7 @@ module Mutations
def resolve(project_path: nil, namespace_path: nil, **attributes)
container_path = project_path || namespace_path
container = authorized_find!(container_path)
+ check_feature_available!(container)
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
type = ::WorkItems::Type.find(attributes[:work_item_type_id])
@@ -81,6 +83,12 @@ module Mutations
private
+ def check_feature_available!(container)
+ return unless container.is_a?(::Group) && Feature.disabled?(:namespace_level_work_items, container)
+
+ raise Gitlab::Graphql::Errors::ArgumentError, DISABLED_FF_ERROR
+ end
+
def global_id_compatibility_params(params)
params[:work_item_type_id] = params[:work_item_type_id]&.model_id
diff --git a/app/graphql/mutations/work_items/linked_items/add.rb b/app/graphql/mutations/work_items/linked_items/add.rb
new file mode 100644
index 00000000000..b346b074e85
--- /dev/null
+++ b/app/graphql/mutations/work_items/linked_items/add.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ module LinkedItems
+ class Add < Base
+ graphql_name 'WorkItemAddLinkedItems'
+ description 'Add linked items to the work item.'
+
+ argument :link_type, ::Types::WorkItems::RelatedLinkTypeEnum,
+ required: false, description: 'Type of link. Defaults to `RELATED`.'
+
+ private
+
+ def update_links(work_item, params)
+ Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/419555')
+
+ gids = params.delete(:work_items_ids)
+ work_items = begin
+ GitlabSchema.parse_gids(gids, expected_type: ::WorkItem).map(&:find)
+ rescue ActiveRecord::RecordNotFound => e
+ raise Gitlab::Graphql::Errors::ArgumentError, e
+ end
+
+ ::WorkItems::RelatedWorkItemLinks::CreateService
+ .new(work_item, current_user, { target_issuable: work_items, link_type: params[:link_type] })
+ .execute
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/linked_items/base.rb b/app/graphql/mutations/work_items/linked_items/base.rb
new file mode 100644
index 00000000000..1d8d74b02ac
--- /dev/null
+++ b/app/graphql/mutations/work_items/linked_items/base.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ module LinkedItems
+ class Base < BaseMutation
+ # Limit maximum number of items that can be linked at a time to avoid overloading the DB
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/419555
+ MAX_WORK_ITEMS = 3
+
+ argument :id, ::Types::GlobalIDType[::WorkItem],
+ required: true, description: 'Global ID of the work item.'
+ argument :work_items_ids, [::Types::GlobalIDType[::WorkItem]],
+ required: true,
+ description: "Global IDs of the items to link. Maximum number of IDs you can provide: #{MAX_WORK_ITEMS}."
+
+ field :work_item, Types::WorkItemType,
+ null: true, description: 'Updated work item.'
+
+ field :message, GraphQL::Types::String,
+ null: true, description: 'Linked items update result message.'
+
+ authorize :read_work_item
+
+ def ready?(**args)
+ if args[:work_items_ids].size > MAX_WORK_ITEMS
+ raise Gitlab::Graphql::Errors::ArgumentError,
+ format(
+ _('No more than %{max_work_items} work items can be linked at the same time.'),
+ max_work_items: MAX_WORK_ITEMS
+ )
+ end
+
+ super
+ end
+
+ def resolve(**args)
+ work_item = authorized_find!(id: args.delete(:id))
+ raise_resource_not_available_error! unless work_item.project.linked_work_items_feature_flag_enabled?
+
+ service_response = update_links(work_item, args)
+
+ {
+ work_item: work_item,
+ errors: service_response[:status] == :error ? Array.wrap(service_response[:message]) : [],
+ message: service_response[:status] == :success ? service_response[:message] : ''
+ }
+ end
+
+ private
+
+ def update_links(work_item, params)
+ raise NotImplementedError
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/subscribe.rb b/app/graphql/mutations/work_items/subscribe.rb
new file mode 100644
index 00000000000..a29c3416c3d
--- /dev/null
+++ b/app/graphql/mutations/work_items/subscribe.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ class Subscribe < BaseMutation
+ graphql_name 'WorkItemSubscribe'
+
+ argument :id, ::Types::GlobalIDType[::WorkItem],
+ required: true,
+ description: 'Global ID of the work item.'
+
+ argument :subscribed,
+ GraphQL::Types::Boolean,
+ required: true,
+ description: 'Desired state of the subscription.'
+
+ field :work_item, Types::WorkItemType,
+ null: true,
+ description: 'Work item after mutation.'
+
+ authorize :update_subscription
+
+ def resolve(args)
+ work_item = authorized_find!(id: args[:id])
+
+ update_subscription(work_item, args[:subscribed])
+
+ {
+ work_item: work_item,
+ errors: []
+ }
+ end
+
+ private
+
+ def update_subscription(work_item, subscribed_state)
+ work_item.set_subscription(current_user, subscribed_state, work_item.project)
+ end
+ end
+ end
+end
diff --git a/app/graphql/queries/repository/blob_info.query.graphql b/app/graphql/queries/repository/blob_info.query.graphql
index fd463436ed4..7419961a564 100644
--- a/app/graphql/queries/repository/blob_info.query.graphql
+++ b/app/graphql/queries/repository/blob_info.query.graphql
@@ -2,6 +2,7 @@ query getBlobInfo(
$projectPath: ID!
$filePath: String!
$ref: String!
+ $refType: RefType
$shouldFetchRawText: Boolean!
) {
project(fullPath: $projectPath) {
@@ -10,7 +11,7 @@ query getBlobInfo(
repository {
__typename
empty
- blobs(paths: [$filePath], ref: $ref) {
+ blobs(paths: [$filePath], ref: $ref, refType: $refType) {
__typename
nodes {
__typename
diff --git a/app/graphql/queries/repository/files.query.graphql b/app/graphql/queries/repository/files.query.graphql
index a83880ce696..bd7bb8ba787 100644
--- a/app/graphql/queries/repository/files.query.graphql
+++ b/app/graphql/queries/repository/files.query.graphql
@@ -19,6 +19,7 @@ query getFiles(
$projectPath: ID!
$path: String
$ref: String!
+ $refType: RefType
$pageSize: Int!
$nextPageCursor: String
) {
@@ -27,7 +28,7 @@ query getFiles(
__typename
repository {
__typename
- tree(path: $path, ref: $ref) {
+ tree(path: $path, ref: $ref, refType: $refType) {
__typename
trees(first: $pageSize, after: $nextPageCursor) {
__typename
diff --git a/app/graphql/queries/repository/paginated_tree.query.graphql b/app/graphql/queries/repository/paginated_tree.query.graphql
index e82bc6d0734..68aa90046b9 100644
--- a/app/graphql/queries/repository/paginated_tree.query.graphql
+++ b/app/graphql/queries/repository/paginated_tree.query.graphql
@@ -7,13 +7,19 @@ fragment TreeEntry on Entry {
type
}
-query getPaginatedTree($projectPath: ID!, $path: String, $ref: String!, $nextPageCursor: String) {
+query getPaginatedTree(
+ $projectPath: ID!
+ $path: String
+ $ref: String!
+ $nextPageCursor: String
+ $refType: RefType
+) {
project(fullPath: $projectPath) {
id
__typename
repository {
__typename
- paginatedTree(path: $path, ref: $ref, after: $nextPageCursor) {
+ paginatedTree(path: $path, ref: $ref, refType: $refType, after: $nextPageCursor) {
__typename
pageInfo {
__typename
diff --git a/app/graphql/queries/repository/path_last_commit.query.graphql b/app/graphql/queries/repository/path_last_commit.query.graphql
index facbf1555fc..738fdf534cb 100644
--- a/app/graphql/queries/repository/path_last_commit.query.graphql
+++ b/app/graphql/queries/repository/path_last_commit.query.graphql
@@ -1,10 +1,10 @@
-query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
+query pathLastCommit($projectPath: ID!, $path: String, $ref: String!, $refType: RefType) {
project(fullPath: $projectPath) {
__typename
id
repository {
__typename
- paginatedTree(path: $path, ref: $ref) {
+ paginatedTree(path: $path, ref: $ref, refType: $refType) {
__typename
nodes {
__typename
diff --git a/app/graphql/resolvers/abuse_report_labels_resolver.rb b/app/graphql/resolvers/abuse_report_labels_resolver.rb
new file mode 100644
index 00000000000..86cebe8e541
--- /dev/null
+++ b/app/graphql/resolvers/abuse_report_labels_resolver.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class AbuseReportLabelsResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ authorize :read_label
+
+ type Types::LabelType.connection_type, null: true
+
+ argument :search_term, GraphQL::Types::String,
+ required: false,
+ description: 'Search term to find labels with.'
+
+ def resolve(**args)
+ ::Admin::AbuseReportLabelsFinder.new(context[:current_user], args).execute
+ end
+ end
+end
diff --git a/app/graphql/resolvers/abuse_report_resolver.rb b/app/graphql/resolvers/abuse_report_resolver.rb
new file mode 100644
index 00000000000..770409601b9
--- /dev/null
+++ b/app/graphql/resolvers/abuse_report_resolver.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class AbuseReportResolver < BaseResolver
+ description 'Retrieve an abuse report'
+
+ type Types::AbuseReportType, null: true
+
+ argument :id, Types::GlobalIDType[AbuseReport], required: true, description: 'ID of the abuse report.'
+
+ def resolve(id:)
+ ::AbuseReport.find_by_id(extract_abuse_report_id(id))
+ end
+
+ private
+
+ def extract_abuse_report_id(gid)
+ GitlabSchema.parse_gid(gid, expected_type: ::AbuseReport).model_id
+ end
+ end
+end
diff --git a/app/graphql/resolvers/autocomplete_users_resolver.rb b/app/graphql/resolvers/autocomplete_users_resolver.rb
new file mode 100644
index 00000000000..40c53a46311
--- /dev/null
+++ b/app/graphql/resolvers/autocomplete_users_resolver.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class AutocompleteUsersResolver < BaseResolver
+ type [::Types::Users::AutocompletedUserType], null: true
+
+ argument :search, GraphQL::Types::String,
+ required: false,
+ description: 'Query to search users by name, username, or public email.'
+
+ def resolve(search: nil)
+ ::Autocomplete::UsersFinder.new(
+ current_user: context[:current_user],
+ project: project,
+ group: group,
+ params: {
+ search: search
+ }
+ ).execute
+ end
+
+ private
+
+ def project
+ object if object.is_a?(Project)
+ end
+
+ def group
+ object if object.is_a?(Group)
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/pipeline_triggers_resolver.rb b/app/graphql/resolvers/ci/pipeline_triggers_resolver.rb
new file mode 100644
index 00000000000..3d6e3b3e75d
--- /dev/null
+++ b/app/graphql/resolvers/ci/pipeline_triggers_resolver.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class PipelineTriggersResolver < BaseResolver
+ include LooksAhead
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ authorize :admin_build
+ type Types::Ci::PipelineTriggerType.connection_type, null: false
+
+ def resolve_with_lookahead
+ apply_lookahead(object.triggers)
+ end
+
+ private
+
+ def unconditional_includes
+ [:trigger_requests]
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/concerns/resolves_merge_requests.rb b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
index c0a068097a7..e9e7ea9f77f 100644
--- a/app/graphql/resolvers/concerns/resolves_merge_requests.rb
+++ b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
@@ -59,7 +59,8 @@ module ResolvesMergeRequests
timelogs: [:timelogs],
pipelines: [:merge_request_diffs], # used by `recent_diff_head_shas` to load pipelines
committers: [merge_request_diff: [:merge_request_diff_commits]],
- suggested_reviewers: [:predictions]
+ suggested_reviewers: [:predictions],
+ diff_stats: [latest_merge_request_diff: [:merge_request_diff_commits]]
}
end
end
diff --git a/app/graphql/resolvers/concerns/work_items/look_ahead_preloads.rb b/app/graphql/resolvers/concerns/work_items/look_ahead_preloads.rb
new file mode 100644
index 00000000000..92fb9ec5cef
--- /dev/null
+++ b/app/graphql/resolvers/concerns/work_items/look_ahead_preloads.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module WorkItems
+ module LookAheadPreloads
+ extend ActiveSupport::Concern
+
+ prepended do
+ include ::LooksAhead
+ end
+
+ private
+
+ def preloads
+ {
+ work_item_type: :work_item_type,
+ web_url: { namespace: :route, project: [:project_namespace, { namespace: :route }] },
+ widgets: { work_item_type: :enabled_widget_definitions }
+ }
+ end
+
+ def nested_preloads
+ {
+ widgets: widget_preloads,
+ user_permissions: { update_work_item: :assignees },
+ project: { jira_import_status: { project: :jira_imports } },
+ author: {
+ location: { author: :user_detail },
+ gitpod_enabled: { author: :user_preference }
+ }
+ }
+ end
+
+ def widget_preloads
+ {
+ last_edited_by: :last_edited_by,
+ assignees: :assignees,
+ parent: :work_item_parent,
+ children: { work_item_children_by_relative_position: [:author, { project: :project_feature }] },
+ labels: :labels,
+ milestone: { milestone: [:project, :group] },
+ subscribed: [:assignees, :award_emoji, { notes: [:author, :award_emoji] }],
+ award_emoji: { award_emoji: :awardable }
+ }
+ end
+
+ def unconditional_includes
+ [
+ {
+ project: [:project_feature, :group]
+ },
+ :author
+ ]
+ end
+ end
+end
+
+WorkItems::LookAheadPreloads.prepend_mod
diff --git a/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb b/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb
index aad9bbebafb..b967460c7ff 100644
--- a/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb
+++ b/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb
@@ -16,11 +16,10 @@ module Resolvers
alias_method :dashboard, :object
- def resolve(**args)
+ def resolve(**_args)
return if Feature.enabled?(:remove_monitor_metrics)
- return [] unless dashboard
- ::Metrics::Dashboards::AnnotationsFinder.new(dashboard: dashboard, params: args).execute
+ []
end
end
end
diff --git a/app/graphql/resolvers/namespaces/work_items_resolver.rb b/app/graphql/resolvers/namespaces/work_items_resolver.rb
new file mode 100644
index 00000000000..54bb8392071
--- /dev/null
+++ b/app/graphql/resolvers/namespaces/work_items_resolver.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Namespaces
+ class WorkItemsResolver < BaseResolver
+ prepend ::WorkItems::LookAheadPreloads
+
+ type Types::WorkItemType.connection_type, null: true
+
+ def resolve_with_lookahead(**args)
+ return unless Feature.enabled?(:namespace_level_work_items, resource_parent)
+ return WorkItem.none if resource_parent.nil?
+
+ finder = ::WorkItems::NamespaceWorkItemsFinder.new(current_user, args.merge(
+ namespace_id: resource_parent
+ ))
+
+ Gitlab::Graphql::Loaders::IssuableLoader.new(resource_parent, finder).batching_find_all do |q|
+ apply_lookahead(q)
+ end
+ end
+
+ private
+
+ def resource_parent
+ # The project could have been loaded in batch by `BatchLoader`.
+ # At this point we need the `id` of the project to query for work items, so
+ # make sure it's loaded and not `nil` before continuing.
+ object.respond_to?(:sync) ? object.sync : object
+ end
+ strong_memoize_attr :resource_parent
+ end
+ end
+end
diff --git a/app/graphql/resolvers/work_items/linked_items_resolver.rb b/app/graphql/resolvers/work_items/linked_items_resolver.rb
new file mode 100644
index 00000000000..9c71cd7c0c9
--- /dev/null
+++ b/app/graphql/resolvers/work_items/linked_items_resolver.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module WorkItems
+ class LinkedItemsResolver < BaseResolver
+ alias_method :linked_items_widget, :object
+
+ type Types::WorkItems::LinkedItemType.connection_type, null: true
+
+ def resolve
+ related_work_items.map do |related_work_item|
+ {
+ link_id: related_work_item.issue_link_id,
+ link_type: related_work_item.issue_link_type,
+ link_created_at: related_work_item.issue_link_created_at,
+ link_updated_at: related_work_item.issue_link_updated_at,
+ work_item: related_work_item
+ }
+ end
+ end
+
+ private
+
+ def related_work_items
+ return [] unless work_item.project.linked_work_items_feature_flag_enabled?
+
+ work_item.related_issues(current_user, preload: { project: [:project_feature, :group] })
+ end
+
+ def work_item
+ linked_items_widget.work_item
+ end
+ strong_memoize_attr :work_item
+ end
+ end
+end
diff --git a/app/graphql/resolvers/work_items_resolver.rb b/app/graphql/resolvers/work_items_resolver.rb
index 14eec4f696a..d4f73361e05 100644
--- a/app/graphql/resolvers/work_items_resolver.rb
+++ b/app/graphql/resolvers/work_items_resolver.rb
@@ -2,8 +2,8 @@
module Resolvers
class WorkItemsResolver < BaseResolver
+ prepend ::WorkItems::LookAheadPreloads
include SearchArguments
- include LooksAhead
include ::WorkItems::SharedFilterArguments
argument :iid,
@@ -28,48 +28,6 @@ module Resolvers
private
- def preloads
- {
- work_item_type: :work_item_type,
- web_url: { namespace: :route, project: [:project_namespace, { namespace: :route }] },
- widgets: { work_item_type: :enabled_widget_definitions }
- }
- end
-
- def nested_preloads
- {
- widgets: widget_preloads,
- user_permissions: { update_work_item: :assignees },
- project: { jira_import_status: { project: :jira_imports } },
- author: {
- location: { author: :user_detail },
- gitpod_enabled: { author: :user_preference }
- }
- }
- end
-
- def widget_preloads
- {
- last_edited_by: :last_edited_by,
- assignees: :assignees,
- parent: :work_item_parent,
- children: { work_item_children_by_relative_position: [:author, { project: :project_feature }] },
- labels: :labels,
- milestone: { milestone: [:project, :group] },
- subscribed: [:assignees, :award_emoji, { notes: [:author, :award_emoji] }],
- award_emoji: { award_emoji: :awardable }
- }
- end
-
- def unconditional_includes
- [
- {
- project: [:project_feature, :group]
- },
- :author
- ]
- end
-
def prepare_finder_params(args)
params = super(args)
params[:iids] ||= [params.delete(:iid)].compact if params[:iid]
@@ -88,4 +46,4 @@ module Resolvers
end
end
-Resolvers::WorkItemsResolver.prepend_mod_with('Resolvers::WorkItemsResolver')
+Resolvers::WorkItemsResolver.prepend_mod
diff --git a/app/graphql/types/abuse_report_type.rb b/app/graphql/types/abuse_report_type.rb
new file mode 100644
index 00000000000..012e709cdb5
--- /dev/null
+++ b/app/graphql/types/abuse_report_type.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class AbuseReportType < BaseObject
+ graphql_name 'AbuseReport'
+ description 'An abuse report'
+ authorize :read_abuse_report
+
+ field :labels, ::Types::LabelType.connection_type,
+ null: true, description: 'Labels of the abuse report.'
+ end
+end
diff --git a/app/graphql/types/access_levels/deploy_key_type.rb b/app/graphql/types/access_levels/deploy_key_type.rb
new file mode 100644
index 00000000000..e4e90619891
--- /dev/null
+++ b/app/graphql/types/access_levels/deploy_key_type.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Types
+ module AccessLevels
+ class DeployKeyType < BaseObject
+ graphql_name 'AccessLevelDeployKey'
+ description 'Representation of a GitLab deploy key.'
+
+ authorize :read_deploy_key
+
+ field :id,
+ type: GraphQL::Types::ID,
+ null: false,
+ description: 'ID of the deploy key.'
+
+ field :title,
+ type: GraphQL::Types::String,
+ null: false,
+ description: 'Title of the deploy key.'
+
+ field :expires_at,
+ type: Types::DateType,
+ null: true,
+ description: 'Expiration date of the deploy key.'
+
+ field :user,
+ type: Types::AccessLevels::UserType,
+ null: false,
+ description: 'User assigned to the deploy key.'
+ end
+ end
+end
diff --git a/app/graphql/types/access_levels/user_type.rb b/app/graphql/types/access_levels/user_type.rb
new file mode 100644
index 00000000000..82aba673250
--- /dev/null
+++ b/app/graphql/types/access_levels/user_type.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Types
+ module AccessLevels
+ class UserType < BaseObject
+ graphql_name 'AccessLevelUser'
+ description 'Representation of a GitLab user.'
+
+ authorize :read_user
+
+ present_using UserPresenter
+
+ field :id,
+ type: GraphQL::Types::ID,
+ null: false,
+ description: 'ID of the user.'
+
+ field :username,
+ type: GraphQL::Types::String,
+ null: false,
+ description: 'Username of the user.'
+
+ field :name,
+ type: GraphQL::Types::String,
+ null: false,
+ resolver_method: :redacted_name,
+ description: <<~DESC
+ Human-readable name of the user.
+ Returns `****` if the user is a project bot and the requester does not have permission to view the project.
+ DESC
+
+ field :public_email,
+ type: GraphQL::Types::String,
+ null: true,
+ description: "User's public email."
+
+ field :avatar_url,
+ type: GraphQL::Types::String,
+ null: true,
+ description: "URL of the user's avatar."
+
+ field :web_url,
+ type: GraphQL::Types::String,
+ null: false,
+ description: 'Web URL of the user.'
+
+ field :web_path,
+ type: GraphQL::Types::String,
+ null: false,
+ description: 'Web path of the user.'
+
+ def redacted_name
+ object.redacted_name(context[:current_user])
+ end
+
+ def avatar_url
+ object.avatar_url(only_path: false)
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/achievements/achievement_type.rb b/app/graphql/types/achievements/achievement_type.rb
index ec558981465..d733bf39a51 100644
--- a/app/graphql/types/achievements/achievement_type.rb
+++ b/app/graphql/types/achievements/achievement_type.rb
@@ -5,6 +5,8 @@ module Types
class AchievementType < BaseObject
graphql_name 'Achievement'
+ connection_type_class Types::CountableConnectionType
+
authorize :read_achievement
field :id,
diff --git a/app/graphql/types/achievements/user_achievement_type.rb b/app/graphql/types/achievements/user_achievement_type.rb
index bf161d2f1e5..7cdcb66576c 100644
--- a/app/graphql/types/achievements/user_achievement_type.rb
+++ b/app/graphql/types/achievements/user_achievement_type.rb
@@ -5,6 +5,8 @@ module Types
class UserAchievementType < BaseObject
graphql_name 'UserAchievement'
+ connection_type_class Types::CountableConnectionType
+
authorize :read_user_achievement
field :id,
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index c17406b3e56..e85d0213613 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -8,8 +8,8 @@ module Types
present_using ::AlertManagement::AlertPresenter
- implements(Types::Notes::NoteableInterface)
- implements(Types::TodoableInterface)
+ implements Types::Notes::NoteableInterface
+ implements Types::TodoableInterface
authorize :read_alert_management_alert
@@ -111,6 +111,12 @@ module Types
null: true,
description: 'Assignees of the alert.'
+ field :metrics_dashboard_url,
+ GraphQL::Types::String,
+ null: true,
+ description: 'URL for metrics embed for the alert.',
+ deprecated: { reason: 'Returns no data. Underlying feature was removed in 16.0',
+ milestone: '16.0' }
field :runbook,
GraphQL::Types::String,
null: true,
@@ -136,6 +142,10 @@ module Types
method: :details_url,
null: false,
description: 'URL of the alert.'
+
+ def metrics_dashboard_url
+ nil
+ end
end
end
end
diff --git a/app/graphql/types/alert_management/http_integration_type.rb b/app/graphql/types/alert_management/http_integration_type.rb
index bba9cb1bbfc..7c026be86a3 100644
--- a/app/graphql/types/alert_management/http_integration_type.rb
+++ b/app/graphql/types/alert_management/http_integration_type.rb
@@ -6,7 +6,7 @@ module Types
graphql_name 'AlertManagementHttpIntegration'
description 'An endpoint and credentials used to accept alerts for a project'
- implements(Types::AlertManagement::IntegrationType)
+ implements Types::AlertManagement::IntegrationType
authorize :admin_operations
diff --git a/app/graphql/types/alert_management/prometheus_integration_type.rb b/app/graphql/types/alert_management/prometheus_integration_type.rb
index 9a2ef78eca7..0f61eeaa177 100644
--- a/app/graphql/types/alert_management/prometheus_integration_type.rb
+++ b/app/graphql/types/alert_management/prometheus_integration_type.rb
@@ -8,7 +8,7 @@ module Types
include ::Gitlab::Routing
- implements(Types::AlertManagement::IntegrationType)
+ implements Types::AlertManagement::IntegrationType
authorize :admin_project
diff --git a/app/graphql/types/branch_protections/push_access_level_type.rb b/app/graphql/types/branch_protections/push_access_level_type.rb
index c5e21fad88d..2a66f1a4ec5 100644
--- a/app/graphql/types/branch_protections/push_access_level_type.rb
+++ b/app/graphql/types/branch_protections/push_access_level_type.rb
@@ -6,6 +6,11 @@ module Types
graphql_name 'PushAccessLevel'
description 'Defines which user roles, users, or groups can push to a protected branch.'
accepts ::ProtectedBranch::PushAccessLevel
+
+ field :deploy_key,
+ Types::AccessLevels::DeployKeyType,
+ null: true,
+ description: 'Deploy key assigned to the access level.'
end
end
end
diff --git a/app/graphql/types/ci/ci_cd_setting_type.rb b/app/graphql/types/ci/ci_cd_setting_type.rb
index f7ef94f58c0..45ecbf5c084 100644
--- a/app/graphql/types/ci/ci_cd_setting_type.rb
+++ b/app/graphql/types/ci/ci_cd_setting_type.rb
@@ -7,32 +7,37 @@ module Types
authorize :admin_project
- field :job_token_scope_enabled,
- GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates CI/CD job tokens generated in this project ' \
- 'have restricted access to other projects.',
- method: :job_token_scope_enabled?
-
field :inbound_job_token_scope_enabled,
- GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates CI/CD job tokens generated in other projects ' \
- 'have restricted access to this project.',
- method: :inbound_job_token_scope_enabled?
-
- field :keep_latest_artifact, GraphQL::Types::Boolean, null: true,
- description: 'Whether to keep the latest builds artifacts.',
- method: :keep_latest_artifacts_available?
- field :merge_pipelines_enabled, GraphQL::Types::Boolean, null: true,
- description: 'Whether merge pipelines are enabled.',
- method: :merge_pipelines_enabled?
- field :merge_trains_enabled, GraphQL::Types::Boolean, null: true,
- description: 'Whether merge trains are enabled.',
- method: :merge_trains_enabled?
-
- field :project, Types::ProjectType, null: true,
- description: 'Project the CI/CD settings belong to.'
+ GraphQL::Types::Boolean,
+ null: true,
+ description: 'Indicates CI/CD job tokens generated in other projects ' \
+ 'have restricted access to this project.',
+ method: :inbound_job_token_scope_enabled?
+ field :job_token_scope_enabled,
+ GraphQL::Types::Boolean,
+ null: true,
+ description: 'Indicates CI/CD job tokens generated in this project ' \
+ 'have restricted access to other projects.',
+ method: :job_token_scope_enabled?
+ field :keep_latest_artifact,
+ GraphQL::Types::Boolean,
+ null: true,
+ description: 'Whether to keep the latest builds artifacts.',
+ method: :keep_latest_artifacts_available?
+ field :merge_pipelines_enabled,
+ GraphQL::Types::Boolean,
+ null: true,
+ description: 'Whether merge pipelines are enabled.',
+ method: :merge_pipelines_enabled?
+ field :merge_trains_enabled,
+ GraphQL::Types::Boolean,
+ null: true,
+ description: 'Whether merge trains are enabled.',
+ method: :merge_trains_enabled?
+ field :project,
+ Types::ProjectType,
+ null: true,
+ description: 'Project the CI/CD settings belong to.'
end
end
end
diff --git a/app/graphql/types/ci/detailed_status_type.rb b/app/graphql/types/ci/detailed_status_type.rb
index 8bc50e974bb..e18770c2708 100644
--- a/app/graphql/types/ci/detailed_status_type.rb
+++ b/app/graphql/types/ci/detailed_status_type.rb
@@ -39,17 +39,15 @@ module Types
end
def action
- if object.has_action?
- {
- button_title: object.action_button_title,
- icon: object.action_icon,
- method: object.action_method,
- path: object.action_path,
- title: object.action_title
- }
- else
- nil
- end
+ return unless object.has_action?
+
+ {
+ button_title: object.action_button_title,
+ icon: object.action_icon,
+ method: object.action_method,
+ path: object.action_path,
+ title: object.action_title
+ }
end
end
# rubocop: enable Graphql/AuthorizeTypes
diff --git a/app/graphql/types/ci/group_environment_scope_type.rb b/app/graphql/types/ci/group_environment_scope_type.rb
index 3a3a5a3f59f..0dd0ad963ac 100644
--- a/app/graphql/types/ci/group_environment_scope_type.rb
+++ b/app/graphql/types/ci/group_environment_scope_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'CiGroupEnvironmentScope'
description 'Ci/CD environment scope for a group.'
- connection_type_class(Types::Ci::GroupEnvironmentScopeConnectionType)
+ connection_type_class Types::Ci::GroupEnvironmentScopeConnectionType
field :name, GraphQL::Types::String,
null: true,
diff --git a/app/graphql/types/ci/group_variable_type.rb b/app/graphql/types/ci/group_variable_type.rb
index 7e2afba0d53..7be9b3df0b8 100644
--- a/app/graphql/types/ci/group_variable_type.rb
+++ b/app/graphql/types/ci/group_variable_type.rb
@@ -7,8 +7,8 @@ module Types
graphql_name 'CiGroupVariable'
description 'CI/CD variables for a group.'
- connection_type_class(Types::Ci::GroupVariableConnectionType)
- implements(VariableInterface)
+ connection_type_class Types::Ci::GroupVariableConnectionType
+ implements VariableInterface
field :environment_scope, GraphQL::Types::String,
null: true,
diff --git a/app/graphql/types/ci/instance_variable_type.rb b/app/graphql/types/ci/instance_variable_type.rb
index 7ffc52deb73..e3230556769 100644
--- a/app/graphql/types/ci/instance_variable_type.rb
+++ b/app/graphql/types/ci/instance_variable_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'CiInstanceVariable'
description 'CI/CD variables for a GitLab instance.'
- implements(VariableInterface)
+ implements VariableInterface
field :id, GraphQL::Types::ID,
null: false,
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index 02b10f3e4bd..22eb32993c5 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -9,7 +9,7 @@ module Types
present_using ::Ci::BuildPresenter
- connection_type_class(Types::LimitedCountableConnectionType)
+ connection_type_class Types::LimitedCountableConnectionType
expose_permissions Types::PermissionTypes::Ci::Job
diff --git a/app/graphql/types/ci/manual_variable_type.rb b/app/graphql/types/ci/manual_variable_type.rb
index ed92a6645b4..dcdaa3a6b19 100644
--- a/app/graphql/types/ci/manual_variable_type.rb
+++ b/app/graphql/types/ci/manual_variable_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'CiManualVariable'
description 'CI/CD variables given to a manual job.'
- implements(VariableInterface)
+ implements VariableInterface
field :environment_scope, GraphQL::Types::String,
null: true,
diff --git a/app/graphql/types/ci/pipeline_schedule_type.rb b/app/graphql/types/ci/pipeline_schedule_type.rb
index 904fa3f1c72..71a1f28ea38 100644
--- a/app/graphql/types/ci/pipeline_schedule_type.rb
+++ b/app/graphql/types/ci/pipeline_schedule_type.rb
@@ -7,7 +7,7 @@ module Types
description 'Represents a pipeline schedule'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
expose_permissions Types::PermissionTypes::Ci::PipelineSchedules
diff --git a/app/graphql/types/ci/pipeline_schedule_variable_type.rb b/app/graphql/types/ci/pipeline_schedule_variable_type.rb
index 1cb407bc2e4..f9c18d6f7df 100644
--- a/app/graphql/types/ci/pipeline_schedule_variable_type.rb
+++ b/app/graphql/types/ci/pipeline_schedule_variable_type.rb
@@ -7,7 +7,7 @@ module Types
authorize :read_pipeline_schedule_variables
- implements(VariableInterface)
+ implements VariableInterface
end
end
end
diff --git a/app/graphql/types/ci/pipeline_trigger_type.rb b/app/graphql/types/ci/pipeline_trigger_type.rb
new file mode 100644
index 00000000000..81345c14ba0
--- /dev/null
+++ b/app/graphql/types/ci/pipeline_trigger_type.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ class PipelineTriggerType < BaseObject
+ graphql_name 'PipelineTrigger'
+
+ present_using ::Ci::TriggerPresenter
+ connection_type_class Types::CountableConnectionType
+
+ authorize :admin_build
+
+ field :can_access_project, GraphQL::Types::Boolean,
+ null: false,
+ description: 'Indicates if the pipeline trigger token has access to the project.',
+ method: :can_access_project?
+
+ field :description, GraphQL::Types::String,
+ null: true,
+ description: 'Description of the pipeline trigger token.'
+
+ field :has_token_exposed, GraphQL::Types::Boolean,
+ null: false,
+ description: 'Indicates if the token is exposed.',
+ method: :has_token_exposed?
+
+ field :id, GraphQL::Types::ID,
+ null: false,
+ description: 'ID of the pipeline trigger token.'
+
+ field :last_used, Types::TimeType,
+ null: true,
+ description: 'Timestamp of the last usage of the pipeline trigger token.'
+
+ field :owner, Types::UserType,
+ null: false,
+ description: 'Owner of the pipeline trigger token.'
+
+ field :token, GraphQL::Types::String,
+ null: false,
+ description: 'Value of the pipeline trigger token.'
+ end
+ end
+end
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index 19d261853a7..ba638d4bc47 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -5,7 +5,7 @@ module Types
class PipelineType < BaseObject
graphql_name 'Pipeline'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
authorize :read_pipeline
present_using ::Ci::PipelinePresenter
diff --git a/app/graphql/types/ci/project_variable_type.rb b/app/graphql/types/ci/project_variable_type.rb
index a9679000511..cd069be3320 100644
--- a/app/graphql/types/ci/project_variable_type.rb
+++ b/app/graphql/types/ci/project_variable_type.rb
@@ -7,8 +7,8 @@ module Types
graphql_name 'CiProjectVariable'
description 'CI/CD variables for a project.'
- connection_type_class(Types::Ci::ProjectVariableConnectionType)
- implements(VariableInterface)
+ connection_type_class Types::Ci::ProjectVariableConnectionType
+ implements VariableInterface
field :environment_scope, GraphQL::Types::String,
null: true,
diff --git a/app/graphql/types/ci/recent_failures_type.rb b/app/graphql/types/ci/recent_failures_type.rb
index 0892cb2735c..37850c62658 100644
--- a/app/graphql/types/ci/recent_failures_type.rb
+++ b/app/graphql/types/ci/recent_failures_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'RecentFailures'
description 'Recent failure history of a test case.'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :count, GraphQL::Types::Int, null: true,
description: 'Number of times the test case has failed in the past 14 days.'
diff --git a/app/graphql/types/ci/runner_manager_type.rb b/app/graphql/types/ci/runner_manager_type.rb
index 9c89b6537ea..9311836cf27 100644
--- a/app/graphql/types/ci/runner_manager_type.rb
+++ b/app/graphql/types/ci/runner_manager_type.rb
@@ -5,7 +5,7 @@ module Types
class RunnerManagerType < BaseObject
graphql_name 'CiRunnerManager'
- connection_type_class(::Types::CountableConnectionType)
+ connection_type_class ::Types::CountableConnectionType
authorize :read_runner_manager
@@ -26,6 +26,11 @@ module Types
description: 'ID of the runner manager.'
field :ip_address, GraphQL::Types::String, null: true,
description: 'IP address of the runner manager.'
+ field :job_execution_status,
+ Types::Ci::RunnerJobExecutionStatusEnum,
+ null: true,
+ description: 'Job execution status of the runner manager.',
+ alpha: { milestone: '16.3' }
field :platform_name, GraphQL::Types::String, null: true,
description: 'Platform provided by the runner manager.',
method: :platform
@@ -44,6 +49,16 @@ module Types
def executor_name
::Ci::Runner::EXECUTOR_TYPE_TO_NAMES[runner_manager.executor_type&.to_sym]
end
+
+ def job_execution_status
+ BatchLoader::GraphQL.for(runner_manager.id).batch(key: :running_builds_exist) do |runner_manager_ids, loader|
+ statuses = ::Ci::RunnerManager.id_in(runner_manager_ids).with_running_builds.index_by(&:id)
+
+ runner_manager_ids.each do |runner_manager_id|
+ loader.call(runner_manager_id, statuses[runner_manager_id] ? :running : :idle)
+ end
+ end
+ end
end
end
end
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 2baf64ca663..c9f92c05975 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(RunnerCountableConnectionType)
+ connection_type_class RunnerCountableConnectionType
authorize :read_runner
present_using ::Ci::RunnerPresenter
@@ -59,7 +59,9 @@ module Types
deprecated: { reason: "Use field in `manager` object instead", milestone: '16.2' },
description: 'IP address of the runner.'
field :job_count, GraphQL::Types::Int, null: true,
- description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to indicate that more items exist).",
+ description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to " \
+ "indicate that more items exist).\n`jobCount` is an optimized version of `jobs { count }`, " \
+ "and can be requested for multiple runners on the same request.",
resolver: ::Resolvers::Ci::RunnerJobCountResolver
field :job_execution_status,
Types::Ci::RunnerJobExecutionStatusEnum,
@@ -76,7 +78,6 @@ module Types
description: 'Runner\'s maintenance notes.'
field :managers, ::Types::Ci::RunnerManagerType.connection_type, null: true,
description: 'Machines associated with the runner configuration.',
- method: :runner_managers,
alpha: { milestone: '15.10' }
field :maximum_timeout, GraphQL::Types::Int, null: true,
description: 'Maximum timeout (in seconds) for jobs processed by the runner.'
@@ -173,6 +174,18 @@ module Types
end
end
+ def managers
+ BatchLoader::GraphQL.for(runner.id).batch(key: :runner_managers) do |runner_ids, loader|
+ runner_managers_by_runner_id =
+ ::Ci::RunnerManager.for_runner(runner_ids).order_id_desc.group_by(&:runner_id)
+
+ runner_ids.each do |runner_id|
+ runner_managers = Array.wrap(runner_managers_by_runner_id[runner_id])
+ loader.call(runner_id, runner_managers)
+ end
+ end
+ end
+
def job_execution_status
BatchLoader::GraphQL.for(runner.id).batch(key: :running_builds_exist) do |runner_ids, loader|
statuses = ::Ci::Runner.id_in(runner_ids).with_running_builds.index_by(&:id)
diff --git a/app/graphql/types/ci/test_case_type.rb b/app/graphql/types/ci/test_case_type.rb
index f88923215eb..78c70fbcc7c 100644
--- a/app/graphql/types/ci/test_case_type.rb
+++ b/app/graphql/types/ci/test_case_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'TestCase'
description 'Test case in pipeline test report.'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :status,
Types::Ci::TestCaseStatusEnum,
diff --git a/app/graphql/types/ci/test_suite_summary_type.rb b/app/graphql/types/ci/test_suite_summary_type.rb
index 8801501c8d4..a98c47c6a30 100644
--- a/app/graphql/types/ci/test_suite_summary_type.rb
+++ b/app/graphql/types/ci/test_suite_summary_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'TestSuiteSummary'
description 'Test suite summary in a pipeline test report.'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :name, GraphQL::Types::String, null: true,
description: 'Name of the test suite.'
diff --git a/app/graphql/types/ci/test_suite_type.rb b/app/graphql/types/ci/test_suite_type.rb
index 8845338ed6d..a5cc6282abc 100644
--- a/app/graphql/types/ci/test_suite_type.rb
+++ b/app/graphql/types/ci/test_suite_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'TestSuite'
description 'Test suite in a pipeline test report.'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :name, GraphQL::Types::String, null: true,
description: 'Name of the test suite.'
diff --git a/app/graphql/types/clusters/agent_activity_event_type.rb b/app/graphql/types/clusters/agent_activity_event_type.rb
index 1d0ec7c4959..8c7dfa9c10a 100644
--- a/app/graphql/types/clusters/agent_activity_event_type.rb
+++ b/app/graphql/types/clusters/agent_activity_event_type.rb
@@ -7,7 +7,7 @@ module Types
authorize :read_cluster_agent
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :recorded_at,
Types::TimeType,
diff --git a/app/graphql/types/clusters/agent_token_type.rb b/app/graphql/types/clusters/agent_token_type.rb
index 720ee2f685b..260c634e12e 100644
--- a/app/graphql/types/clusters/agent_token_type.rb
+++ b/app/graphql/types/clusters/agent_token_type.rb
@@ -7,7 +7,7 @@ module Types
authorize :read_cluster_agent
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :cluster_agent,
Types::Clusters::AgentType,
diff --git a/app/graphql/types/clusters/agent_type.rb b/app/graphql/types/clusters/agent_type.rb
index 317a1aab628..c0989796141 100644
--- a/app/graphql/types/clusters/agent_type.rb
+++ b/app/graphql/types/clusters/agent_type.rb
@@ -7,7 +7,7 @@ module Types
authorize :read_cluster_agent
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :created_at,
Types::TimeType,
diff --git a/app/graphql/types/commit_type.rb b/app/graphql/types/commit_type.rb
index 5dd862c7388..9f83e955f4c 100644
--- a/app/graphql/types/commit_type.rb
+++ b/app/graphql/types/commit_type.rb
@@ -8,7 +8,7 @@ module Types
present_using CommitPresenter
- implements(Types::TodoableInterface)
+ implements Types::TodoableInterface
field :id, type: GraphQL::Types::ID, null: false,
description: 'ID (global ID) of the commit.'
@@ -34,6 +34,9 @@ module Types
field :authored_date, type: Types::TimeType, null: true,
description: 'Timestamp of when the commit was authored.'
+ field :committed_date, type: Types::TimeType, null: true,
+ description: 'Timestamp of when the commit was committed.'
+
field :web_url, type: GraphQL::Types::String, null: false,
description: 'Web URL of the commit.'
@@ -55,10 +58,24 @@ module Types
field :author_name, type: GraphQL::Types::String, null: true,
description: 'Commit authors name.'
+ field :committer_email, type: GraphQL::Types::String, null: true,
+ description: "Email of the committer."
+
+ field :committer_name, type: GraphQL::Types::String, null: true,
+ description: "Name of the committer."
+
# models/commit lazy loads the author by email
field :author, type: Types::UserType, null: true,
description: 'Author of the commit.'
+ field :diffs, [Types::DiffType], null: true, calls_gitaly: true,
+ description: 'Diffs contained within the commit. ' \
+ 'This field can only be resolved for 10 diffs in any single request.' do
+ # Limited to 10 calls per GraphQL request as calling `diffs` multiple times will
+ # lead to N+1 queries to Gitaly.
+ extension ::Gitlab::Graphql::Limit::FieldCallCount, limit: 10
+ end
+
field :pipelines,
null: true,
description: 'Pipelines of the commit ordered latest first.',
@@ -68,6 +85,10 @@ module Types
markdown_field :full_title_html, null: true
markdown_field :description_html, null: true
+ def diffs
+ object.diffs.diffs
+ end
+
def author_gravatar
GravatarService.new.execute(object.author_email, 40)
end
diff --git a/app/graphql/types/custom_emoji_type.rb b/app/graphql/types/custom_emoji_type.rb
index 379a0c44d67..b02cd56e6df 100644
--- a/app/graphql/types/custom_emoji_type.rb
+++ b/app/graphql/types/custom_emoji_type.rb
@@ -7,6 +7,10 @@ module Types
authorize :read_custom_emoji
+ connection_type_class(Types::CountableConnectionType)
+
+ expose_permissions Types::PermissionTypes::CustomEmoji
+
field :id, ::Types::GlobalIDType[::CustomEmoji],
null: false,
description: 'ID of the emoji.'
@@ -23,5 +27,9 @@ module Types
field :external, GraphQL::Types::Boolean,
null: false,
description: 'Whether the emoji is an external link.'
+
+ field :created_at, Types::TimeType,
+ null: false,
+ description: 'Timestamp of when the custom emoji was created.'
end
end
diff --git a/app/graphql/types/deployment_type.rb b/app/graphql/types/deployment_type.rb
index 6d895cc81cf..c49633275fb 100644
--- a/app/graphql/types/deployment_type.rb
+++ b/app/graphql/types/deployment_type.rb
@@ -54,8 +54,7 @@ module Types
field :job,
Types::Ci::JobType,
- description: 'Pipeline job of the deployment.',
- method: :build
+ description: 'Pipeline job of the deployment.'
field :triggerer,
Types::UserType,
diff --git a/app/graphql/types/design_management/design_type.rb b/app/graphql/types/design_management/design_type.rb
index be5edd17643..d253ca8bfea 100644
--- a/app/graphql/types/design_management/design_type.rb
+++ b/app/graphql/types/design_management/design_type.rb
@@ -10,10 +10,10 @@ module Types
alias_method :design, :object
- implements(Types::Notes::NoteableInterface)
- implements(Types::DesignManagement::DesignFields)
- implements(Types::CurrentUserTodos)
- implements(Types::TodoableInterface)
+ implements Types::Notes::NoteableInterface
+ implements Types::DesignManagement::DesignFields
+ implements Types::CurrentUserTodos
+ implements Types::TodoableInterface
field :description,
GraphQL::Types::String,
diff --git a/app/graphql/types/diff_type.rb b/app/graphql/types/diff_type.rb
new file mode 100644
index 00000000000..1c67c8c645a
--- /dev/null
+++ b/app/graphql/types/diff_type.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop: disable Graphql/AuthorizeTypes
+ class DiffType < BaseObject
+ graphql_name 'Diff'
+
+ field :a_mode, GraphQL::Types::String, null: true,
+ description: 'Old file mode of the file.'
+ field :b_mode, GraphQL::Types::String, null: true,
+ description: 'New file mode of the file.'
+ field :deleted_file, GraphQL::Types::String, null: true,
+ description: 'Indicates if the file has been removed. '
+ field :diff, GraphQL::Types::String, null: true,
+ description: 'Diff representation of the changes made to the file.'
+ field :new_file, GraphQL::Types::String, null: true,
+ description: 'Indicates if the file has just been added. '
+ field :new_path, GraphQL::Types::String, null: true,
+ description: 'New path of the file.'
+ field :old_path, GraphQL::Types::String, null: true,
+ description: 'Old path of the file.'
+ field :renamed_file, GraphQL::Types::String, null: true,
+ description: 'Indicates if the file has been renamed.'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+end
diff --git a/app/graphql/types/environment_type.rb b/app/graphql/types/environment_type.rb
index aee09e5a143..63f2b247e01 100644
--- a/app/graphql/types/environment_type.rb
+++ b/app/graphql/types/environment_type.rb
@@ -36,6 +36,9 @@ module Types
field :kubernetes_namespace, GraphQL::Types::String, null: true,
description: 'Kubernetes namespace of the environment.'
+ field :flux_resource_path, GraphQL::Types::String, null: true,
+ description: 'Flux resource path of the environment.'
+
field :created_at, Types::TimeType,
description: 'When the environment was created.'
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 5fd6ee948d3..258cf1539fb 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -87,6 +87,7 @@ module Types
Types::Ci::GroupEnvironmentScopeType.connection_type,
description: 'Environment scopes of the group.',
null: true,
+ authorize: :admin_group,
resolver: Resolvers::GroupEnvironmentScopesResolver
field :milestones,
@@ -261,6 +262,17 @@ module Types
resolver: Resolvers::DataTransfer::GroupDataTransferResolver,
description: 'Data transfer data point for a specific period. This is mocked data under a development feature flag.'
+ field :work_items,
+ null: true,
+ description: 'Work items that belong to the namespace.',
+ alpha: { milestone: '16.3' },
+ resolver: ::Resolvers::Namespaces::WorkItemsResolver
+
+ field :autocomplete_users,
+ null: true,
+ resolver: Resolvers::AutocompleteUsersResolver,
+ description: 'Search users for autocompletion'
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
LabelsFinder
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 488e4d10cbc..4b7118d75a5 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -4,11 +4,11 @@ module Types
class IssueType < BaseObject
graphql_name 'Issue'
- connection_type_class(Types::IssueConnectionType)
+ connection_type_class Types::IssueConnectionType
- implements(Types::Notes::NoteableInterface)
- implements(Types::CurrentUserTodos)
- implements(Types::TodoableInterface)
+ implements Types::Notes::NoteableInterface
+ implements Types::CurrentUserTodos
+ implements Types::TodoableInterface
authorize :read_issue
@@ -92,7 +92,13 @@ module Types
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.'
+ description: 'Indicates if a project 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.'
+
field :human_time_estimate, GraphQL::Types::String, null: true,
description: 'Human-readable time estimate of the issue.'
field :human_total_time_spent, GraphQL::Types::String, null: true,
diff --git a/app/graphql/types/label_type.rb b/app/graphql/types/label_type.rb
index 05b703e60af..4848ee30950 100644
--- a/app/graphql/types/label_type.rb
+++ b/app/graphql/types/label_type.rb
@@ -4,7 +4,7 @@ module Types
class LabelType < BaseObject
graphql_name 'Label'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
authorize :read_label
diff --git a/app/graphql/types/merge_request_state_enum.rb b/app/graphql/types/merge_request_state_enum.rb
index bcf18b836de..e03b79dfeb8 100644
--- a/app/graphql/types/merge_request_state_enum.rb
+++ b/app/graphql/types/merge_request_state_enum.rb
@@ -5,6 +5,7 @@ module Types
graphql_name 'MergeRequestState'
description 'State of a GitLab merge request'
- value 'merged', description: "Merge request has been merged."
+ value 'merged', description: 'Merge request has been merged.'
+ value 'opened', description: 'Opened merge request.'
end
end
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index 99c719f1402..3fe8a05b311 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -4,11 +4,11 @@ module Types
class MergeRequestType < BaseObject
graphql_name 'MergeRequest'
- connection_type_class(Types::MergeRequestConnectionType)
+ connection_type_class Types::MergeRequestConnectionType
- implements(Types::Notes::NoteableInterface)
- implements(Types::CurrentUserTodos)
- implements(Types::TodoableInterface)
+ implements Types::Notes::NoteableInterface
+ implements Types::CurrentUserTodos
+ implements Types::TodoableInterface
authorize :read_merge_request
@@ -192,6 +192,11 @@ module Types
field :total_time_spent, GraphQL::Types::Int, null: false,
description: 'Total time reported as spent on the merge request.'
+ field :approved, GraphQL::Types::Boolean,
+ method: :approved?,
+ null: false, calls_gitaly: true,
+ description: 'Indicates if the merge request has all the required approvals.'
+
field :approved_by, Types::UserType.connection_type, null: true,
description: 'Users who approved the merge request.', method: :approved_by_users
field :auto_merge_strategy, GraphQL::Types::String, null: true,
@@ -221,7 +226,7 @@ module Types
field :award_emoji, Types::AwardEmojis::AwardEmojiType.connection_type,
null: true,
- description: 'List of award emojis associated with the merge request.'
+ description: 'List of emoji reactions associated with the merge request.'
field :prepared_at, Types::TimeType, null: true,
description: 'Timestamp of when the merge request was prepared.'
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 16c46d172f3..957fd10690f 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -143,6 +143,9 @@ module Types
mount_mutation Mutations::Ci::PipelineSchedule::Play
mount_mutation Mutations::Ci::PipelineSchedule::Create
mount_mutation Mutations::Ci::PipelineSchedule::Update
+ mount_mutation Mutations::Ci::PipelineTrigger::Create, alpha: { milestone: '16.3' }
+ mount_mutation Mutations::Ci::PipelineTrigger::Update, alpha: { milestone: '16.3' }
+ mount_mutation Mutations::Ci::PipelineTrigger::Delete, alpha: { milestone: '16.3' }
mount_mutation Mutations::Ci::ProjectCiCdSettingsUpdate
mount_mutation Mutations::Ci::Job::ArtifactsDestroy
mount_mutation Mutations::Ci::Job::Play
@@ -177,12 +180,14 @@ module Types
mount_mutation Mutations::WorkItems::UpdateTask, alpha: { milestone: '15.1' }
mount_mutation Mutations::WorkItems::Export, alpha: { milestone: '15.10' }
mount_mutation Mutations::WorkItems::Convert, alpha: { milestone: '15.11' }
+ mount_mutation Mutations::WorkItems::LinkedItems::Add, alpha: { milestone: '16.3' }
mount_mutation Mutations::SavedReplies::Create
mount_mutation Mutations::SavedReplies::Update
mount_mutation Mutations::Pages::MarkOnboardingComplete
mount_mutation Mutations::SavedReplies::Destroy
mount_mutation Mutations::Uploads::Delete
mount_mutation Mutations::Users::SetNamespaceCommitEmail
+ mount_mutation Mutations::WorkItems::Subscribe, alpha: { milestone: '16.3' }
end
end
diff --git a/app/graphql/types/namespace/package_settings_type.rb b/app/graphql/types/namespace/package_settings_type.rb
index 84becba8001..61240243b1f 100644
--- a/app/graphql/types/namespace/package_settings_type.rb
+++ b/app/graphql/types/namespace/package_settings_type.rb
@@ -20,6 +20,14 @@ module Types
field :maven_duplicates_allowed, GraphQL::Types::Boolean,
null: false,
description: 'Indicates whether duplicate Maven packages are allowed for this namespace.'
+ field :nuget_duplicate_exception_regex, Types::UntrustedRegexp,
+ null: true,
+ description: 'When nuget_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. ' \
+ 'Error is raised if `nuget_duplicates_option` feature flag is disabled.'
+ field :nuget_duplicates_allowed, GraphQL::Types::Boolean,
+ null: false,
+ description: 'Indicates whether duplicate NuGet packages are allowed for this namespace. ' \
+ 'Error is raised if `nuget_duplicates_option` feature flag is disabled.'
field :maven_package_requests_forwarding, GraphQL::Types::Boolean,
null: true,
diff --git a/app/graphql/types/notes/discussion_type.rb b/app/graphql/types/notes/discussion_type.rb
index 5e40c8008a9..7afb1f392d3 100644
--- a/app/graphql/types/notes/discussion_type.rb
+++ b/app/graphql/types/notes/discussion_type.rb
@@ -9,7 +9,7 @@ module Types
authorize :read_note
- implements(Types::ResolvableInterface)
+ implements Types::ResolvableInterface
field :created_at, Types::TimeType, null: false,
description: "Timestamp of the discussion's creation."
diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb
index eb1963f976a..e7e032c67c6 100644
--- a/app/graphql/types/notes/note_type.rb
+++ b/app/graphql/types/notes/note_type.rb
@@ -9,7 +9,7 @@ module Types
expose_permissions Types::PermissionTypes::Note
- implements(Types::ResolvableInterface)
+ implements Types::ResolvableInterface
field :max_access_level_of_author, GraphQL::Types::String,
null: true,
@@ -43,7 +43,7 @@ module Types
field :award_emoji, Types::AwardEmojis::AwardEmojiType.connection_type,
null: true,
- description: 'List of award emojis associated with the note.'
+ description: 'List of emoji reactions associated with the note.'
field :confidential, GraphQL::Types::Boolean,
null: true,
diff --git a/app/graphql/types/notes/position_type_enum.rb b/app/graphql/types/notes/position_type_enum.rb
index 157b0b4b884..b585d531192 100644
--- a/app/graphql/types/notes/position_type_enum.rb
+++ b/app/graphql/types/notes/position_type_enum.rb
@@ -8,6 +8,7 @@ module Types
value 'text', description: "Text file."
value 'image', description: "An image."
+ value 'file', description: "Unknown file type."
end
end
end
diff --git a/app/graphql/types/packages/package_base_type.rb b/app/graphql/types/packages/package_base_type.rb
index 8dd2a4467d6..cc41169bcda 100644
--- a/app/graphql/types/packages/package_base_type.rb
+++ b/app/graphql/types/packages/package_base_type.rb
@@ -6,7 +6,7 @@ module Types
graphql_name 'PackageBase'
description 'Represents a package in the Package Registry'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
authorize :read_package
diff --git a/app/graphql/types/permission_types/group.rb b/app/graphql/types/permission_types/group.rb
index 6a1031e2532..fbd1140babc 100644
--- a/app/graphql/types/permission_types/group.rb
+++ b/app/graphql/types/permission_types/group.rb
@@ -5,7 +5,7 @@ module Types
class Group < BasePermissionType
graphql_name 'GroupPermissions'
- abilities :read_group, :create_projects
+ abilities :read_group, :create_projects, :create_custom_emoji
end
end
end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 992663b4d98..2738d4da6c2 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -4,618 +4,625 @@ module Types
class ProjectType < BaseObject
graphql_name 'Project'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
authorize :read_project
expose_permissions Types::PermissionTypes::Project
field :id, GraphQL::Types::ID,
- null: false,
- description: 'ID of the project.'
+ null: false,
+ description: 'ID of the project.'
field :ci_config_path_or_default, GraphQL::Types::String,
- null: false,
- description: 'Path of the CI configuration file.'
+ null: false,
+ description: 'Path of the CI configuration file.'
field :ci_config_variables, [Types::Ci::ConfigVariableType],
- null: true,
- calls_gitaly: true,
- authorize: :create_pipeline,
- alpha: { milestone: '15.3' },
- description: 'CI/CD config variable.' do
- argument :ref, GraphQL::Types::String,
- required: true,
- description: 'Ref.'
- end
+ null: true,
+ calls_gitaly: true,
+ authorize: :create_pipeline,
+ alpha: { milestone: '15.3' },
+ description: 'CI/CD config variable.' do
+ argument :ref, GraphQL::Types::String,
+ required: true,
+ description: 'Ref.'
+ end
field :full_path, GraphQL::Types::ID,
- null: false,
- description: 'Full path of the project.'
+ null: false,
+ description: 'Full path of the project.'
field :path, GraphQL::Types::String,
- null: false,
- description: 'Path of the project.'
+ null: false,
+ description: 'Path of the project.'
field :incident_management_timeline_event_tags, [Types::IncidentManagement::TimelineEventTagType],
- null: true,
- description: 'Timeline event tags for the project.'
+ null: true,
+ description: 'Timeline event tags for the project.'
field :sast_ci_configuration, Types::CiConfiguration::Sast::Type,
- null: true,
- calls_gitaly: true,
- description: 'SAST CI configuration for the project.'
+ null: true,
+ calls_gitaly: true,
+ description: 'SAST CI configuration for the project.'
field :name, GraphQL::Types::String,
- null: false,
- description: 'Name of the project (without namespace).'
+ null: false,
+ description: 'Name of the project (without namespace).'
field :name_with_namespace, GraphQL::Types::String,
- null: false,
- description: 'Full name of the project with its namespace.'
+ null: false,
+ description: 'Full name of the project with its namespace.'
field :description, GraphQL::Types::String,
- null: true,
- description: 'Short description of the project.'
+ null: true,
+ description: 'Short description of the project.'
field :tag_list, GraphQL::Types::String,
- null: true,
- deprecated: { reason: 'Use `topics`', milestone: '13.12' },
- description: 'List of project topics (not Git tags).',
- method: :topic_list
+ null: true,
+ deprecated: { reason: 'Use `topics`', milestone: '13.12' },
+ description: 'List of project topics (not Git tags).',
+ method: :topic_list
field :topics, [GraphQL::Types::String],
- null: true,
- description: 'List of project topics.',
- method: :topic_list
+ null: true,
+ description: 'List of project topics.',
+ method: :topic_list
field :http_url_to_repo, GraphQL::Types::String,
- null: true,
- description: 'URL to connect to the project via HTTPS.'
+ null: true,
+ description: 'URL to connect to the project via HTTPS.'
field :ssh_url_to_repo, GraphQL::Types::String,
- null: true,
- description: 'URL to connect to the project via SSH.'
+ null: true,
+ description: 'URL to connect to the project via SSH.'
field :web_url, GraphQL::Types::String,
- null: true,
- description: 'Web URL of the project.'
+ null: true,
+ description: 'Web URL of the project.'
field :forks_count, GraphQL::Types::Int,
- null: false,
- calls_gitaly: true, # 4 times
- description: 'Number of times the project has been forked.'
+ null: false,
+ calls_gitaly: true, # 4 times
+ description: 'Number of times the project has been forked.'
field :star_count, GraphQL::Types::Int,
- null: false,
- description: 'Number of times the project has been starred.'
+ null: false,
+ description: 'Number of times the project has been starred.'
field :created_at, Types::TimeType,
- null: true,
- description: 'Timestamp of the project creation.'
+ null: true,
+ description: 'Timestamp of the project creation.'
field :last_activity_at, Types::TimeType,
- null: true,
- description: 'Timestamp of the project last activity.'
+ null: true,
+ description: 'Timestamp of the project last activity.'
field :archived, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates the archived status of the project.'
+ null: true,
+ description: 'Indicates the archived status of the project.'
field :visibility, GraphQL::Types::String,
- null: true,
- description: 'Visibility of the project.'
+ null: true,
+ description: 'Visibility of the project.'
field :lfs_enabled, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if the project has Large File Storage (LFS) enabled.'
+ null: true,
+ description: 'Indicates if the project has Large File Storage (LFS) enabled.'
field :merge_requests_ff_only_enabled, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if no merge commits should be created and all merges should instead be ' \
- 'fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded.'
+ null: true,
+ description: 'Indicates if no merge commits should be created and all merges should instead be ' \
+ 'fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded.'
field :shared_runners_enabled, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if shared runners are enabled for the project.'
+ null: true,
+ description: 'Indicates if shared runners are enabled for the project.'
field :service_desk_enabled, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if the project has Service Desk enabled.'
+ null: true,
+ description: 'Indicates if the project has Service Desk enabled.'
field :service_desk_address, GraphQL::Types::String,
- null: true,
- description: 'E-mail address of the Service Desk.'
+ null: true,
+ description: 'E-mail address of the Service Desk.'
field :avatar_url, GraphQL::Types::String,
- null: true,
- calls_gitaly: true,
- description: 'URL to avatar image file of the project.'
+ null: true,
+ calls_gitaly: true,
+ description: 'URL to avatar image file of the project.'
field :jobs_enabled, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if CI/CD pipeline jobs are enabled for the current user.'
+ null: true,
+ description: 'Indicates if CI/CD pipeline jobs are enabled for the current user.'
field :is_catalog_resource, GraphQL::Types::Boolean,
- alpha: { milestone: '15.11' },
- null: true,
- description: 'Indicates if a project is a catalog resource.'
+ alpha: { milestone: '15.11' },
+ null: true,
+ description: 'Indicates if a project is a catalog resource.'
field :public_jobs, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if there is public access to pipelines and job details of the project, ' \
- 'including output logs and artifacts.',
- method: :public_builds
+ null: true,
+ description: 'Indicates if there is public access to pipelines and job details of the project, ' \
+ 'including output logs and artifacts.',
+ method: :public_builds
field :open_issues_count, GraphQL::Types::Int,
- null: true,
- description: 'Number of open issues for the project.'
+ null: true,
+ description: 'Number of open issues 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 ' \
- 'the project can also be merged with skipped jobs.'
+ null: true,
+ description: 'If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of ' \
+ 'the project can also be merged with skipped jobs.'
field :autoclose_referenced_issues, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if issues referenced by merge requests and commits within the default branch ' \
- 'are closed automatically.'
+ null: true,
+ description: 'Indicates if issues referenced by merge requests and commits within the default branch ' \
+ 'are closed automatically.'
field :import_status, GraphQL::Types::String,
- null: true,
- description: 'Status of import background job of the project.'
+ null: true,
+ description: 'Status of import background job of the project.'
field :jira_import_status, GraphQL::Types::String,
- null: true,
- description: 'Status of Jira import background job of the project.'
+ null: true,
+ description: 'Status of Jira import background job of the project.'
field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if merge requests of the project can only be merged when all the discussions are resolved.'
+ null: true,
+ description: 'Indicates if merge requests of the project can only be merged when all the discussions are resolved.'
field :only_allow_merge_if_pipeline_succeeds, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if merge requests of the project can only be merged with successful jobs.'
+ null: true,
+ description: 'Indicates if merge requests of the project can only be merged with successful jobs.'
field :printing_merge_request_link_enabled, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if a link to create or view a merge request should display after a push to Git ' \
- 'repositories of the project from the command line.'
+ null: true,
+ description: 'Indicates if a link to create or view a merge request should display after a push to Git ' \
+ 'repositories of the project from the command line.'
field :remove_source_branch_after_merge, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if `Delete source branch` option should be enabled by default for all ' \
- 'new merge requests of the project.'
+ null: true,
+ description: 'Indicates if `Delete source branch` option should be enabled by default for all ' \
+ 'new merge requests of the project.'
field :request_access_enabled, GraphQL::Types::Boolean,
- null: true,
- description: 'Indicates if users can request member access to the project.'
+ null: true,
+ description: 'Indicates if users can request member access to the project.'
field :squash_read_only, GraphQL::Types::Boolean,
- null: false,
- description: 'Indicates if `squashReadOnly` is enabled.',
- method: :squash_readonly?
+ null: false,
+ description: 'Indicates if `squashReadOnly` is enabled.',
+ method: :squash_readonly?
field :suggestion_commit_message, GraphQL::Types::String,
- null: true,
- description: 'Commit message used to apply merge request suggestions.'
+ null: true,
+ description: 'Commit message used to apply merge request suggestions.'
# No, the quotes are not a typo. Used to get around circular dependencies.
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27536#note_871009675
field :group, 'Types::GroupType',
- null: true,
- description: 'Group of the project.'
+ null: true,
+ description: 'Group of the project.'
field :namespace, Types::NamespaceType,
- null: true,
- description: 'Namespace of the project.'
+ null: true,
+ description: 'Namespace of the project.'
field :statistics, Types::ProjectStatisticsType,
- null: true,
- description: 'Statistics of the project.'
+ null: true,
+ description: 'Statistics of the project.'
field :statistics_details_paths, Types::ProjectStatisticsRedirectType,
- null: true,
- description: 'Redirects for Statistics of the project.',
- calls_gitaly: true
+ null: true,
+ description: 'Redirects for Statistics of the project.',
+ calls_gitaly: true
field :repository, Types::RepositoryType,
- null: true,
- description: 'Git repository of the project.'
+ null: true,
+ description: 'Git repository of the project.'
field :merge_requests,
- Types::MergeRequestType.connection_type,
- null: true,
- description: 'Merge requests of the project.',
- extras: [:lookahead],
- resolver: Resolvers::ProjectMergeRequestsResolver
+ Types::MergeRequestType.connection_type,
+ null: true,
+ description: 'Merge requests of the project.',
+ extras: [:lookahead],
+ resolver: Resolvers::ProjectMergeRequestsResolver
field :merge_request,
- Types::MergeRequestType,
- null: true,
- description: 'A single merge request of the project.',
- resolver: Resolvers::MergeRequestsResolver.single
+ Types::MergeRequestType,
+ null: true,
+ description: 'A single merge request of the project.',
+ resolver: Resolvers::MergeRequestsResolver.single
field :issues,
- Types::IssueType.connection_type,
- null: true,
- description: 'Issues of the project.',
- resolver: Resolvers::ProjectIssuesResolver
+ Types::IssueType.connection_type,
+ null: true,
+ description: 'Issues of the project.',
+ resolver: Resolvers::ProjectIssuesResolver
field :work_items,
- Types::WorkItemType.connection_type,
- null: true,
- alpha: { milestone: '15.1' },
- description: 'Work items of the project.',
- extras: [:lookahead],
- resolver: Resolvers::WorkItemsResolver
+ Types::WorkItemType.connection_type,
+ null: true,
+ alpha: { milestone: '15.1' },
+ description: 'Work items of the project.',
+ extras: [:lookahead],
+ resolver: Resolvers::WorkItemsResolver
field :issue_status_counts,
- Types::IssueStatusCountsType,
- null: true,
- description: 'Counts of issues by status for the project.',
- resolver: Resolvers::IssueStatusCountsResolver
+ Types::IssueStatusCountsType,
+ null: true,
+ description: 'Counts of issues by status for the project.',
+ resolver: Resolvers::IssueStatusCountsResolver
field :milestones, Types::MilestoneType.connection_type,
- null: true,
- description: 'Milestones of the project.',
- resolver: Resolvers::ProjectMilestonesResolver
+ null: true,
+ description: 'Milestones of the project.',
+ resolver: Resolvers::ProjectMilestonesResolver
field :project_members,
- description: 'Members of the project.',
- resolver: Resolvers::ProjectMembersResolver
+ description: 'Members of the project.',
+ resolver: Resolvers::ProjectMembersResolver
field :environments,
- Types::EnvironmentType.connection_type,
- null: true,
- description: 'Environments of the project. ' \
- 'This field can only be resolved for one project in any single request.',
- resolver: Resolvers::EnvironmentsResolver do
- extension ::Gitlab::Graphql::Limit::FieldCallCount, limit: 1
- end
+ Types::EnvironmentType.connection_type,
+ null: true,
+ description: 'Environments of the project. ' \
+ 'This field can only be resolved for one project in any single request.',
+ resolver: Resolvers::EnvironmentsResolver do
+ extension ::Gitlab::Graphql::Limit::FieldCallCount, limit: 1
+ end
field :environment,
- Types::EnvironmentType,
- null: true,
- description: 'A single environment of the project.',
- resolver: Resolvers::EnvironmentsResolver.single
+ Types::EnvironmentType,
+ null: true,
+ description: 'A single environment of the project.',
+ resolver: Resolvers::EnvironmentsResolver.single
field :nested_environments,
- Types::NestedEnvironmentType.connection_type,
- null: true,
- calls_gitaly: true,
- description: 'Environments for this project with nested folders, ' \
- 'can only be resolved for one project in any single request',
- resolver: Resolvers::Environments::NestedEnvironmentsResolver do
- extension ::Gitlab::Graphql::Limit::FieldCallCount, limit: 1
- end
+ Types::NestedEnvironmentType.connection_type,
+ null: true,
+ calls_gitaly: true,
+ description: 'Environments for this project with nested folders, ' \
+ 'can only be resolved for one project in any single request',
+ resolver: Resolvers::Environments::NestedEnvironmentsResolver do
+ extension ::Gitlab::Graphql::Limit::FieldCallCount, limit: 1
+ end
field :deployment,
- Types::DeploymentType,
- null: true,
- description: 'Details of the deployment of the project.',
- resolver: Resolvers::DeploymentResolver.single
+ Types::DeploymentType,
+ null: true,
+ description: 'Details of the deployment of the project.',
+ resolver: Resolvers::DeploymentResolver.single
field :issue,
- Types::IssueType,
- null: true,
- description: 'A single issue of the project.',
- resolver: Resolvers::ProjectIssuesResolver.single
+ Types::IssueType,
+ null: true,
+ description: 'A single issue of the project.',
+ resolver: Resolvers::ProjectIssuesResolver.single
field :packages,
- description: 'Packages of the project.',
- resolver: Resolvers::ProjectPackagesResolver
+ description: 'Packages of the project.',
+ resolver: Resolvers::ProjectPackagesResolver
field :packages_cleanup_policy,
- Types::Packages::Cleanup::PolicyType,
- null: true,
- description: 'Packages cleanup policy for the project.'
+ Types::Packages::Cleanup::PolicyType,
+ null: true,
+ description: 'Packages cleanup policy for the project.'
field :jobs,
- type: Types::Ci::JobType.connection_type,
- null: true,
- authorize: :read_build,
- description: 'Jobs of a project. This field can only be resolved for one project in any single request.',
- resolver: Resolvers::ProjectJobsResolver
+ type: Types::Ci::JobType.connection_type,
+ null: true,
+ authorize: :read_build,
+ description: 'Jobs of a project. This field can only be resolved for one project in any single request.',
+ resolver: Resolvers::ProjectJobsResolver
field :job,
- type: Types::Ci::JobType,
- null: true,
- authorize: :read_build,
- description: 'One job belonging to the project, selected by ID.' do
- argument :id, Types::GlobalIDType[::CommitStatus],
- required: true,
- description: 'ID of the job.'
- end
+ type: Types::Ci::JobType,
+ null: true,
+ authorize: :read_build,
+ description: 'One job belonging to the project, selected by ID.' do
+ argument :id, Types::GlobalIDType[::CommitStatus],
+ required: true,
+ description: 'ID of the job.'
+ end
field :pipelines,
- null: true,
- description: 'Build pipelines of the project.',
- extras: [:lookahead],
- resolver: Resolvers::ProjectPipelinesResolver
+ null: true,
+ description: 'Build pipelines of the project.',
+ extras: [:lookahead],
+ resolver: Resolvers::ProjectPipelinesResolver
field :pipeline_schedules,
- type: Types::Ci::PipelineScheduleType.connection_type,
- null: true,
- description: 'Pipeline schedules of the project. This field can only be resolved for one project per request.',
- resolver: Resolvers::ProjectPipelineSchedulesResolver
+ type: Types::Ci::PipelineScheduleType.connection_type,
+ null: true,
+ description: 'Pipeline schedules of the project. This field can only be resolved for one project per request.',
+ resolver: Resolvers::ProjectPipelineSchedulesResolver
+
+ field :pipeline_triggers,
+ Types::Ci::PipelineTriggerType.connection_type,
+ null: true,
+ description: 'List of pipeline trigger tokens.',
+ resolver: Resolvers::Ci::PipelineTriggersResolver,
+ alpha: { milestone: '16.3' }
field :pipeline, Types::Ci::PipelineType,
- null: true,
- description: 'Build pipeline of the project.',
- extras: [:lookahead],
- resolver: Resolvers::ProjectPipelineResolver
+ null: true,
+ description: 'Build pipeline of the project.',
+ extras: [:lookahead],
+ resolver: Resolvers::ProjectPipelineResolver
field :pipeline_counts, Types::Ci::PipelineCountsType,
- null: true,
- description: 'Build pipeline counts of the project.',
- resolver: Resolvers::Ci::ProjectPipelineCountsResolver
+ null: true,
+ description: 'Build pipeline counts of the project.',
+ resolver: Resolvers::Ci::ProjectPipelineCountsResolver
field :ci_variables, Types::Ci::ProjectVariableType.connection_type,
- null: true,
- description: "List of the project's CI/CD variables.",
- authorize: :admin_build,
- resolver: Resolvers::Ci::VariablesResolver
+ null: true,
+ description: "List of the project's CI/CD variables.",
+ authorize: :admin_build,
+ resolver: Resolvers::Ci::VariablesResolver
field :inherited_ci_variables, Types::Ci::InheritedCiVariableType.connection_type,
- null: true,
- description: "List of CI/CD variables the project inherited from its parent group and ancestors.",
- authorize: :admin_build,
- resolver: Resolvers::Ci::InheritedVariablesResolver
+ null: true,
+ description: "List of CI/CD variables the project inherited from its parent group and ancestors.",
+ authorize: :admin_build,
+ resolver: Resolvers::Ci::InheritedVariablesResolver
field :ci_cd_settings, Types::Ci::CiCdSettingType,
- null: true,
- description: 'CI/CD settings for the project.'
+ null: true,
+ description: 'CI/CD settings for the project.'
field :sentry_detailed_error, Types::ErrorTracking::SentryDetailedErrorType,
- null: true,
- description: 'Detailed version of a Sentry error on the project.',
- resolver: Resolvers::ErrorTracking::SentryDetailedErrorResolver
+ null: true,
+ description: 'Detailed version of a Sentry error on the project.',
+ resolver: Resolvers::ErrorTracking::SentryDetailedErrorResolver
field :grafana_integration, Types::GrafanaIntegrationType,
- null: true,
- description: 'Grafana integration details for the project.',
- resolver: Resolvers::Projects::GrafanaIntegrationResolver
+ null: true,
+ description: 'Grafana integration details for the project.',
+ resolver: Resolvers::Projects::GrafanaIntegrationResolver
field :snippets, Types::SnippetType.connection_type,
- null: true,
- description: 'Snippets of the project.',
- resolver: Resolvers::Projects::SnippetsResolver
+ null: true,
+ description: 'Snippets of the project.',
+ resolver: Resolvers::Projects::SnippetsResolver
field :sentry_errors, Types::ErrorTracking::SentryErrorCollectionType,
- null: true,
- description: 'Paginated collection of Sentry errors on the project.',
- resolver: Resolvers::ErrorTracking::SentryErrorCollectionResolver
+ null: true,
+ description: 'Paginated collection of Sentry errors on the project.',
+ resolver: Resolvers::ErrorTracking::SentryErrorCollectionResolver
field :boards, Types::BoardType.connection_type,
- null: true,
- description: 'Boards of the project.',
- max_page_size: 2000,
- resolver: Resolvers::BoardsResolver
+ null: true,
+ description: 'Boards of the project.',
+ max_page_size: 2000,
+ resolver: Resolvers::BoardsResolver
field :recent_issue_boards, Types::BoardType.connection_type,
- null: true,
- description: 'List of recently visited boards of the project. Maximum size is 4.',
- resolver: Resolvers::RecentBoardsResolver
+ null: true,
+ description: 'List of recently visited boards of the project. Maximum size is 4.',
+ resolver: Resolvers::RecentBoardsResolver
field :board, Types::BoardType,
- null: true,
- description: 'A single board of the project.',
- resolver: Resolvers::BoardResolver
+ null: true,
+ description: 'A single board of the project.',
+ resolver: Resolvers::BoardResolver
field :jira_imports, Types::JiraImportType.connection_type,
- null: true,
- description: 'Jira imports into the project.'
+ null: true,
+ description: 'Jira imports into the project.'
field :services, Types::Projects::ServiceType.connection_type,
- null: true,
- deprecated: {
- reason: 'This will be renamed to `Project.integrations`',
- milestone: '15.9'
- },
- description: 'Project services.',
- resolver: Resolvers::Projects::ServicesResolver
+ null: true,
+ deprecated: {
+ reason: 'This will be renamed to `Project.integrations`',
+ milestone: '15.9'
+ },
+ description: 'Project services.',
+ resolver: Resolvers::Projects::ServicesResolver
field :alert_management_alerts, Types::AlertManagement::AlertType.connection_type,
- null: true,
- description: 'Alert Management alerts of the project.',
- extras: [:lookahead],
- resolver: Resolvers::AlertManagement::AlertResolver
+ null: true,
+ description: 'Alert Management alerts of the project.',
+ extras: [:lookahead],
+ resolver: Resolvers::AlertManagement::AlertResolver
field :alert_management_alert, Types::AlertManagement::AlertType,
- null: true,
- description: 'A single Alert Management alert of the project.',
- resolver: Resolvers::AlertManagement::AlertResolver.single
+ null: true,
+ description: 'A single Alert Management alert of the project.',
+ resolver: Resolvers::AlertManagement::AlertResolver.single
field :alert_management_alert_status_counts, Types::AlertManagement::AlertStatusCountsType,
- null: true,
- description: 'Counts of alerts by status for the project.',
- resolver: Resolvers::AlertManagement::AlertStatusCountsResolver
+ null: true,
+ description: 'Counts of alerts by status for the project.',
+ resolver: Resolvers::AlertManagement::AlertStatusCountsResolver
field :alert_management_integrations, Types::AlertManagement::IntegrationType.connection_type,
- null: true,
- description: 'Integrations which can receive alerts for the project.',
- resolver: Resolvers::AlertManagement::IntegrationsResolver
+ null: true,
+ description: 'Integrations which can receive alerts for the project.',
+ resolver: Resolvers::AlertManagement::IntegrationsResolver
field :alert_management_http_integrations, Types::AlertManagement::HttpIntegrationType.connection_type,
- null: true,
- description: 'HTTP Integrations which can receive alerts for the project.',
- resolver: Resolvers::AlertManagement::HttpIntegrationsResolver
+ null: true,
+ description: 'HTTP Integrations which can receive alerts for the project.',
+ resolver: Resolvers::AlertManagement::HttpIntegrationsResolver
field :incident_management_timeline_events, Types::IncidentManagement::TimelineEventType.connection_type,
- null: true,
- description: 'Incident Management Timeline events associated with the incident.',
- extras: [:lookahead],
- resolver: Resolvers::IncidentManagement::TimelineEventsResolver
+ null: true,
+ description: 'Incident Management Timeline events associated with the incident.',
+ extras: [:lookahead],
+ resolver: Resolvers::IncidentManagement::TimelineEventsResolver
field :incident_management_timeline_event, Types::IncidentManagement::TimelineEventType,
- null: true,
- description: 'Incident Management Timeline event associated with the incident.',
- resolver: Resolvers::IncidentManagement::TimelineEventsResolver.single
+ null: true,
+ description: 'Incident Management Timeline event associated with the incident.',
+ resolver: Resolvers::IncidentManagement::TimelineEventsResolver.single
field :releases, Types::ReleaseType.connection_type,
- null: true,
- description: 'Releases of the project.',
- resolver: Resolvers::ReleasesResolver
+ null: true,
+ description: 'Releases of the project.',
+ resolver: Resolvers::ReleasesResolver
field :release, Types::ReleaseType,
- null: true,
- description: 'A single release of the project.',
- resolver: Resolvers::ReleasesResolver.single,
- authorize: :read_release
+ null: true,
+ description: 'A single release of the project.',
+ resolver: Resolvers::ReleasesResolver.single,
+ authorize: :read_release
field :container_expiration_policy, Types::ContainerExpirationPolicyType,
- null: true,
- description: 'Container expiration policy of the project.'
+ null: true,
+ description: 'Container expiration policy of the project.'
field :container_repositories, Types::ContainerRepositoryType.connection_type,
- null: true,
- description: 'Container repositories of the project.',
- resolver: Resolvers::ContainerRepositoriesResolver
+ null: true,
+ description: 'Container repositories of the project.',
+ resolver: Resolvers::ContainerRepositoriesResolver
field :container_repositories_count, GraphQL::Types::Int,
- null: false,
- description: 'Number of container repositories in the project.'
+ null: false,
+ description: 'Number of container repositories in the project.'
field :label, Types::LabelType,
- null: true,
- description: 'Label available on this project.' do
- argument :title, GraphQL::Types::String,
- required: true,
- description: 'Title of the label.'
- end
+ null: true,
+ description: 'Label available on this project.' do
+ argument :title, GraphQL::Types::String,
+ required: true,
+ description: 'Title of the label.'
+ end
field :terraform_state, Types::Terraform::StateType,
- null: true,
- description: 'Find a single Terraform state by name.',
- resolver: Resolvers::Terraform::StatesResolver.single
+ null: true,
+ description: 'Find a single Terraform state by name.',
+ resolver: Resolvers::Terraform::StatesResolver.single
field :terraform_states, Types::Terraform::StateType.connection_type,
- null: true,
- description: 'Terraform states associated with the project.',
- resolver: Resolvers::Terraform::StatesResolver
+ null: true,
+ description: 'Terraform states associated with the project.',
+ resolver: Resolvers::Terraform::StatesResolver
field :pipeline_analytics, Types::Ci::AnalyticsType,
- null: true,
- description: 'Pipeline analytics.',
- resolver: Resolvers::ProjectPipelineStatisticsResolver
+ null: true,
+ description: 'Pipeline analytics.',
+ resolver: Resolvers::ProjectPipelineStatisticsResolver
field :ci_template, Types::Ci::TemplateType,
- null: true,
- description: 'Find a single CI/CD template by name.',
- resolver: Resolvers::Ci::TemplateResolver
+ null: true,
+ description: 'Find a single CI/CD template by name.',
+ resolver: Resolvers::Ci::TemplateResolver
field :ci_job_token_scope, Types::Ci::JobTokenScopeType,
- null: true,
- description: 'The CI Job Tokens scope of access.',
- resolver: Resolvers::Ci::JobTokenScopeResolver
+ null: true,
+ description: 'The CI Job Tokens scope of access.',
+ resolver: Resolvers::Ci::JobTokenScopeResolver
field :timelogs, Types::TimelogType.connection_type,
- null: true,
- description: 'Time logged on issues and merge requests in the project.',
- extras: [:lookahead],
- complexity: 5,
- resolver: ::Resolvers::TimelogResolver
+ null: true,
+ description: 'Time logged on issues and merge requests in the project.',
+ extras: [:lookahead],
+ complexity: 5,
+ resolver: ::Resolvers::TimelogResolver
field :agent_configurations, ::Types::Kas::AgentConfigurationType.connection_type,
- null: true,
- description: 'Agent configurations defined by the project',
- resolver: ::Resolvers::Kas::AgentConfigurationsResolver
+ null: true,
+ description: 'Agent configurations defined by the project',
+ resolver: ::Resolvers::Kas::AgentConfigurationsResolver
field :cluster_agent, ::Types::Clusters::AgentType,
- null: true,
- description: 'Find a single cluster agent by name.',
- resolver: ::Resolvers::Clusters::AgentsResolver.single
+ null: true,
+ description: 'Find a single cluster agent by name.',
+ resolver: ::Resolvers::Clusters::AgentsResolver.single
field :cluster_agents, ::Types::Clusters::AgentType.connection_type,
- extras: [:lookahead],
- null: true,
- description: 'Cluster agents associated with the project.',
- resolver: ::Resolvers::Clusters::AgentsResolver
+ extras: [:lookahead],
+ null: true,
+ description: 'Cluster agents associated with the project.',
+ resolver: ::Resolvers::Clusters::AgentsResolver
field :ci_access_authorized_agents, ::Types::Clusters::Agents::Authorizations::CiAccessType.connection_type,
- null: true,
- description: 'Authorized cluster agents for the project through ci_access keyword.',
- resolver: ::Resolvers::Clusters::Agents::Authorizations::CiAccessResolver,
- authorize: :read_cluster_agent
+ null: true,
+ description: 'Authorized cluster agents for the project through ci_access keyword.',
+ resolver: ::Resolvers::Clusters::Agents::Authorizations::CiAccessResolver,
+ authorize: :read_cluster_agent
field :user_access_authorized_agents, ::Types::Clusters::Agents::Authorizations::UserAccessType.connection_type,
- null: true,
- description: 'Authorized cluster agents for the project through user_access keyword.',
- resolver: ::Resolvers::Clusters::Agents::Authorizations::UserAccessResolver,
- authorize: :read_cluster_agent
+ null: true,
+ description: 'Authorized cluster agents for the project through user_access keyword.',
+ resolver: ::Resolvers::Clusters::Agents::Authorizations::UserAccessResolver,
+ authorize: :read_cluster_agent
field :merge_commit_template, GraphQL::Types::String,
- null: true,
- description: 'Template used to create merge commit message in merge requests.'
+ null: true,
+ description: 'Template used to create merge commit message in merge requests.'
field :squash_commit_template, GraphQL::Types::String,
- null: true,
- description: 'Template used to create squash commit message in merge requests.'
+ null: true,
+ description: 'Template used to create squash commit message in merge requests.'
field :labels, Types::LabelType.connection_type,
- null: true,
- description: 'Labels available on this project.',
- resolver: Resolvers::LabelsResolver
+ null: true,
+ description: 'Labels available on this project.',
+ resolver: Resolvers::LabelsResolver
field :work_item_types, Types::WorkItems::TypeType.connection_type,
- resolver: Resolvers::WorkItems::TypesResolver,
- description: 'Work item types available to the project.'
+ resolver: Resolvers::WorkItems::TypesResolver,
+ description: 'Work item types available to the project.'
field :timelog_categories, Types::TimeTracking::TimelogCategoryType.connection_type,
- null: true,
- description: "Timelog categories for the project.",
- alpha: { milestone: '15.3' }
+ null: true,
+ description: "Timelog categories for the project.",
+ alpha: { milestone: '15.3' }
field :fork_targets, Types::NamespaceType.connection_type,
- resolver: Resolvers::Projects::ForkTargetsResolver,
- description: 'Namespaces in which the current user can fork the project into.'
+ resolver: Resolvers::Projects::ForkTargetsResolver,
+ description: 'Namespaces in which the current user can fork the project into.'
field :fork_details, Types::Projects::ForkDetailsType,
- calls_gitaly: true,
- alpha: { milestone: '15.7' },
- authorize: :read_code,
- resolver: Resolvers::Projects::ForkDetailsResolver,
- description: 'Details of the fork project compared to its upstream project.'
+ calls_gitaly: true,
+ alpha: { milestone: '15.7' },
+ authorize: :read_code,
+ resolver: Resolvers::Projects::ForkDetailsResolver,
+ description: 'Details of the fork project compared to its upstream project.'
field :branch_rules,
- Types::Projects::BranchRuleType.connection_type,
- null: true,
- description: "Branch rules configured for the project.",
- resolver: Resolvers::Projects::BranchRulesResolver
+ Types::Projects::BranchRuleType.connection_type,
+ null: true,
+ description: "Branch rules configured for the project.",
+ resolver: Resolvers::Projects::BranchRulesResolver
field :languages, [Types::Projects::RepositoryLanguageType],
- null: true,
- description: "Programming languages used in the project.",
- calls_gitaly: true
+ null: true,
+ description: "Programming languages used in the project.",
+ calls_gitaly: true
field :runners, Types::Ci::RunnerType.connection_type,
- null: true,
- resolver: ::Resolvers::Ci::ProjectRunnersResolver,
- description: "Find runners visible to the current user."
+ null: true,
+ resolver: ::Resolvers::Ci::ProjectRunnersResolver,
+ description: "Find runners visible to the current user."
field :data_transfer, Types::DataTransfer::ProjectDataTransferType,
- null: true, # disallow null once data_transfer_monitoring feature flag is rolled-out! https://gitlab.com/gitlab-org/gitlab/-/issues/391682
- resolver: Resolvers::DataTransfer::ProjectDataTransferResolver,
- description: 'Data transfer data point for a specific period. This is mocked data under a development feature flag.'
+ null: true, # disallow null once data_transfer_monitoring feature flag is rolled-out! https://gitlab.com/gitlab-org/gitlab/-/issues/391682
+ resolver: Resolvers::DataTransfer::ProjectDataTransferResolver,
+ description: 'Data transfer data point for a specific period. This is mocked data under a development feature flag.'
field :visible_forks, Types::ProjectType.connection_type,
- null: true,
- alpha: { milestone: '15.10' },
- description: "Visible forks of the project." do
- argument :minimum_access_level,
- type: ::Types::AccessLevelEnum,
- required: false,
- description: 'Minimum access level.'
- end
+ null: true,
+ alpha: { milestone: '15.10' },
+ description: "Visible forks of the project." do
+ argument :minimum_access_level,
+ type: ::Types::AccessLevelEnum,
+ required: false,
+ description: 'Minimum access level.'
+ end
field :flow_metrics,
- ::Types::Analytics::CycleAnalytics::FlowMetrics[:project],
- null: true,
- description: 'Flow metrics for value stream analytics.',
- method: :project_namespace,
- authorize: :read_cycle_analytics,
- alpha: { milestone: '15.10' }
+ ::Types::Analytics::CycleAnalytics::FlowMetrics[:project],
+ null: true,
+ description: 'Flow metrics for value stream analytics.',
+ method: :project_namespace,
+ authorize: :read_cycle_analytics,
+ alpha: { milestone: '15.10' }
field :commit_references, ::Types::CommitReferencesType,
null: true,
@@ -623,6 +630,11 @@ module Types
alpha: { milestone: '16.0' },
description: "Get tag names containing a given commit."
+ field :autocomplete_users,
+ null: true,
+ resolver: Resolvers::AutocompleteUsersResolver,
+ description: 'Search users for autocompletion'
+
def timelog_categories
object.project_namespace.timelog_categories if Feature.enabled?(:timelog_categories)
end
@@ -644,7 +656,7 @@ module Types
container_registry: 'Container Registry is'
}.each do |feature, name_string|
field "#{feature}_enabled", GraphQL::Types::Boolean, null: true,
- description: "Indicates if #{name_string} enabled for the current user"
+ description: "Indicates if #{name_string} enabled for the current user"
define_method "#{feature}_enabled" do
object.feature_available?(feature, context[:current_user])
@@ -707,7 +719,7 @@ module Types
if project.repository.empty?
raise Gitlab::Graphql::Errors::MutationError,
- Gitlab::Utils::ErrorMessage.to_user_facing(_(format('You must %s before using Security features.', add_file_docs_link.html_safe)).html_safe)
+ _(format('You must %s before using Security features.', add_file_docs_link.html_safe)).html_safe
end
::Security::CiConfiguration::SastParserService.new(object).configuration
@@ -754,11 +766,11 @@ module Types
def add_file_docs_link
ActionController::Base.helpers.link_to _('add at least one file to the repository'),
- Rails.application.routes.url_helpers.help_page_url(
- 'user/project/repository/index.md',
- anchor: 'add-files-to-a-repository'),
- target: '_blank',
- rel: 'noopener noreferrer'
+ Rails.application.routes.url_helpers.help_page_url(
+ 'user/project/repository/index.md',
+ anchor: 'add-files-to-a-repository'),
+ target: '_blank',
+ rel: 'noopener noreferrer'
end
end
end
diff --git a/app/graphql/types/projects/services/base_service_type.rb b/app/graphql/types/projects/services/base_service_type.rb
index 9a48aafa5a8..c77dc5c8539 100644
--- a/app/graphql/types/projects/services/base_service_type.rb
+++ b/app/graphql/types/projects/services/base_service_type.rb
@@ -7,7 +7,7 @@ module Types
class BaseServiceType < BaseObject
graphql_name 'BaseService'
- implements(Types::Projects::ServiceType)
+ implements Types::Projects::ServiceType
authorize :admin_project
end
diff --git a/app/graphql/types/projects/services/jira_service_type.rb b/app/graphql/types/projects/services/jira_service_type.rb
index ac274d7f890..a774d381e2b 100644
--- a/app/graphql/types/projects/services/jira_service_type.rb
+++ b/app/graphql/types/projects/services/jira_service_type.rb
@@ -7,7 +7,7 @@ module Types
class JiraServiceType < BaseObject
graphql_name 'JiraService'
- implements(Types::Projects::ServiceType)
+ implements Types::Projects::ServiceType
authorize :admin_project
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index b26e447f622..38b8973034d 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -171,6 +171,18 @@ module Types
description: 'Definitions for all audit events available on the instance.',
resolver: Resolvers::AuditEvents::AuditEventDefinitionsResolver
+ field :abuse_report, ::Types::AbuseReportType,
+ null: true,
+ alpha: { milestone: '16.3' },
+ description: 'Find an abuse report.',
+ resolver: Resolvers::AbuseReportResolver
+
+ field :abuse_report_labels, ::Types::LabelType.connection_type,
+ null: true,
+ alpha: { milestone: '16.3' },
+ description: 'Abuse report labels.',
+ resolver: Resolvers::AbuseReportLabelsResolver
+
def design_management
DesignManagementObject.new(nil)
end
diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb
index 8516256b433..0bf723bcb1b 100644
--- a/app/graphql/types/release_type.rb
+++ b/app/graphql/types/release_type.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'Release'
description 'Represents a release'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
authorize :read_release
diff --git a/app/graphql/types/saved_reply_type.rb b/app/graphql/types/saved_reply_type.rb
index 8c9f3d19810..74b3796ef8a 100644
--- a/app/graphql/types/saved_reply_type.rb
+++ b/app/graphql/types/saved_reply_type.rb
@@ -4,7 +4,7 @@ module Types
class SavedReplyType < BaseObject
graphql_name 'SavedReply'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
authorize :read_saved_replies
diff --git a/app/graphql/types/snippet_type.rb b/app/graphql/types/snippet_type.rb
index 5ee0500b1e0..6e6d0edbe15 100644
--- a/app/graphql/types/snippet_type.rb
+++ b/app/graphql/types/snippet_type.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'Snippet'
description 'Represents a snippet entry'
- implements(Types::Notes::NoteableInterface)
+ implements Types::Notes::NoteableInterface
present_using SnippetPresenter
diff --git a/app/graphql/types/snippets/blob_type.rb b/app/graphql/types/snippets/blob_type.rb
index bb4a0a64de8..2d1993225d1 100644
--- a/app/graphql/types/snippets/blob_type.rb
+++ b/app/graphql/types/snippets/blob_type.rb
@@ -8,7 +8,7 @@ module Types
description 'Represents the snippet blob'
present_using SnippetBlobPresenter
- connection_type_class(Types::Snippets::BlobConnectionType)
+ connection_type_class Types::Snippets::BlobConnectionType
field :rich_data, GraphQL::Types::String,
description: 'Blob highlighted data.',
diff --git a/app/graphql/types/terraform/state_type.rb b/app/graphql/types/terraform/state_type.rb
index be17fc41c2c..0870194a934 100644
--- a/app/graphql/types/terraform/state_type.rb
+++ b/app/graphql/types/terraform/state_type.rb
@@ -7,7 +7,7 @@ module Types
authorize :read_terraform_state
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class Types::CountableConnectionType
field :id, GraphQL::Types::ID,
null: false,
diff --git a/app/graphql/types/timelog_type.rb b/app/graphql/types/timelog_type.rb
index 88baca028ef..2adf2847221 100644
--- a/app/graphql/types/timelog_type.rb
+++ b/app/graphql/types/timelog_type.rb
@@ -4,7 +4,7 @@ module Types
class TimelogType < BaseObject
graphql_name 'Timelog'
- connection_type_class(Types::TimeTracking::TimelogConnectionType)
+ connection_type_class Types::TimeTracking::TimelogConnectionType
authorize :read_issuable
diff --git a/app/graphql/types/todo_action_enum.rb b/app/graphql/types/todo_action_enum.rb
index fda96796c0f..45b83ea1d64 100644
--- a/app/graphql/types/todo_action_enum.rb
+++ b/app/graphql/types/todo_action_enum.rb
@@ -12,5 +12,6 @@ module Types
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 or project access requested from the user.'
+ value 'review_submitted', value: 11, description: 'Merge request authored by the user received a review.'
end
end
diff --git a/app/graphql/types/users/autocompleted_user_type.rb b/app/graphql/types/users/autocompleted_user_type.rb
new file mode 100644
index 00000000000..8a70f398954
--- /dev/null
+++ b/app/graphql/types/users/autocompleted_user_type.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Types
+ module Users
+ class AutocompletedUserType < ::Types::UserType
+ graphql_name 'AutocompletedUser'
+
+ authorize :read_user
+
+ field :merge_request_interaction, Types::UserMergeRequestInteractionType,
+ null: true,
+ description: 'Merge request state related to the user.' do
+ argument :id, ::Types::GlobalIDType[::MergeRequest], required: true,
+ description: 'Global ID of the merge request.'
+ end
+
+ def merge_request_interaction(id: nil)
+ Gitlab::Graphql::Lazy.with_value(GitlabSchema.object_from_id(id, expected_class: ::MergeRequest)) do |mr|
+ ::Users::MergeRequestInteraction.new(user: object.user, merge_request: mr) if mr
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/work_item_type.rb b/app/graphql/types/work_item_type.rb
index 1e58781dbb9..05798ba3d2f 100644
--- a/app/graphql/types/work_item_type.rb
+++ b/app/graphql/types/work_item_type.rb
@@ -4,7 +4,7 @@ module Types
class WorkItemType < BaseObject
graphql_name 'WorkItem'
- implements(Types::TodoableInterface)
+ implements Types::TodoableInterface
authorize :read_work_item
diff --git a/app/graphql/types/work_items/linked_item_type.rb b/app/graphql/types/work_items/linked_item_type.rb
new file mode 100644
index 00000000000..a4dbeed7480
--- /dev/null
+++ b/app/graphql/types/work_items/linked_item_type.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ # rubocop:disable Graphql/AuthorizeTypes
+ class LinkedItemType < BaseObject
+ graphql_name 'LinkedWorkItemType'
+
+ field :link_created_at, Types::TimeType,
+ description: 'Timestamp the link was created.', null: false
+ field :link_id, ::Types::GlobalIDType[::WorkItems::RelatedWorkItemLink],
+ description: 'Global ID of the link.', null: false
+ field :link_type, GraphQL::Types::String,
+ description: 'Type of link.', null: false
+ field :link_updated_at, Types::TimeType,
+ description: 'Timestamp the link was updated.', null: false
+ field :work_item, Types::WorkItemType,
+ description: 'Linked work item.', null: false
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+end
diff --git a/app/graphql/types/work_items/related_link_type_enum.rb b/app/graphql/types/work_items/related_link_type_enum.rb
new file mode 100644
index 00000000000..d4bbc7cc404
--- /dev/null
+++ b/app/graphql/types/work_items/related_link_type_enum.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ class RelatedLinkTypeEnum < BaseEnum
+ graphql_name 'WorkItemRelatedLinkType'
+ description 'Values for work item link types'
+
+ value 'RELATED', 'Related type.', value: 'relates_to'
+ end
+ end
+end
+
+Types::WorkItems::RelatedLinkTypeEnum.prepend_mod_with('Types::WorkItems::RelatedLinkTypeEnum')
diff --git a/app/graphql/types/work_items/widget_interface.rb b/app/graphql/types/work_items/widget_interface.rb
index 53ea901ea10..9f4dbdd1038 100644
--- a/app/graphql/types/work_items/widget_interface.rb
+++ b/app/graphql/types/work_items/widget_interface.rb
@@ -21,7 +21,8 @@ module Types
::Types::WorkItems::Widgets::NotesType,
::Types::WorkItems::Widgets::NotificationsType,
::Types::WorkItems::Widgets::CurrentUserTodosType,
- ::Types::WorkItems::Widgets::AwardEmojiType
+ ::Types::WorkItems::Widgets::AwardEmojiType,
+ ::Types::WorkItems::Widgets::LinkedItemsType
].freeze
def self.ce_orphan_types
@@ -53,6 +54,8 @@ module Types
::Types::WorkItems::Widgets::CurrentUserTodosType
when ::WorkItems::Widgets::AwardEmoji
::Types::WorkItems::Widgets::AwardEmojiType
+ when ::WorkItems::Widgets::LinkedItems
+ ::Types::WorkItems::Widgets::LinkedItemsType
else
raise "Unknown GraphQL type for widget #{object}"
end
diff --git a/app/graphql/types/work_items/widgets/award_emoji_type.rb b/app/graphql/types/work_items/widgets/award_emoji_type.rb
index 421bb8f0e98..eee04696df2 100644
--- a/app/graphql/types/work_items/widgets/award_emoji_type.rb
+++ b/app/graphql/types/work_items/widgets/award_emoji_type.rb
@@ -8,14 +8,14 @@ module Types
# rubocop:disable Graphql/AuthorizeTypes
class AwardEmojiType < BaseObject
graphql_name 'WorkItemWidgetAwardEmoji'
- description 'Represents the award emoji widget'
+ description 'Represents the emoji reactions widget'
implements Types::WorkItems::WidgetInterface
field :award_emoji,
::Types::AwardEmojis::AwardEmojiType.connection_type,
null: true,
- description: 'Award emoji on the work item.'
+ description: 'Emoji reactions on the work item.'
field :downvotes,
GraphQL::Types::Int,
null: false,
diff --git a/app/graphql/types/work_items/widgets/linked_items_type.rb b/app/graphql/types/work_items/widgets/linked_items_type.rb
new file mode 100644
index 00000000000..fa51742b9c1
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/linked_items_type.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ # rubocop:disable Graphql/AuthorizeTypes
+ class LinkedItemsType < BaseObject
+ graphql_name 'WorkItemWidgetLinkedItems'
+ description 'Represents the linked items widget'
+
+ implements Types::WorkItems::WidgetInterface
+
+ field :linked_items, Types::WorkItems::LinkedItemType.connection_type,
+ null: true, complexity: 5,
+ alpha: { milestone: '16.3' },
+ description: 'Linked items for the work item. Returns `null`' \
+ 'if `linked_work_items` feature flag is disabled.',
+ resolver: Resolvers::WorkItems::LinkedItemsResolver
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+ end
+end
+
+Types::WorkItems::Widgets::LinkedItemsType.prepend_mod