| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- import { PermissionAction } from '@supabase/shared-types/out/constants'
- import { useParams } from 'common'
- import { Search } from 'lucide-react'
- import { useMemo, useRef, useState } from 'react'
- import { Card, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from 'ui'
- import { Admonition } from 'ui-patterns'
- import { Input } from 'ui-patterns/DataInputs/Input'
- import { PublicationTablesSkeleton } from './PublicationSkeleton'
- import { PublicationsTableItem } from './PublicationsTableItem'
- import { AlertError } from '@/components/ui/AlertError'
- import { NoSearchResults } from '@/components/ui/NoSearchResults'
- import { useDatabasePublicationsQuery } from '@/data/database-publications/database-publications-query'
- import { useTablesQuery } from '@/data/tables/tables-query'
- import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
- import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
- import { onSearchInputEscape } from '@/lib/keyboard'
- import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
- import { useShortcut } from '@/state/shortcuts/useShortcut'
- export const PublicationsTables = () => {
- const { id } = useParams()
- const { data: project } = useSelectedProjectQuery()
- const [filterString, setFilterString] = useState<string>('')
- const searchInputRef = useRef<HTMLInputElement>(null)
- const { can: canUpdatePublications, isLoading: isLoadingPermissions } = useAsyncCheckPermissions(
- PermissionAction.TENANT_SQL_ADMIN_WRITE,
- 'publications'
- )
- useShortcut(
- SHORTCUT_IDS.LIST_PAGE_FOCUS_SEARCH,
- () => {
- searchInputRef.current?.focus()
- searchInputRef.current?.select()
- },
- { label: 'Search publications' }
- )
- const { data: publications = [] } = useDatabasePublicationsQuery({
- projectRef: project?.ref,
- connectionString: project?.connectionString,
- })
- const selectedPublication = publications.find((pub) => pub.id === Number(id))
- const {
- data: tablesData = [],
- isPending: isLoading,
- isSuccess,
- isError,
- error,
- } = useTablesQuery({
- projectRef: project?.ref,
- connectionString: project?.connectionString,
- })
- const tables = useMemo(() => {
- return tablesData.filter((table) =>
- filterString.length === 0 ? table : table.name.includes(filterString)
- )
- }, [tablesData, filterString])
- return (
- <>
- <div className="flex items-center justify-between mb-4">
- <Input
- size="tiny"
- ref={searchInputRef}
- icon={<Search />}
- className="w-48"
- placeholder="Search for a table"
- value={filterString}
- onChange={(e) => setFilterString(e.target.value)}
- onKeyDown={onSearchInputEscape(filterString, setFilterString)}
- />
- </div>
- {!isLoadingPermissions && !canUpdatePublications && (
- <Admonition
- type="warning"
- className="mb-4 w-full"
- description="You need additional permissions to update database replications."
- />
- )}
- <Card>
- <Table>
- <TableHeader>
- <TableRow>
- <TableHead>Name</TableHead>
- <TableHead>Schema</TableHead>
- <TableHead className="hidden lg:table-cell">Description</TableHead>
- {/*
- We've disabled All tables toggle for publications.
- See https://github.com/briven/briven/pull/7233.
- */}
- <TableHead />
- </TableRow>
- </TableHeader>
- <TableBody>
- {(isLoading || isLoadingPermissions) &&
- Array.from({ length: 2 }).map((_, i) => (
- <PublicationTablesSkeleton key={i} index={i} />
- ))}
- {isError && (
- <TableRow>
- <TableCell colSpan={4}>
- <AlertError error={error} subject="Failed to retrieve tables" />
- </TableCell>
- </TableRow>
- )}
- {!isLoading && !isLoadingPermissions && tables.length === 0 && (
- <TableRow>
- <TableCell colSpan={4}>
- <NoSearchResults
- className="border-none !p-0"
- searchString={filterString}
- onResetFilter={() => setFilterString('')}
- />
- </TableCell>
- </TableRow>
- )}
- {isSuccess ? (
- !!selectedPublication ? (
- tables.map((table) => (
- <PublicationsTableItem
- key={table.id}
- table={table}
- selectedPublication={selectedPublication}
- />
- ))
- ) : (
- <TableRow>
- <TableCell colSpan={4}>
- <p>The selected publication with ID {id} cannot be found</p>
- <p className="text-foreground-light">
- Head back to the list of publications to select one from there
- </p>
- </TableCell>
- </TableRow>
- )
- ) : null}
- </TableBody>
- </Table>
- </Card>
- </>
- )
- }
|