+ {/* Display mentioned documents as chips */}
+ {mentionedDocs && mentionedDocs.length > 0 && (
+
+ {mentionedDocs.map((doc) => (
+
+
+ {doc.title}
+
+ ))}
+
+ )}
-
diff --git a/surfsense_web/components/new-chat/DocumentsDataTable.tsx b/surfsense_web/components/new-chat/DocumentsDataTable.tsx
new file mode 100644
index 000000000..49aeff75c
--- /dev/null
+++ b/surfsense_web/components/new-chat/DocumentsDataTable.tsx
@@ -0,0 +1,248 @@
+"use client";
+
+import { useQuery } from "@tanstack/react-query";
+import { FileText } from "lucide-react";
+import {
+ forwardRef,
+ useCallback,
+ useEffect,
+ useImperativeHandle,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
+import type { Document } from "@/contracts/types/document.types";
+import { documentsApiService } from "@/lib/apis/documents-api.service";
+import { cacheKeys } from "@/lib/query-client/cache-keys";
+import { cn } from "@/lib/utils";
+
+export interface DocumentsDataTableRef {
+ selectHighlighted: () => void;
+ moveUp: () => void;
+ moveDown: () => void;
+}
+
+interface DocumentsDataTableProps {
+ searchSpaceId: number;
+ onSelectionChange: (documents: Document[]) => void;
+ onDone: () => void;
+ initialSelectedDocuments?: Document[];
+ externalSearch?: string;
+}
+
+function useDebounced
(value: T, delay = 300) {
+ const [debounced, setDebounced] = useState(value);
+ useEffect(() => {
+ const t = setTimeout(() => setDebounced(value), delay);
+ return () => clearTimeout(t);
+ }, [value, delay]);
+ return debounced;
+}
+
+export const DocumentsDataTable = forwardRef(
+ function DocumentsDataTable(
+ {
+ searchSpaceId,
+ onSelectionChange,
+ onDone,
+ initialSelectedDocuments = [],
+ externalSearch = "",
+ },
+ ref
+ ) {
+ // Use external search
+ const search = externalSearch;
+ const debouncedSearch = useDebounced(search, 150);
+ const [highlightedIndex, setHighlightedIndex] = useState(0);
+ const itemRefs = useRef