Improve workspace page browsing#16
Conversation
Greptile SummaryThis PR adds scope-based workspace page browsing (Recently Updated, Favorites, Created by Me) to
Confidence Score: 5/5Safe to merge; scope-switching and the new endpoint are well-guarded against races and offline conditions, all previously flagged issues are resolved, and unit tests cover all three scopes. The docmostly/Features/PageTree/PageBrowserViewModel.swift — a one-line fix to clear Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User taps scope tab] --> B[selectedScope changes]
B --> C[pageBrowserTaskKey recomputes]
C --> D[SwiftUI cancels old task, starts new .task]
D --> E[refreshBrowser calls browserViewModel.load]
E --> F[isLoading = true, items cleared, errorMessage = nil]
F --> G{apiClient available?}
G -- No --> H[createdCachedPages / recentCachedPages / throw]
G -- Yes --> I[API call: loadRecentPages / loadFavorites / loadCreatedByPages]
I -- Success --> J{activeLoadID == loadID AND selectedScope == requestedScope?}
I -- Error --> K{canUseOfflineCache?}
K -- Yes --> H
K -- No --> L[throw error]
J -- No --> M[Discard result, return]
J -- Yes --> N[items = loadedItems, isLoading = false]
H --> N
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[User taps scope tab] --> B[selectedScope changes]
B --> C[pageBrowserTaskKey recomputes]
C --> D[SwiftUI cancels old task, starts new .task]
D --> E[refreshBrowser calls browserViewModel.load]
E --> F[isLoading = true, items cleared, errorMessage = nil]
F --> G{apiClient available?}
G -- No --> H[createdCachedPages / recentCachedPages / throw]
G -- Yes --> I[API call: loadRecentPages / loadFavorites / loadCreatedByPages]
I -- Success --> J{activeLoadID == loadID AND selectedScope == requestedScope?}
I -- Error --> K{canUseOfflineCache?}
K -- Yes --> H
K -- No --> L[throw error]
J -- No --> M[Discard result, return]
J -- Yes --> N[items = loadedItems, isLoading = false]
H --> N
Reviews (5): Last reviewed commit: "Avoid full tree reloads on page filter c..." | Re-trigger Greptile |
| icon = favorite.page?.icon | ||
| spaceId = favorite.page?.spaceId ?? favorite.spaceId | ||
| subtitle = fallbackSpaceName | ||
| updatedAt = favorite.createdAt |
There was a problem hiding this comment.
Favorites
updatedAt reflects favorited-at, not page updated-at
updatedAt is set to favorite.createdAt — the moment the user saved the favorite — rather than when the page itself was last changed. PageBrowserRowView surfaces this date unlabelled next to the space name, so users scanning the Favorites list will read "Yesterday" as the page modification time when it is actually the bookmark creation time. Either use favorite.page?.updatedAt (when available) or omit the date entirely for the favorites path.
| updatedAt = favorite.createdAt | |
| updatedAt = favorite.page?.updatedAt ?? favorite.createdAt |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ecc137c04f
ℹ️ 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".
| ForEach(browserViewModel.items) { item in | ||
| NavigationLink(value: item) { | ||
| PageBrowserRowView(item: item) | ||
| } |
There was a problem hiding this comment.
Restore the full page tree in spaces
In the iOS/iPad space content route, MainShellContentView still instantiates PageTreeView, but this view now renders only browserViewModel.items from the recent/favorites/created-by-me loaders and no longer calls loadRoot; I also checked that the remaining PageTreeNodeView usage is macOS-only. This means any accessible page in the selected space that is not recent, favorited, or created by the current user disappears from the space browser, so users can no longer browse much of a workspace's nested page hierarchy from iPhone/iPad.
Useful? React with 👍 / 👎.
| cursor: nil, | ||
| limit: Self.defaultPageLimit | ||
| ) | ||
| items = response.items.map { PageBrowserItem(page: $0, fallbackSpaceName: space.name) } |
There was a problem hiding this comment.
When the user switches from Recently Updated to Favorites/Created by Me before the recent request returns, this assignment still writes the older response after the await. PageTreeView cancels and restarts the task on scope changes, but AppState treats non-HTTP errors such as cancellation as cache-eligible, so the canceled recent load can still return cached/recent items and overwrite the newly selected tab. Capture the requested scope/token and ignore cancellation or stale completions before mutating items.
Useful? React with 👍 / 👎.
| moveToSpace: beginMoveToSpace, | ||
| delete: deletePage | ||
| ForEach(browserViewModel.items) { item in | ||
| NavigationLink(value: item) { |
There was a problem hiding this comment.
Preserve page row management actions
On iOS/iPad, these rows now use PageBrowserRowView instead of PageTreeNodeView, but the new row has no context menu or callbacks for New subpage, Duplicate, Move to Space, or Move to Trash. I checked the page/space feature files and the only remaining menu with those actions is on PageTreeNodeView, which is now only reached from the macOS sidebar, so visible pages in the mobile/tablet space browser can no longer be managed from their rows.
Useful? React with 👍 / 👎.
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
Summary
Verification