import { ChevronRight } from 'lucide-react'; import { FunctionRow } from '../components/FunctionRow'; import FunctionEmptyState from '../components/FunctionEmptyState'; import { useFunctions } from '../hooks/useFunctions'; import { useToast } from '@/lib/hooks/useToast'; import { useEffect, useRef, useState } from 'react'; import RefreshIcon from '@/assets/icons/refresh.svg?react'; import { CodeEditor, Button, Skeleton, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components'; import { DataUpdatePayload, DataUpdateResourceType, ServerEvents, SocketMessage, useSocket, } from '@/lib/contexts/SocketContext'; export default function FunctionsPage() { const toastShownRef = useRef(false); const [isRefreshing, setIsRefreshing] = useState(false); const { showToast } = useToast(); const { functions, isRuntimeAvailable, selectedFunction, isLoading: loading, selectFunction, clearSelection, refetch, } = useFunctions(); const { socket, isConnected } = useSocket(); const handleRefresh = async () => { setIsRefreshing(true); try { await refetch(); } finally { setIsRefreshing(false); } }; useEffect(() => { if (!isRuntimeAvailable && !toastShownRef.current) { toastShownRef.current = true; showToast('Function container is unhealthy.', 'error'); } }, [isRuntimeAvailable, showToast]); useEffect(() => { if (!socket || !isConnected) { return; } const handleDataUpdate = (message: SocketMessage) => { if (message.payload?.resource === DataUpdateResourceType.FUNCTIONS) { void refetch(); } }; socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate); return () => { socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate); }; }, [socket, isConnected, refetch]); // If a function is selected, show the detail view if (selectedFunction) { return (

{selectedFunction.name}

); } // Default list view return (

Functions

{/* Separator */}
{/* Refresh button */}

{isRefreshing ? 'Refreshing...' : 'Refresh'}

{/* Table Header */}
Name
URL
Created
Last Update
{loading ? ( <> {[...Array(4)].map((_, i) => ( ))} ) : functions.length >= 1 ? ( <> {functions.map((func) => ( void selectFunction(func)} className="cols-span-full" /> ))} ) : (
)} {/* Loading mask overlay */} {isRefreshing && (
Loading
)}
); }