import { IS_PLATFORM, useFlag } from 'common' import { useParams } from 'common/hooks' import dayjs from 'dayjs' import { Check, Copy } from 'lucide-react' import { useRouter } from 'next/router' import { useMemo, useState, type MouseEvent } from 'react' import { cn, copyToClipboard, TableCell, TableRow } from 'ui' import { ShimmeringLoader, TimestampInfo } from 'ui-patterns' import { formatErrorRate } from './EdgeFunctionsListItem.utils' import { useProjectApiUrl } from '@/data/config/project-endpoint-query' import { useEdgeFunctionsLastHourStatsQuery } from '@/data/edge-functions/edge-functions-last-hour-stats-query' import { useEdgeFunctionsQuery, type EdgeFunctionsResponse, } from '@/data/edge-functions/edge-functions-query' import { normalizeFunctionIds } from '@/data/edge-functions/keys' import { createNavigationHandler } from '@/lib/navigation' interface EdgeFunctionsListItemProps { function: EdgeFunctionsResponse } export const EdgeFunctionsListItem = ({ function: item }: EdgeFunctionsListItemProps) => { const router = useRouter() const { ref } = useParams() const [isCopied, setIsCopied] = useState(false) const showLastHourStats = useFlag('edgeFunctionsRequestMetrics') const { data: endpoint } = useProjectApiUrl({ projectRef: ref }) const functionUrl = `${endpoint}/functions/v1/${item.slug}` const handleNavigation = createNavigationHandler( `/project/${ref}/functions/${item.slug}${IS_PLATFORM ? '' : `/details`}`, router ) const { data: functions } = useEdgeFunctionsQuery({ projectRef: ref }) const functionIds = useMemo(() => { if (!showLastHourStats || !functions) return [] return normalizeFunctionIds(functions.map((item) => item.id)) }, [functions, showLastHourStats]) // [Joshen] We may be paginating the edge functions query in the future // So this will eventually need to be a list of visibleFunctionIds instead + debounced const { data: lastHourStatsAll, isPending: isStatsPending, isError: isStatsError, } = useEdgeFunctionsLastHourStatsQuery( { projectRef: ref, functionIds }, { enabled: showLastHourStats } ) const lastHourStats = lastHourStatsAll?.[item.id] return (

{item.name}

{functionUrl}

{item.created_at ? ( ) : ( )} {item.updated_at ? ( ) : ( )} {showLastHourStats && ( <> {isStatsPending ? ( ) : isStatsError ? (

-

) : (

{lastHourStats !== undefined ? lastHourStats.requestsCount.toLocaleString() : '-'}

)}
{isStatsPending ? ( ) : isStatsError ? (

-

) : lastHourStats !== undefined ? ( = 1 ? 'text-destructive' : lastHourStats.errorRate > 0.1 ? 'text-warning' : 'text-foreground-light' )} > {formatErrorRate(lastHourStats.errorRate)} ) : (

-

)}
)}

{item.version}

) }