From a8965fee2a6cd0e923a6c021dd101cbab3281a64 Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Tue, 5 Nov 2024 15:43:16 +0100 Subject: [PATCH] [58521] API endpoint for fetching a custom field item's branch - Added OpenAPI spec for new endpoint - Added new API endpoint: /api/v3/custom_field_items/{id}/branch - Used HierarchicalItemService to retrieve branch for item --- docs/api/apiv3/openapi-spec.yml | 2 + .../apiv3/paths/custom_field_item_branch.yml | 63 +++++++++++++++++++ lib/api/v3/custom_fields/custom_fields_api.rb | 2 +- .../v3/custom_fields/hierarchy/item_api.rb | 2 + .../hierarchy/item_branch_api.rb | 59 +++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 docs/api/apiv3/paths/custom_field_item_branch.yml create mode 100644 lib/api/v3/custom_fields/hierarchy/item_branch_api.rb diff --git a/docs/api/apiv3/openapi-spec.yml b/docs/api/apiv3/openapi-spec.yml index 8b08defb7108..e3afad89a8f4 100644 --- a/docs/api/apiv3/openapi-spec.yml +++ b/docs/api/apiv3/openapi-spec.yml @@ -190,6 +190,8 @@ paths: "$ref": "./paths/custom_field_items.yml" "/api/v3/custom_field_items/{id}": "$ref": "./paths/custom_field_item.yml" + "/api/v3/custom_field_items/{id}/branch": + "$ref": "./paths/custom_field_item_branch.yml" "/api/v3/custom_options/{id}": "$ref": "./paths/custom_option.yml" "/api/v3/days/non_working": diff --git a/docs/api/apiv3/paths/custom_field_item_branch.yml b/docs/api/apiv3/paths/custom_field_item_branch.yml new file mode 100644 index 000000000000..9b84412b5851 --- /dev/null +++ b/docs/api/apiv3/paths/custom_field_item_branch.yml @@ -0,0 +1,63 @@ +# /api/v3/custom_field_items/{id}/branch +--- +get: + summary: Get a custom field hierarchy item's branch + operationId: get_custom_field_item_branch + description: |- + Retrieves the branch of a single custom field item specified by its unique identifier. + + A branch is list of all ancestors, starting with the root item and finishing with the item itself. + parameters: + - name: id + description: The custom field item's unique identifier + in: path + example: '42' + required: true + schema: + type: integer + responses: + '200': + description: OK + content: + application/hal+json: + schema: + $ref: '../components/schemas/hierarchy_item_collection_model.yml' + examples: + 'simple response': + $ref: '../components/examples/hierarchy_item_collection_response.yml' + '403': + description: Returned if the user is not logged in. + content: + application/hal+json: + schema: + $ref: '../components/schemas/error_response.yml' + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission + message: You are not authorized to access this resource. + '404': + description: Returned if the custom field does not exist. + content: + application/hal+json: + schema: + $ref: '../components/schemas/error_response.yml' + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + '422': + description: Returned if the custom field is not of type hierarchy. + content: + application/hal+json: + schema: + $ref: '../components/schemas/error_response.yml' + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:UnprocessableContent + message: The requested custom field resource is of wrong type. diff --git a/lib/api/v3/custom_fields/custom_fields_api.rb b/lib/api/v3/custom_fields/custom_fields_api.rb index a8332356928d..64cc6b6514b3 100644 --- a/lib/api/v3/custom_fields/custom_fields_api.rb +++ b/lib/api/v3/custom_fields/custom_fields_api.rb @@ -38,7 +38,7 @@ class CustomFieldsAPI < ::API::OpenProjectAPI @custom_field = CustomField.find(params[:id]) end - mount API::V3::CustomFields::Hierarchy::ItemsAPI + mount Hierarchy::ItemsAPI end end end diff --git a/lib/api/v3/custom_fields/hierarchy/item_api.rb b/lib/api/v3/custom_fields/hierarchy/item_api.rb index d0ce2d51b6ae..1231b9fb57a2 100644 --- a/lib/api/v3/custom_fields/hierarchy/item_api.rb +++ b/lib/api/v3/custom_fields/hierarchy/item_api.rb @@ -44,6 +44,8 @@ class ItemAPI < ::API::OpenProjectAPI render_representer: HierarchyItemRepresenter, instance_generator: ->(*) { @custom_field_item }) .mount + + mount ItemBranchAPI end end end diff --git a/lib/api/v3/custom_fields/hierarchy/item_branch_api.rb b/lib/api/v3/custom_fields/hierarchy/item_branch_api.rb new file mode 100644 index 000000000000..68e7e98f37e8 --- /dev/null +++ b/lib/api/v3/custom_fields/hierarchy/item_branch_api.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module API + module V3 + module CustomFields + module Hierarchy + class ItemBranchAPI < ::API::OpenProjectAPI + include Dry::Monads[:result] + + resource :branch do + get do + ::CustomFields::Hierarchy::HierarchicalItemService + .new + .get_branch(item: @custom_field_item) + .either( + ->(items) do + self_link = api_v3_paths.custom_field_item(@custom_field_item.id) + HierarchyItemCollectionRepresenter.new(items, self_link:, current_user:) + end, + ->(error) do + msg = "#{I18n.t('api_v3.errors.code_500')} #{error}" + raise ::API::Errors::InternalError.new(msg) + end + ) + end + end + end + end + end + end +end