refactor: simplify DocumentsTableShell and DocumentsSidebar components by removing unused column visibility state and optimizing document loading logic in useDocuments hook

This commit is contained in:
Anish Sarkar 2026-03-06 12:12:03 +05:30
parent b7ca656823
commit 889af57d3f
3 changed files with 248 additions and 227 deletions

View file

@ -54,7 +54,7 @@ import {
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { documentsApiService } from "@/lib/apis/documents-api.service"; import { documentsApiService } from "@/lib/apis/documents-api.service";
import { getDocumentTypeIcon, getDocumentTypeLabel } from "./DocumentTypeIcon"; import { getDocumentTypeIcon, getDocumentTypeLabel } from "./DocumentTypeIcon";
import type { ColumnVisibility, Document, DocumentStatus } from "./types"; import type { Document, DocumentStatus } from "./types";
const EDITABLE_DOCUMENT_TYPES = ["FILE", "NOTE"] as const; const EDITABLE_DOCUMENT_TYPES = ["FILE", "NOTE"] as const;
const NON_DELETABLE_DOCUMENT_TYPES = ["SURFSENSE_DOCS"] as const; const NON_DELETABLE_DOCUMENT_TYPES = ["SURFSENSE_DOCS"] as const;
@ -288,7 +288,6 @@ export function DocumentsTableShell({
error, error,
selectedIds, selectedIds,
setSelectedIds, setSelectedIds,
columnVisibility: _columnVisibility,
sortKey, sortKey,
sortDesc, sortDesc,
onSortChange, onSortChange,
@ -304,7 +303,6 @@ export function DocumentsTableShell({
error: boolean; error: boolean;
selectedIds: Set<number>; selectedIds: Set<number>;
setSelectedIds: (update: Set<number>) => void; setSelectedIds: (update: Set<number>) => void;
columnVisibility: ColumnVisibility;
sortKey: SortKey; sortKey: SortKey;
sortDesc: boolean; sortDesc: boolean;
onSortChange: (key: SortKey) => void; onSortChange: (key: SortKey) => void;
@ -641,7 +639,37 @@ export function DocumentsTableShell({
</div> </div>
))} ))}
</div> </div>
) : !error && sorted.length > 0 && ( ) : error ? (
<div className="md:hidden flex flex-1 w-full items-center justify-center">
<div className="flex flex-col items-center gap-3">
<AlertCircle className="h-8 w-8 text-destructive" />
<p className="text-sm text-destructive">{t("error_loading")}</p>
</div>
</div>
) : sorted.length === 0 ? (
<div className="md:hidden flex flex-1 w-full items-center justify-center">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4 }}
className="flex flex-col items-center gap-4 max-w-md px-4 text-center"
>
<div className="rounded-full bg-muted/50 p-4">
<FileX className="h-8 w-8 text-muted-foreground" />
</div>
<div className="space-y-1.5">
<h3 className="text-lg font-semibold">{t("no_documents")}</h3>
<p className="text-sm text-muted-foreground">
Get started by uploading your first document.
</p>
</div>
<Button onClick={openDialog} className="mt-2">
<Plus className="mr-2 h-4 w-4" />
Upload Documents
</Button>
</motion.div>
</div>
) : (
<div ref={mobileScrollRef} className="md:hidden divide-y divide-border/50 flex-1 overflow-auto"> <div ref={mobileScrollRef} className="md:hidden divide-y divide-border/50 flex-1 overflow-auto">
{sorted.map((doc, index) => { {sorted.map((doc, index) => {
const isSelected = selectedIds.has(doc.id); const isSelected = selectedIds.has(doc.id);

View file

@ -19,7 +19,6 @@ import {
DocumentsTableShell, DocumentsTableShell,
type SortKey, type SortKey,
} from "@/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell"; } from "@/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell";
import type { ColumnVisibility } from "@/app/dashboard/[search_space_id]/documents/(manage)/components/types";
import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel"; import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel";
const SEARCH_INITIAL_SIZE = 20; const SEARCH_INITIAL_SIZE = 20;
@ -49,12 +48,6 @@ export function DocumentsSidebar({ open, onOpenChange }: DocumentsSidebarProps)
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const debouncedSearch = useDebounced(search, 250); const debouncedSearch = useDebounced(search, 250);
const [activeTypes, setActiveTypes] = useState<DocumentTypeEnum[]>([]); const [activeTypes, setActiveTypes] = useState<DocumentTypeEnum[]>([]);
const [columnVisibility, setColumnVisibility] = useState<ColumnVisibility>({
document_type: true,
created_by: false,
created_at: true,
status: true,
});
const [sortKey, setSortKey] = useState<SortKey>("created_at"); const [sortKey, setSortKey] = useState<SortKey>("created_at");
const [sortDesc, setSortDesc] = useState(true); const [sortDesc, setSortDesc] = useState(true);
const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set()); const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
@ -288,13 +281,6 @@ export function DocumentsSidebar({ open, onOpenChange }: DocumentsSidebarProps)
}); });
}, []); }, []);
useEffect(() => {
if (!open) return;
const panelWidth = isMobile ? window.innerWidth : 720;
const isNarrow = panelWidth < 600;
setColumnVisibility((prev) => ({ ...prev, created_by: !isNarrow, created_at: !isNarrow }));
}, [open, isMobile]);
useEffect(() => { useEffect(() => {
const handleEscape = (e: KeyboardEvent) => { const handleEscape = (e: KeyboardEvent) => {
if (e.key === "Escape" && open) { if (e.key === "Escape" && open) {
@ -345,7 +331,6 @@ export function DocumentsSidebar({ open, onOpenChange }: DocumentsSidebarProps)
error={!!error} error={!!error}
selectedIds={selectedIds} selectedIds={selectedIds}
setSelectedIds={setSelectedIds} setSelectedIds={setSelectedIds}
columnVisibility={columnVisibility}
sortKey={sortKey} sortKey={sortKey}
sortDesc={sortDesc} sortDesc={sortDesc}
onSortChange={handleSortChange} onSortChange={handleSortChange}

View file

@ -77,6 +77,7 @@ export function useDocuments(
const apiLoadedCountRef = useRef(0); const apiLoadedCountRef = useRef(0);
const initialLoadDoneRef = useRef(false); const initialLoadDoneRef = useRef(false);
const prevParamsRef = useRef<{ sortBy: string; sortOrder: string; typeFilterKey: string } | null>(null);
// Snapshot of all doc IDs from Electric's first callback after initial load. // Snapshot of all doc IDs from Electric's first callback after initial load.
// Anything appearing in subsequent callbacks NOT in this set is genuinely new. // Anything appearing in subsequent callbacks NOT in this set is genuinely new.
const electricBaselineIdsRef = useRef<Set<number> | null>(null); const electricBaselineIdsRef = useRef<Set<number> | null>(null);
@ -156,8 +157,15 @@ export function useDocuments(
let cancelled = false; let cancelled = false;
const isRefresh = initialLoadDoneRef.current; const prev = prevParamsRef.current;
if (!isRefresh) { const isSortOnlyChange =
initialLoadDoneRef.current &&
prev !== null &&
prev.typeFilterKey === typeFilterKey &&
(prev.sortBy !== sortBy || prev.sortOrder !== sortOrder);
prevParamsRef.current = { sortBy, sortOrder, typeFilterKey };
if (!isSortOnlyChange) {
setLoading(true); setLoading(true);
setDocuments([]); setDocuments([]);
setTotal(0); setTotal(0);