import { PermissionAction } from '@supabase/shared-types/out/constants' import { includes, noop, sortBy } from 'lodash' import { Copy, Edit, Edit2, FileText, MoreVertical, Trash } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, TableCell, TableRow, } from 'ui' import { getDatabaseTriggersHref } from './FunctionList.utils' import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import type { DatabaseFunction } from '@/data/database-functions/database-functions-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state' import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state' interface FunctionListProps { schema: string filterString: string isLocked: boolean returnTypeFilter: string[] securityFilter: string[] duplicateFunction: (fn: any) => void editFunction: (fn: any) => void deleteFunction: (fn: any) => void functions: DatabaseFunction[] } const FunctionList = ({ schema, filterString, isLocked, returnTypeFilter, securityFilter, duplicateFunction = noop, editFunction = noop, deleteFunction = noop, functions, }: FunctionListProps) => { const router = useRouter() const { data: selectedProject } = useSelectedProjectQuery() const aiSnap = useAiAssistantStateSnapshot() const { openSidebar } = useSidebarManagerSnapshot() const filteredFunctions = (functions ?? []).filter((x) => { const matchesName = includes(x.name.toLowerCase(), filterString.toLowerCase()) const matchesReturnType = returnTypeFilter.length === 0 || returnTypeFilter.includes(x.return_type) const matchesSecurity = securityFilter.length === 0 || (securityFilter.includes('definer') && x.security_definer) || (securityFilter.includes('invoker') && !x.security_definer) return matchesName && matchesReturnType && matchesSecurity }) const _functions = sortBy( filteredFunctions.filter((x) => x.schema == schema), (func) => func.name.toLocaleLowerCase() ) const projectRef = selectedProject?.ref const { can: canUpdateFunctions } = useAsyncCheckPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'functions' ) if (_functions.length === 0 && filterString.length === 0) { return (

No functions created yet

There are no functions found in the schema "{schema}"

) } if (_functions.length === 0 && filterString.length > 0) { return (

No results found

Your search for "{filterString}" did not return any results

) } return ( <> {_functions.map((x) => { const isApiDocumentAvailable = schema == 'public' && x.return_type !== 'trigger' return (

{x.argument_types || '–'}

{x.return_type === 'trigger' ? ( {x.return_type} ) : (

{x.return_type}

)}

{x.security_definer ? 'Definer' : 'Invoker'}

{!isLocked && (
{canUpdateFunctions ? (
)}
) })} ) } export default FunctionList