diff --git a/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx b/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx index 74e4e6c19e1..d87be9046c1 100644 --- a/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx +++ b/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx @@ -38,11 +38,13 @@ import { JsonEditValue } from './SidePanelEditor/RowEditor/RowEditor.types' import { ForeignRowSelectorProps } from './SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector' import TableDefinition from './TableDefinition' import APIDocumentationPanel from './APIDocumentationPanel' +import Connecting from 'components/ui/Loading/Loading' export interface TableGridEditorProps { /** Theme for the editor */ theme?: 'dark' | 'light' + isLoadingSelectedTable?: boolean selectedTable: any // PostgresTable | SchemaView /** Determines what side panel editor to show */ @@ -77,6 +79,7 @@ export interface TableGridEditorProps { const TableGridEditor = ({ theme = 'dark', + isLoadingSelectedTable = false, selectedTable, sidePanelKey, isDuplicating, @@ -202,6 +205,10 @@ const TableGridEditor = ({ const entityType = useEntityType(selectedTable?.id) + if (isLoadingSelectedTable) { + return + } + // NOTE: DO NOT PUT HOOKS AFTER THIS LINE if (isUndefined(selectedTable)) { return diff --git a/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx b/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx index 8ab79999ccf..d27a43a4c85 100644 --- a/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx +++ b/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx @@ -1,21 +1,13 @@ import { PropsWithChildren, useEffect } from 'react' -import { useRouter } from 'next/router' import { noop } from 'lodash' import { observer } from 'mobx-react-lite' import { PermissionAction } from '@supabase/shared-types/out/constants' import { checkPermissions, useStore } from 'hooks' -import { useParams } from 'common/hooks' import { Entity } from 'data/entity-types/entity-type-query' -import { ENTITY_TYPE } from 'data/entity-types/entity-type-constants' -import { useIsTableLoaded, useTableEditorGlobalStateSnapshot } from 'state/table-editor-global' import ProjectLayout from '../' import TableEditorMenu from './TableEditorMenu' import NoPermission from 'components/ui/NoPermission' -import useEntityType from 'hooks/misc/useEntityType' -import Connecting from 'components/ui/Loading/Loading' -import useLatest from 'hooks/misc/useLatest' -import useTableRowsPrefetchWrapper from './TableEditorLayout.utils' export interface TableEditorLayoutProps { onAddTable: () => void @@ -32,11 +24,7 @@ const TableEditorLayout = ({ children, }: PropsWithChildren) => { const { vault, meta, ui } = useStore() - const router = useRouter() - const { ref, id: _id } = useParams() - const id = _id ? Number(_id) : undefined - const snap = useTableEditorGlobalStateSnapshot() const canReadTables = checkPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'tables') const vaultExtension = meta.extensions.byId('supabase_vault') @@ -51,56 +39,6 @@ const TableEditorLayout = ({ } }, [ui.selectedProject?.ref]) - const isLoaded = useIsTableLoaded(ref, id) - - const entity = useEntityType(id, function onNotFound(id) { - if (ref) snap.addLoadedId(ref, id) - }) - - const prefetch = useLatest(useTableRowsPrefetchWrapper()) - - useEffect(() => { - let mounted = true - - function loadTable() { - if (entity?.type) { - switch (entity.type) { - case ENTITY_TYPE.MATERIALIZED_VIEW: - return meta.materializedViews.loadById(entity.id) - - case ENTITY_TYPE.VIEW: - return meta.views.loadById(entity.id) - - case ENTITY_TYPE.FOREIGN_TABLE: - return meta.foreignTables.loadById(entity.id) - - default: - return meta.tables.loadById(entity.id) - } - } - } - - loadTable() - ?.then(async (entity: any) => { - await prefetch.current(entity) - return entity - }) - .then((entity: any) => { - if (mounted && ref) { - snap.addLoadedId(ref, entity.id) - } - }) - .catch(() => { - if (mounted && entity?.id && ref) { - snap.addLoadedId(ref, entity.id) - } - }) - - return () => { - mounted = false - } - }, [entity?.id]) - useEffect(() => { if (isVaultEnabled) { vault.load() @@ -127,7 +65,7 @@ const TableEditorLayout = ({ /> } > - {router.isReady && id !== undefined ? isLoaded ? children : : children} + {children} ) } diff --git a/studio/data/foreign-tables/foreign-table-query.ts b/studio/data/foreign-tables/foreign-table-query.ts new file mode 100644 index 00000000000..b10d74e0928 --- /dev/null +++ b/studio/data/foreign-tables/foreign-table-query.ts @@ -0,0 +1,57 @@ +import { PostgresTable } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { foreignTableKeys } from './keys' + +export type ForeignTableVariables = { + id?: number + projectRef?: string + connectionString?: string +} + +export type ForeignTable = PostgresTable + +export type ForeignTableResponse = ForeignTable | { error?: any } + +export async function getForeignTable( + { id, projectRef, connectionString }: ForeignTableVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + if (!id) { + throw new Error('id is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/foreign-tables?id=${id}`, { + headers: Object.fromEntries(headers), + signal, + })) as ForeignTableResponse + + if ('error' in response) { + throw response.error + } + + return response as PostgresTable +} + +export type ForeignTableData = Awaited> +export type ForeignTableError = unknown + +export const useForeignTableQuery = ( + { projectRef, id }: ForeignTableVariables, + { enabled = true, ...options }: UseQueryOptions = {} +) => + useQuery( + foreignTableKeys.foreignTable(projectRef, id), + ({ signal }) => getForeignTable({ projectRef, id }, signal), + { + enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined', + ...options, + } + ) diff --git a/studio/data/foreign-tables/foreign-tables-query.ts b/studio/data/foreign-tables/foreign-tables-query.ts new file mode 100644 index 00000000000..99ce73a2a0f --- /dev/null +++ b/studio/data/foreign-tables/foreign-tables-query.ts @@ -0,0 +1,49 @@ +import { PostgresTable } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { ForeignTable } from './foreign-table-query' +import { foreignTableKeys } from './keys' + +export type ForeignTablesVariables = { + projectRef?: string + connectionString?: string +} + +export type ForeignTablesResponse = ForeignTable[] | { error?: any } + +export async function getForeignTables( + { projectRef, connectionString }: ForeignTablesVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/foreign-tables`, { + headers: Object.fromEntries(headers), + signal, + })) as ForeignTablesResponse + + if (!Array.isArray(response) && response.error) { + throw response.error + } + + return response as PostgresTable[] +} + +export type ForeignTablesData = Awaited> +export type ForeignTablesError = unknown + +export const useForeignTablesQuery = ( + { projectRef, connectionString }: ForeignTablesVariables, + { enabled = true, ...options }: UseQueryOptions = {} +) => + useQuery( + foreignTableKeys.list(projectRef), + ({ signal }) => getForeignTables({ projectRef, connectionString }, signal), + { enabled: enabled && typeof projectRef !== 'undefined', ...options } + ) diff --git a/studio/data/foreign-tables/keys.ts b/studio/data/foreign-tables/keys.ts new file mode 100644 index 00000000000..869cd2ccfad --- /dev/null +++ b/studio/data/foreign-tables/keys.ts @@ -0,0 +1,5 @@ +export const foreignTableKeys = { + list: (projectRef: string | undefined) => ['projects', projectRef, 'foreignTables'] as const, + foreignTable: (projectRef: string | undefined, id: number | undefined) => + ['projects', projectRef, 'foreignTables', id] as const, +} diff --git a/studio/data/materialized-views/keys.ts b/studio/data/materialized-views/keys.ts new file mode 100644 index 00000000000..6e34f29b960 --- /dev/null +++ b/studio/data/materialized-views/keys.ts @@ -0,0 +1,5 @@ +export const materializedViewKeys = { + list: (projectRef: string | undefined) => ['projects', projectRef, 'materializedViews'] as const, + materializedView: (projectRef: string | undefined, id: number | undefined) => + ['projects', projectRef, 'materializedViews', id] as const, +} diff --git a/studio/data/materialized-views/materialized-view-query.ts b/studio/data/materialized-views/materialized-view-query.ts new file mode 100644 index 00000000000..6efd95ded42 --- /dev/null +++ b/studio/data/materialized-views/materialized-view-query.ts @@ -0,0 +1,60 @@ +import { PostgresMaterializedView } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { materializedViewKeys } from './keys' + +export type MaterializedViewVariables = { + id?: number + projectRef?: string + connectionString?: string +} + +export type MaterializedView = PostgresMaterializedView + +export type MaterializedViewResponse = MaterializedView | { error?: any } + +export async function getMaterializedView( + { id, projectRef, connectionString }: MaterializedViewVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + if (!id) { + throw new Error('id is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/materialized-views?id=${id}`, { + headers: Object.fromEntries(headers), + signal, + })) as MaterializedViewResponse + + if ('error' in response) { + throw response.error + } + + return response as PostgresMaterializedView +} + +export type MaterializedViewData = Awaited> +export type MaterializedViewError = unknown + +export const useMaterializedViewQuery = ( + { projectRef, connectionString, id }: MaterializedViewVariables, + { + enabled = true, + ...options + }: UseQueryOptions = {} +) => + useQuery( + materializedViewKeys.materializedView(projectRef, id), + ({ signal }) => getMaterializedView({ projectRef, connectionString, id }, signal), + { + enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined', + ...options, + } + ) diff --git a/studio/data/materialized-views/materialized-views-query.ts b/studio/data/materialized-views/materialized-views-query.ts new file mode 100644 index 00000000000..5f84c001834 --- /dev/null +++ b/studio/data/materialized-views/materialized-views-query.ts @@ -0,0 +1,52 @@ +import { PostgresMaterializedView } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { materializedViewKeys } from './keys' +import { MaterializedView } from './materialized-view-query' + +export type MaterializedViewsVariables = { + projectRef?: string + connectionString?: string +} + +export type MaterializedViewsResponse = MaterializedView[] | { error?: any } + +export async function getMaterializedViews( + { projectRef, connectionString }: MaterializedViewsVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/materialized-views`, { + headers: Object.fromEntries(headers), + signal, + })) as MaterializedViewsResponse + + if (!Array.isArray(response) && response.error) { + throw response.error + } + + return response as PostgresMaterializedView[] +} + +export type MaterializedViewsData = Awaited> +export type MaterializedViewsError = unknown + +export const useMaterializedViewsQuery = ( + { projectRef, connectionString }: MaterializedViewsVariables, + { + enabled = true, + ...options + }: UseQueryOptions = {} +) => + useQuery( + materializedViewKeys.list(projectRef), + ({ signal }) => getMaterializedViews({ projectRef, connectionString }, signal), + { enabled: enabled && typeof projectRef !== 'undefined', ...options } + ) diff --git a/studio/data/tables/keys.ts b/studio/data/tables/keys.ts new file mode 100644 index 00000000000..f40847ed5a5 --- /dev/null +++ b/studio/data/tables/keys.ts @@ -0,0 +1,5 @@ +export const tableKeys = { + list: (projectRef: string | undefined) => ['projects', projectRef, 'tables'] as const, + table: (projectRef: string | undefined, id: number | undefined) => + ['projects', projectRef, 'tables', id] as const, +} diff --git a/studio/data/tables/table-query.ts b/studio/data/tables/table-query.ts new file mode 100644 index 00000000000..447a371a43d --- /dev/null +++ b/studio/data/tables/table-query.ts @@ -0,0 +1,57 @@ +import { PostgresTable } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { tableKeys } from './keys' + +export type TableVariables = { + id?: number + projectRef?: string + connectionString?: string +} + +export type Table = PostgresTable + +export type TableResponse = Table | { error?: any } + +export async function getTable( + { id, projectRef, connectionString }: TableVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + if (!id) { + throw new Error('id is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/tables?id=${id}`, { + headers: Object.fromEntries(headers), + signal, + })) as TableResponse + + if ('error' in response) { + throw response.error + } + + return response as PostgresTable +} + +export type TableData = Awaited> +export type TableError = unknown + +export const useTableQuery = ( + { projectRef, connectionString, id }: TableVariables, + { enabled = true, ...options }: UseQueryOptions = {} +) => + useQuery( + tableKeys.table(projectRef, id), + ({ signal }) => getTable({ projectRef, connectionString, id }, signal), + { + enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined', + ...options, + } + ) diff --git a/studio/data/tables/tables-query.ts b/studio/data/tables/tables-query.ts new file mode 100644 index 00000000000..c258a168e3b --- /dev/null +++ b/studio/data/tables/tables-query.ts @@ -0,0 +1,49 @@ +import { PostgresTable } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { tableKeys } from './keys' +import { Table } from './table-query' + +export type TablesVariables = { + projectRef?: string + connectionString?: string +} + +export type TablesResponse = Table[] | { error?: any } + +export async function getTables( + { projectRef, connectionString }: TablesVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/tables`, { + headers: Object.fromEntries(headers), + signal, + })) as TablesResponse + + if (!Array.isArray(response) && response.error) { + throw response.error + } + + return response as PostgresTable[] +} + +export type TablesData = Awaited> +export type TablesError = unknown + +export const useTablesQuery = ( + { projectRef, connectionString }: TablesVariables, + { enabled = true, ...options }: UseQueryOptions = {} +) => + useQuery( + tableKeys.list(projectRef), + ({ signal }) => getTables({ projectRef, connectionString }, signal), + { enabled: enabled && typeof projectRef !== 'undefined', ...options } + ) diff --git a/studio/data/views/keys.ts b/studio/data/views/keys.ts new file mode 100644 index 00000000000..943f32500f1 --- /dev/null +++ b/studio/data/views/keys.ts @@ -0,0 +1,5 @@ +export const viewKeys = { + list: (projectRef: string | undefined) => ['projects', projectRef, 'views'] as const, + view: (projectRef: string | undefined, id: number | undefined) => + ['projects', projectRef, 'views', id] as const, +} diff --git a/studio/data/views/view-query.ts b/studio/data/views/view-query.ts new file mode 100644 index 00000000000..7b7b12a4793 --- /dev/null +++ b/studio/data/views/view-query.ts @@ -0,0 +1,57 @@ +import { PostgresView } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { viewKeys } from './keys' + +export type ViewVariables = { + id?: number + projectRef?: string + connectionString?: string +} + +export type View = PostgresView + +export type ViewResponse = View | { error?: any } + +export async function getView( + { id, projectRef, connectionString }: ViewVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + if (!id) { + throw new Error('id is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/views?id=${id}`, { + headers: Object.fromEntries(headers), + signal, + })) as ViewResponse + + if ('error' in response) { + throw response.error + } + + return response as PostgresView +} + +export type ViewData = Awaited> +export type ViewError = unknown + +export const useViewQuery = ( + { projectRef, connectionString, id }: ViewVariables, + { enabled = true, ...options }: UseQueryOptions = {} +) => + useQuery( + viewKeys.view(projectRef, id), + ({ signal }) => getView({ projectRef, connectionString, id }, signal), + { + enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined', + ...options, + } + ) diff --git a/studio/data/views/views-query.ts b/studio/data/views/views-query.ts new file mode 100644 index 00000000000..08300ba9dfd --- /dev/null +++ b/studio/data/views/views-query.ts @@ -0,0 +1,49 @@ +import { PostgresView } from '@supabase/postgres-meta' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { viewKeys } from './keys' +import { View } from './view-query' + +export type ViewsVariables = { + projectRef?: string + connectionString?: string +} + +export type ViewsResponse = View[] | { error?: any } + +export async function getViews( + { projectRef, connectionString }: ViewsVariables, + signal?: AbortSignal +) { + if (!projectRef) { + throw new Error('projectRef is required') + } + + let headers = new Headers() + if (connectionString) headers.set('x-connection-encrypted', connectionString) + + const response = (await get(`${API_URL}/pg-meta/${projectRef}/views`, { + headers: Object.fromEntries(headers), + signal, + })) as ViewsResponse + + if (!Array.isArray(response) && response.error) { + throw response.error + } + + return response as PostgresView[] +} + +export type ViewsData = Awaited> +export type ViewsError = unknown + +export const useViewsQuery = ( + { projectRef, connectionString }: ViewsVariables, + { enabled = true, ...options }: UseQueryOptions = {} +) => + useQuery( + viewKeys.list(projectRef), + ({ signal }) => getViews({ projectRef, connectionString }, signal), + { enabled: enabled && typeof projectRef !== 'undefined', ...options } + ) diff --git a/studio/hooks/misc/useTable.ts b/studio/hooks/misc/useTable.ts new file mode 100644 index 00000000000..505ecf23e95 --- /dev/null +++ b/studio/hooks/misc/useTable.ts @@ -0,0 +1,76 @@ +import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' +import { ENTITY_TYPE } from 'data/entity-types/entity-type-constants' +import { useForeignTableQuery } from 'data/foreign-tables/foreign-table-query' +import { useMaterializedViewQuery } from 'data/materialized-views/materialized-view-query' +import { useTableQuery } from 'data/tables/table-query' +import { useViewQuery } from 'data/views/view-query' +import useEntityType from './useEntityType' + +/** + * A hook that loads all table-like objects. e.g. tables, views, materialized views, etc... + */ +function useTable(id?: number) { + const { project } = useProjectContext() + const entity = useEntityType(id) + + const tableResult = useTableQuery( + { + projectRef: project?.ref, + connectionString: project?.connectionString, + id: entity?.id, + }, + { + enabled: entity?.type === ENTITY_TYPE.TABLE, + } + ) + + const viewResult = useViewQuery( + { + projectRef: project?.ref, + connectionString: project?.connectionString, + id: entity?.id, + }, + { + enabled: entity?.type === ENTITY_TYPE.VIEW, + } + ) + + const materializedViewResult = useMaterializedViewQuery( + { + projectRef: project?.ref, + connectionString: project?.connectionString, + id: entity?.id, + }, + { + enabled: entity?.type === ENTITY_TYPE.MATERIALIZED_VIEW, + } + ) + + const foreignTableResult = useForeignTableQuery( + { + projectRef: project?.ref, + connectionString: project?.connectionString, + id: entity?.id, + }, + { + enabled: entity?.type === ENTITY_TYPE.FOREIGN_TABLE, + } + ) + + switch (entity?.type) { + case ENTITY_TYPE.TABLE: + return tableResult + case ENTITY_TYPE.VIEW: + return viewResult + case ENTITY_TYPE.MATERIALIZED_VIEW: + return materializedViewResult + case ENTITY_TYPE.FOREIGN_TABLE: + return foreignTableResult + default: + // While entity is loading, we can fallback + // to the loading state of the table query. + return tableResult + } +} + +export default useTable diff --git a/studio/pages/project/[ref]/editor/[id].tsx b/studio/pages/project/[ref]/editor/[id].tsx index 3415d635902..93d2646c4fc 100644 --- a/studio/pages/project/[ref]/editor/[id].tsx +++ b/studio/pages/project/[ref]/editor/[id].tsx @@ -1,9 +1,9 @@ import { useQueryClient } from '@tanstack/react-query' -import { useEffect, useState } from 'react' +import { useState } from 'react' import Link from 'next/link' import { useRouter } from 'next/router' import { observer } from 'mobx-react-lite' -import { isUndefined, isNaN } from 'lodash' +import { isUndefined } from 'lodash' import { Alert, Button, Checkbox, IconExternalLink, Modal } from 'ui' import type { PostgresTable, PostgresColumn } from '@supabase/postgres-meta' @@ -25,11 +25,13 @@ import { import { ForeignRowSelectorProps } from 'components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector' import { useTheme } from 'common' import { useTableEditorStateSnapshot } from 'state/table-editor' +import useTable from 'hooks/misc/useTable' const TableEditorPage: NextPageWithLayout = () => { const router = useRouter() const { isDarkMode } = useTheme() - const { id, ref: projectRef } = useParams() + const { id: _id, ref: projectRef } = useParams() + const id = _id ? Number(_id) : undefined const [_, setParams] = useUrlState({ arrayKeys: ['filter', 'sort'] }) const { project } = useProjectContext() @@ -59,28 +61,7 @@ const TableEditorPage: NextPageWithLayout = () => { column: any }>() - const tables: PostgresTable[] = meta.tables.list() - const views: SchemaView[] = meta.views.list() - const materializedViews = meta.materializedViews.list() - const foreignTables: Partial[] = meta.foreignTables.list() - - const selectedTable = !isNaN(Number(id)) - ? // @ts-ignore - tables - // @ts-ignore - .concat(views) - // @ts-ignore - .concat(materializedViews) - // @ts-ignore - .concat(foreignTables) - .find((table) => table.id === Number(id)) - : undefined - - // useEffect(() => { - // if (selectedTable && 'schema' in selectedTable) { - // setSelectedSchema(selectedTable.schema) - // } - // }, [selectedTable?.name]) + const { data: selectedTable, isLoading } = useTable(id) const onAddRow = () => { setSidePanelKey('row') @@ -278,6 +259,7 @@ const TableEditorPage: NextPageWithLayout = () => { onDuplicateTable={onDuplicateTable} >