"use client"; import { useAtomValue } from "jotai"; import { createContext, type FC, type ReactNode, useCallback, useContext, useRef, useState, } from "react"; import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms"; import { DocumentUploadTab } from "@/components/sources/DocumentUploadTab"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; // Context for opening the dialog from anywhere interface DocumentUploadDialogContextType { openDialog: () => void; closeDialog: () => void; } const DocumentUploadDialogContext = createContext(null); const NOOP_DIALOG: DocumentUploadDialogContextType = { openDialog: () => {}, closeDialog: () => {}, }; export const useDocumentUploadDialog = (): DocumentUploadDialogContextType => { const context = useContext(DocumentUploadDialogContext); return context ?? NOOP_DIALOG; }; // Provider component export const DocumentUploadDialogProvider: FC<{ children: ReactNode }> = ({ children }) => { const [isOpen, setIsOpen] = useState(false); const isClosingRef = useRef(false); const openDialog = useCallback(() => { // Prevent opening if we just closed (debounce) if (isClosingRef.current) { return; } setIsOpen(true); }, []); const closeDialog = useCallback(() => { isClosingRef.current = true; setIsOpen(false); // Reset the flag after a short delay to allow for file picker to close setTimeout(() => { isClosingRef.current = false; }, 300); }, []); const handleOpenChange = useCallback( (open: boolean) => { if (!open) { // Only close if not already in closing state if (!isClosingRef.current) { closeDialog(); } } else { // Only open if not in the middle of closing if (!isClosingRef.current) { setIsOpen(true); } } }, [closeDialog] ); return ( {children} ); }; // Internal component that renders the dialog const DocumentUploadPopupContent: FC<{ isOpen: boolean; onOpenChange: (open: boolean) => void; }> = ({ isOpen, onOpenChange }) => { const searchSpaceId = useAtomValue(activeSearchSpaceIdAtom); if (!searchSpaceId) return null; const handleSuccess = () => { onOpenChange(false); }; return ( e.preventDefault()} onInteractOutside={(e) => e.preventDefault()} onEscapeKeyDown={(e) => e.preventDefault()} className="select-none max-w-2xl w-[95vw] sm:w-[640px] h-[min(440px,75dvh)] sm:h-[min(520px,80vh)] flex flex-col p-0 gap-0 overflow-hidden ring-0 [&>button]:right-3 sm:[&>button]:right-6 [&>button]:top-5 sm:[&>button]:top-8 [&>button]:opacity-80 [&>button]:hover:opacity-100 [&>button]:hover:bg-accent [&>button]:hover:text-accent-foreground [&>button]:z-[100] [&>button>svg]:size-4 sm:[&>button>svg]:size-5" >
Upload Documents Upload and sync your documents to your search space
); };