diff --git a/surfsense_backend/app/routes/editor_routes.py b/surfsense_backend/app/routes/editor_routes.py index 0d7f6eba6..9beebfc8e 100644 --- a/surfsense_backend/app/routes/editor_routes.py +++ b/surfsense_backend/app/routes/editor_routes.py @@ -17,9 +17,7 @@ from app.utils.rbac import check_permission router = APIRouter() -@router.get( - "/search-spaces/{search_space_id}/documents/{document_id}/editor-content" -) +@router.get("/search-spaces/{search_space_id}/documents/{document_id}/editor-content") async def get_editor_content( search_space_id: int, document_id: int, diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/RowActions.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/RowActions.tsx index ea4c66228..1c4d440e7 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/RowActions.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/RowActions.tsx @@ -1,6 +1,7 @@ "use client"; -import { FileText, MoreHorizontal, Pencil, Trash2 } from "lucide-react"; +import { FileText, Pencil, Trash2 } from "lucide-react"; +import { motion } from "motion/react"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { toast } from "sonner"; @@ -13,16 +14,9 @@ import { AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, - AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import type { Document } from "./types"; export function RowActions({ @@ -36,7 +30,8 @@ export function RowActions({ refreshDocuments: () => Promise; searchSpaceId: string; }) { - const [isOpen, setIsOpen] = useState(false); + const [isDeleteOpen, setIsDeleteOpen] = useState(false); + const [isMetadataOpen, setIsMetadataOpen] = useState(false); const [isDeleting, setIsDeleting] = useState(false); const router = useRouter(); @@ -52,7 +47,7 @@ export function RowActions({ toast.error("Failed to delete document"); } finally { setIsDeleting(false); - setIsOpen(false); + setIsDeleteOpen(false); } }; @@ -61,64 +56,105 @@ export function RowActions({ }; return ( -
- - - - - - - - Edit Document - - - e.preventDefault()}> - - View Metadata - - } - /> - - - - { - e.preventDefault(); - setIsOpen(true); - }} - > - - Delete - - - - - Are you sure? - - - Cancel - { - e.preventDefault(); - handleDelete(); - }} - disabled={isDeleting} - > - {isDeleting ? "Deleting..." : "Delete"} - - - - - - +
+ {/* Edit Button */} + + + + + + + +

Edit Document

+
+
+ + {/* View Metadata Button */} + + + + + + + +

View Metadata

+
+
+ + + {/* Delete Button */} + + + + + + + +

Delete

+
+
+ + + + Are you sure? + + + Cancel + { + e.preventDefault(); + handleDelete(); + }} + disabled={isDeleting} + className="bg-destructive text-destructive-foreground hover:bg-destructive/90" + > + {isDeleting ? "Deleting..." : "Delete"} + + + +
); } diff --git a/surfsense_web/app/globals.css b/surfsense_web/app/globals.css index a1ee277c6..5aee982bb 100644 --- a/surfsense_web/app/globals.css +++ b/surfsense_web/app/globals.css @@ -27,7 +27,7 @@ --accent: oklch(0.97 0 0); --accent-foreground: oklch(0.205 0 0); --destructive: oklch(0.577 0.245 27.325); - --destructive-foreground: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(0.985 0 0); --border: oklch(0.922 0 0); --input: oklch(0.922 0 0); --ring: oklch(0.708 0 0); @@ -63,8 +63,8 @@ --muted-foreground: oklch(0.708 0 0); --accent: oklch(0.269 0 0); --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.396 0.141 25.723); - --destructive-foreground: oklch(0.637 0.237 25.331); + --destructive: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(0.985 0 0); --border: oklch(0.269 0 0); --input: oklch(0.269 0 0); --ring: oklch(0.439 0 0); diff --git a/surfsense_web/components/json-metadata-viewer.tsx b/surfsense_web/components/json-metadata-viewer.tsx index 11dd71581..8fe1b10ae 100644 --- a/surfsense_web/components/json-metadata-viewer.tsx +++ b/surfsense_web/components/json-metadata-viewer.tsx @@ -15,9 +15,17 @@ interface JsonMetadataViewerProps { title: string; metadata: any; trigger?: React.ReactNode; + open?: boolean; + onOpenChange?: (open: boolean) => void; } -export function JsonMetadataViewer({ title, metadata, trigger }: JsonMetadataViewerProps) { +export function JsonMetadataViewer({ + title, + metadata, + trigger, + open, + onOpenChange, +}: JsonMetadataViewerProps) { // Ensure metadata is a valid object const jsonData = React.useMemo(() => { if (!metadata) return {}; @@ -35,6 +43,23 @@ export function JsonMetadataViewer({ title, metadata, trigger }: JsonMetadataVie } }, [metadata]); + // Controlled mode: when open and onOpenChange are provided + if (open !== undefined && onOpenChange !== undefined) { + return ( + + + + {title} - Metadata + +
+ +
+
+
+ ); + } + + // Uncontrolled mode: when using trigger return (