diff --git a/surfsense_web/components/chat_v2/ChatInputGroup.tsx b/surfsense_web/components/chat_v2/ChatInputGroup.tsx new file mode 100644 index 0000000..ebef6fd --- /dev/null +++ b/surfsense_web/components/chat_v2/ChatInputGroup.tsx @@ -0,0 +1,272 @@ +"use client"; + +import { ChatInput } from "@llamaindex/chat-ui"; +import { FolderOpen } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Suspense, useState, useCallback } from "react"; +import { useParams } from "next/navigation"; +import { useDocuments, Document } from "@/hooks/use-documents"; +import { DocumentsDataTable } from "@/components/chat_v2/DocumentsDataTable"; +import { ResearchMode } from "@/components/chat"; +import React from "react"; + +const DocumentSelector = React.memo( + ({ + onSelectionChange, + selectedDocuments = [], + }: { + onSelectionChange?: (documents: Document[]) => void; + selectedDocuments?: Document[]; + }) => { + const { search_space_id } = useParams(); + const [isOpen, setIsOpen] = useState(false); + + const { documents, loading, isLoaded, fetchDocuments } = useDocuments( + Number(search_space_id) + ); + + const handleOpenChange = useCallback( + (open: boolean) => { + setIsOpen(open); + if (open && !isLoaded) { + fetchDocuments(); + } + }, + [fetchDocuments, isLoaded] + ); + + const handleSelectionChange = useCallback( + (documents: Document[]) => { + onSelectionChange?.(documents); + }, + [onSelectionChange] + ); + + const handleDone = useCallback(() => { + setIsOpen(false); + }, [selectedDocuments]); + + const selectedCount = selectedDocuments.length; + + return ( + + + + + + +
+
+ + Select Documents + + + Choose documents to include in your research + context + +
+ +
+ {loading ? ( +
+
+
+

+ Loading documents... +

+
+
+ ) : isLoaded ? ( + + ) : null} +
+
+ +
+ ); + } +); + +const SearchModeSelector = ({ + searchMode, + onSearchModeChange, +}: { + searchMode?: "DOCUMENTS" | "CHUNKS"; + onSearchModeChange?: (mode: "DOCUMENTS" | "CHUNKS") => void; +}) => { + return ( +
+ + Scope: + +
+ + +
+
+ ); +}; + +const ResearchModeSelector = ({ + researchMode, + onResearchModeChange, +}: { + researchMode?: ResearchMode; + onResearchModeChange?: (mode: ResearchMode) => void; +}) => { + const researchModeLabels: Record = { + QNA: "Q&A", + REPORT_GENERAL: "General Report", + REPORT_DEEP: "Deep Report", + REPORT_DEEPER: "Deeper Report", + }; + + const researchModeShortLabels: Record = { + QNA: "Q&A", + REPORT_GENERAL: "General", + REPORT_DEEP: "Deep", + REPORT_DEEPER: "Deeper", + }; + + return ( +
+ + Mode: + + +
+ ); +}; + +const CustomChatInputOptions = ({ + onDocumentSelectionChange, + selectedDocuments, + searchMode, + onSearchModeChange, + researchMode, + onResearchModeChange, +}: { + onDocumentSelectionChange?: (documents: Document[]) => void; + selectedDocuments?: Document[]; + searchMode?: "DOCUMENTS" | "CHUNKS"; + onSearchModeChange?: (mode: "DOCUMENTS" | "CHUNKS") => void; + researchMode?: ResearchMode; + onResearchModeChange?: (mode: ResearchMode) => void; +}) => { + return ( +
+ Loading...
}> + + + + + + ); +}; + +export const CustomChatInput = ({ + onDocumentSelectionChange, + selectedDocuments, + searchMode, + onSearchModeChange, + researchMode, + onResearchModeChange, +}: { + onDocumentSelectionChange?: (documents: Document[]) => void; + selectedDocuments?: Document[]; + searchMode?: "DOCUMENTS" | "CHUNKS"; + onSearchModeChange?: (mode: "DOCUMENTS" | "CHUNKS") => void; + researchMode?: ResearchMode; + onResearchModeChange?: (mode: ResearchMode) => void; +}) => { + return ( + + + + + + + + ); +}; diff --git a/surfsense_web/components/chat_v2/ChatInterface.tsx b/surfsense_web/components/chat_v2/ChatInterface.tsx index 02aa77f..8df94eb 100644 --- a/surfsense_web/components/chat_v2/ChatInterface.tsx +++ b/surfsense_web/components/chat_v2/ChatInterface.tsx @@ -3,32 +3,11 @@ import { ChatSection, ChatHandler, - ChatInput, ChatCanvas, ChatMessages, } from "@llamaindex/chat-ui"; -import { Button } from "../ui/button"; -import { FolderOpen } from "lucide-react"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "../ui/dialog"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "../ui/select"; -import { Badge } from "../ui/badge"; -import { Suspense, useState, useCallback } from "react"; -import { useParams } from "next/navigation"; -import { useDocuments, DocumentType, Document } from "@/hooks/use-documents"; -import { DocumentsDataTable } from "./DocumentsDataTable"; +import { Document } from "@/hooks/use-documents"; +import { CustomChatInput } from "@/components/chat_v2/ChatInputGroup"; import { ResearchMode } from "@/components/chat"; import React from "react"; @@ -42,253 +21,6 @@ interface ChatInterfaceProps { onResearchModeChange?: (mode: ResearchMode) => void; } -const DocumentSelector = React.memo( - ({ - onSelectionChange, - selectedDocuments = [], - }: { - onSelectionChange?: (documents: Document[]) => void; - selectedDocuments?: Document[]; - }) => { - const { search_space_id } = useParams(); - const [isOpen, setIsOpen] = useState(false); - - const { documents, loading, isLoaded, fetchDocuments } = useDocuments( - Number(search_space_id) - ); - - const handleOpenChange = useCallback( - (open: boolean) => { - setIsOpen(open); - if (open && !isLoaded) { - fetchDocuments(); - } - }, - [fetchDocuments, isLoaded] - ); - - const handleSelectionChange = useCallback( - (documents: Document[]) => { - onSelectionChange?.(documents); - }, - [onSelectionChange] - ); - - const handleDone = useCallback(() => { - setIsOpen(false); - }, [selectedDocuments]); - - const selectedCount = selectedDocuments.length; - - return ( - - - - - - -
-
- - Select Documents - - - Choose documents to include in your research - context - -
- -
- {loading ? ( -
-
-
-

- Loading documents... -

-
-
- ) : isLoaded ? ( - - ) : null} -
-
- -
- ); - } -); - -const SearchModeSelector = ({ - searchMode, - onSearchModeChange, -}: { - searchMode?: "DOCUMENTS" | "CHUNKS"; - onSearchModeChange?: (mode: "DOCUMENTS" | "CHUNKS") => void; -}) => { - return ( -
- - Scope: - -
- - -
-
- ); -}; - -const ResearchModeSelector = ({ - researchMode, - onResearchModeChange, -}: { - researchMode?: ResearchMode; - onResearchModeChange?: (mode: ResearchMode) => void; -}) => { - const researchModeLabels: Record = { - QNA: "Q&A", - REPORT_GENERAL: "General Report", - REPORT_DEEP: "Deep Report", - REPORT_DEEPER: "Deeper Report", - }; - - const researchModeShortLabels: Record = { - QNA: "Q&A", - REPORT_GENERAL: "General", - REPORT_DEEP: "Deep", - REPORT_DEEPER: "Deeper", - }; - - return ( -
- - Mode: - - -
- ); -}; - -const CustomChatInputOptions = ({ - onDocumentSelectionChange, - selectedDocuments, - searchMode, - onSearchModeChange, - researchMode, - onResearchModeChange, -}: { - onDocumentSelectionChange?: (documents: Document[]) => void; - selectedDocuments?: Document[]; - searchMode?: "DOCUMENTS" | "CHUNKS"; - onSearchModeChange?: (mode: "DOCUMENTS" | "CHUNKS") => void; - researchMode?: ResearchMode; - onResearchModeChange?: (mode: ResearchMode) => void; -}) => { - return ( -
- Loading...
}> - - - - - - ); -}; - -const CustomChatInput = ({ - onDocumentSelectionChange, - selectedDocuments, - searchMode, - onSearchModeChange, - researchMode, - onResearchModeChange, -}: { - onDocumentSelectionChange?: (documents: Document[]) => void; - selectedDocuments?: Document[]; - searchMode?: "DOCUMENTS" | "CHUNKS"; - onSearchModeChange?: (mode: "DOCUMENTS" | "CHUNKS") => void; - researchMode?: ResearchMode; - onResearchModeChange?: (mode: ResearchMode) => void; -}) => { - return ( - - - - - - - - ); -}; - export default function ChatInterface({ handler, onDocumentSelectionChange,