import { PermissionAction } from '@supabase/shared-types/out/constants' import Link from 'next/link' import { useCallback } from 'react' import { useRouter } from 'next/compat/router' import { useParams } from 'common' import { Footer } from 'components/grid/components/footer/Footer' import { SupabaseGrid } from 'components/grid/SupabaseGrid' import { useSyncTableEditorStateFromLocalStorageWithUrl } from 'components/grid/SupabaseGrid.utils' import { isForeignTable, isMaterializedView, isTableLike, isView, } from 'data/table-editor/table-editor-types' import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions' import { useDashboardHistory } from 'hooks/misc/useDashboardHistory' import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState' import { useUrlState } from 'hooks/ui/useUrlState' import { useIsProtectedSchema } from 'hooks/useProtectedSchemas' import { TableEditorTableStateContextProvider } from 'state/table-editor-table' import { createTabId, useTabsStateSnapshot } from 'state/tabs' import { Button } from 'ui' import { Admonition, GenericSkeletonLoader } from 'ui-patterns' import type { Entity, TableLike } from 'data/table-editor/table-editor-types' import { V2TableDataGrid } from '@/components/v2/views/V2TableDataGrid' import DeleteConfirmationDialogs from './DeleteConfirmationDialogs' import { SidePanelEditor } from './SidePanelEditor/SidePanelEditor' import { TableDefinition } from './TableDefinition' export interface TableGridEditorProps { isLoadingSelectedTable?: boolean selectedTable?: Entity variant?: 'pages' | 'v2' projectRefOverride?: string tableIdOverride?: string | number } export const TableGridEditor = ({ isLoadingSelectedTable = false, selectedTable, variant = 'pages', projectRefOverride, tableIdOverride, }: TableGridEditorProps) => { const router = useRouter() const { ref: routeProjectRef, id: routeId } = useParams() const projectRef = projectRefOverride ?? routeProjectRef const id = tableIdOverride ? String(tableIdOverride) : routeId const { setLastVisitedTable } = useDashboardHistory() const { selectedSchema } = useQuerySchemaState() const tabs = useTabsStateSnapshot() useSyncTableEditorStateFromLocalStorageWithUrl({ projectRef, table: selectedTable, }) const [{ view: selectedView = 'data' }] = useUrlState() const { can: canEditTables } = useAsyncCheckPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'tables' ) const { can: canEditColumns } = useAsyncCheckPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'columns' ) const isReadOnly = !canEditTables && !canEditColumns const tabId = !!id ? tabs.openTabs.find((x) => x.endsWith(id)) : undefined const openTabs = tabs.openTabs.filter((x) => !x.startsWith('sql')) const onTableCreated = useCallback( (table: { id: number }) => { if (variant === 'v2') { const base = projectRef ? `/v2/project/${projectRef}` : '' if (router) { router.push( `${base}/data/tables/${table.id}/data${ !!selectedSchema ? `?schema=${selectedSchema}` : '' }` ) } else if (typeof window !== 'undefined') { window.location.assign( `${base}/data/tables/${table.id}/data${ !!selectedSchema ? `?schema=${selectedSchema}` : '' }` ) } return } if (!router) return router.push( `/project/${projectRef}/editor/${table.id}${ !!selectedSchema ? `?schema=${selectedSchema}` : '' }` ) }, [projectRef, router, selectedSchema, variant] ) const closeLegacyTab = useCallback( (id: string) => { if (!router) return tabs.handleTabClose({ id, router, editor: 'table', onClearDashboardHistory: () => setLastVisitedTable(undefined), }) }, [router, setLastVisitedTable, tabs] ) const onTableDeleted = useCallback(async () => { if (!selectedTable) return // For now, just close the deleted table tab. // v2 uses v2 URLs, pages uses the legacy tab-close router logic. const tabId = createTabId(selectedTable.entity_type, { id: selectedTable.id }) if (variant === 'v2') { tabs.removeTab(tabId) setLastVisitedTable(undefined) const base = projectRef ? `/v2/project/${projectRef}` : '' if (router) { router.push(`${base}/data/tables`) } else if (typeof window !== 'undefined') { window.location.assign(`${base}/data/tables`) } return } closeLegacyTab(tabId) }, [closeLegacyTab, projectRef, router, selectedTable, tabs, setLastVisitedTable, variant]) const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedTable?.schema ?? '' }) // NOTE: DO NOT PUT HOOKS AFTER THIS LINE if (isLoadingSelectedTable || !projectRef) { return (
SQL Definition of {selectedTable.name}{' '}
(Read only)