import * as Tooltip from '@radix-ui/react-tooltip' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import { partition } from 'lodash' import { useMemo, useState } from 'react' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button, DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, IconChevronsDown, IconEdit, IconLoader, IconRefreshCw, IconSearch, IconX, Input, Menu, Modal, } from 'ui' import InfiniteList from 'components/ui/InfiniteList' import SchemaSelector from 'components/ui/SchemaSelector' import { useSchemasQuery } from 'data/database/schemas-query' import { useEntityTypesQuery } from 'data/entity-types/entity-types-infinite-query' import { useCheckPermissions, useLocalStorage } from 'hooks' import { EXCLUDED_SCHEMAS } from 'lib/constants/schemas' import { useTableEditorStateSnapshot } from 'state/table-editor' import { useProjectContext } from '../ProjectLayout/ProjectContext' import EntityListItem from './EntityListItem' const TableEditorMenu = () => { const { id } = useParams() const snap = useTableEditorStateSnapshot() const [showModal, setShowModal] = useState(false) const [searchText, setSearchText] = useState('') const [sort, setSort] = useLocalStorage<'alphabetical' | 'grouped-alphabetical'>( 'table-editor-sort', 'alphabetical' ) const { project } = useProjectContext() const { data, isLoading, refetch, isRefetching, hasNextPage, isFetchingNextPage, fetchNextPage, isPreviousData: isSearching, } = useEntityTypesQuery( { projectRef: project?.ref, connectionString: project?.connectionString, schema: snap.selectedSchemaName, search: searchText || undefined, sort, }, { keepPreviousData: true, } ) const totalCount = data?.pages?.[0].data.count const entityTypes = useMemo( () => data?.pages.flatMap((page) => page.data.entities), [data?.pages] ) const { data: schemas } = useSchemasQuery({ projectRef: project?.ref, connectionString: project?.connectionString, }) const schema = schemas?.find((schema) => schema.name === snap.selectedSchemaName) const canCreateTables = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'tables') const refreshTables = async () => { await refetch() } const [protectedSchemas] = partition( (schemas ?? []).sort((a, b) => a.name.localeCompare(b.name)), (schema) => EXCLUDED_SCHEMAS.includes(schema?.name ?? '') ) const isLocked = protectedSchemas.some((s) => s.id === schema?.id) return ( <>
{ setSearchText('') snap.setSelectedSchemaName(name) }} onSelectCreateSchema={() => snap.onAddSchema()} />
{!isLocked ? (
} type="default" style={{ justifyContent: 'start' }} onClick={snap.onAddTable} > New table {!canCreateTables && (
You need additional permissions to create tables
)} ) : ( Viewing protected schema

This schema is managed by Supabase and is read-only through the table editor

)} {/* Table search input */}
) : ( ) } placeholder="Search tables" onChange={(e) => setSearchText(e.target.value.trim())} value={searchText} size="tiny" actions={ searchText && ( ) } />
{isLoading ? (

Loading entities...

) : searchText.length === 0 && (entityTypes?.length ?? 0) === 0 ? (

No entities available

This schema has no entities available yet

) : searchText.length > 0 && (entityTypes?.length ?? 0) === 0 ? (

No results found

There are no entities that match your search

) : (

Tables

{totalCount !== undefined && (

({totalCount})

)}
Sort By
setSort(value)} > Alphabetical Entity Type
} />
28} hasNextPage={hasNextPage} isLoadingNextPage={isFetchingNextPage} onLoadNextPage={() => fetchNextPage()} />
)} } onCancel={() => setShowModal(false)} >

The following schemas are managed by Supabase and are currently protected from write access through the Table Editor.

{EXCLUDED_SCHEMAS.map((schema) => ( {schema} ))}

These schemas are critical to the functionality of your Supabase project and hence we highly recommend not altering them.

You can, however, still interact with those schemas through the SQL Editor although we advise you only do so if you know what you are doing.

) } export default TableEditorMenu