mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
feat(studio): paginate Schema Designer via useInfiniteTablesQuery (#46402)
## 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? Performance improvement / feature ## What is the current behavior? The Schema Designer fetches all tables in a single request via `useTablesQuery`. For schemas with 400+ tables this blocks first paint on a large payload. ## What is the new behavior? `SchemaGraph` uses `useInfiniteTablesQuery` (pageSize: 100) so the first 100 tables paint immediately. A "Load more tables" button appears above the legend whenever more pages remain, letting users load the rest on demand. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a "Find table…" selector and keyboard shortcut to quickly locate and focus tables; supports incremental loading and debounced name search (with literal wildcard handling). * Schema Graph shows a bottom "Load more tables" control with loading state and preserves view after loading more. * **Refactor** * Table listing switched to infinite/paginated retrieval and improved "no tables" logic; server-side name filtering supported. * **Tests** * E2E tests add a schema-visualizer wait helper and update flows to support the paginated visualizer. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46402?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
91db2d6989
commit
a4334a2cc7
11 files changed
+394
-43
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { expect, type Page } from '@playwright/test'
|
||||
|
||||
import { env } from '../env.config.js'
|
||||
import { expectClipboardValue } from '../utils/clipboard.js'
|
||||
@@ -10,8 +10,15 @@ import {
|
||||
createApiResponseWaiter,
|
||||
waitForApiResponse,
|
||||
waitForDatabaseToLoad,
|
||||
waitForSchemaVisualizerToLoad,
|
||||
} from '../utils/wait-for-response.js'
|
||||
|
||||
async function focusTableInVisualizer(page: Page, tableName: string) {
|
||||
await page.getByTestId('find-table-selector').click()
|
||||
await page.getByPlaceholder('Find table…').fill(tableName)
|
||||
await page.getByRole('option', { name: tableName, exact: true }).click()
|
||||
}
|
||||
|
||||
test.describe('Database', () => {
|
||||
test.describe('Schema Visualizer', () => {
|
||||
test('actions works as expected', async ({ page, ref }) => {
|
||||
@@ -25,15 +32,19 @@ test.describe('Database', () => {
|
||||
await dropTable(databaseTableName)
|
||||
}
|
||||
)
|
||||
|
||||
const wait = createApiResponseWaiter(
|
||||
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/schemas?schema=public`))
|
||||
await wait
|
||||
|
||||
// focus the test table so it mounts inside the viewport
|
||||
await focusTableInVisualizer(page, databaseTableName)
|
||||
|
||||
// validates table and column exists
|
||||
await expect(page.getByText(databaseTableName, { exact: true })).toBeVisible()
|
||||
await expect(page.getByText(databaseColumnName, { exact: true })).toBeVisible()
|
||||
@@ -69,10 +80,12 @@ test.describe('Database', () => {
|
||||
// changing schema -> auth
|
||||
await page.getByTestId('schema-selector').click()
|
||||
await page.getByRole('option', { name: 'auth' }).click()
|
||||
await waitForDatabaseToLoad(page, ref, 'auth')
|
||||
await expect(page.getByText('users', { exact: true })).toBeVisible()
|
||||
await expect(page.getByText('sso_providers', { exact: true })).toBeVisible()
|
||||
await expect(page.getByText('saml_providers', { exact: true })).toBeVisible()
|
||||
await waitForSchemaVisualizerToLoad(page, ref, 'auth')
|
||||
|
||||
for (const tableName of ['users', 'sso_providers', 'saml_providers']) {
|
||||
await focusTableInVisualizer(page, tableName)
|
||||
await expect(page.getByText(tableName, { exact: true })).toBeVisible()
|
||||
}
|
||||
})
|
||||
|
||||
test('table actions work as expected', async ({ page, ref }) => {
|
||||
@@ -90,11 +103,14 @@ 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/schemas?schema=public`))
|
||||
await wait
|
||||
|
||||
// focus the test table so it mounts inside the viewport
|
||||
await focusTableInVisualizer(page, databaseTableName)
|
||||
|
||||
// validates table and column exists
|
||||
await expect(page.getByText(databaseTableName, { exact: true })).toBeVisible()
|
||||
// test we can edit the column
|
||||
@@ -158,11 +174,14 @@ 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/schemas?schema=public`))
|
||||
await wait
|
||||
|
||||
// focus the test table so it mounts inside the viewport
|
||||
await focusTableInVisualizer(page, databaseTableName)
|
||||
|
||||
// validates table and column exists
|
||||
await expect(page.getByText(databaseTableName, { exact: true })).toBeVisible()
|
||||
await expect(page.getByText(databaseColumnName, { exact: true })).toBeVisible()
|
||||
|
||||
Reference in new issue
Block a user