import { useMemo, useState } from 'react' import { noop, partition } from 'lodash' import { observer } from 'mobx-react-lite' import { Button, Dropdown, IconCheck, IconChevronsDown, IconEdit, IconLoader, IconRefreshCw, IconSearch, IconX, Input, Listbox, Menu, } from 'ui' import * as Tooltip from '@radix-ui/react-tooltip' import { PermissionAction } from '@supabase/shared-types/out/constants' import type { PostgresSchema } from '@supabase/postgres-meta' import { useParams } from 'common/hooks' import { checkPermissions, useStore, useLocalStorage } from 'hooks' import { useEntityTypesQuery } from 'data/entity-types/entity-types-infinite-query' import { Entity } from 'data/entity-types/entity-type-query' import { useProjectContext } from '../ProjectLayout/ProjectContext' import InfiniteList from 'components/ui/InfiniteList' import EntityListItem from './EntityListItem' export interface TableEditorMenuProps { selectedSchema?: string onSelectSchema: (schema: string) => void onAddTable: () => void onEditTable: (table: Entity) => void onDeleteTable: (table: Entity) => void onDuplicateTable: (table: Entity) => void } const TableEditorMenu = ({ selectedSchema, onSelectSchema = noop, onAddTable = noop, onEditTable = noop, onDeleteTable = noop, onDuplicateTable = noop, }: TableEditorMenuProps) => { const { meta } = useStore() const { id } = useParams() 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: selectedSchema, 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 schemas: PostgresSchema[] = meta.schemas.list() const schema = schemas.find((schema) => schema.name === selectedSchema) const canCreateTables = checkPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'tables') const isLoadingTableMetadata = id ? !meta.tables.byId(id) : true const refreshTables = async () => { await refetch() } const [protectedSchemas, openSchemas] = partition(schemas, (schema) => meta.excludedSchemas.includes(schema?.name ?? '') ) const isLocked = protectedSchemas.some((s) => s.id === schema?.id) return (
{/* Schema selection dropdown */}
{!meta.schemas.isInitialized ? (
Loading schemas...
) : ( { setSearchText('') onSelectSchema(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={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 observer(TableEditorMenu)