diff --git a/frontend/components/knowledge-actions-dropdown.tsx b/frontend/components/knowledge-actions-dropdown.tsx index ecf77e22..d4c0e6c0 100644 --- a/frontend/components/knowledge-actions-dropdown.tsx +++ b/frontend/components/knowledge-actions-dropdown.tsx @@ -1,6 +1,7 @@ "use client"; import { EllipsisVertical } from "lucide-react"; +import { useState } from "react"; import { DropdownMenu, DropdownMenuContent, @@ -8,18 +9,59 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Button } from "./ui/button"; +import { DeleteConfirmationDialog } from "./confirmation-dialog"; +import { useDeleteDocument } from "@/app/api/mutations/useDeleteDocument"; +import { toast } from "sonner"; -export function KnowledgeActionsDropdown() { - return ( - - - - - - Delete - - - ); +interface KnowledgeActionsDropdownProps { + filename: string; } + +export const KnowledgeActionsDropdown = ({ + filename, +}: KnowledgeActionsDropdownProps) => { + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + const deleteDocumentMutation = useDeleteDocument(); + + const handleDelete = async () => { + try { + await deleteDocumentMutation.mutateAsync({ filename }); + toast.success(`Successfully deleted "${filename}"`); + setShowDeleteDialog(false); + } catch (error) { + toast.error( + error instanceof Error ? error.message : "Failed to delete document" + ); + } + }; + + return ( + <> + + + + + + setShowDeleteDialog(true)} + > + Delete + + + + + + + ); +}; diff --git a/frontend/src/app/api/mutations/useDeleteDocument.ts b/frontend/src/app/api/mutations/useDeleteDocument.ts new file mode 100644 index 00000000..78985498 --- /dev/null +++ b/frontend/src/app/api/mutations/useDeleteDocument.ts @@ -0,0 +1,45 @@ +"use client"; + +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +interface DeleteDocumentRequest { + filename: string; +} + +interface DeleteDocumentResponse { + success: boolean; + deleted_chunks: number; + filename: string; + message: string; +} + +const deleteDocument = async ( + data: DeleteDocumentRequest +): Promise => { + const response = await fetch("/api/documents/delete-by-filename", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.error || "Failed to delete document"); + } + + return response.json(); +}; + +export const useDeleteDocument = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: deleteDocument, + onSuccess: () => { + // Invalidate and refetch search queries to update the UI + queryClient.invalidateQueries({ queryKey: ["search"] }); + }, + }); +}; diff --git a/frontend/src/app/knowledge/page.tsx b/frontend/src/app/knowledge/page.tsx index 2116f4d1..3df72944 100644 --- a/frontend/src/app/knowledge/page.tsx +++ b/frontend/src/app/knowledge/page.tsx @@ -133,8 +133,8 @@ function SearchPage() { }, }, { - cellRenderer: () => { - return ; + cellRenderer: ({ data }: CustomCellRendererProps) => { + return ; }, cellStyle: { alignItems: "center",