feat(knowledge): folder tree sidebar, folder path storage, and document re-filing - #2528
Merged
lyingbug merged 10 commits intoAug 4, 2026
Merged
Conversation
…er tree API Folder uploads used to encode their relative directory inside file_name, which made the document list render the whole path as the title and left no way to browse or query a single folder. The directory now lives in a dedicated folder_path column (with a backfill for existing rows), the document list accepts folder_path / folder_recursive filters, and a new GET /knowledge-bases/:id/knowledge/folders endpoint returns the folder tree with per-folder document counts.
The documents tab gains a left folder column built from the folder_path now stored on each knowledge entry. Selecting a folder filters the existing document list (so search, tags, type, status and date filters all keep working), a breadcrumb above the list shows where you are, and uploads made while browsing a folder land in that folder. A per-row folder chip appears only when the list can span folders.
The upload-path builder, breadcrumb/ancestor derivation, folder lookup and tree flattening were inline in the view and the sidebar component. Moving them into folderTree.ts follows the convention of kbListMerge.ts and wikiStatusRefresh.ts, removes the duplicated webkitRelativePath handling, and makes the folder navigation logic directly testable.
The sidebar listed "all documents" and "root" as two rows sitting next to the top-level folders, but those folders are inside the root, so the three rows contradicted each other and reaching the top level for an upload meant selecting a row that did not look like a parent. There is now a single root row with every folder nested beneath it, and what a row lists is decided by one uniform rule at every level: the direct documents, or the whole subtree when the scope toggle is on. "Documents not in any folder" is the root with the toggle off, which is also why the toggle now defaults to on. The upload destination is no longer implied by the sidebar selection either: the confirmation dialog shows which folder the batch lands in, lets it be switched back to the top level, and lists each file's own sub-directory.
…n the tree A folder-only tree cannot show a node for a document that is not in any folder, so single-file uploads were unreachable from the sidebar: a base with 5 documents and one 3-document folder just left two of them unaccounted for. Rather than add a second pseudo-folder row for them (the ambiguity the previous commit removed), the one existing mechanism is made visible: the scope switch is now a labeled segmented control instead of an icon behind a tooltip, and the root row is named after whatever the current scope makes it list - the whole base, or exactly the unfiled documents. The breadcrumb's leading crumb follows the same rule.
The scope switch is gone. It existed because "select a folder" was ambiguous in a list that could not show folders, and turning that ambiguity into a control just moved the problem onto the user. The list now shows what a folder contains: its sub-folders as entries first, then the documents directly inside it. So the mode follows what the user is already doing instead of a switch - browsing shows one level, and any active filter searches the whole subtree flat, with a breadcrumb note saying so. A document uploaded on its own needs no special row either: it sits at the top level next to the folders, exactly where it is. Folders can also be adjusted now, which they could not before - a mis-filed upload previously had to be deleted and re-uploaded. Documents move via the row menu or the batch bar into an existing or newly typed folder, and a folder can be renamed in place, carrying its subtree. Both are plain folder_path updates: nothing is re-parsed, re-chunked or re-embedded.
…e the folder picker to a popup Two things the folder UI got wrong. The rename state used the empty string to mean "nothing is being renamed", but the empty string is also the root folder's own path, so the root row matched and permanently rendered a stray rename input. The sentinel is now null, and rename is additionally gated on the row being a real folder, so no sentinel value can reach the root again. Moving documents also did not deserve a modal dialog: it is one small, reversible choice. In a row's menu the picker is now another level of the menu that is already open, mirroring the "move to knowledge base" sub-menu right next to it; in the batch bar it hangs off the button. Picking a folder performs the move, since there is nothing else to confirm. The upload destination line was also mangling folder names: truncating from the left with direction: rtl reorders CJK text. It now shows the destination's last segment with the full path in the title, reads as a quiet line instead of a grey banner, and only appears when the destination is not the top level.
…alog - Added folder options to the upload confirmation dialog, allowing users to select from existing folders as upload destinations. - Updated folder tree UI to improve folder browsing experience, displaying sub-folders and documents more intuitively. - Enhanced folder picker functionality to support creating new sub-folders directly from the picker. - Improved localization for folder-related strings across multiple languages. - Refactored related components and tests to accommodate new features and ensure proper functionality. This commit streamlines the user experience for managing folders and uploading documents, making it easier to navigate and organize content.
Document folder tree/move/rename endpoints in docs/api, Swagger, and the Go client; align frontend path normalization with server caps; guard rename no-ops and duplicate folder creation; enforce KB ownership on folder rename.
…nderscore scenarios - Updated SQL queries to properly escape LIKE wildcards in folder path filters. - Added tests for renaming knowledge folder paths, including cases with underscores in paths. - Enhanced existing tests to ensure correct folder listing behavior when using underscores.
lyingbug
force-pushed
the
cursor/knowledge-folder-tree-5c67
branch
from
August 4, 2026 12:42
cb7db8f to
e5b1f78
Compare
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
folder_pathon knowledge documents (DB migration + API) so folder uploads retain their directory structure.Changes
Backend
folder_pathcolumn and migrations (versioned + sqlite)Frontend
KbFolderTreesidebar component with rename/create/delete folder actionsFolderPickerMenupopup for choosing upload/move destinationsTest plan
scripts/verify_frontend_pr.sh(unit tests, type-check, build)