import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import Link from 'next/link' import { useRouter } from 'next/router' import { parseAsString, useQueryState } from 'nuqs' import { useCallback } from 'react' import { Button } from 'ui' import { Admonition, GenericSkeletonLoader } from 'ui-patterns' import DeleteConfirmationDialogs from './DeleteConfirmationDialogs' import { SidePanelEditor } from './SidePanelEditor/SidePanelEditor' import { TableDefinition } from './TableDefinition' import { SupabaseGrid } from '@/components/grid/SupabaseGrid' import { useSyncTableEditorStateFromLocalStorageWithUrl } from '@/components/grid/SupabaseGrid.utils' import { Entity, isForeignTable, isMaterializedView, isTableLike, isView, TableLike, } 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 { useIsProtectedSchema } from '@/hooks/useProtectedSchemas' import { TableEditorTableStateContextProvider } from '@/state/table-editor-table' import { createTabId, useTabsStateSnapshot } from '@/state/tabs' export interface TableGridEditorProps { isLoadingSelectedTable?: boolean selectedTable?: Entity } export const TableGridEditor = ({ isLoadingSelectedTable = false, selectedTable, }: TableGridEditorProps) => { const router = useRouter() const { ref: projectRef, id } = useParams() const { setLastVisitedTable } = useDashboardHistory() const { selectedSchema } = useQuerySchemaState() const tabs = useTabsStateSnapshot() useSyncTableEditorStateFromLocalStorageWithUrl({ projectRef, table: selectedTable, }) const [selectedView] = useQueryState('view', parseAsString.withDefault('data')) 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 }) => { router.push( `/project/${projectRef}/editor/${table.id}${!!selectedSchema ? `?schema=${selectedSchema}` : ''}` ) }, [projectRef, router, selectedSchema] ) const onTableDeleted = useCallback(async () => { // For simplicity for now, we just open the first table within the same schema if (selectedTable) { // Close tab const tabId = createTabId(selectedTable.entity_type, { id: selectedTable.id }) tabs.handleTabClose({ id: tabId, router, editor: 'table', onClearDashboardHistory: () => setLastVisitedTable(undefined), }) } }, [router, selectedTable, setLastVisitedTable, tabs]) const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedTable?.schema ?? '' }) // NOTE: DO NOT PUT HOOKS AFTER THIS LINE if (isLoadingSelectedTable || !projectRef) { return (
) } const isViewSelected = isView(selectedTable) || isMaterializedView(selectedTable) const isTableSelected = isTableLike(selectedTable) const isForeignTableSelected = isForeignTable(selectedTable) const canEditViaTableEditor = isTableSelected && !isSchemaLocked const editable = !isReadOnly && canEditViaTableEditor const gridKey = !!selectedTable ? `${selectedTable.schema}_${selectedTable.name}` : 'unknown-table' /** [Joshen] We're going to need to refactor SupabaseGrid eventually to make the code here more readable * For context we previously built the SupabaseGrid as a reusable npm component, but eventually decided * to just integrate it directly into the dashboard. The header, and body (+footer) should be decoupled. */ return ( // When any click happens in a table tab, the tab becomes permanent
tabs.makeActiveTabPermanent()}> {!selectedTable ? (
{!!tabId ? ( ) : openTabs.length > 0 ? ( ) : ( )}
) : (

SQL Definition of {selectedTable.name}{' '}

(Read only)

) : null } > {(isViewSelected || isTableSelected) && selectedView === 'definition' && ( )} )}
) }