"use client"; import { useAtomValue, useSetAtom } from "jotai"; import { AlertTriangle, Settings } from "lucide-react"; import { createContext, type FC, type ReactNode, useCallback, useContext, useRef, useState, } from "react"; import { globalNewLLMConfigsAtom, llmPreferencesAtom, } from "@/atoms/new-llm-config/new-llm-config-query.atoms"; import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms"; import { searchSpaceSettingsDialogAtom } from "@/atoms/settings/settings-dialog.atoms"; import { DocumentUploadTab } from "@/components/sources/DocumentUploadTab"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; // Context for opening the dialog from anywhere interface DocumentUploadDialogContextType { openDialog: () => void; closeDialog: () => void; } const DocumentUploadDialogContext = createContext(null); export const useDocumentUploadDialog = () => { const context = useContext(DocumentUploadDialogContext); if (!context) { throw new Error("useDocumentUploadDialog must be used within DocumentUploadDialogProvider"); } return context; }; // 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); const setSearchSpaceSettingsDialog = useSetAtom(searchSpaceSettingsDialogAtom); const { data: preferences = {}, isFetching: preferencesLoading } = useAtomValue(llmPreferencesAtom); const { data: globalConfigs = [], isFetching: globalConfigsLoading } = useAtomValue(globalNewLLMConfigsAtom); if (!searchSpaceId) return null; const handleSuccess = () => { onOpenChange(false); }; // Check if document summary LLM is properly configured // - If ID is 0 (Auto mode), we need global configs to be available // - If ID is positive (user config) or negative (specific global config), it's configured // - If ID is null/undefined, it's not configured const docSummaryLlmId = preferences.document_summary_llm_id; const isAutoMode = docSummaryLlmId === 0; const hasGlobalConfigs = globalConfigs.length > 0; const hasDocumentSummaryLLM = docSummaryLlmId !== null && docSummaryLlmId !== undefined && // If it's Auto mode, we need global configs to actually be available (!isAutoMode || hasGlobalConfigs); const isLoading = preferencesLoading || globalConfigsLoading; 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 border border-border ring-0 bg-muted dark:bg-muted text-foreground [&>button]:right-3 sm:[&>button]:right-6 [&>button]:top-5 sm:[&>button]:top-8 [&>button]:opacity-80 [&>button]:hover:opacity-100 [&>button]:hover:bg-foreground/10 [&>button]:z-[100] [&>button>svg]:size-4 sm:[&>button>svg]:size-5" > Upload Document

Upload Documents

Upload and sync your documents to your search space

{!isLoading && !hasDocumentSummaryLLM ? ( LLM Configuration Required

{isAutoMode && !hasGlobalConfigs ? "Auto mode requires a global LLM configuration. Please add one in Settings" : "A Document Summary LLM is required to process uploads, configure one in Settings"}

) : ( )}
); };