Let me nest folders inside other folders in the blocks sidebar, so I can organize blocks into a hierarchy (e.g. a top-level "Metals" folder with "Iron", "Copper", … sub-folders).
Why
Folders are currently single-level. The blockGroups table already has a parentId column reserved for nesting (db/schema.ts), but it's unused — renderFolder() in routes/block.tsx renders a flat list and the "Ungrouped" pseudo-folder, with no parent/child traversal. Folder reorder and block move/reorder already work (dropFolderBefore/setGroupOrder, dropBlockBefore/setBlockOrder); this extends that to a tree.
Scope
- Use the existing
blockGroups.parentId to model the tree; render folders recursively in renderFolder().
- Drag/drop a folder into another folder (set
parentId), not just reorder among siblings — extend dropFolderBefore to also adopt a parent, mirroring how dropBlockBefore adopts a groupId.
sortOrder becomes order-among-siblings (per parent).
- Collapse/expand state per folder (already localStorage-based) should work at every depth.
- Guard against cycles (can't drop a folder into its own descendant).
- Deleting a folder: decide whether children re-parent to the grandparent or move to Ungrouped (today blocks move to Ungrouped).
Relates to #7 (sub-blocks) — both are about hierarchy, but this is sidebar organization (folders of blocks), not composition of recipes within a block.
Let me nest folders inside other folders in the blocks sidebar, so I can organize blocks into a hierarchy (e.g. a top-level "Metals" folder with "Iron", "Copper", … sub-folders).
Why
Folders are currently single-level. The
blockGroupstable already has aparentIdcolumn reserved for nesting (db/schema.ts), but it's unused —renderFolder()inroutes/block.tsxrenders a flat list and the "Ungrouped" pseudo-folder, with no parent/child traversal. Folder reorder and block move/reorder already work (dropFolderBefore/setGroupOrder,dropBlockBefore/setBlockOrder); this extends that to a tree.Scope
blockGroups.parentIdto model the tree; render folders recursively inrenderFolder().parentId), not just reorder among siblings — extenddropFolderBeforeto also adopt a parent, mirroring howdropBlockBeforeadopts agroupId.sortOrderbecomes order-among-siblings (per parent).Relates to #7 (sub-blocks) — both are about hierarchy, but this is sidebar organization (folders of blocks), not composition of recipes within a block.