import type { DropOptions, NodeModel } from "@minoru/react-dnd-treeview"; import type { Menu, TreeMenu } from "../model/menu-interface"; export const generateTreeData = (data: Menu[]): NodeModel[] => { return data.reduce[]>((acc, menu) => { const node: NodeModel = { id: menu.menuCd ?? 0, parent: menu.parentId ?? 0, text: menu.menuKornNm, droppable: true, data: menu, }; acc.push(node); if (menu.children?.length) { acc.push(...generateTreeData(menu.children)); } return acc; }, []); }; export const generateNewTreeData = ( treeData: NodeModel[], options: DropOptions, ): TreeMenu | null => { const { dragSourceId, dragSource, dropTargetId, dropTarget } = options; if (!dragSource?.data) return null; const siblings = treeData.filter((node) => node.parent === dropTargetId); const newSortSeq = siblings.findIndex((sibling) => sibling.id === dragSourceId) + 1; const childNodes = treeData.filter( (node) => node.parent === dragSourceId && node.data, ); const baseNode = (node: NodeModel): TreeMenu => { if (!node.data) return {}; return { menuCd: node.data?.menuCd, name: node.data?.menuKornNm, icon: node.data?.iconNm, }; }; const treeMenu: TreeMenu = { ...baseNode(dragSource), parentId: dropTargetId === 0 ? null : (dropTargetId as number), sortSeq: newSortSeq, levelNo: (dropTarget?.data?.levelNo ?? 0) + 1, }; const result: TreeMenu = { ...treeMenu, children: childNodes.map((child) => ({ ...baseNode(child), parentId: child.data?.parentId === 0 ? null : (dropTargetId as number), sortSeq: child.data?.sortSeq, levelNo: (treeMenu?.levelNo ?? 0) + 1, })), }; return result; }; export const handleSelectNode = (callback: (node: NodeModel) => void) => (node: NodeModel) => { callback(node); }; export const handleDropNode = (callback: (newTree: TreeMenu) => void) => (newTree: NodeModel[], options: DropOptions) => { const newTreeData = generateNewTreeData(newTree, options); if (!newTreeData) return; callback(newTreeData); }; export const handleNodeTextChange = (treeData: NodeModel[]) => (callback: (newTree: NodeModel[]) => void) => (id: NodeModel["id"], value: string) => { const newTree = treeData.map((node) => { if (node.id === id) { return { ...node, text: value, }; } return node; }); callback(newTree); };