feat: Refactor folder tree management to use FoldersManager and remove onToggle functionality

This commit is contained in:
2025-12-07 01:12:28 +01:00
parent bd1cdc0817
commit 47599aba4a
13 changed files with 165 additions and 488 deletions
@@ -4,11 +4,12 @@ import type { Identifier } from '../../types/identifiers';
import { FolderPlusIcon } from '../../components/icons';
import FolderNode, { FolderIdentifier } from './SidebarFolderNode';
import type { FolderTreeNode } from '../../lib/api/apiTypes';
import { useAppShell } from '../../lib/context/AppShellContext';
import FoldersManager from '../../documents/FoldersManager';
import { useSyncExternalStore } from 'react';
interface SidebarFolderListProps {
roots: FolderTreeNode[];
selectedFolder: FolderIdentifier | null;
onToggle: (folderId: FolderIdentifier) => void;
onSelect: (folderId: FolderIdentifier) => void;
onDrop: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
onDragOver: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
@@ -23,9 +24,7 @@ interface SidebarFolderListProps {
}
const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
roots,
selectedFolder,
onToggle,
onSelect,
onDrop,
onDragOver,
@@ -38,17 +37,56 @@ const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
onCreateFolder,
creatingFolder,
}) => {
// Local expansion state for the UI
const { foldersManager } = useAppShell();
const getTreeSnapshot = useCallback(() => {
if (!foldersManager) return [];
return (foldersManager as FoldersManager).getTreeSnapshot();
}, [foldersManager]);
const getFolderMap = useCallback(() => {
if (!foldersManager) return new Map();
return (foldersManager as FoldersManager).getSnapshot();
}, [foldersManager]);
const subscribeToTree = useCallback((callback: () => void) => {
if (!foldersManager) return () => { };
return (foldersManager as FoldersManager).subscribe(callback);
}, [foldersManager]);
const roots = useSyncExternalStore(subscribeToTree, getTreeSnapshot);
const folderMap = useSyncExternalStore(subscribeToTree, getFolderMap);
const [expandedIds, setExpandedIds] = React.useState<Set<string>>(new Set(['root']));
// Override validation or external toggle if needed
// Auto-expand ancestors when selected folder changes
React.useEffect(() => {
if (selectedFolder) {
// ensure parent paths are expanded?
// Without a parent map, we can't easily auto-expand up.
// Rely on user or initial state for now, or add parent pointers.
if (!selectedFolder || !folderMap) return;
const ancestors = new Set<string>();
let current = folderMap.get(String(selectedFolder));
while (current) {
const parentId = current.parentId || current.parent_id;
if (!parentId || parentId === 'root') break;
ancestors.add(String(parentId));
current = folderMap.get(String(parentId));
}
}, [selectedFolder]);
if (ancestors.size > 0) {
setExpandedIds((prev) => {
const next = new Set(prev);
let changed = false;
ancestors.forEach(id => {
if (!next.has(id)) {
next.add(id);
changed = true;
}
});
return changed ? next : prev;
});
}
}, [selectedFolder, folderMap]);
const handleToggle = useCallback((folderId: FolderIdentifier) => {
setExpandedIds((prev) => {
@@ -61,8 +99,7 @@ const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
}
return next;
});
onToggle(folderId); // propagate event just in case parent needs it
}, [onToggle]);
}, []);
const renderNodes = useCallback(
(nodes: FolderTreeNode[], depth: number): ReactNode =>
@@ -126,7 +163,7 @@ const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
) : null}
</div>
<ul className="folder-tree">
{renderNodes(roots, 0)}
{renderNodes(roots as FolderTreeNode[], 0)}
</ul>
</div>
);