[FR] Show a "This repository is empty" message in the browse file tree when folder contents is empty
Problem
When a user opens an empty repository in the browse UI, the file-tree panel shows a generic, unhelpful state. For an empty repository at the root path, the panel renders an empty <ScrollArea> with no items and no message — the user can't tell whether the sync is broken or the repo genuinely has no files. For an empty subdirectory (path != ''), the same thing happens. The current "Error loading tree preview" string only fires on actual API failures, not on the empty-list case.
This was reported with screenshots in #821 (Improve UX for empty repositories). The user expected a clear, user-friendly message like "This repository is empty" or "This directory is empty" in the main UI and the file tree panel.
Background
Files affected:
packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanelClient.tsx:38-40 — the empty-list case falls through to the normal render path (PureTreePreviewPanel with an empty items array), which produces a blank scroll area.
packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanel.tsx:14-16 — the getRepoInfoByName service-error path always shows "Error loading tree preview", even when the actual error is a 404 ("Repository not found") which is a different user-facing concern.
packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.tsx — the empty-state could be hoisted here so the panel itself owns the empty message, keeping the client wrapper focused on data fetching.
Current behavior
A user navigates to /browse/<host>/<org>/<empty-repo>@HEAD/-/tree:
treePreviewPanel.tsx calls getRepoInfoByName(repoName). For an indexed-but-empty repo, this returns the repo successfully (the Prisma row exists with indexedAt set).
TreePreviewPanelClient calls getFolderContents({ repoName, revisionName: 'HEAD', path: '' }). For an empty repo, git ls-tree HEAD returns empty output, so the API returns [].
PureTreePreviewPanel is rendered with items={[]}. It renders an empty <ScrollArea> — no message, no items.
Expected behavior
The file-tree panel should show a clear, user-friendly empty-state message:
path === '' and the response is [] → "This repository is empty."
path !== '' and the response is [] → "This directory is empty."
- API error → keep the existing "Error loading tree preview" but distinguish 404 ("Repository not found") from other errors.
Proposed solution
-
In pureTreePreviewPanel.tsx, add an empty-state branch: if items.length === 0, render a centered "This directory is empty." message. The "directory" wording covers both the repo-root case (a repo is a directory of all its files) and the sub-directory case. The root-path wording ("This repository is empty.") is shown by the client wrapper, which has the path and can distinguish.
-
In treePreviewPanelClient.tsx, when the folder-contents response is [] and path === '', render a separate "This repository is empty." message that takes the full panel (no PathHeader, no Separator). This is a more emphatic message than the directory empty-state and avoids showing a path header for a non-existent root.
-
In treePreviewPanel.tsx, when getRepoInfoByName returns a service error with errorCode === 'NOT_FOUND', show "Repository not found." instead of "Error loading tree preview". Other service errors keep the existing message.
Alternatives considered
- Add an
isEmpty boolean to the getRepoInfoByName response. Rejected: isEmpty is a derived property (no files in the root), and the cleanest place to derive it is at the call site that already knows about the folder contents. The DB schema doesn't need to know.
- Add a server-side check in
getFolderContents that returns a distinct error code for empty repos. Rejected: the API already returns an empty array for empty repos, which is the correct semantic. The fix is purely a UI concern.
- Use a single empty-state copy everywhere ("This folder has no items."). Rejected: the user explicitly asked for a distinction between "This repository is empty" and the sub-directory case, which makes the message more actionable for the most common empty-repo case.
Scope
- 2 files modified (
treePreviewPanelClient.tsx, pureTreePreviewPanel.tsx).
- 1 file optionally modified (
treePreviewPanel.tsx) for the 404 distinction — small, but adds a regression test.
- 1 new test file (
pureTreePreviewPanel.test.tsx) with 3 vitest cases.
- No schema, no dependency, no API change.
Acceptance criteria
Backward compatibility
Pure UI change. No API, no schema. The same data flows through the components; only the rendered output changes for the empty case.
Risks
Minimal. The empty-state messages don't conflict with any existing copy. The 404 distinction in treePreviewPanel.tsx is a small win — users who hit a typo in a repo name currently see "Error loading tree preview", which sounds like a system error.
[FR] Show a "This repository is empty" message in the browse file tree when folder contents is empty
Problem
When a user opens an empty repository in the browse UI, the file-tree panel shows a generic, unhelpful state. For an empty repository at the root path, the panel renders an empty
<ScrollArea>with no items and no message — the user can't tell whether the sync is broken or the repo genuinely has no files. For an empty subdirectory (path != ''), the same thing happens. The current "Error loading tree preview" string only fires on actual API failures, not on the empty-list case.This was reported with screenshots in #821 (Improve UX for empty repositories). The user expected a clear, user-friendly message like "This repository is empty" or "This directory is empty" in the main UI and the file tree panel.
Background
Files affected:
packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanelClient.tsx:38-40— the empty-list case falls through to the normal render path (PureTreePreviewPanelwith an emptyitemsarray), which produces a blank scroll area.packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/treePreviewPanel.tsx:14-16— thegetRepoInfoByNameservice-error path always shows "Error loading tree preview", even when the actual error is a 404 ("Repository not found") which is a different user-facing concern.packages/web/src/app/(app)/browse/[...path]/components/treePreviewPanel/pureTreePreviewPanel.tsx— the empty-state could be hoisted here so the panel itself owns the empty message, keeping the client wrapper focused on data fetching.Current behavior
A user navigates to
/browse/<host>/<org>/<empty-repo>@HEAD/-/tree:treePreviewPanel.tsxcallsgetRepoInfoByName(repoName). For an indexed-but-empty repo, this returns the repo successfully (the Prisma row exists withindexedAtset).TreePreviewPanelClientcallsgetFolderContents({ repoName, revisionName: 'HEAD', path: '' }). For an empty repo,git ls-tree HEADreturns empty output, so the API returns[].PureTreePreviewPanelis rendered withitems={[]}. It renders an empty<ScrollArea>— no message, no items.Expected behavior
The file-tree panel should show a clear, user-friendly empty-state message:
path === ''and the response is[]→ "This repository is empty."path !== ''and the response is[]→ "This directory is empty."Proposed solution
In
pureTreePreviewPanel.tsx, add an empty-state branch: ifitems.length === 0, render a centered "This directory is empty." message. The "directory" wording covers both the repo-root case (a repo is a directory of all its files) and the sub-directory case. The root-path wording ("This repository is empty.") is shown by the client wrapper, which has thepathand can distinguish.In
treePreviewPanelClient.tsx, when the folder-contents response is[]andpath === '', render a separate "This repository is empty." message that takes the full panel (noPathHeader, noSeparator). This is a more emphatic message than the directory empty-state and avoids showing a path header for a non-existent root.In
treePreviewPanel.tsx, whengetRepoInfoByNamereturns a service error witherrorCode === 'NOT_FOUND', show "Repository not found." instead of "Error loading tree preview". Other service errors keep the existing message.Alternatives considered
isEmptyboolean to thegetRepoInfoByNameresponse. Rejected:isEmptyis a derived property (no files in the root), and the cleanest place to derive it is at the call site that already knows about the folder contents. The DB schema doesn't need to know.getFolderContentsthat returns a distinct error code for empty repos. Rejected: the API already returns an empty array for empty repos, which is the correct semantic. The fix is purely a UI concern.Scope
treePreviewPanelClient.tsx,pureTreePreviewPanel.tsx).treePreviewPanel.tsx) for the 404 distinction — small, but adds a regression test.pureTreePreviewPanel.test.tsx) with 3 vitest cases.Acceptance criteria
[], the panel shows "This repository is empty." with no path header and no separator.[], the panel shows "This directory is empty." under the path header.Backward compatibility
Pure UI change. No API, no schema. The same data flows through the components; only the rendered output changes for the empty case.
Risks
Minimal. The empty-state messages don't conflict with any existing copy. The 404 distinction in
treePreviewPanel.tsxis a small win — users who hit a typo in a repo name currently see "Error loading tree preview", which sounds like a system error.