WrapperTable.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import { useParams } from 'common'
  2. import { parseAsString, useQueryState } from 'nuqs'
  3. import { useEffect, useMemo, useState } from 'react'
  4. import { toast } from 'sonner'
  5. import {
  6. Card,
  7. cn,
  8. Sheet,
  9. SheetContent,
  10. Table,
  11. TableBody,
  12. TableCell,
  13. TableFooter,
  14. TableHead,
  15. TableHeader,
  16. TableRow,
  17. } from 'ui'
  18. import { INTEGRATIONS } from '../Landing/Integrations.constants'
  19. import { DeleteWrapperModal } from './DeleteWrapperModal'
  20. import { EditWrapperSheet } from './EditWrapperSheet'
  21. import { WrapperRow } from './WrapperRow'
  22. import { wrapperMetaComparator } from './Wrappers.utils'
  23. import { useFDWsQuery } from '@/data/fdw/fdws-query'
  24. import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
  25. interface WrapperTableProps {
  26. isLatest?: boolean
  27. }
  28. export const WrapperTable = ({ isLatest = false }: WrapperTableProps) => {
  29. const { id, ref } = useParams()
  30. const { data: project } = useSelectedProjectQuery()
  31. const integration = INTEGRATIONS.find((i) => i.id === id)
  32. const [isClosingEditWrapper, setIsClosingEditWrapper] = useState(false)
  33. const { data, isError } = useFDWsQuery({
  34. projectRef: ref,
  35. connectionString: project?.connectionString,
  36. })
  37. const wrappers = useMemo(
  38. () =>
  39. integration && integration.type === 'wrapper' && data
  40. ? data.filter((wrapper) => wrapperMetaComparator(integration.meta, wrapper))
  41. : [],
  42. [data, integration]
  43. )
  44. const [selectedWrapperIdToEdit, setSelectedWrapperToEdit] = useQueryState('edit', parseAsString)
  45. const selectedWrapperToEdit = wrappers.find((w) => w.id.toString() === selectedWrapperIdToEdit)
  46. useEffect(() => {
  47. if (isError && !!selectedWrapperIdToEdit && !selectedWrapperToEdit) {
  48. toast('Wrapper not found')
  49. setSelectedWrapperToEdit(null)
  50. }
  51. }, [isError, selectedWrapperIdToEdit, selectedWrapperToEdit, setSelectedWrapperToEdit])
  52. if (!integration || integration.type !== 'wrapper') {
  53. return (
  54. <p className="text-foreground-light text-sm">
  55. The referenced ID doesn't correspond to a wrapper integration
  56. </p>
  57. )
  58. }
  59. return (
  60. <>
  61. <Card className="max-w-5xl">
  62. <Table>
  63. <TableHeader>
  64. <TableRow>
  65. <TableHead className="w-[220px]">Name</TableHead>
  66. <TableHead>Tables</TableHead>
  67. <TableHead>Encrypted key</TableHead>
  68. <TableHead className="w-24">
  69. <span className="sr-only">Actions</span>
  70. </TableHead>
  71. </TableRow>
  72. </TableHeader>
  73. <TableBody>
  74. {(isLatest ? wrappers.slice(0, 3) : wrappers).map((x) => {
  75. return <WrapperRow key={x.id} wrapper={x} />
  76. })}
  77. </TableBody>
  78. <TableFooter
  79. className={cn(
  80. 'text-xs font-normal text-center text-foreground-muted',
  81. // Prevent the footer from being highlighted on hover
  82. '[&>tr>td]:hover:bg-inherit',
  83. // Conditionally remove the border-top if there are no wrappers
  84. wrappers.length === 0 ? 'border-t-0' : ''
  85. )}
  86. >
  87. <TableRow className="border-b-0">
  88. <TableCell colSpan={4}>
  89. {wrappers.length} {integration?.name}
  90. {wrappers.length === 0 || wrappers.length > 1 ? 's' : ''} created
  91. </TableCell>
  92. </TableRow>
  93. </TableFooter>
  94. </Table>
  95. </Card>
  96. <Sheet
  97. open={!!selectedWrapperToEdit}
  98. onOpenChange={(open) => {
  99. if (!open) setIsClosingEditWrapper(true)
  100. }}
  101. >
  102. <SheetContent size="lg" tabIndex={undefined}>
  103. {selectedWrapperToEdit && (
  104. <EditWrapperSheet
  105. wrapper={selectedWrapperToEdit}
  106. wrapperMeta={integration.meta}
  107. onClose={() => {
  108. setSelectedWrapperToEdit(null)
  109. setIsClosingEditWrapper(false)
  110. }}
  111. isClosing={isClosingEditWrapper}
  112. setIsClosing={setIsClosingEditWrapper}
  113. />
  114. )}
  115. </SheetContent>
  116. </Sheet>
  117. <DeleteWrapperModal />
  118. </>
  119. )
  120. }