mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
adds react-query queries for table-like objects
This commit is contained in:
1 parent
3b93964cd1
commit
faecbd3736
16 files changed
+541
-88
No files matched your search
@@ -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 <Connecting />
|
||||
}
|
||||
|
||||
// NOTE: DO NOT PUT HOOKS AFTER THIS LINE
|
||||
if (isUndefined(selectedTable)) {
|
||||
return <NotFoundState id={Number(id)} />
|
||||
|
||||
@@ -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<TableEditorLayoutProps>) => {
|
||||
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 : <Connecting /> : children}
|
||||
{children}
|
||||
</ProjectLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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<ReturnType<typeof getForeignTable>>
|
||||
export type ForeignTableError = unknown
|
||||
|
||||
export const useForeignTableQuery = <TData = ForeignTableData>(
|
||||
{ projectRef, id }: ForeignTableVariables,
|
||||
{ enabled = true, ...options }: UseQueryOptions<ForeignTableData, ForeignTableError, TData> = {}
|
||||
) =>
|
||||
useQuery<ForeignTableData, ForeignTableError, TData>(
|
||||
foreignTableKeys.foreignTable(projectRef, id),
|
||||
({ signal }) => getForeignTable({ projectRef, id }, signal),
|
||||
{
|
||||
enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined',
|
||||
...options,
|
||||
}
|
||||
)
|
||||
@@ -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<ReturnType<typeof getForeignTables>>
|
||||
export type ForeignTablesError = unknown
|
||||
|
||||
export const useForeignTablesQuery = <TData = ForeignTablesData>(
|
||||
{ projectRef, connectionString }: ForeignTablesVariables,
|
||||
{ enabled = true, ...options }: UseQueryOptions<ForeignTablesData, ForeignTablesError, TData> = {}
|
||||
) =>
|
||||
useQuery<ForeignTablesData, ForeignTablesError, TData>(
|
||||
foreignTableKeys.list(projectRef),
|
||||
({ signal }) => getForeignTables({ projectRef, connectionString }, signal),
|
||||
{ enabled: enabled && typeof projectRef !== 'undefined', ...options }
|
||||
)
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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<ReturnType<typeof getMaterializedView>>
|
||||
export type MaterializedViewError = unknown
|
||||
|
||||
export const useMaterializedViewQuery = <TData = MaterializedViewData>(
|
||||
{ projectRef, connectionString, id }: MaterializedViewVariables,
|
||||
{
|
||||
enabled = true,
|
||||
...options
|
||||
}: UseQueryOptions<MaterializedViewData, MaterializedViewError, TData> = {}
|
||||
) =>
|
||||
useQuery<MaterializedViewData, MaterializedViewError, TData>(
|
||||
materializedViewKeys.materializedView(projectRef, id),
|
||||
({ signal }) => getMaterializedView({ projectRef, connectionString, id }, signal),
|
||||
{
|
||||
enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined',
|
||||
...options,
|
||||
}
|
||||
)
|
||||
@@ -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<ReturnType<typeof getMaterializedViews>>
|
||||
export type MaterializedViewsError = unknown
|
||||
|
||||
export const useMaterializedViewsQuery = <TData = MaterializedViewsData>(
|
||||
{ projectRef, connectionString }: MaterializedViewsVariables,
|
||||
{
|
||||
enabled = true,
|
||||
...options
|
||||
}: UseQueryOptions<MaterializedViewsData, MaterializedViewsError, TData> = {}
|
||||
) =>
|
||||
useQuery<MaterializedViewsData, MaterializedViewsError, TData>(
|
||||
materializedViewKeys.list(projectRef),
|
||||
({ signal }) => getMaterializedViews({ projectRef, connectionString }, signal),
|
||||
{ enabled: enabled && typeof projectRef !== 'undefined', ...options }
|
||||
)
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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<ReturnType<typeof getTable>>
|
||||
export type TableError = unknown
|
||||
|
||||
export const useTableQuery = <TData = TableData>(
|
||||
{ projectRef, connectionString, id }: TableVariables,
|
||||
{ enabled = true, ...options }: UseQueryOptions<TableData, TableError, TData> = {}
|
||||
) =>
|
||||
useQuery<TableData, TableError, TData>(
|
||||
tableKeys.table(projectRef, id),
|
||||
({ signal }) => getTable({ projectRef, connectionString, id }, signal),
|
||||
{
|
||||
enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined',
|
||||
...options,
|
||||
}
|
||||
)
|
||||
@@ -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<ReturnType<typeof getTables>>
|
||||
export type TablesError = unknown
|
||||
|
||||
export const useTablesQuery = <TData = TablesData>(
|
||||
{ projectRef, connectionString }: TablesVariables,
|
||||
{ enabled = true, ...options }: UseQueryOptions<TablesData, TablesError, TData> = {}
|
||||
) =>
|
||||
useQuery<TablesData, TablesError, TData>(
|
||||
tableKeys.list(projectRef),
|
||||
({ signal }) => getTables({ projectRef, connectionString }, signal),
|
||||
{ enabled: enabled && typeof projectRef !== 'undefined', ...options }
|
||||
)
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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<ReturnType<typeof getView>>
|
||||
export type ViewError = unknown
|
||||
|
||||
export const useViewQuery = <TData = ViewData>(
|
||||
{ projectRef, connectionString, id }: ViewVariables,
|
||||
{ enabled = true, ...options }: UseQueryOptions<ViewData, ViewError, TData> = {}
|
||||
) =>
|
||||
useQuery<ViewData, ViewError, TData>(
|
||||
viewKeys.view(projectRef, id),
|
||||
({ signal }) => getView({ projectRef, connectionString, id }, signal),
|
||||
{
|
||||
enabled: enabled && typeof projectRef !== 'undefined' && typeof id !== 'undefined',
|
||||
...options,
|
||||
}
|
||||
)
|
||||
@@ -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<ReturnType<typeof getViews>>
|
||||
export type ViewsError = unknown
|
||||
|
||||
export const useViewsQuery = <TData = ViewsData>(
|
||||
{ projectRef, connectionString }: ViewsVariables,
|
||||
{ enabled = true, ...options }: UseQueryOptions<ViewsData, ViewsError, TData> = {}
|
||||
) =>
|
||||
useQuery<ViewsData, ViewsError, TData>(
|
||||
viewKeys.list(projectRef),
|
||||
({ signal }) => getViews({ projectRef, connectionString }, signal),
|
||||
{ enabled: enabled && typeof projectRef !== 'undefined', ...options }
|
||||
)
|
||||
@@ -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
|
||||
@@ -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<PostgresTable>[] = 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}
|
||||
>
|
||||
<TableGridEditor
|
||||
isLoadingSelectedTable={isLoading}
|
||||
selectedTable={selectedTable}
|
||||
sidePanelKey={sidePanelKey}
|
||||
isDuplicating={isDuplicating}
|
||||
|
||||
Reference in new issue
Block a user