feat: support nested (sub-)folders - #73
Merged
Merged
Conversation
Adds an optional parentId to BookmarkFolder, capped at
MAX_FOLDER_DEPTH = 3 levels (root-level folders are depth 1). New
commands:
- createSubfolder (context menu on a folder): creates a folder
directly under it, skipping a parent picker since the parent is
implied by the click. Blocked with a warning if it would exceed
the depth cap.
- moveFolderToParent (context menu on a folder): reparents an
existing folder via a picker (pickParentFolder) that excludes the
folder itself, its descendants, and any parent that would exceed
the depth cap.
deleteFolder now promotes direct child folders to the root (not
deleted) the same way it already does for direct bookmarks.
getChildren recurses through the hierarchy; FolderGroupItem carries
its direct child folders and shows a subfolder count alongside the
bookmark count. List view shows a full breadcrumb path
("Backend › Auth Service") instead of just the immediate folder name.
Drag-and-drop: dropping a folder onto another folder now nests it as
that folder's last child (VS Code's tree DnD API can't distinguish
"dropped near" from "dropped on," so nesting wins over the reordering
shipped in #38 — reordering root-level folders now happens by
dropping on empty space, which still appends to the end). Nesting
that would exceed the depth cap or create a cycle is refused with a
warning message.
pickFolder (for bookmarks) now renders breadcrumb labels too, for
disambiguating same-named folders at different nesting levels; its
match-by-name matching becomes match-by-breadcrumb, a no-op change
for anyone not using nesting since a root folder's breadcrumb is
just its name.
Includes unit tests for the store, the depth/cycle helper functions,
both new commands, the provider's recursive getChildren, and the
new drag-and-drop nesting semantics, plus an e2e test exercising
real nested creation, tree recursion, and drag-and-drop reparenting.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
parentIdtoBookmarkFolder, capped atMAX_FOLDER_DEPTH = 3levels (root-level folders are depth 1) — depth limit and DnD-reparenting scope were confirmed with the maintainer before implementing.createSubfolder(context menu on a folder): creates a folder directly under it, skipping a parent picker since the parent is implied by the click. Blocked with a warning if it would exceed the depth cap.moveFolderToParent(context menu on a folder): reparents an existing folder via a picker (pickParentFolder) that excludes the folder itself, its descendants, and any parent that would exceed the depth cap.deleteFoldernow promotes direct child folders to the root (not deleted) the same way it already does for direct bookmarks.getChildrenrecurses through the hierarchy;FolderGroupItemcarries its direct child folders and shows a subfolder count alongside the bookmark count. List view shows a full breadcrumb path (Backend › Auth Service) instead of just the immediate folder name.pickFolder(for bookmarks) now renders breadcrumb labels too, for disambiguating same-named folders at different nesting levels — a no-op change for anyone not using nesting, since a root folder's breadcrumb is just its name.Closes #41
Test plan
npm run lintnpm run test:coverage— 100% statements/lines, 95.71% branchesnpm run buildnpm run test:e2e— 8/8 passing against a real VS Code instance, including nested creation/recursion and a real drag-and-drop reparentnpm audit --audit-level=high— 0 vulnerabilitiesscripts/local-patch-report.sh— 100% patch coverage (112/112)