| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import { PermissionAction } from '@supabase/shared-types/out/constants'
- import { useParams } from 'common'
- import { ChevronDown } from 'lucide-react'
- import { useMemo } from 'react'
- import {
- Button,
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
- } from 'ui'
- import { Hook, HOOK_DEFINITION_TITLE, HOOKS_DEFINITIONS } from './hooks.constants'
- import { extractMethod, isValidHook } from './hooks.utils'
- import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
- import { InlineLink } from '@/components/ui/InlineLink'
- import { useAuthConfigQuery } from '@/data/auth/auth-config-query'
- import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
- import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
- import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
- interface AddHookDropdownProps {
- buttonText?: string
- align?: 'end' | 'center'
- type?: 'primary' | 'default'
- open?: boolean
- onOpenChange?: (open: boolean) => void
- onSelectHook: (hook: HOOK_DEFINITION_TITLE) => void
- }
- export const AddHookDropdown = ({
- buttonText = 'Add hook',
- align = 'end',
- type = 'primary',
- open,
- onOpenChange,
- onSelectHook,
- }: AddHookDropdownProps) => {
- const { ref: projectRef } = useParams()
- const { data: organization } = useSelectedOrganizationQuery()
- const { data: authConfig } = useAuthConfigQuery({ projectRef })
- const { can: canUpdateAuthHook } = useAsyncCheckPermissions(PermissionAction.AUTH_EXECUTE, '*')
- const { getEntitlementSetValues: getEntitledHookSet } = useCheckEntitlements('auth.hooks')
- const entitledHookSet = getEntitledHookSet()
- const { availableHooks, nonAvailableHooks } = useMemo(() => {
- const allHooks: Hook[] = HOOKS_DEFINITIONS.map((definition) => ({
- ...definition,
- enabled: authConfig?.[definition.enabledKey] || false,
- method: extractMethod(
- authConfig?.[definition.uriKey] || '',
- authConfig?.[definition.secretsKey] || ''
- ),
- }))
- const availableHooks: Hook[] = allHooks.filter(
- (h) => !isValidHook(h) && entitledHookSet.includes(h.entitlementKey)
- )
- const nonAvailableHooks: Hook[] = allHooks.filter(
- (h) => !isValidHook(h) && !entitledHookSet.includes(h.entitlementKey)
- )
- return { availableHooks, nonAvailableHooks }
- }, [entitledHookSet, authConfig])
- if (!canUpdateAuthHook) {
- return (
- <ButtonTooltip
- disabled
- type={type}
- tooltip={{
- content: { side: 'bottom', text: 'You need additional permissions to add auth hooks' },
- }}
- >
- {buttonText}
- </ButtonTooltip>
- )
- }
- return (
- <DropdownMenu open={open} onOpenChange={onOpenChange}>
- <DropdownMenuTrigger asChild>
- <Button type={type} iconRight={<ChevronDown />}>
- {buttonText}
- </Button>
- </DropdownMenuTrigger>
- <DropdownMenuContent className="w-76" align={align}>
- <div>
- {availableHooks.length === 0 && (
- <DropdownMenuLabel className="text-foreground-light">
- All available hooks have been added
- </DropdownMenuLabel>
- )}
- {availableHooks.map((h) => (
- <DropdownMenuItem key={h.title} onClick={() => onSelectHook(h.title)}>
- {h.title}
- </DropdownMenuItem>
- ))}
- </div>
- {nonAvailableHooks.length > 0 && (
- <>
- {availableHooks.length > 0 && <DropdownMenuSeparator />}
- <DropdownMenuLabel className="grid gap-1 bg-surface-200">
- <p className="text-foreground-light">Team or Enterprise Plan required</p>
- <p className="text-foreground-lighter text-xs">
- The following hooks are not available on{' '}
- <InlineLink href={`/org/${organization?.slug ?? '_'}/billing`}>
- your plan
- </InlineLink>
- .
- </p>
- </DropdownMenuLabel>
- {nonAvailableHooks.map((h) => (
- <DropdownMenuItem key={h.title} disabled={true}>
- {h.title}
- </DropdownMenuItem>
- ))}
- </>
- )}
- </DropdownMenuContent>
- </DropdownMenu>
- )
- }
|