Skip to content

Commit

Permalink
[58520] added first atempts to fetch full tree
Browse files Browse the repository at this point in the history
  • Loading branch information
Kharonus committed Nov 4, 2024
1 parent d6ac7fb commit 06d22cf
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 8 deletions.
46 changes: 46 additions & 0 deletions app/models/queries/custom_fields/hierarchy/item_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#-- 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 Queries
module CustomFields
module Hierarchy
class ItemQuery
include ::Queries::BaseQuery
include ::Queries::UnpersistedQuery

def self.model
CustomField::Hierarchy::Item
end

def default_scope
super
end

Check warning on line 42 in app/models/queries/custom_fields/hierarchy/item_query.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/models/queries/custom_fields/hierarchy/item_query.rb#L40-L42 <Lint/UselessMethodDefinition>

Useless method definition detected.
Raw output
app/models/queries/custom_fields/hierarchy/item_query.rb:40:9: W: Lint/UselessMethodDefinition: Useless method definition detected.
end
end
end
end
16 changes: 16 additions & 0 deletions docs/api/apiv3/paths/custom_field_items.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ get:
has a reference to its parent and children. The list is ordered in a depth-first manner. The first item is the
requested parent. If parent was unset, the root item is returned as first element.
Passing the `depth` query parameter allows to limit the depth of the hierarchy. If the depth is unset, the full
hierarchy tree is returned. If the depth is set to `0`, only the requested parent is returned. Any other positive
integer will return the number of children levels specified by this value.
This endpoint only returns, if the custom field is of type `hierarchy`.
parameters:
- name: id
Expand Down Expand Up @@ -45,6 +49,18 @@ get:
$ref: '../components/examples/hierarchy_item_collection_response.yml'
'filtered response':
$ref: '../components/examples/hierarchy_item_collection_filtered_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:
Expand Down
5 changes: 1 addition & 4 deletions lib/api/errors/unprocessable_content.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ class UnprocessableContent < ErrorBase
identifier "UnprocessableContent"
code 422

def initialize(property, message)
def initialize(message)
super(message)

Check notice on line 36 in lib/api/errors/unprocessable_content.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] lib/api/errors/unprocessable_content.rb#L36 <Style/SuperArguments>

Call `super` without arguments and parentheses when the signature is identical.
Raw output
lib/api/errors/unprocessable_content.rb:36:9: C: Style/SuperArguments: Call `super` without arguments and parentheses when the signature is identical.

@property = property
@details = { attribute: property }
end

Check warning on line 37 in lib/api/errors/unprocessable_content.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] lib/api/errors/unprocessable_content.rb#L35-L37 <Lint/UselessMethodDefinition>

Useless method definition detected.
Raw output
lib/api/errors/unprocessable_content.rb:35:7: W: Lint/UselessMethodDefinition: Useless method definition detected.

Check notice on line 37 in lib/api/errors/unprocessable_content.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] lib/api/errors/unprocessable_content.rb#L35-L37 <Style/RedundantInitialize>

Remove unnecessary `initialize` method.
Raw output
lib/api/errors/unprocessable_content.rb:35:7: C: Style/RedundantInitialize: Remove unnecessary `initialize` method.
end
end
Expand Down
47 changes: 47 additions & 0 deletions lib/api/v3/custom_fields/custom_fields_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#-- 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
class CustomFieldsAPI < ::API::OpenProjectAPI
resource :custom_fields do
route_param :id, type: Integer, desc: "Custom Field ID" do
after_validation do
authorize_logged_in

@custom_field = CustomField.find(params[:id])
end

mount API::V3::CustomFields::Hierarchy::ItemsAPI
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#-- 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 HierarchyItemCollectionRepresenter < ::API::Decorators::UnpaginatedCollection
property :count, getter: ->(*) { count.size }

def model_count(models)
super.size
end
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ def _type
end

property :id

property :label, render_nil: true

property :short, render_nil: true
end
end
end
Expand Down
110 changes: 110 additions & 0 deletions lib/api/v3/custom_fields/hierarchy/items_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#-- 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 ItemsAPI < ::API::OpenProjectAPI
helpers do
def start_item(root, parent)
return root if parent.nil?

start = ::CustomField::Hierarchy::Item.find_by(id: parent)
raise ::API::Errors::NotFound if start.nil?
raise ::API::Errors::NotImplemented unless start.descendant_of?(root)

start
end

def item_list(item, depth)
return item.self_and_descendants_preordered if depth.nil?

d = parse_int(depth)
raise ::API::Errors::InvalidQuery.new("Depth must be a natural number.") if d.nil? || d < 0

t = flatten_tree_hash item.hash_tree(limit_depth: d + 1)

Check warning on line 51 in lib/api/v3/custom_fields/hierarchy/items_api.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] lib/api/v3/custom_fields/hierarchy/items_api.rb#L51 <Lint/UselessAssignment>

Useless assignment to variable - `t`.
Raw output
lib/api/v3/custom_fields/hierarchy/items_api.rb:51:15: W: Lint/UselessAssignment: Useless assignment to variable - `t`.

item.self_and_descendants_preordered
end

def flatten_tree_hash(hash)
flat_list = hash.keys

queue = hash.values

# {:a => {:b => {:c1 => {:d1 => {}}, :c2 => {:d2 => {}}}, :b2 => {}}}

while queue.any?
current = queue.shift
flat_list += current.keys
queue.unshift(current.values)
end

flat_list
end

def parse_int(str)
Integer(str)
rescue ArgumentError
nil
end
end

resource :items do
after_validation do
unless @custom_field.field_format_hierarchy?
message = "Hierarchy items do only exists for custom fields of type hierarchy."
raise ::API::Errors::UnprocessableContent.new(message)
end
end

get do
query = ParamsToQueryService.new(::CustomField::Hierarchy::Item,
current_user,
query_class: ::Queries::CustomFields::Hierarchy::ItemQuery)
.call(params)

unless query.valid?
raise ::API::Errors::NotImplemented
end

root_item = query.results.where(custom_field: @custom_field)
raise ::API::Errors::NotImplemented if root_item.count != 1

self_link = api_v3_paths.custom_field_items(@custom_field.id, params[:parent], params[:depth])
start = start_item(root_item.first, params[:parent])
models = item_list(start, params[:depth])
HierarchyItemCollectionRepresenter.new(models, self_link:, current_user:)
end
end
end
end
end
end
end
3 changes: 2 additions & 1 deletion lib/api/v3/root.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ class Root < ::API::OpenProjectAPI
mount ::API::V3::Actions::ActionsAPI
mount ::API::V3::Activities::ActivitiesAPI
mount ::API::V3::Attachments::AttachmentsAPI
mount ::API::V3::Capabilities::CapabilitiesAPI
mount ::API::V3::Backups::BackupsAPI
mount ::API::V3::Capabilities::CapabilitiesAPI
mount ::API::V3::Categories::CategoriesAPI
mount ::API::V3::Configuration::ConfigurationAPI
mount ::API::V3::CustomActions::CustomActionsAPI
mount ::API::V3::CustomFields::CustomFieldsAPI
mount ::API::V3::CustomOptions::CustomOptionsAPI
mount ::API::V3::Days::DaysAPI
mount ::API::V3::Grids::GridsAPI
Expand Down
Loading

0 comments on commit 06d22cf

Please sign in to comment.