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 0483940e0..a2fee25a4 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 @@ -150,7 +150,7 @@ export function DocumentsTableShell({ <>
- + { - router.push(`/dashboard/${searchSpaceId}/editor/${note.id}`); - }, 500); + // Invalidate notes query to refresh the sidebar + queryClient.invalidateQueries({ + queryKey: ["notes", String(searchSpaceId)], + }); + + // Update URL to reflect the new document ID without navigation + window.history.replaceState( + {}, + "", + `/dashboard/${searchSpaceId}/editor/${note.id}` + ); + // Update document state to reflect the new ID + setDocument({ + document_id: note.id, + title: title, + document_type: "NOTE", + blocknote_document: editorContent, + updated_at: new Date().toISOString(), + }); } else { // Existing document - save normally if (!editorContent) { @@ -241,10 +258,12 @@ export default function EditorPage() { setHasUnsavedChanges(false); toast.success("Document saved! Reindexing in background..."); - // Small delay before redirect to show success message - setTimeout(() => { - router.push(`/dashboard/${params.search_space_id}/documents`); - }, 500); + // Invalidate notes query when updating notes to refresh the sidebar + if (isNote) { + queryClient.invalidateQueries({ + queryKey: ["notes", String(searchSpaceId)], + }); + } } } catch (error) { console.error("Error saving document:", error); @@ -265,13 +284,13 @@ export default function EditorPage() { if (hasUnsavedChanges) { setShowUnsavedDialog(true); } else { - router.back(); + router.push(`/dashboard/${searchSpaceId}/researcher`); } }; const handleConfirmLeave = () => { setShowUnsavedDialog(false); - router.back(); + router.push(`/dashboard/${searchSpaceId}/researcher`); }; if (loading) { @@ -304,9 +323,9 @@ export default function EditorPage() { {error} - @@ -356,17 +375,10 @@ export default function EditorPage() { {isNewNote ? "Creating..." : "Saving..."} ) : ( - isNewNote ? ( - <> - - Create Note - - ) : ( - <> - - Save & Exit - - ) + <> + + Save + )} diff --git a/surfsense_web/components/sidebar/AppSidebarProvider.tsx b/surfsense_web/components/sidebar/AppSidebarProvider.tsx index 62c127120..ce9911641 100644 --- a/surfsense_web/components/sidebar/AppSidebarProvider.tsx +++ b/surfsense_web/components/sidebar/AppSidebarProvider.tsx @@ -84,7 +84,7 @@ export function AppSidebarProvider({ queryFn: () => notesApiService.getNotes({ search_space_id: Number(searchSpaceId), - page_size: 10, // Get recent 10 notes + page_size: 5, // Get 5 notes (changed from 10) }), enabled: !!searchSpaceId, }); @@ -183,32 +183,40 @@ export function AppSidebarProvider({ // Transform notes to the format expected by NavNotes const recentNotes = useMemo(() => { - return notesData?.items - ? notesData.items.map((note) => ({ - name: note.title, - url: `/dashboard/${note.search_space_id}/editor/${note.id}`, - icon: "FileText", - id: note.id, - search_space_id: note.search_space_id, - actions: [ - { - name: "Delete", - icon: "Trash2", - onClick: async () => { - try { - await notesApiService.deleteNote({ - search_space_id: note.search_space_id, - note_id: note.id, - }); - refetchNotes(); - } catch (error) { - console.error("Error deleting note:", error); - } - }, - }, - ], - })) - : []; + if (!notesData?.items) return []; + + // Sort notes by updated_at (most recent first), fallback to created_at if updated_at is null + const sortedNotes = [...notesData.items].sort((a, b) => { + const dateA = a.updated_at ? new Date(a.updated_at).getTime() : new Date(a.created_at).getTime(); + const dateB = b.updated_at ? new Date(b.updated_at).getTime() : new Date(b.created_at).getTime(); + return dateB - dateA; // Descending order (most recent first) + }); + + // Limit to 5 notes + return sortedNotes.slice(0, 5).map((note) => ({ + name: note.title, + url: `/dashboard/${note.search_space_id}/editor/${note.id}`, + icon: "FileText", + id: note.id, + search_space_id: note.search_space_id, + actions: [ + { + name: "Delete", + icon: "Trash2", + onClick: async () => { + try { + await notesApiService.deleteNote({ + search_space_id: note.search_space_id, + note_id: note.id, + }); + refetchNotes(); + } catch (error) { + console.error("Error deleting note:", error); + } + }, + }, + ], + })); }, [notesData, refetchNotes]); // Handle add note diff --git a/surfsense_web/components/sidebar/all-notes-sidebar.tsx b/surfsense_web/components/sidebar/all-notes-sidebar.tsx index 8a3c70083..a0e8f0072 100644 --- a/surfsense_web/components/sidebar/all-notes-sidebar.tsx +++ b/surfsense_web/components/sidebar/all-notes-sidebar.tsx @@ -31,6 +31,7 @@ import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { cn } from "@/lib/utils"; import { useEffect, useRef } from "react"; +import { createPortal } from "react-dom"; // Map of icon names to their components const actionIconMap: Record = { @@ -284,42 +285,40 @@ export function AllNotesSidebar({ [isDeleting, router, onOpenChange, handleDeleteNote] ); - return ( - <> - {/* Floating Sidebar */} -
{ - // Clear any pending close timeout when hovering over sidebar - if (hoverTimeoutRef?.current) { - clearTimeout(hoverTimeoutRef.current); - hoverTimeoutRef.current = null; - } - }} - onMouseLeave={() => { - // Close sidebar when mouse leaves - if (hoverTimeoutRef) { - hoverTimeoutRef.current = setTimeout(() => { - onOpenChange(false); - }, 200); - } else { + const sidebarContent = ( +
{ + // Clear any pending close timeout when hovering over sidebar + if (hoverTimeoutRef?.current) { + clearTimeout(hoverTimeoutRef.current); + hoverTimeoutRef.current = null; + } + }} + onMouseLeave={() => { + // Close sidebar when mouse leaves + if (hoverTimeoutRef) { + hoverTimeoutRef.current = setTimeout(() => { onOpenChange(false); - } - }} - > + }, 200); + } else { + onOpenChange(false); + } + }} + >
{/* Header */}
@@ -348,13 +347,13 @@ export function AllNotesSidebar({ ) : allNotes.length > 0 ? ( - + {allNotes.map((note) => ( ))} ) : ( - + {onAddNote ? ( { @@ -398,7 +397,13 @@ export function AllNotesSidebar({ )}
- ); + + // Render sidebar via portal to avoid stacking context issues + if (typeof window === "undefined") { + return null; + } + + return createPortal(sidebarContent, document.body); } diff --git a/surfsense_web/components/sidebar/nav-notes.tsx b/surfsense_web/components/sidebar/nav-notes.tsx index b89ebd4a0..29a078357 100644 --- a/surfsense_web/components/sidebar/nav-notes.tsx +++ b/surfsense_web/components/sidebar/nav-notes.tsx @@ -170,7 +170,7 @@ export function NavNotes({ notes, onAddNote, defaultOpen = true, searchSpaceId }
- {searchSpaceId && ( + {searchSpaceId && notes.length > 0 && (