Merge pull request #589 from AnishSarkar22/feature/note-management

Feature: Note Management system
This commit is contained in:
Rohan Verma 2025-12-16 22:44:57 -08:00 committed by GitHub
commit f18425d739
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 1801 additions and 86 deletions

View file

@ -2,6 +2,7 @@
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import { Trash2 } from "lucide-react";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
import { useCallback, useEffect, useMemo, useState } from "react";
import { deleteChatMutationAtom } from "@/atoms/chats/chat-mutation.atoms";
@ -18,6 +19,7 @@ import {
DialogTitle,
} from "@/components/ui/dialog";
import { useQuery } from "@tanstack/react-query";
import { notesApiService } from "@/lib/apis/notes-api.service";
import { searchSpacesApiService } from "@/lib/apis/search-spaces-api.service";
import { cacheKeys } from "@/lib/query-client/cache-keys";
import { currentUserAtom } from "@/atoms/user/user-query.atoms";
@ -48,6 +50,7 @@ export function AppSidebarProvider({
}: AppSidebarProviderProps) {
const t = useTranslations("dashboard");
const tCommon = useTranslations("common");
const router = useRouter();
const setChatsQueryParams = useSetAtom(globalChatsQueryParamsAtom);
const { data: chats, error: chatError, isLoading: isLoadingChats } = useAtomValue(chatsAtom);
const [{ isPending: isDeletingChat, mutateAsync: deleteChat, error: deleteError }] =
@ -70,6 +73,22 @@ export function AppSidebarProvider({
const { data: user } = useAtomValue(currentUserAtom);
// Fetch notes
const {
data: notesData,
error: notesError,
isLoading: isLoadingNotes,
refetch: refetchNotes,
} = useQuery({
queryKey: ["notes", searchSpaceId],
queryFn: () =>
notesApiService.getNotes({
search_space_id: Number(searchSpaceId),
page_size: 5, // Get 5 notes (changed from 10)
}),
enabled: !!searchSpaceId,
});
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [chatToDelete, setChatToDelete] = useState<{ id: number; name: string } | null>(null);
const [isClient, setIsClient] = useState(false);
@ -162,6 +181,53 @@ export function AppSidebarProvider({
// Use fallback chats if there's an error or no chats
const displayChats = recentChats.length > 0 ? recentChats : fallbackChats;
// Transform notes to the format expected by NavNotes
const recentNotes = useMemo(() => {
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
const handleAddNote = useCallback(() => {
router.push(`/dashboard/${searchSpaceId}/editor/new`);
}, [router, searchSpaceId]);
// Memoized updated navSecondary
const updatedNavSecondary = useMemo(() => {
const updated = [...navSecondary];
@ -204,6 +270,7 @@ export function AppSidebarProvider({
navSecondary={navSecondary}
navMain={navMain}
RecentChats={[]}
RecentNotes={[]}
pageUsage={pageUsage}
/>
);
@ -216,6 +283,8 @@ export function AppSidebarProvider({
navSecondary={updatedNavSecondary}
navMain={navMain}
RecentChats={displayChats}
RecentNotes={recentNotes}
onAddNote={handleAddNote}
pageUsage={pageUsage}
/>