Skip to content

feat: show all collections and add reload button in sidebar - #13

Open
EMTumariscal wants to merge 8 commits into
Flowdesktech:masterfrom
EMTumariscal:feat/show-collections
Open

feat: show all collections and add reload button in sidebar#13
EMTumariscal wants to merge 8 commits into
Flowdesktech:masterfrom
EMTumariscal:feat/show-collections

Conversation

@EMTumariscal

Copy link
Copy Markdown
Contributor

Summary

This PR addresses two issues with the Firestore collection list in the sidebar:

  1. Incomplete collection list: projects with more than one page of root collections silently truncated the list because listCollectionIds was called without a pageSize and never followed nextPageToken.
  2. No way to refresh: when collections changed on the Firestore side (new collection created, one removed, etc.) the user had to fully leave and re-enter the project to see the update.

Changes

Fix: list every root and subcollection via pagination

  • Extract the existing listCollectionIds call from googleController.js into a shared helper in recursiveDeleteRest.js that paginates with pageSize: 300 and follows nextPageToken until exhausted.
  • Use the helper from getFirestoreCollections, google:getCollections and google:exportCollections. Error responses from the REST API are now surfaced as ipcResult instead of being swallowed.
  • Cover the root and subcollection paths with two new tests in recursiveDeleteRest.test.js (multi-page tokens + subcollection URL).

Feature: reload collections from the sidebar

  • A small refresh icon button is rendered next to each Firestore database header in SidebarProjectsList (root projects, service-account projects and OAuth accounts).
  • The button calls the new onRefreshFirestoreDatabase(project, firestoreDatabaseId) prop when available, falling back to onRefreshCollections(project) for legacy callers. Both paths stop event propagation so expanding or collapsing the tree is not affected.
  • Tooltip text is "Refresh collections" so the action is self-explanatory. The icon uses the standard RefreshIcon from @mui/icons-material and inherits the existing hover treatment (secondary text colour that turns primary on hover).

Tidy: deterministic collection ordering in the sidebar

  • normalizeCollections now deduplicates by id, guards against non-array and falsy entries, and sorts the resulting list alphabetically. The sidebar shows a stable, predictable order even when the REST response order changes between requests.
  • New regression test loadProjects deduplicates and sorts collections alphabetically pins the new behaviour.

Files changed

File Change
electron/controllers/firestore/recursiveDeleteRest.js listCollectionIds now paginates with pageSize: 300 and follows nextPageToken; supports both root and subcollection paths.
electron/controllers/firestore/recursiveDeleteRest.test.js Two new tests covering pagination and the subcollection URL shape.
electron/controllers/googleController.js All three call sites (getFirestoreCollections, google:getCollections, google:exportCollections) route through listCollectionIds. REST error responses propagate as ipcResult.
src/features/projects/components/ProjectSidebar.tsx Wires onRefreshCollections / onRefreshFirestoreDatabase through to SidebarProjectsList.
src/features/projects/components/sidebar/SidebarProjectsList.tsx Renders the refresh icon button next to each Firestore database header in all three project contexts.
src/features/projects/store/projectsSlice.ts normalizeCollections deduplicates, guards against non-arrays, and sorts alphabetically.
src/features/projects/store/projectsSlice.test.ts Regression test for dedupe + alphabetical sort.

Behavior

  • Projects that previously showed only the first page of collections now show the complete list, with no UI change beyond more entries appearing.
  • The reload button hits the same code path as opening the project, so the user sees the latest collection list without restarting the app.
  • Collection order in the sidebar is now stable and alphabetical, independent of REST response order.
  • No changes to public APIs, no breaking schema changes, and no new dependencies.

Test plan

  • pnpm test — 85 tests pass across 10 test files
  • pnpm lint — clean
  • pnpm typecheck — clean
  • Manual: open a project with more than 300 root collections and confirm every collection is listed
  • Manual: add a collection in the Firebase console, click the new refresh icon, and verify the new entry appears without leaving the project

doc.data() decodes referenceValue fields into DocumentReference
instances that carry the whole Firestore client, which Electron
structured clone rejects with 'An object could not be cloned' in
firestore:getDocuments and firestore:executeJsQuery handlers.

Decode documents through parseFirestoreDocument(doc._fieldsProto) so
references, timestamps and geopoints arrive as plain cloneable values,
matching the googleController REST path. Applies to getDocument, query,
exportCollection, exportCollections, executeJsQuery and the phantom-doc
page loader. Adds a regression test covering reference fields.
The admin SDK exposes timestampValue in _fieldsProto as a
{ seconds, nanos } object from the gRPC binary proto, not the RFC3339
string used by the REST JSON path. Treating the object as a Date made
_seconds NaN, crashing document rendering with 'RangeError: Invalid
time value' in formatDisplayValue.

Handle both shapes so timestamps decode to valid { _seconds,
_nanoseconds } regardless of the source API.
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.

1 participant