Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/studio-lint-ratchet-decrease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
git add apps/studio/.github/eslint-rule-baselines.json
git commit --message "chore: decrease ESLint ratchet baselines"
git push --force origin "$BRANCH"
git -c credential.helper= push --force "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${BRANCH}"
pr_url=$(gh pr list --state open --head "$BRANCH" --json url --jq '.[0].url // ""' 2>/dev/null || echo "")
if [ -z "$pr_url" ]; then
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/public/humans.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,15 @@ Mats Kindahl
Mert Yerekapan
Michal Kleczek
Michelle Jubrey
Miranda Limonczenko
Monica Khoury
Mykhailo Mischa Lieibenson
Natalie Roberge
Nick B
Nick Littman
Nick Nowlan
Nicolas Nosenzo
Noah Moss
Nyannyacha
Oli R
Pamela Chia
Expand Down
61 changes: 40 additions & 21 deletions apps/studio/components/interfaces/Database/Tables/TableList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { useDebounce, useIntersectionObserver } from '@uidotdev/usehooks'
import { useParams } from 'common'
import { noop } from 'lodash'
import { Check, Copy, Edit, Eye, Filter, MoreVertical, Plus, Search, Trash, X } from 'lucide-react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { parseAsString, useQueryState } from 'nuqs'
import { useRef, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import {
Button,
Card,
Expand Down Expand Up @@ -47,7 +48,7 @@ import { ENTITY_TYPE } from '@/data/entity-types/entity-type-constants'
import { useForeignTablesQuery } from '@/data/foreign-tables/foreign-tables-query'
import { useMaterializedViewsQuery } from '@/data/materialized-views/materialized-views-query'
import { usePrefetchEditorTablePage } from '@/data/prefetchers/project.$ref.editor.$id'
import { useTablesQuery } from '@/data/tables/tables-query'
import { useInfiniteTablesQuery } from '@/data/tables/tables-query'
import { useViewsQuery } from '@/data/views/views-query'
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
import { useQuerySchemaState } from '@/hooks/misc/useSchemaQueryState'
Expand Down Expand Up @@ -80,6 +81,7 @@ export const TableList = ({
const { selectedSchema, setSelectedSchema } = useQuerySchemaState()

const [filterString, setFilterString] = useQueryState('search', parseAsString.withDefault(''))
const debouncedFilterString = useDebounce(filterString, 300)
const [visibleTypes, setVisibleTypes] = useState<string[]>(Object.values(ENTITY_TYPE))
const [schemaSelectorOpen, setSchemaSelectorOpen] = useState(false)
const searchInputRef = useRef<HTMLInputElement>(null)
Expand All @@ -90,27 +92,40 @@ export const TableList = ({
)

const {
data: tables,
data: tablesData,
error: tablesError,
isError: isErrorTables,
isPending: isLoadingTables,
isSuccess: isSuccessTables,
} = useTablesQuery(
{
projectRef: project?.ref,
connectionString: project?.connectionString,
schema: selectedSchema,
sortByProperty: 'name',
includeColumns: true,
},
{
select(tables) {
return filterString.length === 0
? tables
: tables.filter((table) => table.name.toLowerCase().includes(filterString.toLowerCase()))
},
hasNextPage: hasNextTablesPage,
isFetchingNextPage: isFetchingNextTablesPage,
fetchNextPage: fetchNextTablesPage,
} = useInfiniteTablesQuery({
projectRef: project?.ref,
connectionString: project?.connectionString,
schema: selectedSchema,
includeColumns: true,
pageSize: 50,
nameFilter: debouncedFilterString,
})

const tables = tablesData?.pages.flat() ?? []

const [sentinelRef, sentinelEntry] = useIntersectionObserver({
threshold: 0,
rootMargin: '200px 0px 200px 0px',
})

useEffect(() => {
if (sentinelEntry?.isIntersecting && hasNextTablesPage && !isFetchingNextTablesPage) {
fetchNextTablesPage()
}
)
}, [
sentinelEntry?.isIntersecting,
hasNextTablesPage,
isFetchingNextTablesPage,
fetchNextTablesPage,
])

const {
data: views,
Expand Down Expand Up @@ -589,9 +604,13 @@ export const TableList = ({
</>
</TableBody>
<TableFooter className="font-normal">
<TableRow className="border-b-0 [&>td]:hover:bg-inherit">
<TableCell colSpan={7} className="text-foreground-muted">
{entities.length} {entities.length === 1 ? 'table' : 'tables'}
<TableRow ref={sentinelRef} className="border-b-0">
<TableCell colSpan={7} className="text-foreground-muted hover:bg-inherit">
{isFetchingNextTablesPage
? 'Loading more tables…'
: `${entities.length} ${entities.length === 1 ? 'table' : 'tables'}${
hasNextTablesPage ? ' loaded' : ''
}`}
</TableCell>
</TableRow>
</TableFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,9 @@ export const SidePanelEditor = ({
queryClient.invalidateQueries({
queryKey: tableKeys.list(project?.ref, table.schema, includeColumns),
}),
queryClient.invalidateQueries({
queryKey: tableKeys.infiniteListPrefix(project?.ref, table.schema),
}),
queryClient.invalidateQueries({
queryKey: entityTypeKeys.list(project?.ref),
}),
Expand Down Expand Up @@ -782,6 +785,9 @@ export const SidePanelEditor = ({
queryClient.invalidateQueries({
queryKey: tableKeys.list(project?.ref, table.schema, includeColumns),
}),
queryClient.invalidateQueries({
queryKey: tableKeys.infiniteListPrefix(project?.ref, table.schema),
}),
queryClient.invalidateQueries({ queryKey: entityTypeKeys.list(project?.ref) }),
queryClient.invalidateQueries({
queryKey: privilegeKeys.tablePrivilegesList(project?.ref),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'

import { customProviderAdminRequest } from './custom-provider-admin-request'
import { oAuthCustomProvidersKeys } from './keys'
import { handleError } from '@/data/fetchers'
import { createProjectSupabaseClient } from '@/lib/project-supabase-client'
import type { ResponseError, UseCustomMutationOptions } from '@/types'

export type OAuthCustomProviderDeleteVariables = {
Expand All @@ -20,12 +21,10 @@ export async function deleteOAuthCustomProvider({
if (!clientEndpoint) throw new Error('Client endpoint is required')
if (!identifier) throw new Error('Provider identifier is required')

await customProviderAdminRequest({
method: 'DELETE',
projectRef,
clientEndpoint,
identifier,
})
const supabaseClient = await createProjectSupabaseClient(projectRef, clientEndpoint)
const { error } = await supabaseClient.auth.admin.customProviders.deleteProvider(identifier)

if (error) handleError(error)
return null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { UpdateCustomProviderParams } from '@supabase/auth-js'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'

import { customProviderAdminRequest } from './custom-provider-admin-request'
import { oAuthCustomProvidersKeys } from './keys'
import { handleError } from '@/data/fetchers'
import { createProjectSupabaseClient } from '@/lib/project-supabase-client'
import type { ResponseError, UseCustomMutationOptions } from '@/types'

export type OAuthCustomProviderUpdateVariables = UpdateCustomProviderParams & {
Expand All @@ -22,13 +23,14 @@ export async function updateOAuthCustomProvider({
if (!clientEndpoint) throw new Error('Client endpoint is required')
if (!identifier) throw new Error('Provider identifier is required')

return customProviderAdminRequest({
method: 'PUT',
projectRef,
clientEndpoint,
const supabaseClient = await createProjectSupabaseClient(projectRef, clientEndpoint)
const { data, error } = await supabaseClient.auth.admin.customProviders.updateProvider(
identifier,
body: params,
})
params
)

if (error) handleError(error)
return data!
}

type OAuthCustomProviderUpdateData = Awaited<ReturnType<typeof updateOAuthCustomProvider>>
Expand Down
9 changes: 4 additions & 5 deletions e2e/studio/features/database.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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`))

Expand Down
2 changes: 1 addition & 1 deletion e2e/studio/utils/wait-for-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`
)
}

Expand Down
Loading