Commit 899cc9b0 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch...

Merge branch '292466-add-hidebackloglist-and-hideclosedlist-to-createboard-mutation-input' into 'master'

Add missing fields to `createBoard` mutation input

See merge request gitlab-org/gitlab!49947
parents bf02b947 bca895fc
# frozen_string_literal: true
module Mutations
module Boards
module CommonMutationArguments
extend ActiveSupport::Concern
included do
argument :name,
GraphQL::STRING_TYPE,
required: false,
description: 'The board name.'
argument :hide_backlog_list,
GraphQL::BOOLEAN_TYPE,
required: false,
description: copy_field_description(Types::BoardType, :hide_backlog_list)
argument :hide_closed_list,
GraphQL::BOOLEAN_TYPE,
required: false,
description: copy_field_description(Types::BoardType, :hide_closed_list)
end
end
end
end
......@@ -7,36 +7,18 @@ module Mutations
graphql_name 'CreateBoard'
include Mutations::Boards::CommonMutationArguments
field :board,
Types::BoardType,
null: true,
description: 'The board after mutation.'
argument :name,
GraphQL::STRING_TYPE,
required: false,
description: 'The board name.'
argument :assignee_id,
GraphQL::STRING_TYPE,
required: false,
description: 'The ID of the user to be assigned to the board.'
argument :milestone_id,
Types::GlobalIDType[Milestone],
required: false,
description: 'The ID of the milestone to be assigned to the board.'
argument :weight,
GraphQL::BOOLEAN_TYPE,
required: false,
description: 'The weight of the board.'
argument :label_ids,
[Types::GlobalIDType[Label]],
required: false,
description: 'The IDs of labels to be added to the board.'
authorize :admin_board
def resolve(args)
board_parent = authorized_resource_parent_find!(args)
response = ::Boards::CreateService.new(board_parent, current_user, args).execute
{
......@@ -47,3 +29,5 @@ module Mutations
end
end
end
Mutations::Boards::Create.prepend_if_ee('::EE::Mutations::Boards::Create')
# frozen_string_literal: true
module Mutations
module Boards
class Update < ::Mutations::BaseMutation
graphql_name 'UpdateBoard'
include Mutations::Boards::CommonMutationArguments
argument :id,
::Types::GlobalIDType[::Board],
required: true,
description: 'The board global ID.'
field :board,
Types::BoardType,
null: true,
description: 'The board after mutation.'
authorize :admin_board
def resolve(id:, **args)
board = authorized_find!(id: id)
::Boards::UpdateService.new(board.resource_parent, current_user, args).execute(board)
{
board: board,
errors: errors_on_object(board)
}
end
def find_object(id:)
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
id = ::Types::GlobalIDType[::Board].coerce_isolated_input(id)
GitlabSchema.find_by_gid(id)
end
end
end
end
Mutations::Boards::Update.prepend_if_ee('::EE::Mutations::Boards::Update')
......@@ -12,6 +12,12 @@ module Types
field :name, type: GraphQL::STRING_TYPE, null: true,
description: 'Name of the board'
field :hide_backlog_list, type: GraphQL::BOOLEAN_TYPE, null: true,
description: 'Whether or not backlog list is hidden'
field :hide_closed_list, type: GraphQL::BOOLEAN_TYPE, null: true,
description: 'Whether or not closed list is hidden'
field :lists,
Types::BoardListType.connection_type,
null: true,
......
---
title: Allow updating `hideBacklogList` and `hideClosedList` board attributes
merge_request: 49947
author:
type: changed
......@@ -3975,11 +3975,6 @@ type CreateAnnotationPayload {
Autogenerated input type of CreateBoard
"""
input CreateBoardInput {
"""
The ID of the user to be assigned to the board.
"""
assigneeId: String
"""
A unique identifier for the client performing the mutation.
"""
......@@ -3991,14 +3986,14 @@ input CreateBoardInput {
groupPath: ID
"""
The IDs of labels to be added to the board.
Whether or not backlog list is hidden
"""
labelIds: [LabelID!]
hideBacklogList: Boolean
"""
The ID of the milestone to be assigned to the board.
Whether or not closed list is hidden
"""
milestoneId: MilestoneID
hideClosedList: Boolean
"""
The board name.
......@@ -4009,11 +4004,6 @@ input CreateBoardInput {
The project full path the resource is associated with
"""
projectPath: ID
"""
The weight of the board.
"""
weight: Boolean
}
"""
......@@ -23399,11 +23389,6 @@ type UpdateBoardEpicUserPreferencesPayload {
Autogenerated input type of UpdateBoard
"""
input UpdateBoardInput {
"""
The ID of user to be assigned to the board
"""
assigneeId: UserID
"""
A unique identifier for the client performing the mutation.
"""
......@@ -23420,39 +23405,14 @@ input UpdateBoardInput {
hideClosedList: Boolean
"""
The board global ID
The board global ID.
"""
id: BoardID!
"""
The ID of iteration to be assigned to the board.
"""
iterationId: IterationID
"""
The IDs of labels to be added to the board
"""
labelIds: [LabelID!]
"""
Labels of the issue
"""
labels: [String!]
"""
The ID of milestone to be assigned to the board
"""
milestoneId: MilestoneID
"""
Name of the board
The board name.
"""
name: String
"""
The weight value to be assigned to the board
"""
weight: Int
}
"""
......@@ -23505,7 +23465,7 @@ Autogenerated return type of UpdateBoard
"""
type UpdateBoardPayload {
"""
The board after mutation
The board after mutation.
"""
board: Board
......
......@@ -10945,28 +10945,18 @@
"defaultValue": null
},
{
"name": "assigneeId",
"description": "The ID of the user to be assigned to the board.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "milestoneId",
"description": "The ID of the milestone to be assigned to the board.",
"name": "hideBacklogList",
"description": "Whether or not backlog list is hidden",
"type": {
"kind": "SCALAR",
"name": "MilestoneID",
"name": "Boolean",
"ofType": null
},
"defaultValue": null
},
{
"name": "weight",
"description": "The weight of the board.",
"name": "hideClosedList",
"description": "Whether or not closed list is hidden",
"type": {
"kind": "SCALAR",
"name": "Boolean",
......@@ -10974,24 +10964,6 @@
},
"defaultValue": null
},
{
"name": "labelIds",
"description": "The IDs of labels to be added to the board.",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "LabelID",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
......@@ -68541,23 +68513,9 @@
"description": "Autogenerated input type of UpdateBoard",
"fields": null,
"inputFields": [
{
"name": "id",
"description": "The board global ID",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "BoardID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "name",
"description": "Name of the board",
"description": "The board name.",
"type": {
"kind": "SCALAR",
"name": "String",
......@@ -68586,77 +68544,15 @@
"defaultValue": null
},
{
"name": "assigneeId",
"description": "The ID of user to be assigned to the board",
"type": {
"kind": "SCALAR",
"name": "UserID",
"ofType": null
},
"defaultValue": null
},
{
"name": "milestoneId",
"description": "The ID of milestone to be assigned to the board",
"type": {
"kind": "SCALAR",
"name": "MilestoneID",
"ofType": null
},
"defaultValue": null
},
{
"name": "iterationId",
"description": "The ID of iteration to be assigned to the board.",
"type": {
"kind": "SCALAR",
"name": "IterationID",
"ofType": null
},
"defaultValue": null
},
{
"name": "weight",
"description": "The weight value to be assigned to the board",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "labels",
"description": "Labels of the issue",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "labelIds",
"description": "The IDs of labels to be added to the board",
"name": "id",
"description": "The board global ID.",
"type": {
"kind": "LIST",
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "LabelID",
"ofType": null
}
"kind": "SCALAR",
"name": "BoardID",
"ofType": null
}
},
"defaultValue": null
......@@ -68805,7 +68701,7 @@
"fields": [
{
"name": "board",
"description": "The board after mutation",
"description": "The board after mutation.",
"args": [
],
......@@ -3584,7 +3584,7 @@ Autogenerated return type of UpdateBoard.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `board` | Board | The board after mutation |
| `board` | Board | The board after mutation. |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
......
# frozen_string_literal: true
module EE
module Mutations
module Boards
module Create
include Mutations::Boards::ScopedBoardMutation
end
end
end
end
# frozen_string_literal: true
module EE
module Mutations
module Boards
module ScopedBoardArguments
extend ActiveSupport::Concern
included do
argument :assignee_id,
::Types::GlobalIDType[::User],
required: false,
loads: ::Types::UserType,
description: 'The ID of user to be assigned to the board.'
# Cannot pre-load ::Types::MilestoneType because we are also assigning values like:
# ::Timebox::None(0), ::Timebox::Upcoming(-2) or ::Timebox::Started(-3), that cannot be resolved to a DB record.
argument :milestone_id,
::Types::GlobalIDType[::Milestone],
required: false,
description: 'The ID of milestone to be assigned to the board.'
# Cannot pre-load ::Types::IterationType because we are also assigning values like:
# ::Iteration::Predefined::None(0) or ::Iteration::Predefined::Current(-4), that cannot be resolved to a DB record.
argument :iteration_id,
::Types::GlobalIDType[::Iteration],
required: false,
description: 'The ID of iteration to be assigned to the board.'
argument :weight,
GraphQL::INT_TYPE,
required: false,
description: 'The weight value to be assigned to the board.'
argument :labels, [GraphQL::STRING_TYPE],
required: false,
description: copy_field_description(Types::IssueType, :labels)
argument :label_ids, [::Types::GlobalIDType[::Label]],
required: false,
description: 'The IDs of labels to be added to the board.'
end
end
end
end
end
# frozen_string_literal: true
module EE
module Mutations
module Boards
module ScopedBoardMutation
extend ActiveSupport::Concern
prepended do
include ScopedBoardArguments
end
def resolve(**args)
parsed_params = parse_arguments(args)
super(parsed_params)
end
def ready?(**args)
if args.slice(*mutually_exclusive_args).size > 1
arg_str = mutually_exclusive_args.map { |x| x.to_s.camelize(:lower) }.join(' or ')
raise ::Gitlab::Graphql::Errors::ArgumentError, "one and only one of #{arg_str} is required"
end
super
end
private
def parse_arguments(args = {})
if args[:assignee_id]
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
args[:assignee_id] = ::Types::GlobalIDType[::User].coerce_isolated_input(args[:assignee_id])
args[:assignee_id] = args[:assignee_id].model_id
end
if args[:milestone_id]
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
args[:milestone_id] = ::Types::GlobalIDType[::Milestone].coerce_isolated_input(args[:milestone_id])
args[:milestone_id] = args[:milestone_id].model_id
end
args[:label_ids] &&= args[:label_ids].map do |label_id|
::GitlabSchema.parse_gid(label_id, expected_type: ::Label).model_id
end
# we need this because we also pass `gid://gitlab/Iteration/-4` or `gid://gitlab/Iteration/-4`
# as `iteration_id` when we scope board to `Iteration::Predefined::Current` or `Iteration::Predefined::None`
args[:iteration_id] = args[:iteration_id].model_id if args[:iteration_id]
args
end
def mutually_exclusive_args
[:labels, :label_ids]
end
end
end
end
end
# frozen_string_literal: true
module EE
module Mutations
module Boards
module Update
include Mutations::Boards::ScopedBoardMutation
end
end
end
end
......@@ -14,12 +14,6 @@ module EE
resolver: ::Resolvers::BoardGroupings::EpicsResolver,
complexity: 5
field :hide_backlog_list, type: GraphQL::BOOLEAN_TYPE, null: true,
description: 'Whether or not backlog list is hidden'
field :hide_closed_list, type: GraphQL::BOOLEAN_TYPE, null: true,
description: 'Whether or not closed list is hidden'
field :labels, ::Types::LabelType.connection_type, null: true,
description: 'Labels of the board'
......
# frozen_string_literal: true
module Mutations
module Boards
class Update < ::Mutations::BaseMutation
graphql_name 'UpdateBoard'
argument :id,
::Types::GlobalIDType[::Board],
required: true,
description: 'The board global ID'
argument :name,
GraphQL::STRING_TYPE,
required: false,
description: copy_field_description(Types::BoardType, :name)
argument :hide_backlog_list,
GraphQL::BOOLEAN_TYPE,
required: false,
description: copy_field_description(Types::BoardType, :hide_backlog_list)
argument :hide_closed_list,
GraphQL::BOOLEAN_TYPE,
required: false,
description: copy_field_description(Types::BoardType, :hide_closed_list)
argument :assignee_id,
::Types::GlobalIDType[::User],
required: false,
loads: ::Types::UserType,
description: 'The ID of user to be assigned to the board'
# Cannot pre-load ::Types::MilestoneType because we are also assigning values like:
# ::Timebox::None(0), ::Timebox::Upcoming(-2) or ::Timebox::Started(-3), that cannot be resolved to a DB record.
argument :milestone_id,
::Types::GlobalIDType[::Milestone],
required: false,
description: 'The ID of milestone to be assigned to the board'
# Cannot pre-load ::Types::IterationType because we are also assigning values like:
# ::Iteration::Predefined::None(0) or ::Iteration::Predefined::Current(-4), that cannot be resolved to a DB record.
argument :iteration_id,
::Types::GlobalIDType[::Iteration],
required: false,
description: 'The ID of iteration to be assigned to the board.'
argument :weight,
GraphQL::INT_TYPE,
required: false,
description: 'The weight value to be assigned to the board'
argument :labels, [GraphQL::STRING_TYPE],
required: false,
description: copy_field_description(Types::IssueType, :labels)
argument :label_ids, [::Types::GlobalIDType[::Label]],
required: false,
description: 'The IDs of labels to be added to the board'
field :board,
Types::BoardType,
null: true,
description: "The board after mutation"
authorize :admin_board
def resolve(id:, assignee: nil, **args)
board = authorized_find!(id: id)
parsed_params = parse_arguments(args)
::Boards::UpdateService.new(board.resource_parent, current_user, parsed_params).execute(board)
{
board: board,
errors: errors_on_object(board)
}
end
def ready?(**args)
if args.slice(*mutually_exclusive_args).size > 1
arg_str = mutually_exclusive_args.map { |x| x.to_s.camelize(:lower) }.join(' or ')
raise Gitlab::Graphql::Errors::ArgumentError, "one and only one of #{arg_str} is required"
end
super
end
private
def find_object(id:)
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
id = ::Types::GlobalIDType[::Board].coerce_isolated_input(id)
GitlabSchema.find_by_gid(id)
end
def parse_arguments(args = {})
if args[:assignee_id]
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
args[:assignee_id] = ::Types::GlobalIDType[::User].coerce_isolated_input(args[:assignee_id])
args[:assignee_id] = args[:assignee_id].model_id
end
if args[:milestone_id]
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
args[:milestone_id] = ::Types::GlobalIDType[::Milestone].coerce_isolated_input(args[:milestone_id])
args[:milestone_id] = args[:milestone_id].model_id
end
args[:label_ids] &&= args[:label_ids].map do |label_id|
::GitlabSchema.parse_gid(label_id, expected_type: ::Label).model_id
end
# we need this because we also pass `gid://gitlab/Iteration/-4` or `gid://gitlab/Iteration/-4`
# as `iteration_id` when we scope board to `Iteration::Predefined::Current` or `Iteration::Predefined::None`
args[:iteration_id] = args[:iteration_id].model_id if args[:iteration_id]
args
end
def mutually_exclusive_args
[:labels, :label_ids]
end
end
end
end
---
title: Add `hideBacklogList` and `hideClosedList` and `iteration_id` to `createBoard` mutation input
merge_request: 49947
author:
type: changed
......@@ -40,6 +40,30 @@ RSpec.shared_examples 'boards create mutation' do
end
end
context 'when hide_backlog_list parameter is true' do
before do
params[:hide_backlog_list] = true
end
it 'returns the board with correct hide_backlog_list field' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['board']['hideBacklogList']).to eq(true)
end
end
context 'when hide_closed_list parameter is true' do
before do
params[:hide_closed_list] = true
end
it 'returns the board with correct hide_closed_list field' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['board']['hideClosedList']).to eq(true)
end
end
context 'when the Boards::CreateService returns an error response' do
before do
allow_next_instance_of(Boards::CreateService) do |service|
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment