From 25b56f585eaa44783b8bf14ee0397c4655ade3b5 Mon Sep 17 00:00:00 2001 From: Ida Date: Wed, 6 May 2026 08:19:37 +0200 Subject: [PATCH] fix: readded new folder button to folder tree component --- .../FormGeneratorTree/FormGeneratorTree.tsx | 62 +++++++++ .../__tests__/FormGeneratorTree.test.tsx | 122 ++++++++++++++++-- .../FormGeneratorTree/__tests__/dnd.test.tsx | 6 + .../providers/FolderFileProvider.tsx | 6 +- .../FormGenerator/FormGeneratorTree/types.ts | 2 + src/pages/basedata/FilesPage.tsx | 1 + 6 files changed, 186 insertions(+), 13 deletions(-) diff --git a/src/components/FormGenerator/FormGeneratorTree/FormGeneratorTree.tsx b/src/components/FormGenerator/FormGeneratorTree/FormGeneratorTree.tsx index e480963..5b9f92e 100644 --- a/src/components/FormGenerator/FormGeneratorTree/FormGeneratorTree.tsx +++ b/src/components/FormGenerator/FormGeneratorTree/FormGeneratorTree.tsx @@ -3,7 +3,9 @@ import { FaChevronRight, FaUnlink, FaSyncAlt, + FaFolderPlus, } from 'react-icons/fa'; +import { usePrompt } from '../../../hooks/usePrompt'; import type { TreeNode, TreeNodeProvider, @@ -81,6 +83,15 @@ function _flatten( return result; } +function _resolveNewFolderParentId(selectedIds: Set, nodes: TreeNode[]): string | null { + if (selectedIds.size !== 1) return null; + const id = [...selectedIds][0]; + const node = nodes.find((n) => n.id === id); + if (!node) return null; + if (node.type === 'folder') return node.id; + return node.parentId ?? null; +} + function _collectDescendantIds(nodeId: string, nodes: TreeNode[]): string[] { const childMap = _buildChildMap(nodes); const result: string[] = []; @@ -390,8 +401,10 @@ export function FormGeneratorTree({ onSelectionChange, onRefresh, onSendToChat, + allowCreateFolder = true, className, }: FormGeneratorTreeProps) { + const { prompt, PromptDialog } = usePrompt(); const [nodes, setNodes] = useState[]>([]); const [expandedIds, setExpandedIds] = useState>(new Set()); const [selectedIds, setSelectedIds] = useState>(new Set()); @@ -577,6 +590,32 @@ export function FormGeneratorTree({ onRefresh?.(); }, [_loadRoot, _updateSelection, onRefresh]); + const _handleNewFolder = useCallback(async () => { + if (ownership !== 'own' || !provider.createChild || !allowCreateFolder) return; + const parentId = _resolveNewFolderParentId(selectedIds, nodes); + if (provider.canCreate && !provider.canCreate(parentId)) return; + const name = await prompt('Neuer Ordnername:', { title: 'Neuer Ordner', placeholder: 'Ordnername' }); + const trimmed = name?.trim(); + if (!trimmed) return; + try { + const newNode = await provider.createChild(parentId, trimmed); + setNodes((prev) => [...prev, newNode]); + if (parentId) { + setExpandedIds((prev) => new Set(prev).add(parentId)); + } + } catch { + await _handleRefresh(); + } + }, [ + ownership, + provider, + allowCreateFolder, + selectedIds, + nodes, + prompt, + _handleRefresh, + ]); + const _handleDelete = useCallback( async (id: string) => { const node = nodes.find((n) => n.id === id); @@ -801,6 +840,13 @@ export function FormGeneratorTree({ const totalNodeCount = nodes.filter((n) => n.parentId === null).length; + const showNewFolderButton = + Boolean(title) && + ownership === 'own' && + allowCreateFolder && + Boolean(provider.createChild) && + (provider.canCreate?.(_resolveNewFolderParentId(selectedIds, nodes)) ?? true); + const wrapperClasses = [ styles.formGeneratorTree, compact && styles.compactMode, @@ -825,6 +871,20 @@ export function FormGeneratorTree({ )} {title} {totalNodeCount} + {showNewFolderButton && ( + + )}