Uh oh!
There was an error while loading. Please reload this page.
feat(tables): add export, import column creation, infinite row pagination - #4373
Conversation
…tion - Add `/api/table/[tableId]/export` route streaming CSV/JSON downloads - Rename `/import-csv` route to `/import` and extend to auto-create new columns from unmapped CSV headers via `createColumns` form field - Switch table view to `useInfiniteQuery` so tables larger than 1000 rows fully load; reconcile created rows into the paginated cache so "New row" past 1000 no longer reverts on invalidate - Wire scroll-driven prefetch (600px from bottom) and pre-drain pages before append to keep new-row position consistent - Polish import-csv dialog flow and add Export action to header Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Renames the existing-table CSV import route to Fixes >1000-row table behavior by switching row fetching to Reviewed by Cursor Bugbot for commit 63dc3ab. Configure here. |
Greptile SummaryReview completed and submitted via mcp__greptile-review__submit_review. Confidence Score: 5/5Safe to merge — no blocking defects; all remaining findings are P2 style/edge-case concerns. All P0/P1 issues are absent. Three P2 findings: transient optimistic-UI edge case in reconcileCreatedRow, known offset-pagination snapshot gap in export route, and browser memory concern for large blob downloads. apps/sim/hooks/queries/tables.ts — reconcileCreatedRow page-selection heuristic and downloadTableExport blob buffering. Reviews (4): Last reviewed commit: "fix(table): run batch unique check insid..." | Re-trigger Greptile |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Switch the table query hooks and the import/export routes to the codebase's contract-based request pattern so the API validation audit and boundary policy ratchet pass. - `hooks/queries/tables.ts` now calls every endpoint via `requestJson(contract, ...)`; the only remaining raw `fetch` calls are the streaming export download and the multipart CSV upload, both annotated `boundary-raw-fetch:`. - The import and export routes parse `params`, the `format` query, and the multipart form fields with shared schemas from `@/lib/api/contracts/tables`. Two new contract schemas (`csvImportCreateColumnsSchema`, `tableExportFormatSchema`) cover the fields specific to these routes. - Bumps the audit baseline by one route to account for the new export endpoint.
- Move the `isAppendingRowRef` reset into the create-row mutation's `onSettled` callback. The previous `try/finally` cleared the guard immediately after `mutate()` returned, before the request completed, so a rapid second click on "New row" could fire a duplicate create. - Drop the unused `addTableColumns` wrapper from `lib/table/service`. The CSV import flow only ever uses the transaction-bound `addTableColumnsWithTx`; the standalone wrapper was dead code.
waleedlatif1
commented
May 1, 2026
waleedlatif1
commented
May 1, 2026
@cursor review |
Uh oh!
There was an error while loading. Please reload this page.
`useInfiniteQuery.fetchNextPage()` resolves (rather than rejects) when a page request fails — the resolved value carries `status: 'error'` while `hasNextPage` still reflects the last successful page. The drain loop in `handleAppendRow` relied on a thrown error to bail, so a failed mid-drain fetch could spin indefinitely and leave the append guard stuck on. Re-throw inside `fetchNextPageWrapped` when the result is an error so the caller's `try/catch` runs as intended.
…t of client bundle The client hook `use-table-data.ts` was importing `TABLE_LIMITS` as a value from the `@/lib/table` barrel, which transitively pulls in `service.ts` and the `postgres` driver. Turbopack then tried to bundle `fs`, `net`, `tls`, and `perf_hooks` into the client component graph and the production build failed. Import `TABLE_LIMITS` directly from `@/lib/table/constants` (a pure constants module) and keep the type imports against the barrel.
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6b79524. Configure here.
waleedlatif1
commented
May 1, 2026
waleedlatif1
commented
May 1, 2026
@cursor review |
Uh oh!
There was an error while loading. Please reload this page.
`checkBatchUniqueConstraintsDb` queried the global `db` connection, so inside a single import transaction (one tx wrapping all batches) the constraint lookup couldn't see uncommitted rows from prior batches — duplicates that crossed `CSV_MAX_BATCH_SIZE` boundaries slipped through. Accept an optional executor and pass `trx` from `batchInsertRowsWithTx` so the lookup observes the in-flight transaction state.
waleedlatif1
commented
May 1, 2026
waleedlatif1
commented
May 1, 2026
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 63dc3ab. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
PR #4373 added apps/sim/app/api/table/[tableId]/export/route.ts but didn't update the audit baseline, so unrelated PRs fail check:api-validation:strict. Bump baseline to match current route count.
… builds (#4378) * improvement(workflow): narrow zustand selectors and optimize log tree builds - Add useIsCurrentWorkflowExecuting selector; swap broad useCurrentWorkflowExecution in action-bar/chat - Use useShallow for execution-state subset in useWorkflowExecution - Drop useCallback-wrapped object selectors in diff-controls and use-block-state (use primitive selectors) - Stabilize EMPTY_SUBBLOCK_VALUES constant for empty-workflow selector results in api-info-modal, mcp, tag-dropdown - O(n) Map lookups in buildEntryTree (was O(n^2) filter scans) - Skip expanded-paths reset when structured-output data is content-stable - Extract ReactFlow constants out of workflow.tsx into workflow-constants.ts * fix(workflow): seed structured-output JSON ref and centralize EMPTY_SUBBLOCK_VALUES - Use null sentinel for prevDataJsonRef and lazily stringify prevDataRef on first compare so the optimization holds on the first stream refresh after mount - Export EMPTY_SUBBLOCK_VALUES from the subblock store; remove three duplicated module constants * chore(ci): bump api-validation route baseline to 717 PR #4373 added apps/sim/app/api/table/[tableId]/export/route.ts but didn't update the audit baseline, so unrelated PRs fail check:api-validation:strict. Bump baseline to match current route count.
Summary
/api/table/[tableId]/exportroute streams full table contents as CSV or JSON; wired into the table header as an Export action./import-csv→/import. The dialog now lets users auto-create new columns from unmapped CSV headers (passed via acreateColumnsform field).useInfiniteQuery(1000 rows/page), reconciled created rows into the paginated cache (position bumping + totalCount increment), added scroll-driven prefetch when within 600px of the bottom, and pre-drain pending pages before append so the new row's position stays consistent with the cache.Test plan
invalidate, lands at correct position.