import * as Tooltip from '@radix-ui/react-tooltip' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import { AnimatePresence, motion } from 'framer-motion' import { partition } from 'lodash' import { Loader2 } from 'lucide-react' import { useRouter } from 'next/router' import { useEffect, useMemo, useRef, useState } from 'react' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button, DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, IconChevronsDown, IconPlusCircle, IconSearch, IconX, cn, } from 'ui' import { ProtectedSchemaModal } from 'components/interfaces/Database/ProtectedSchemaWarning' import AlertError from 'components/ui/AlertError' import InfiniteList from 'components/ui/InfiniteList' import SchemaSelector from 'components/ui/SchemaSelector' import ShimmeringLoader from 'components/ui/ShimmeringLoader' 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 router = useRouter() 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 [isSearchOpen, setIsSearchOpen] = useState(false) const inputRef = useRef(null) const [isSearchInputFocused, setIsSearchInputFocused] = useState(false) const { project } = useProjectContext() const { data, isLoading, isSuccess, isError, error, refetch, isRefetching, hasNextPage, isFetchingNextPage, fetchNextPage, isPreviousData: isSearching, } = useEntityTypesQuery( { projectRef: project?.ref, connectionString: project?.connectionString, schema: snap.selectedSchemaName, search: searchText || undefined, sort, }, { keepPreviousData: Boolean(searchText), } ) 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() } refreshTables 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) const expandSearch = () => { setIsSearchOpen(!isSearchOpen) } useEffect(() => { if (isSearchOpen && inputRef.current) { inputRef.current.focus() } }, [isSearchOpen]) const handleSearchInputFocusChange = () => { setIsSearchInputFocused(inputRef.current === document.activeElement) } return ( <>
{ setSearchText('') snap.setSelectedSchemaName(name) router.push(`/project/${project?.ref}/editor`) }} onSelectCreateSchema={() => snap.onAddSchema()} />
{!isLocked ? (
} type="default" className="justify-start h-7" 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

)}
{isSearchOpen && ( )} expandSearch() : () => { setSearchText('') expandSearch() } } initial={{ x: 0 }} animate={{ x: isSearchOpen ? 185 : 0, transition: { duration: 0 } }} className="px-2 py-0.5 rounded-md mt-1 transition transform hover:scale-105 focus:ring-2 " > {isSearchOpen ? ( isSearching ? ( ) : ( ) ) : ( )}
Sort By setSort(value)} > Alphabetical Entity Type
{isLoading && (
)} {isError && ( )} {isSuccess && ( <> {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

Your search for "{searchText}" did not return any results

)} {(entityTypes?.length ?? 0) > 0 && (
28} hasNextPage={hasNextPage} isLoadingNextPage={isFetchingNextPage} onLoadNextPage={() => fetchNextPage()} />
)} )}
setShowModal(false)} /> ) } export default TableEditorMenu