import * as Tooltip from '@radix-ui/react-tooltip' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' 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 { 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 { partition } from 'lodash' import { Plus } from 'lucide-react' import { useRouter } from 'next/router' import { useMemo, useState } from 'react' import { useTableEditorStateSnapshot } from 'state/table-editor' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button } from 'ui' import { InnerSideBarEmptyPanel, InnerSideBarFilterSearchInput, InnerSideBarFilterSortDropdown, InnerSideBarFilterSortDropdownItem, InnerSideBarFilters, InnerSideBarShimmeringLoaders, } from 'ui-patterns/InnerSideMenu' 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 { project } = useProjectContext() const { data, isLoading, isSuccess, isError, error, refetch, hasNextPage, isFetchingNextPage, fetchNextPage, } = 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) return ( <>
{ setSearchText('') snap.setSelectedSchemaName(name) router.push(`/project/${project?.ref}/editor`) }} onSelectCreateSchema={() => snap.onAddSchema()} />
{!isLocked ? ( {!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

)}
{ setSearchText(e.target.value.trim()) }} value={searchText} placeholder="Search tables..." > setSort(value)} > Alphabetical Entity Type {isLoading && } {isError && ( )} {isSuccess && ( <> {searchText.length === 0 && (entityTypes?.length ?? 0) <= 0 && ( )} {searchText.length > 0 && (entityTypes?.length ?? 0) <= 0 && ( )} {(entityTypes?.length ?? 0) > 0 && (
28} hasNextPage={hasNextPage} isLoadingNextPage={isFetchingNextPage} onLoadNextPage={() => fetchNextPage()} />
)} )}
setShowModal(false)} /> ) } export default TableEditorMenu