From ede7020b61408a47d06585b28d318c08c4436b76 Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Mon, 8 Dec 2025 10:03:17 +0000 Subject: [PATCH] refactor: replace imperative deleteDocument with mutation atom - Replaced deleteDocument from useDocuments with deleteDocumentMutationAtom - Removed unused useDocuments hook completely - Updated DocumentsTable to use mutation atom for single and bulk deletes - Maintains backward compatibility with existing delete functionality --- .../documents/(manage)/page.tsx | 44 +++++++---- surfsense_web/hooks/use-documents.ts | 78 ------------------- 2 files changed, 31 insertions(+), 91 deletions(-) delete mode 100644 surfsense_web/hooks/use-documents.ts diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx index 9ed28dbcf..d52b8fcf9 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx @@ -6,12 +6,11 @@ import { useTranslations } from "next-intl"; import { useCallback, useEffect, useId, useMemo, useState } from "react"; import { toast } from "sonner"; import { useQuery } from "@tanstack/react-query"; -import { useAtomValue } from "jotai"; +import { useAtomValue, useSetAtom } from "jotai"; import { documentsApiService } from "@/lib/apis/documents-api.service"; import { cacheKeys } from "@/lib/query-client/cache-keys"; import { documentTypeCountsAtom } from "@/atoms/documents/document-query.atoms"; - -import { useDocuments } from "@/hooks/use-documents"; +import { deleteDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms"; import { DocumentsFilters } from "./components/DocumentsFilters"; import { DocumentsTableShell, type SortKey } from "./components/DocumentsTableShell"; @@ -50,6 +49,9 @@ export default function DocumentsTable() { const [selectedIds, setSelectedIds] = useState>(new Set()); const {data: typeCounts} = useAtomValue(documentTypeCountsAtom) ; + // Set up the delete mutation + const deleteDocumentMutation = useSetAtom(deleteDocumentMutationAtom); + // Build query parameters for fetching documents const queryParams = useMemo( () => ({ @@ -109,14 +111,6 @@ export default function DocumentsTable() { const loading = debouncedSearch.trim() ? isSearchLoading : isDocumentsLoading; const error = debouncedSearch.trim() ? searchError : documentsError - // Use server-side pagination, search, and filtering - const { - deleteDocument, - } = useDocuments(searchSpaceId, { - page: pageIndex, - pageSize: pageSize, - }); - // Display server-filtered results directly const displayDocs = documents || []; const displayTotal = total; @@ -140,13 +134,37 @@ export default function DocumentsTable() { } }, [debouncedSearch, refetchSearch, refetchDocuments]); + // Create a delete function for single document deletion + const deleteDocument = useCallback( + async (id: number) => { + try { + await deleteDocumentMutation([{ id }]); + return true; + } catch (error) { + console.error("Failed to delete document:", error); + return false; + } + }, + [deleteDocumentMutation] + ); + const onBulkDelete = async () => { if (selectedIds.size === 0) { toast.error(t("no_rows_selected")); return; } try { - const results = await Promise.all(Array.from(selectedIds).map((id) => deleteDocument?.(id))); + // Delete documents one by one using the mutation + const results = await Promise.all( + Array.from(selectedIds).map(async (id) => { + try { + await deleteDocumentMutation([{ id }]); + return true; + } catch { + return false; + } + }) + ); const okCount = results.filter((r) => r === true).length; if (okCount === selectedIds.size) toast.success(t("delete_success_count", { count: okCount })); @@ -198,7 +216,7 @@ export default function DocumentsTable() { selectedIds={selectedIds} setSelectedIds={setSelectedIds} columnVisibility={columnVisibility} - deleteDocument={(id) => deleteDocument?.(id) ?? Promise.resolve(false)} + deleteDocument={deleteDocument} sortKey={sortKey} sortDesc={sortDesc} onSortChange={(key) => { diff --git a/surfsense_web/hooks/use-documents.ts b/surfsense_web/hooks/use-documents.ts deleted file mode 100644 index 0a00c7cd9..000000000 --- a/surfsense_web/hooks/use-documents.ts +++ /dev/null @@ -1,78 +0,0 @@ -"use client"; -import { useCallback, useEffect, useState } from "react"; -import { toast } from "sonner"; -import { authenticatedFetch } from "@/lib/auth-utils"; - -export interface Document { - id: number; - title: string; - document_type: DocumentType; - document_metadata: any; - content: string; - created_at: string; - search_space_id: number; -} - -export type DocumentType = - | "EXTENSION" - | "CRAWLED_URL" - | "SLACK_CONNECTOR" - | "NOTION_CONNECTOR" - | "FILE" - | "YOUTUBE_VIDEO" - | "GITHUB_CONNECTOR" - | "LINEAR_CONNECTOR" - | "DISCORD_CONNECTOR" - | "JIRA_CONNECTOR" - | "CONFLUENCE_CONNECTOR" - | "CLICKUP_CONNECTOR" - | "GOOGLE_CALENDAR_CONNECTOR" - | "GOOGLE_GMAIL_CONNECTOR" - | "AIRTABLE_CONNECTOR" - | "LUMA_CONNECTOR" - | "ELASTICSEARCH_CONNECTOR"; - -export interface UseDocumentsOptions { - page?: number; - pageSize?: number; - lazy?: boolean; - documentTypes?: string[]; -} - -export function useDocuments(searchSpaceId: number, options?: UseDocumentsOptions | boolean) { - // Support both old boolean API and new options API for backward compatibility - const opts = typeof options === "boolean" ? { lazy: options } : options || {}; - - const [error, setError] = useState(null); - - // Function to delete a document - const deleteDocument = useCallback( - async (documentId: number) => { - try { - const response = await authenticatedFetch( - `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/${documentId}`, - { method: "DELETE" } - ); - - if (!response.ok) { - toast.error("Failed to delete document"); - throw new Error("Failed to delete document"); - } - - toast.success("Document deleted successfully"); - // Note: The caller should handle refetching the documents list - return true; - } catch (err: any) { - toast.error(err.message || "Failed to delete document"); - console.error("Error deleting document:", err); - return false; - } - }, - [] - ); - - return { - error, - deleteDocument, - }; -}