Skip to content

All documents folder paths#2098

Open
mfts wants to merge 1 commit intomainfrom
cursor/all-documents-folder-paths-5418
Open

All documents folder paths#2098
mfts wants to merge 1 commit intomainfrom
cursor/all-documents-folder-paths-5418

Conversation

@mfts
Copy link
Owner

@mfts mfts commented Mar 5, 2026

Add folder names and their paths to the "All Documents" search results to improve search functionality.


Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features
    • Search results now include matching folders with breadcrumb navigation paths displayed
    • Pagination displays folder match counts when search filters are active

…crumbs

- API: search folders by name when query is present, build parent path
  breadcrumbs (folderList), exclude hidden folders and children of hidden
  folders, return matching folders alongside documents
- SWR hook: add FolderWithCountAndPath type, expose searchFolders from
  useDocuments hook
- Documents page: display search-matched folders when filtered instead
  of empty array, pass correct loading state for filtered folders
- Folder card: render path breadcrumb (Home > parent > folder) when
  search query is active, matching the existing document card pattern
- Pagination: add optional extraInfo prop showing folder match count

Co-authored-by: Marc Seitz <mfts@users.noreply.github.com>
@cursor
Copy link

cursor bot commented Mar 5, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@vercel
Copy link

vercel bot commented Mar 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
papermark Ready Ready Preview, Comment Mar 5, 2026 3:38am

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

Walkthrough

Introduces folder breadcrumb trails in search results by extending folder types to include path data (FolderWithCountAndPath), updating API responses to return matching folders with parent paths during searches, and displaying search folder counts in pagination.

Changes

Cohort / File(s) Summary
Folder Search Data
lib/swr/use-documents.ts, pages/api/teams/[teamId]/documents/index.ts
Introduces new FolderWithCountAndPath type combining folder metadata with parent path list; API endpoint implements folder search with case-insensitive matching, parent path resolution, and conditional response to include matching folders when search query is present.
Folder Components & UI
components/documents/documents-list.tsx, components/documents/folder-card.tsx, components/documents/pagination.tsx
Updates DocumentsList and FolderCard to accept FolderWithCountAndPath; FolderCard now renders horizontal breadcrumb trail with folder icons and links when search query is active; Pagination adds optional extraInfo property to display search folder counts.
Search Results Integration
pages/documents/index.tsx
Consumes searchFolders from hook return; conditionally displays search results using searchFolders instead of empty array when filtered; passes extraInfo to Pagination showing matching folder count and plurality; controls folder loading state based on filter status.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'All documents folder paths' is directly related to the main change: adding folder names and their paths to search results and displaying breadcrumb paths on folder cards.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
components/documents/folder-card.tsx (1)

71-74: Unused variable sortQuery.

The sortQuery variable is extracted from query params but never used in this component.

🧹 Remove unused variable
   const router = useRouter();
   const queryParams = router.query;
   const searchQuery = queryParams["search"];
-  const sortQuery = queryParams["sort"];
   const folderList = "folderList" in folder ? folder.folderList : undefined;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/documents/folder-card.tsx` around lines 71 - 74, The variable
sortQuery is extracted from router.query but not used; remove the unused
declaration to satisfy linting and reduce clutter by deleting the line that
assigns sortQuery (the const sortQuery = queryParams["sort"]; statement) in the
component where router.query and searchQuery are handled (leave router.query and
searchQuery intact and keep folderList logic as-is).
pages/api/teams/[teamId]/documents/index.ts (2)

281-307: N+1 query pattern for parent folder lookups.

Each matching folder triggers a separate query to fetch its parent path hierarchy. For searches returning many folders, this could impact performance.

Consider batching: collect all unique parent paths from all matching folders first, then fetch them in a single query, and map results back to each folder.

⚡ Batch parent folder lookups
+      // Collect all unique parent paths across all folders
+      const allParentPaths = new Set<string>();
+      for (const folder of folders) {
+        const parentPath = folder.path.substring(0, folder.path.lastIndexOf("/"));
+        if (parentPath) {
+          const pathSegments = parentPath.split("/").filter(Boolean);
+          for (let i = 0; i < pathSegments.length; i++) {
+            allParentPaths.add("/" + pathSegments.slice(0, i + 1).join("/"));
+          }
+        }
+      }
+
+      // Single query for all parent folders
+      const allParentFolders = allParentPaths.size > 0
+        ? await prisma.folder.findMany({
+            where: { teamId, path: { in: Array.from(allParentPaths) } },
+            select: { path: true, name: true },
+          })
+        : [];
+      const parentFolderMap = new Map(allParentFolders.map((f) => [f.path, f.name]));
+
+      // Build folderList for each folder using the map
       matchingFolders = folders.map((folder) => {
-        // ... async parent lookup
+        const folderNames: string[] = [];
+        const parentPath = folder.path.substring(0, folder.path.lastIndexOf("/"));
+        if (parentPath) {
+          const pathSegments = parentPath.split("/").filter(Boolean);
+          for (let i = 0; i < pathSegments.length; i++) {
+            const segmentPath = "/" + pathSegments.slice(0, i + 1).join("/");
+            const name = parentFolderMap.get(segmentPath);
+            if (name) folderNames.push(name);
+          }
+        }
+        return { ...folder, folderList: folderNames };
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pages/api/teams/`[teamId]/documents/index.ts around lines 281 - 307, The
current folders.map block causes an N+1 query pattern by calling
prisma.folder.findMany for each folder to fetch parentPaths; instead, gather all
unique parentPaths for every folder (use the same parentPath split logic to
produce parentPaths arrays and flatten+dedupe), run a single
prisma.folder.findMany({ where: { teamId, path: { in: allParentPaths } },
select: { path, name } }) to fetch all parent folders, then build a lookup map
from path to name and map those names back into each original folder to set
folderList (replace the per-folder prisma call inside the matchingFolders
computation with the batched query + mapping).

251-251: Avoid any[] type for better type safety.

Using any[] loses type information. Consider defining or reusing a proper type.

🛡️ Add explicit typing
-      let matchingFolders: any[] = [];
+      let matchingFolders: Array<{
+        id: string;
+        name: string;
+        path: string;
+        parentId: string | null;
+        _count: { documents: number; childFolders: number };
+        folderList: string[];
+        [key: string]: unknown;
+      }> = [];

Alternatively, import and extend FolderWithCount from the types if available server-side.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pages/api/teams/`[teamId]/documents/index.ts at line 251, The variable
matchingFolders is typed as any[] which loses type safety; change it to a
concrete folder type by importing or defining the appropriate type (e.g.,
FolderWithCount or an interface matching the folder shape) and declare
matchingFolders with that type (for example: let matchingFolders:
FolderWithCount[] = [];), then update any downstream uses to respect the new
properties (or narrow types) and add/adjust imports for the type in the file; if
a server-side type isn’t available, create a local interface (e.g., interface
FolderWithCount { id: string; name: string; documentCount: number; /*...*/ })
and use that instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@components/documents/folder-card.tsx`:
- Around line 71-74: The variable sortQuery is extracted from router.query but
not used; remove the unused declaration to satisfy linting and reduce clutter by
deleting the line that assigns sortQuery (the const sortQuery =
queryParams["sort"]; statement) in the component where router.query and
searchQuery are handled (leave router.query and searchQuery intact and keep
folderList logic as-is).

In `@pages/api/teams/`[teamId]/documents/index.ts:
- Around line 281-307: The current folders.map block causes an N+1 query pattern
by calling prisma.folder.findMany for each folder to fetch parentPaths; instead,
gather all unique parentPaths for every folder (use the same parentPath split
logic to produce parentPaths arrays and flatten+dedupe), run a single
prisma.folder.findMany({ where: { teamId, path: { in: allParentPaths } },
select: { path, name } }) to fetch all parent folders, then build a lookup map
from path to name and map those names back into each original folder to set
folderList (replace the per-folder prisma call inside the matchingFolders
computation with the batched query + mapping).
- Line 251: The variable matchingFolders is typed as any[] which loses type
safety; change it to a concrete folder type by importing or defining the
appropriate type (e.g., FolderWithCount or an interface matching the folder
shape) and declare matchingFolders with that type (for example: let
matchingFolders: FolderWithCount[] = [];), then update any downstream uses to
respect the new properties (or narrow types) and add/adjust imports for the type
in the file; if a server-side type isn’t available, create a local interface
(e.g., interface FolderWithCount { id: string; name: string; documentCount:
number; /*...*/ }) and use that instead.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 86af3754-4d4f-4fdb-aec6-1dac011c85db

📥 Commits

Reviewing files that changed from the base of the PR and between 7e3dc31 and 1976b9f.

📒 Files selected for processing (6)
  • components/documents/documents-list.tsx
  • components/documents/folder-card.tsx
  • components/documents/pagination.tsx
  • lib/swr/use-documents.ts
  • pages/api/teams/[teamId]/documents/index.ts
  • pages/documents/index.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants