| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import { PermissionAction } from '@supabase/shared-types/out/constants'
- import { includes, map as lodashMap, uniqBy } from 'lodash'
- import { Search } from 'lucide-react'
- import { parseAsBoolean, useQueryState } from 'nuqs'
- import { useState } from 'react'
- import { InputGroup, InputGroupAddon, InputGroupInput } from 'ui'
- import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
- import { HooksListEmpty } from './HooksListEmpty'
- import { SchemaTable } from './SchemaTable'
- import AlertError from '@/components/ui/AlertError'
- import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
- import { DocsButton } from '@/components/ui/DocsButton'
- import { NoSearchResults } from '@/components/ui/NoSearchResults'
- import { useDatabaseHooksQuery } from '@/data/database-triggers/database-triggers-query'
- import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
- import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
- import { DOCS_URL } from '@/lib/constants'
- export const HooksList = () => {
- const { data: project } = useSelectedProjectQuery()
- const [, setShowCreateHookForm] = useQueryState('new', parseAsBoolean.withDefault(false))
- const {
- data: hooks = [],
- isPending: isLoading,
- isSuccess,
- isError,
- error,
- } = useDatabaseHooksQuery({
- projectRef: project?.ref,
- connectionString: project?.connectionString,
- })
- const [filterString, setFilterString] = useState<string>('')
- const filteredHooks = hooks.filter((x) =>
- includes(x.name.toLowerCase(), filterString.toLowerCase())
- )
- const filteredHookSchemas = lodashMap(uniqBy(filteredHooks, 'schema'), 'schema')
- const { can: canCreateWebhooks, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
- PermissionAction.TENANT_SQL_ADMIN_WRITE,
- 'triggers'
- )
- return (
- <div className="w-full space-y-4">
- <div className="flex items-center justify-between">
- <InputGroup className="w-52">
- <InputGroupInput
- size="tiny"
- placeholder="Search for a webhook"
- value={filterString}
- onChange={(e) => setFilterString(e.target.value)}
- />
- <InputGroupAddon>
- <Search />
- </InputGroupAddon>
- </InputGroup>
- <div className="flex items-center gap-x-2">
- <DocsButton href={`${DOCS_URL}/guides/database/webhooks`} />
- <ButtonTooltip
- onClick={() => setShowCreateHookForm(true)}
- disabled={!isPermissionsLoaded || !canCreateWebhooks}
- tooltip={{
- content: {
- side: 'bottom',
- text:
- isPermissionsLoaded && !canCreateWebhooks
- ? 'You need additional permissions to create webhooks'
- : undefined,
- },
- }}
- >
- Create a new hook
- </ButtonTooltip>
- </div>
- </div>
- {isLoading && (
- <div className="py-4">
- <GenericSkeletonLoader />
- </div>
- )}
- {isError && <AlertError error={error} subject="Failed to retrieve database webhooks" />}
- {isSuccess &&
- (hooks.length <= 0 ? (
- <HooksListEmpty />
- ) : (
- <>
- {filteredHooks.length <= 0 && (
- <NoSearchResults
- searchString={filterString}
- onResetFilter={() => setFilterString('')}
- />
- )}
- {filteredHookSchemas.map((schema) => (
- <SchemaTable key={schema} filterString={filterString} schema={schema} />
- ))}
- </>
- ))}
- </div>
- )
- }
|