feat(storage): paginate remote storage listings with a "Load more" button#9834
feat(storage): paginate remote storage listings with a "Load more" button#9834Light2Dark wants to merge 3 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
2 issues found across 15 files
Architecture diagram
sequenceDiagram
participant User
participant UI as Storage Inspector (React)
participant State as Jotai State (Atom/Reducer)
participant Backend as Runtime Commands
participant Storage as Storage Backend (Obstore/Fsspec)
participant External as Object Store (S3/GCS/...)
Note over UI,External: Paginated storage listing flow (NEW)
UI->>State: useStorageEntries(namespace, prefix)
State-->>UI: cached entries & pageMetadata (if any)
alt Cache miss (first fetch)
UI->>Backend: ListStorageEntries (pageToken: null)
Backend->>Storage: list_entries(limit=150, page_token=None)
Storage->>External: list entries (e.g., list_with_delimiter)
External-->>Storage: raw entries (may be provider-truncated)
alt Obstore: result length >= 1000
Storage->>Storage: set may_have_more=true (provider limit)
end
Storage-->>Backend: StorageListResult(entries, next_page_token, may_have_more)
Backend-->>UI: StorageEntriesNotification(entries, next_page_token, may_have_more)
UI->>State: setEntries({entries, nextPageToken, mayHaveMore, append: false})
State-->>UI: entriesByPath + pageMetadataByPath updated
end
UI->>UI: Render entries + "Load more" button (if next_page_token != null)
UI->>UI: Render "More files may exist" hint (if may_have_more && !next_page_token)
User->>UI: Click "Load more"
UI->>UI: loadMore() – guard: skip if isLoadingMoreRef or no token
UI->>Backend: ListStorageEntries (pageToken: next_page_token)
Backend->>Storage: list_entries(limit=150, page_token)
Storage->>Storage: slice entries[offset:offset+limit]
Storage-->>Backend: StorageListResult(new_entries, new_next_page_token, may_have_more)
Backend-->>UI: StorageEntriesNotification(new_entries, new_next_page_token, ...)
UI->>State: setEntries({append: true, entries: new_entries, nextPageToken, mayHaveMore})
State-->>UI: entries appended, pageMetadata updated
UI->>UI: Re-render button (hidden if new_next_page_token null)
UI->>UI: Show "More files may exist" if applicable
opt Error during loadMore
UI->>UI: setLoadMoreError(error)
UI->>UI: Display error message next to button
end
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…tton Thread page tokens through the storage backends, runtime command, and notification, and surface a "Load more" control (plus a "may have more" hint when a provider truncates a listing) in the storage inspector. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fe2773c to
e446002
Compare
… more" tooltip - loadMore now guards on `nextPageToken == null` instead of falsy, so an empty-string token (treated as a valid page by hasMore and the page fetcher) is no longer silently dropped. - Make the "More files may exist" info tooltip keyboard-focusable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 3 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
The previous label duplicated the adjacent visible text; give the focusable icon a concise accessible name instead, leaving the detail to the tooltip description. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds end-to-end pagination support for remote storage listings, enabling the frontend storage inspector to fetch additional pages of entries via a “Load more” interaction while also signaling when a provider may have truncated results that cannot be paged further.
Changes:
- Introduces
StorageListResult(entries +next_page_token+may_have_more) and threadspage_tokenthrough backend implementations, runtime command handling, and notifications. - Updates the frontend storage state/hook layer to track pagination metadata per namespace/prefix and append subsequent pages into the cached listing.
- Adds UI affordances in the storage inspector for “Load more” and a “More files may exist” hint, with corresponding test updates.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/_runtime/test_runtime_external_storage.py | Updates runtime storage listing tests to exercise page_token and next_page_token. |
| tests/_data/_external_storage/test_storage_models.py | Updates backend model tests for StorageListResult and adds pagination/may-have-more coverage. |
| packages/openapi/src/api.ts | Extends generated OpenAPI TS types for new pagination fields. |
| packages/openapi/api.yaml | Extends OpenAPI schema for pageToken request field and pagination fields on notifications. |
| marimo/_server/models/models.py | Threads page_token from HTTP request model into the runtime command. |
| marimo/_runtime/commands.py | Adds page_token to StorageListEntriesCommand. |
| marimo/_runtime/callbacks/external_storage.py | Calls backend list_entries(..., page_token=...) and includes pagination metadata in StorageEntriesNotification. |
| marimo/_messaging/notification.py | Adds next_page_token and may_have_more to StorageEntriesNotification. |
| marimo/_data/_external_storage/storage.py | Changes storage backends to return StorageListResult and implements page slicing + “may have more” detection for obstore listings. |
| marimo/_data/_external_storage/models.py | Introduces StorageListResult and updates the StorageBackend.list_entries contract accordingly. |
| frontend/src/core/storage/types.ts | Extends storage state types with per-path pagination metadata. |
| frontend/src/core/storage/state.ts | Implements page fetching/append logic and exposes loadMore and pagination state from useStorageEntries. |
| frontend/src/core/storage/tests/useStorageEntries.test.tsx | Adds coverage for load-more behavior, empty-string page tokens, and duplicate load-more suppression. |
| frontend/src/core/storage/tests/state.test.ts | Adds reducer/state coverage for pagination metadata + append behavior. |
| frontend/src/components/storage/storage-inspector.tsx | Adds “Load more” button and “More files may exist” hint UI using new hook outputs. |
📝 Summary
Split out from #9708. Part of the work for #9662.
Adds pagination to remote storage listings:
page_tokenthrough the storage backends, theStorageListEntriesCommand, and theStorageEntriesNotification.list_entriesnow returns aStorageListResult(entries +next_page_token+may_have_more).Screen.Recording.2026-06-10.at.11.56.00.AM.mov
📋 Pre-Review Checklist
✅ Merge Checklist