From fc120bcb381b95eeaefcb8a3446e5a86e34ba03d Mon Sep 17 00:00:00 2001
From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com>
Date: Fri, 6 Mar 2026 11:32:08 +0530
Subject: [PATCH] refactor: improve infinite scroll implementation in
DocumentsTableShell by adding separate scroll references for desktop and
mobile views
---
.../components/DocumentsTableShell.tsx | 49 +++++++++----------
1 file changed, 22 insertions(+), 27 deletions(-)
diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx
index 736ea183f..914207c71 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx
@@ -178,10 +178,6 @@ function DocumentNameTooltip({
Created:{" "}
{formatAbsoluteDate(doc.created_at)}
-
- Source:{" "}
- {getDocumentTypeLabel(doc.document_type)}
-
@@ -331,27 +327,30 @@ export function DocumentsTableShell({
const desktopSentinelRef = useRef(null);
const mobileSentinelRef = useRef(null);
+ const desktopScrollRef = useRef(null);
+ const mobileScrollRef = useRef(null);
useEffect(() => {
if (!onLoadMore || !hasMore || loadingMore) return;
- const observer = new IntersectionObserver(
- (entries) => {
- if (entries.some((e) => e.isIntersecting)) {
- onLoadMore();
- }
- },
- { root: null, rootMargin: "200px", threshold: 0 }
- );
+ const observers: IntersectionObserver[] = [];
- if (desktopSentinelRef.current) {
- observer.observe(desktopSentinelRef.current);
- }
- if (mobileSentinelRef.current) {
- observer.observe(mobileSentinelRef.current);
- }
+ const observe = (root: HTMLElement | null, sentinel: HTMLElement | null) => {
+ if (!root || !sentinel) return;
+ const observer = new IntersectionObserver(
+ (entries) => {
+ if (entries.some((e) => e.isIntersecting)) onLoadMore();
+ },
+ { root, rootMargin: "150px", threshold: 0 }
+ );
+ observer.observe(sentinel);
+ observers.push(observer);
+ };
- return () => observer.disconnect();
+ observe(desktopScrollRef.current, desktopSentinelRef.current);
+ observe(mobileScrollRef.current, mobileSentinelRef.current);
+
+ return () => { for (const o of observers) o.disconnect(); };
}, [onLoadMore, hasMore, loadingMore]);
const handleViewDocument = useCallback(async (doc: Document) => {
@@ -589,7 +588,7 @@ export function DocumentsTableShell({
-
+
{sorted.map((doc, index) => {
@@ -661,15 +660,13 @@ export function DocumentsTableShell({
{hasMore && (
-
- {loadingMore && }
-
+
)}
{/* Mobile Card View */}
-
+
{sorted.map((doc, index) => {
const isSelected = selectedIds.has(doc.id);
const canSelect = isSelectable(doc);
@@ -731,9 +728,7 @@ export function DocumentsTableShell({
);
})}
{hasMore && (
-
- {loadingMore && }
-
+
)}
>