feat(studio): paginate Tables list with server-side search (#46514)

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Feature / performance improvement.

## What is the current behavior?

The Database > Tables list renders every table for the selected schema
in a single `useTablesQuery({ includeColumns: true })` fetch.

## What is the new behavior?

- Database > Tables list uses `useInfiniteTablesQuery` with a 50-row
page size, streaming pages as the user scrolls.
- An `IntersectionObserver` sentinel attached to the footer status row
triggers `fetchNextPage()` while `hasNextPage` is true; the same row
doubles as the table count / loading indicator.
- Search is debounced (300 ms) and passed as `nameFilter` to the hook,
which forwards it to pg-meta's `getTablesPaginatedSql`. The backend
returns only matching rows, so search works across the whole schema
rather than only the loaded pages.

## Additional context

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Debounced search filtering for tables
  * Infinite-scroll pagination with sentinel-driven loading
  * Footer shows “Loading more tables…” and dynamic table counts

* **Bug Fixes**
* Ensure table list refresh after create/duplicate by invalidating
infinite-list cache

* **Tests**
* Updated end-to-end waits and helpers to match the new paginated
table-loading API
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Charis authored and GitHub committed 2026-06-02 16:41:52 -04:00
1 parent 0da841321f
commit 4ae803c3d7
4 files changed
+51 -27

No files matched your search

+4 -5
View File
@@ -232,7 +232,7 @@ test.describe('Database', () => {
page,
'pg-meta',
ref,
'tables?include_columns=true&included_schemas=public'
'query?key=project:default-schema:public-infinite_tables'
)
await page.goto(toUrl(`/project/${env.PROJECT_REF}/database/tables?schema=public`))
await wait
@@ -256,7 +256,7 @@ test.describe('Database', () => {
page,
'pg-meta',
ref,
'tables?include_columns=true&included_schemas=auth'
'query?key=project:default-schema:auth-infinite_tables'
)
await page.getByRole('option', { name: 'auth' }).click()
await authSchemaWait
@@ -293,7 +293,7 @@ test.describe('Database', () => {
page,
'pg-meta',
ref,
'tables?include_columns=true&included_schemas=public'
'query?key=project:default-schema:public-infinite_tables'
)
await page.goto(toUrl(`/project/${env.PROJECT_REF}/database/tables?schema=public`))
// Wait for database tables to be populated
@@ -313,7 +313,6 @@ test.describe('Database', () => {
// validate table creation
await createTableWait
await waitForDatabaseToLoad(page, ref)
await expect(page.getByRole('dialog')).not.toBeVisible()
await expect(page.getByText(databaseTableNameNew, { exact: true })).toBeVisible()
@@ -435,7 +434,7 @@ test.describe('Database', () => {
page,
'pg-meta',
ref,
'tables?include_columns=true&included_schemas=public'
'query?key=project:default-schema:public-infinite_tables'
)
await page.goto(toUrl(`/project/${env.PROJECT_REF}/database/tables?schema=public`))
+1 -1
View File
@@ -109,7 +109,7 @@ export async function waitForDatabaseToLoad(page: Page, ref: string, schema?: st
page,
'pg-meta',
ref,
`tables?include_columns=true&included_schemas=${databaseSchema}`
`query?key=project:default-schema:${databaseSchema}-infinite_tables`
)
}