From 505558c84404096c9a53b0963db75ffa8aa7f899 Mon Sep 17 00:00:00 2001 From: zdienos Date: Sun, 13 Oct 2024 19:19:17 +0800 Subject: [PATCH 1/2] Update MenuBuilder.tsx add maxLevel nesting props --- src/Builder/MenuBuilder.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Builder/MenuBuilder.tsx b/src/Builder/MenuBuilder.tsx index bb1b1d0..960296e 100755 --- a/src/Builder/MenuBuilder.tsx +++ b/src/Builder/MenuBuilder.tsx @@ -79,12 +79,14 @@ interface Props { style?: "bordered" | "shadow"; items: TreeItems; setItems(items: ((items: any) => TreeItem[]) | TreeItems): void; + maxLevel?: number; } export function MenuBuilder({ style = "bordered", items: itemsProps, setItems, + maxLevel, }: Props) { const items = generateItemChildren(itemsProps); const indentationWidth = 50; @@ -294,6 +296,13 @@ export function MenuBuilder({ if (projected && over) { const { depth, parentId } = projected; + + // Check if the depth exceeds the maxLevel limit + if (maxLevel !== undefined && depth >= maxLevel) { + alert('MaxLevel Exceed!!'); + return; // Block the drop if the new depth exceeds maxLevel + } + const clonedItems: FlattenedItem[] = JSON.parse( JSON.stringify(flattenTree(items)) ); From 75a406def0f768f59c560100225f317b41d7015d Mon Sep 17 00:00:00 2001 From: zdienos Date: Tue, 15 Oct 2024 12:02:19 +0800 Subject: [PATCH 2/2] Update MenuBuilder.tsx update validation max level, when dragging an item with sub item --- src/Builder/MenuBuilder.tsx | 73 ++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/src/Builder/MenuBuilder.tsx b/src/Builder/MenuBuilder.tsx index 960296e..92893c0 100755 --- a/src/Builder/MenuBuilder.tsx +++ b/src/Builder/MenuBuilder.tsx @@ -292,32 +292,55 @@ export function MenuBuilder({ } function handleDragEnd({ active, over }: DragEndEvent) { - resetState(); - - if (projected && over) { - const { depth, parentId } = projected; - - // Check if the depth exceeds the maxLevel limit - if (maxLevel !== undefined && depth >= maxLevel) { - alert('MaxLevel Exceed!!'); - return; // Block the drop if the new depth exceeds maxLevel - } - - const clonedItems: FlattenedItem[] = JSON.parse( - JSON.stringify(flattenTree(items)) - ); - const overIndex = clonedItems.findIndex(({ id }) => id === over.id); - const activeIndex = clonedItems.findIndex(({ id }) => id === active.id); - const activeTreeItem = clonedItems[activeIndex]; - - clonedItems[activeIndex] = { ...activeTreeItem, depth, parentId }; - - const sortedItems = arrayMove(clonedItems, activeIndex, overIndex); - const newItems = buildTree(sortedItems); - - setItems(newItems); + resetState(); + + if (projected && over) { + const { depth, parentId } = projected; + + // Helper function to calculate the new depth of an item and its children + const calculateDepthForSubItems = (item: FlattenedItem, baseDepth: number): boolean => { + if (maxLevel !== undefined && baseDepth >= maxLevel) { + return false; // Return false if any item exceeds maxLevel + } + + if (item.children && item.children.length) { + return item.children.every((child) => { + const childItem = clonedItems.find(({ id }) => id === child.id); + if (childItem) { + return calculateDepthForSubItems(childItem, baseDepth + 1); // Recursively calculate depth for each child + } + return true; + }); + } + + return true; + }; + + const clonedItems: FlattenedItem[] = JSON.parse( + JSON.stringify(flattenTree(items)) + ); + const overIndex = clonedItems.findIndex(({ id }) => id === over.id); + const activeIndex = clonedItems.findIndex(({ id }) => id === active.id); + const activeTreeItem = clonedItems[activeIndex]; + + // Check if the depth exceeds the maxLevel for the dragged item and its children + const isValidDepth = calculateDepthForSubItems(activeTreeItem, depth); + + if (!isValidDepth) { + alert('Level Exceed!'); + return; // Block the drop if the new depth exceeds maxLevel + } + + // Update the depth of the dragged item + clonedItems[activeIndex] = { ...activeTreeItem, depth, parentId }; + + // Adjust the order of the items + const sortedItems = arrayMove(clonedItems, activeIndex, overIndex); + const newItems = buildTree(sortedItems); + + setItems(newItems); + } } - } function handleDragCancel() { resetState();