From a1c2c27c833ae9ae3e88a80a2ba5d9dcdc27a1d3 Mon Sep 17 00:00:00 2001 From: Andreas Pfohl Date: Mon, 4 Nov 2024 14:26:56 +0100 Subject: [PATCH] [58520] Fixed hashed subtree flattening --- .../hierarchy/hierarchical_item_service.rb | 4 +++ .../hierarchy_item_collection_representer.rb | 5 --- .../v3/custom_fields/hierarchy/items_api.rb | 31 +++++++++---------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/app/services/custom_fields/hierarchy/hierarchical_item_service.rb b/app/services/custom_fields/hierarchy/hierarchical_item_service.rb index e0274491d148..472c56975df2 100644 --- a/app/services/custom_fields/hierarchy/hierarchical_item_service.rb +++ b/app/services/custom_fields/hierarchy/hierarchical_item_service.rb @@ -117,6 +117,10 @@ def soft_delete_item(item) raise NotImplementedError end + def hashed_subtree(item:, depth:) + Success(item.hash_tree(limit_depth: depth + 1)) + end + private def create_root_item(custom_field) diff --git a/lib/api/v3/custom_fields/hierarchy/hierarchy_item_collection_representer.rb b/lib/api/v3/custom_fields/hierarchy/hierarchy_item_collection_representer.rb index 562dad207cda..badb8cad2e77 100644 --- a/lib/api/v3/custom_fields/hierarchy/hierarchy_item_collection_representer.rb +++ b/lib/api/v3/custom_fields/hierarchy/hierarchy_item_collection_representer.rb @@ -31,11 +31,6 @@ 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 diff --git a/lib/api/v3/custom_fields/hierarchy/items_api.rb b/lib/api/v3/custom_fields/hierarchy/items_api.rb index 04da904acee8..f8da3cb04145 100644 --- a/lib/api/v3/custom_fields/hierarchy/items_api.rb +++ b/lib/api/v3/custom_fields/hierarchy/items_api.rb @@ -31,6 +31,8 @@ module V3 module CustomFields module Hierarchy class ItemsAPI < ::API::OpenProjectAPI + include Dry::Monads[:result] + helpers do def start_item(root, parent) return root if parent.nil? @@ -42,28 +44,18 @@ def start_item(root, parent) 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) - - item.self_and_descendants_preordered - end - def flatten_tree_hash(hash) - flat_list = hash.keys - - queue = hash.values + flat_list = [] + queue = [hash] # {:a => {:b => {:c1 => {:d1 => {}}, :c2 => {:d2 => {}}}, :b2 => {}}} while queue.any? current = queue.shift - flat_list += current.keys - queue.unshift(current.values) + item, children = current.shift + flat_list << item + queue.unshift(current) unless current.empty? + queue.unshift(children) unless children.empty? end flat_list @@ -99,7 +91,12 @@ def parse_int(str) 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]) + + models = ::CustomFields::Hierarchy::HierarchicalItemService + .new.hashed_subtree(item: start, + depth: parse_int(params[:depth])).fmap do |subtree| + flatten_tree_hash(subtree) + end.value! HierarchyItemCollectionRepresenter.new(models, self_link:, current_user:) end end