import * as Tooltip from '@radix-ui/react-tooltip' import { PermissionAction } from '@supabase/shared-types/out/constants' import { partition } from 'lodash' import { useMemo, useState } from 'react' import { useParams } from 'common/hooks' import InfiniteList from 'components/ui/InfiniteList' 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 { Alert, Button, Dropdown, IconCheck, IconChevronsDown, IconEdit, IconLoader, IconRefreshCw, IconSearch, IconX, Input, Listbox, Menu, } from 'ui' import { useProjectContext } from '../ProjectLayout/ProjectContext' import EntityListItem from './EntityListItem' const TableEditorMenu = () => { const { id } = useParams() const snap = useTableEditorStateSnapshot() 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, isLoading: isSchemasLoading, isSuccess: isSchemasSuccess, isError: isSchemasError, error: schemasError, refetch: refetchSchemas, } = 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, openSchemas] = partition(schemas, (schema) => EXCLUDED_SCHEMAS.includes(schema?.name ?? '') ) const isLocked = protectedSchemas.some((s) => s.id === schema?.id) return (
{/* Schema selection dropdown */}
{isSchemasLoading && (
Loading schemas...
)} {isSchemasError && (

Error: {schemasError.message}

)} {isSchemasSuccess && ( { setSearchText('') snap.setSelectedSchemaName(name) }} >

Schemas

{openSchemas.map((schema) => ( schema} > {schema.name} ))}

Protected schemas

{protectedSchemas.map((schema) => ( schema} > {schema.name} ))}
)}
{!isLocked && (
{/* Add new table button */}
} type="default" style={{ justifyContent: 'start' }} onClick={snap.onAddTable} > New table {!canCreateTables && (
You need additional permissions to create tables
)}
)} {/* 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})

)}
) : (
) } onClick={() => { setSort('alphabetical') }} > Alphabetical , ) : (
) } onClick={() => { setSort('grouped-alphabetical') }} > Entity Type , ]} >
Sort By
} />
28} hasNextPage={hasNextPage} isLoadingNextPage={isFetchingNextPage} onLoadNextPage={() => fetchNextPage()} />
)} ) } export default TableEditorMenu