fix: split display path and query base path#714
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4020c536c7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
4020c53 to
187030d
Compare
187030d to
28d5c05
Compare
444f3bd to
e79b733
Compare
e79b733 to
a7c6808
Compare
2fa22a3 to
48a55c0
Compare
|
Related Documentation 1 document(s) may need updating based on files changed in this PR: Zerobyte's Space Repositories in Zerobyte: Types, Architecture, and OperationsView Suggested Changes@@ -341,6 +341,10 @@
- [List snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L222-L252)
- [Get snapshot details](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L388-L418)
- [Browse files](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L254-L317)
+ - The snapshot tree browser in the UI distinguishes between "query base path" (the actual path queried from the snapshot API) and "display base path" (the path shown to users in the UI)
+ - This split allows showing a different root directory to users than what is actually being queried from the snapshot
+ - Example use case: querying files from a deep subdirectory while displaying them as if they're at the root of a volume mount point
+ - The file tree building logic ensures all parent directories are properly created in the tree structure, preventing gaps in the folder hierarchy
- [Delete snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L515-L531)
- [Tag snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L553-L575)
- [Download snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L394-L451)
@@ -357,6 +361,10 @@
- `targetPath`: Custom location for restore
- `overwrite`: Overwrite mode for existing files (`'always'`, `'if-changed'`, `'if-newer'`, or `'never'`)
- Single-file restore behavior: When restoring a single file to a custom location with `selectedItemKind: "file"`, the system uses the file's parent directory as the common ancestor for proper path resolution, ensuring the file is placed correctly at the target path
+ - **Path handling in restore form**: The restore form accepts two path parameters:
+ - `queryBasePath`: The actual path used for API queries when browsing snapshot contents
+ - `displayBasePath`: Optional path prefix shown to users in the file browser. If not provided, defaults to `queryBasePath`
+ - This allows flexible path presentation during restore operations (e.g., showing files as if they're at a volume root while querying from a subdirectory)
- **Protected path restrictions**: To prevent accidental overwriting of critical system files or application data, restore operations are blocked from targeting certain protected paths. If a restore is attempted to any of these locations, the operation will fail with a `BadRequestError: "Restore target path is not allowed. Restoring to this path could overwrite critical system files or application data."` The following paths and their subdirectories are protected from restore operations:
- Repository base directory (`/var/lib/zerobyte/repositories`)
- Restic cache directory (`/var/lib/zerobyte/cache`)
@@ -583,3 +591,30 @@
This visual feedback helps users understand the path handling behavior before creating or importing a repository.
+### SnapshotTreeBrowser
+The `SnapshotTreeBrowser` component provides a file browser interface for exploring snapshot contents.
+
+**Location:** `app/client/components/file-browsers/snapshot-tree-browser.tsx`
+
+**Path Handling:**
+- `queryBasePath`: The actual path used when fetching files from the API (defaults to `/`)
+- `displayBasePath`: Optional path prefix for display purposes. If not provided, defaults to `queryBasePath`
+- The component properly displays ancestor folders in the tree even when they weren't explicitly returned by the API
+- This enables flexible presentation where the query path differs from the displayed path (e.g., querying from `/var/data` while displaying paths as if they start from `/`)
+
+**Usage:**
+The component is used in both snapshot browsing and restore operations, allowing users to navigate snapshot contents with appropriate path context based on the use case.
+
+### RestoreForm
+The `RestoreForm` component provides the interface for restoring files from snapshots.
+
+**Location:** `app/client/components/restore-form.tsx`
+
+**Path Parameters:**
+- `queryBasePath`: The actual path used for API queries when browsing snapshot contents (defaults to `/`)
+- `displayBasePath`: Optional path prefix shown to users in the file browser. If not provided, defaults to `queryBasePath`
+- These parameters are passed through to the `SnapshotTreeBrowser` component for consistent path handling
+
+**Path Presentation:**
+The split between query and display paths enables flexible path presentation during restore operations. For example, when restoring a backup of `/var/data`, the form can query from `/var/data` while displaying paths as if they're at the root of a volume mount point, improving user experience by showing familiar paths.
+Note: You must be authenticated to accept/decline updates. |
|
Documentation Updates 1 document(s) were updated by changes in this PR: Repositories in Zerobyte: Types, Architecture, and OperationsView Changes@@ -340,7 +340,10 @@
**Snapshot Management:**
- [List snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L222-L252)
- [Get snapshot details](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L388-L418)
-- [Browse files](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L254-L317)
+- [Browse files](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L254-L317) - The `SnapshotTreeBrowser` component provides snapshot browsing functionality with path handling that separates display and query concerns:
+ - `queryBasePath`: The path used for API queries to fetch snapshot files (typically the common ancestor of snapshot paths)
+ - `displayBasePath`: The path prefix used for displaying file paths in the UI (typically the volume mount path)
+ - This separation allows proper rendering of ancestor folders when browsing snapshots with a nested query root - the display path can show the full hierarchy while queries are scoped to a specific subtree
- [Delete snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L515-L531)
- [Tag snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L553-L575)
- [Download snapshots](https://github.com/nicotsx/zerobyte/blob/bad944a2329540088a51f7699d6f53d9ac82137c/app/server/modules/repositories/repositories.service.ts#L394-L451)
@@ -357,6 +360,9 @@
- `targetPath`: Custom location for restore
- `overwrite`: Overwrite mode for existing files (`'always'`, `'if-changed'`, `'if-newer'`, or `'never'`)
- Single-file restore behavior: When restoring a single file to a custom location with `selectedItemKind: "file"`, the system uses the file's parent directory as the common ancestor for proper path resolution, ensuring the file is placed correctly at the target path
+ - The `RestoreForm` component accepts both `queryBasePath` and `displayBasePath` parameters for path handling:
+ - `queryBasePath`: The base path for API queries (scoped to snapshot contents)
+ - `displayBasePath`: The path prefix for displaying file paths in the UI
- **Protected path restrictions**: To prevent accidental overwriting of critical system files or application data, restore operations are blocked from targeting certain protected paths. If a restore is attempted to any of these locations, the operation will fail with a `BadRequestError: "Restore target path is not allowed. Restoring to this path could overwrite critical system files or application data."` The following paths and their subdirectories are protected from restore operations:
- Repository base directory (`/var/lib/zerobyte/repositories`)
- Restic cache directory (`/var/lib/zerobyte/cache`) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 48a55c0183
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| nextFullPaths.add(displayPathFns.add(displayPath)); | ||
| } | ||
|
|
||
| if (onSingleSelectionKindChange) { |
There was a problem hiding this comment.
Preserve kind for remapped ancestor selections
With the new display/query path split, users can now select ancestor folders that are synthesized in the tree (for example selecting /project while querying /mnt/project/subdir). In handleSelectionChange this path is remapped to /mnt/project, but onSingleSelectionKindChange still relies on displayPathKinds, which is built only from API-returned entries and does not include synthesized ancestors. That emits null for a single-folder selection, so RestoreForm omits the kind query param on /dump requests and the server rejects the download (Path kind is required when downloading a specific snapshot path) in this new flow.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 48a55c0183
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| fileMap.set(parentPath, { | ||
| kind: "folder", | ||
| id: fileMap.size, | ||
| name: parentName, | ||
| fullPath: parentPath, |
There was a problem hiding this comment.
Propagate kind for synthesized ancestor folders
This change adds virtual ancestor folders (for example, /project) into the tree, but those paths are not present in SnapshotTreeBrowser’s displayPathKinds map because that map is built only from fetched API entries. In the new nested-base flow (queryBasePath under displayBasePath), selecting one of these ancestor rows sets selectedPathKind to null; then the restore page’s download action sends path without kind, and the backend rejects it with 400 Path kind is required. This makes single-item download fail for exactly the ancestor nodes introduced here.
Useful? React with 👍 / 👎.

#709