diff options
Diffstat (limited to 'app/graphql/mutations/work_items')
-rw-r--r-- | app/graphql/mutations/work_items/create.rb | 8 | ||||
-rw-r--r-- | app/graphql/mutations/work_items/linked_items/add.rb | 32 | ||||
-rw-r--r-- | app/graphql/mutations/work_items/linked_items/base.rb | 58 | ||||
-rw-r--r-- | app/graphql/mutations/work_items/subscribe.rb | 41 |
4 files changed, 139 insertions, 0 deletions
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 |