fix(ui): l’arbre latéral n’affiche plus que les carnets
Les notes restent dans la page. Le chiffre à droite du nom, la recherche par titre et les sous-carnets sont inchangés.
This commit is contained in:
@@ -32,7 +32,6 @@ import {
|
|||||||
Home,
|
Home,
|
||||||
Search,
|
Search,
|
||||||
GraduationCap,
|
GraduationCap,
|
||||||
FileText,
|
|
||||||
Folder,
|
Folder,
|
||||||
FolderOpen,
|
FolderOpen,
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
@@ -56,7 +55,7 @@ import { Notebook, Note } from '@/lib/types'
|
|||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import { motion, AnimatePresence } from 'motion/react'
|
import { motion, AnimatePresence } from 'motion/react'
|
||||||
import { getNoteDisplayTitle } from '@/lib/note-preview'
|
import { getNoteDisplayTitle } from '@/lib/note-preview'
|
||||||
import { listAiCreatedNotebookIds, isRecentlyCreated } from '@/lib/ai-created-highlight'
|
import { listAiCreatedNotebookIds } from '@/lib/ai-created-highlight'
|
||||||
import dynamic from 'next/dynamic'
|
import dynamic from 'next/dynamic'
|
||||||
|
|
||||||
const CreateNotebookDialog = dynamic(() => import('./create-notebook-dialog').then(m => ({ default: m.CreateNotebookDialog })), { ssr: false })
|
const CreateNotebookDialog = dynamic(() => import('./create-notebook-dialog').then(m => ({ default: m.CreateNotebookDialog })), { ssr: false })
|
||||||
@@ -84,71 +83,6 @@ const SIDEBAR_WIDTH_KEY = 'memento-sidebar-width'
|
|||||||
const SIDEBAR_WIDTH_MIN_PX = 280
|
const SIDEBAR_WIDTH_MIN_PX = 280
|
||||||
const SIDEBAR_WIDTH_MAX_PX = 560
|
const SIDEBAR_WIDTH_MAX_PX = 560
|
||||||
|
|
||||||
function NoteLink({
|
|
||||||
title,
|
|
||||||
isActive,
|
|
||||||
isPinned,
|
|
||||||
autoGenerated,
|
|
||||||
isRecent,
|
|
||||||
onClick,
|
|
||||||
}: {
|
|
||||||
title: string
|
|
||||||
isActive: boolean
|
|
||||||
isPinned?: boolean
|
|
||||||
/** Note créée par l'IA (agents, wizard, …) */
|
|
||||||
autoGenerated?: boolean
|
|
||||||
/** Créée récemment (< 48h) — point discret « nouveau » */
|
|
||||||
isRecent?: boolean
|
|
||||||
onClick: () => void
|
|
||||||
}) {
|
|
||||||
const { language, t } = useLanguage()
|
|
||||||
const slideX = language === 'fa' || language === 'ar' ? 10 : -10
|
|
||||||
return (
|
|
||||||
<motion.button
|
|
||||||
initial={{ opacity: 0, x: slideX }}
|
|
||||||
animate={{ opacity: 1, x: 0 }}
|
|
||||||
onClick={onClick}
|
|
||||||
className={cn(
|
|
||||||
'w-full flex items-center gap-2 ps-6 pe-3 py-1.5 text-[11px] transition-all rounded-lg text-start',
|
|
||||||
isActive
|
|
||||||
? 'bg-white dark:bg-white/10 shadow-sm border border-border/50 text-foreground font-semibold'
|
|
||||||
: autoGenerated
|
|
||||||
? 'text-foreground/90 hover:text-foreground hover:bg-brand-accent/5 border border-transparent'
|
|
||||||
: 'text-muted-foreground hover:text-foreground hover:bg-white/30 dark:hover:bg-white/5',
|
|
||||||
autoGenerated && !isActive && 'bg-brand-accent/[0.04]',
|
|
||||||
)}
|
|
||||||
title={autoGenerated ? (t('sidebar.aiGeneratedNote') || 'Note générée par l\'IA') : undefined}
|
|
||||||
>
|
|
||||||
{autoGenerated ? (
|
|
||||||
<Sparkles
|
|
||||||
size={12}
|
|
||||||
className={cn('shrink-0', isActive ? 'text-brand-accent' : 'text-brand-accent/80')}
|
|
||||||
aria-hidden
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<FileText
|
|
||||||
size={12}
|
|
||||||
className={cn('shrink-0', isActive ? 'text-brand-accent' : 'text-muted-foreground/70')}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<span className="truncate flex-1">{title}</span>
|
|
||||||
{autoGenerated && (
|
|
||||||
<span className="shrink-0 text-[8px] font-bold uppercase tracking-wider text-brand-accent/90 bg-brand-accent/10 px-1.5 py-0.5 rounded">
|
|
||||||
{t('sidebar.aiBadge') || 'IA'}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{isRecent && !autoGenerated && (
|
|
||||||
<span
|
|
||||||
className="shrink-0 w-1.5 h-1.5 rounded-full bg-brand-accent"
|
|
||||||
title={t('sidebar.recentNote') || 'Récemment créée'}
|
|
||||||
aria-label={t('sidebar.recentNote') || 'Récemment créée'}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{isPinned && <Pin size={10} className="text-amber-500 fill-amber-500 shrink-0" />}
|
|
||||||
</motion.button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function SidebarBrainstorms() {
|
function SidebarBrainstorms() {
|
||||||
const { data: sessions, isLoading } = useBrainstormSessions()
|
const { data: sessions, isLoading } = useBrainstormSessions()
|
||||||
const deleteBrainstorm = useDeleteBrainstorm()
|
const deleteBrainstorm = useDeleteBrainstorm()
|
||||||
@@ -377,17 +311,14 @@ function SidebarReminders({ onOpenNote }: { onOpenNote: (noteId: string, noteboo
|
|||||||
function SidebarCarnetItem({
|
function SidebarCarnetItem({
|
||||||
carnet,
|
carnet,
|
||||||
isActive,
|
isActive,
|
||||||
notes,
|
noteCount,
|
||||||
activeNoteId,
|
|
||||||
onCarnetClick,
|
onCarnetClick,
|
||||||
onNoteClick,
|
|
||||||
onAddSubNotebook,
|
onAddSubNotebook,
|
||||||
onRename,
|
onRename,
|
||||||
onDelete,
|
onDelete,
|
||||||
onTogglePin,
|
onTogglePin,
|
||||||
isPinned,
|
isPinned,
|
||||||
isAiCreated,
|
isAiCreated,
|
||||||
children,
|
|
||||||
isDragging,
|
isDragging,
|
||||||
dragHandleProps,
|
dragHandleProps,
|
||||||
level,
|
level,
|
||||||
@@ -398,10 +329,8 @@ function SidebarCarnetItem({
|
|||||||
}: {
|
}: {
|
||||||
carnet: { id: string; name: string; initial: string; isPrivate?: boolean }
|
carnet: { id: string; name: string; initial: string; isPrivate?: boolean }
|
||||||
isActive: boolean
|
isActive: boolean
|
||||||
notes: { id: string; title: string; isPinned?: boolean; autoGenerated?: boolean; isRecent?: boolean }[]
|
noteCount: number
|
||||||
activeNoteId: string | null
|
|
||||||
onCarnetClick: () => void
|
onCarnetClick: () => void
|
||||||
onNoteClick: (noteId: string, carnetId: string) => void
|
|
||||||
onAddSubNotebook: () => void
|
onAddSubNotebook: () => void
|
||||||
onRename: () => void
|
onRename: () => void
|
||||||
onDelete: () => void
|
onDelete: () => void
|
||||||
@@ -409,7 +338,6 @@ function SidebarCarnetItem({
|
|||||||
isPinned: boolean
|
isPinned: boolean
|
||||||
/** Carnet créé via wizard IA (repère temporaire) */
|
/** Carnet créé via wizard IA (repère temporaire) */
|
||||||
isAiCreated?: boolean
|
isAiCreated?: boolean
|
||||||
children?: React.ReactNode
|
|
||||||
isDragging?: boolean
|
isDragging?: boolean
|
||||||
dragHandleProps?: React.HTMLAttributes<HTMLDivElement>
|
dragHandleProps?: React.HTMLAttributes<HTMLDivElement>
|
||||||
level: number
|
level: number
|
||||||
@@ -420,7 +348,8 @@ function SidebarCarnetItem({
|
|||||||
}) {
|
}) {
|
||||||
const { t, language } = useLanguage()
|
const { t, language } = useLanguage()
|
||||||
const isRtl = language === 'fa' || language === 'ar'
|
const isRtl = language === 'fa' || language === 'ar'
|
||||||
const hasChildren = hasChildNotebooks || React.Children.count(children) > 0 || notes.length > 0
|
const hasChildren = Boolean(hasChildNotebooks)
|
||||||
|
const showOpenFolder = hasChildren && isExpanded
|
||||||
const [contextMenu, setContextMenu] = useState<{ x: number; y: number } | null>(null)
|
const [contextMenu, setContextMenu] = useState<{ x: number; y: number } | null>(null)
|
||||||
|
|
||||||
// Close context menu on outside click
|
// Close context menu on outside click
|
||||||
@@ -434,6 +363,7 @@ function SidebarCarnetItem({
|
|||||||
return (
|
return (
|
||||||
<div className={cn('transition-opacity', isDragging && 'opacity-40')}>
|
<div className={cn('transition-opacity', isDragging && 'opacity-40')}>
|
||||||
<div
|
<div
|
||||||
|
data-notebook-id={carnet.id}
|
||||||
className="flex items-center group relative h-10"
|
className="flex items-center group relative h-10"
|
||||||
style={{ paddingInlineStart: `${level * 24 + 8}px` }}
|
style={{ paddingInlineStart: `${level * 24 + 8}px` }}
|
||||||
onContextMenu={(e) => {
|
onContextMenu={(e) => {
|
||||||
@@ -461,6 +391,8 @@ function SidebarCarnetItem({
|
|||||||
|
|
||||||
{hasChildren ? (
|
{hasChildren ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-expanded={isExpanded}
|
||||||
onClick={(e) => { e.stopPropagation(); toggleExpand() }}
|
onClick={(e) => { e.stopPropagation(); toggleExpand() }}
|
||||||
className="shrink-0 w-5 h-5 flex items-center justify-center hover:bg-foreground/5 rounded-md transition-colors text-muted-foreground"
|
className="shrink-0 w-5 h-5 flex items-center justify-center hover:bg-foreground/5 rounded-md transition-colors text-muted-foreground"
|
||||||
>
|
>
|
||||||
@@ -500,7 +432,7 @@ function SidebarCarnetItem({
|
|||||||
'w-5 h-5 flex items-center justify-center shrink-0 transition-colors',
|
'w-5 h-5 flex items-center justify-center shrink-0 transition-colors',
|
||||||
isActive ? 'text-brand-accent' : 'text-muted-foreground/80',
|
isActive ? 'text-brand-accent' : 'text-muted-foreground/80',
|
||||||
)}>
|
)}>
|
||||||
{isExpanded ? <FolderOpen size={13} /> : <Folder size={13} />}
|
{showOpenFolder ? <FolderOpen size={13} /> : <Folder size={13} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1 text-start flex items-center gap-2 min-w-0">
|
<div className="flex-1 text-start flex items-center gap-2 min-w-0">
|
||||||
@@ -523,9 +455,9 @@ function SidebarCarnetItem({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Compteur de notes (toujours visible, à droite du nom) */}
|
{/* Compteur de notes (toujours visible, à droite du nom) */}
|
||||||
{notes.length > 0 && (
|
{noteCount > 0 && (
|
||||||
<span className="text-[11px] font-medium tabular-nums text-foreground/75 px-1.5 bg-brand-accent/5 border border-border/40 rounded-full transition-colors shrink-0 ms-auto">
|
<span className="text-[11px] font-medium tabular-nums text-foreground/75 px-1.5 bg-brand-accent/5 border border-border/40 rounded-full transition-colors shrink-0 ms-auto">
|
||||||
{notes.length}
|
{noteCount}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -609,42 +541,6 @@ function SidebarCarnetItem({
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
<AnimatePresence initial={false}>
|
|
||||||
{isExpanded && (
|
|
||||||
<motion.div
|
|
||||||
initial={{ height: 0, opacity: 0 }}
|
|
||||||
animate={{ height: 'auto', opacity: 1 }}
|
|
||||||
exit={{ height: 0, opacity: 0 }}
|
|
||||||
transition={{ duration: 0.3, ease: [0.23, 1, 0.32, 1] }}
|
|
||||||
className="overflow-hidden"
|
|
||||||
>
|
|
||||||
<div className="relative" style={{ marginInlineStart: `${(level + 1) * 16 + 10}px` }}>
|
|
||||||
<div className="absolute start-[-6px] top-0 bottom-4 w-px bg-border/30" />
|
|
||||||
|
|
||||||
<div className="space-y-0.5 py-1">
|
|
||||||
{children}
|
|
||||||
{isExpanded && notes.map(note => (
|
|
||||||
<NoteLink
|
|
||||||
key={note.id}
|
|
||||||
title={note.title}
|
|
||||||
isPinned={note.isPinned}
|
|
||||||
autoGenerated={note.autoGenerated}
|
|
||||||
isRecent={note.isRecent}
|
|
||||||
isActive={activeNoteId === note.id}
|
|
||||||
onClick={() => onNoteClick(note.id, carnet.id)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
{isExpanded && notes.length === 0 && !hasChildren && (
|
|
||||||
<p className="ps-6 py-1 text-[9px] italic text-muted-foreground/40 font-light">
|
|
||||||
{t('sidebar.notebookEmpty')}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
)}
|
|
||||||
</AnimatePresence>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -693,7 +589,7 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
const [isRenaming, setIsRenaming] = useState(false)
|
const [isRenaming, setIsRenaming] = useState(false)
|
||||||
const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())
|
const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())
|
||||||
const [pinnedIds, setPinnedIds] = useState<Set<string>>(new Set())
|
const [pinnedIds, setPinnedIds] = useState<Set<string>>(new Set())
|
||||||
const [notebookNotes, setNotebookNotes] = useState<Record<string, { id: string; title: string; isPinned?: boolean; autoGenerated?: boolean; isRecent?: boolean }[]>>({})
|
const [notebookNotes, setNotebookNotes] = useState<Record<string, { id: string; title: string }[]>>({})
|
||||||
const [aiNotebookIds, setAiNotebookIds] = useState<Set<string>>(() => new Set())
|
const [aiNotebookIds, setAiNotebookIds] = useState<Set<string>>(() => new Set())
|
||||||
const [activeView, setActiveView] = useState<NavigationView>('notebooks')
|
const [activeView, setActiveView] = useState<NavigationView>('notebooks')
|
||||||
const [sortOrder, setSortOrder] = useState<SortOrder>('newest')
|
const [sortOrder, setSortOrder] = useState<SortOrder>('newest')
|
||||||
@@ -838,19 +734,23 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
const filteredNotebookIds = useMemo(() => {
|
const filteredNotebookIds = useMemo(() => {
|
||||||
const q = notebookSearchQuery.trim().toLowerCase()
|
const q = notebookSearchQuery.trim().toLowerCase()
|
||||||
if (!q) return null
|
if (!q) return null
|
||||||
return new Set(
|
const byId = new Map(notebooks.map((nb) => [nb.id, nb]))
|
||||||
notebooks
|
const ids = new Set<string>()
|
||||||
.filter(
|
for (const nb of notebooks) {
|
||||||
(nb) =>
|
const nameHit = nb.name.toLowerCase().includes(q)
|
||||||
nb.name.toLowerCase().includes(q) ||
|
const noteHit = (notebookNotes[nb.id] || []).some((n) => n.title.toLowerCase().includes(q))
|
||||||
(notebookNotes[nb.id] || []).some((n) => n.title.toLowerCase().includes(q)),
|
if (!nameHit && !noteHit) continue
|
||||||
)
|
ids.add(nb.id)
|
||||||
.map((nb) => nb.id),
|
let parentId = nb.parentId ?? null
|
||||||
)
|
while (parentId && !ids.has(parentId)) {
|
||||||
|
ids.add(parentId)
|
||||||
|
parentId = byId.get(parentId)?.parentId ?? null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ids
|
||||||
}, [notebooks, notebookNotes, notebookSearchQuery])
|
}, [notebooks, notebookNotes, notebookSearchQuery])
|
||||||
|
|
||||||
const currentNotebookId = searchParams.get('notebook')
|
const currentNotebookId = searchParams.get('notebook')
|
||||||
const currentNoteId = searchParams.get('openNote')
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentNotebookId) return
|
if (!currentNotebookId) return
|
||||||
@@ -866,6 +766,29 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
})
|
})
|
||||||
}, [currentNotebookId, notebooks])
|
}, [currentNotebookId, notebooks])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!filteredNotebookIds) return
|
||||||
|
setExpandedIds((prev) => {
|
||||||
|
const next = new Set(prev)
|
||||||
|
for (const id of filteredNotebookIds) {
|
||||||
|
const kids = childNotebooks.get(id) || []
|
||||||
|
if (kids.some((c) => filteredNotebookIds.has(c.id))) next.add(id)
|
||||||
|
}
|
||||||
|
return next
|
||||||
|
})
|
||||||
|
}, [filteredNotebookIds, childNotebooks])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!currentNotebookId) return
|
||||||
|
const timer = window.setTimeout(() => {
|
||||||
|
const el = notebooksPanelRef.current?.querySelector(
|
||||||
|
`[data-notebook-id="${currentNotebookId}"]`,
|
||||||
|
) as HTMLElement | null
|
||||||
|
el?.scrollIntoView({ block: 'nearest', inline: 'nearest' })
|
||||||
|
}, 80)
|
||||||
|
return () => window.clearTimeout(timer)
|
||||||
|
}, [currentNotebookId])
|
||||||
|
|
||||||
const isDashboardRoute = isDashboardHomeRoute(pathname, searchParams)
|
const isDashboardRoute = isDashboardHomeRoute(pathname, searchParams)
|
||||||
const panelView: NavigationView = pathname.startsWith('/settings') ? 'settings' : activeView
|
const panelView: NavigationView = pathname.startsWith('/settings') ? 'settings' : activeView
|
||||||
|
|
||||||
@@ -981,9 +904,6 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
const mapped = notes.map((n: Note) => ({
|
const mapped = notes.map((n: Note) => ({
|
||||||
id: n.id,
|
id: n.id,
|
||||||
title: getNoteDisplayTitle(n, t('notes.untitled')),
|
title: getNoteDisplayTitle(n, t('notes.untitled')),
|
||||||
isPinned: n.isPinned,
|
|
||||||
autoGenerated: Boolean(n.autoGenerated),
|
|
||||||
isRecent: isRecentlyCreated(n.createdAt, 48),
|
|
||||||
}))
|
}))
|
||||||
return [nb.id, mapped] as const
|
return [nb.id, mapped] as const
|
||||||
})
|
})
|
||||||
@@ -1018,7 +938,7 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
if (list.some((n) => n.id === detail.note.id)) return prev
|
if (list.some((n) => n.id === detail.note.id)) return prev
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[nbId]: [{ id: detail.note.id, title, isPinned: detail.note.isPinned }, ...list],
|
[nbId]: [{ id: detail.note.id, title }, ...list],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -1027,14 +947,14 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
const note = detail.note
|
const note = detail.note
|
||||||
const title = getNoteDisplayTitle(note, t('notes.untitled'))
|
const title = getNoteDisplayTitle(note, t('notes.untitled'))
|
||||||
setNotebookNotes((prev) => {
|
setNotebookNotes((prev) => {
|
||||||
const next: Record<string, { id: string; title: string; isPinned?: boolean }[]> = {}
|
const next: Record<string, { id: string; title: string }[]> = {}
|
||||||
for (const [key, list] of Object.entries(prev)) {
|
for (const [key, list] of Object.entries(prev)) {
|
||||||
const filtered = list.filter((n) => n.id !== note.id)
|
const filtered = list.filter((n) => n.id !== note.id)
|
||||||
if (filtered.length > 0) next[key] = filtered
|
if (filtered.length > 0) next[key] = filtered
|
||||||
}
|
}
|
||||||
if (note.notebookId) {
|
if (note.notebookId) {
|
||||||
next[note.notebookId] = [
|
next[note.notebookId] = [
|
||||||
{ id: note.id, title, isPinned: note.isPinned },
|
{ id: note.id, title },
|
||||||
...(next[note.notebookId] || []),
|
...(next[note.notebookId] || []),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1070,14 +990,6 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
router.push('/home?forceList=1')
|
router.push('/home?forceList=1')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNoteClick = (noteId: string, notebookId: string) => {
|
|
||||||
const params = new URLSearchParams(searchParams.toString())
|
|
||||||
params.set('notebook', notebookId)
|
|
||||||
params.set('openNote', noteId)
|
|
||||||
params.delete('forceList')
|
|
||||||
router.push(`/home?${params.toString()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Drag state ──
|
// ── Drag state ──
|
||||||
const [dropTarget, setDropTarget] = useState<string | null>(null)
|
const [dropTarget, setDropTarget] = useState<string | null>(null)
|
||||||
const [dropAction, setDropAction] = useState<'into' | 'before' | 'after' | null>(null)
|
const [dropAction, setDropAction] = useState<'into' | 'before' | 'after' | null>(null)
|
||||||
@@ -1329,16 +1241,14 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
isPrivate: notebook.isPrivate,
|
isPrivate: notebook.isPrivate,
|
||||||
}}
|
}}
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
notes={notes}
|
noteCount={notes.length}
|
||||||
activeNoteId={currentNoteId}
|
|
||||||
onCarnetClick={() => {
|
onCarnetClick={() => {
|
||||||
if (currentNotebookId === notebook.id) {
|
if (currentNotebookId === notebook.id) {
|
||||||
toggleExpand(notebook.id)
|
if (children.length > 0) toggleExpand(notebook.id)
|
||||||
} else {
|
} else {
|
||||||
handleCarnetClick(notebook.id)
|
handleCarnetClick(notebook.id)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onNoteClick={handleNoteClick}
|
|
||||||
onAddSubNotebook={() => {
|
onAddSubNotebook={() => {
|
||||||
setCreateParentId(notebook.id)
|
setCreateParentId(notebook.id)
|
||||||
setIsCreateDialogOpen(true)
|
setIsCreateDialogOpen(true)
|
||||||
@@ -1361,7 +1271,7 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}, [rootNotebooks, childNotebooks, filteredNotebookIds, currentNotebookId, currentNoteId, notebookNotes, draggedId, dropTarget, dropAction, expandedIds, pinnedIds, aiNotebookIds, toggleExpand, handleCarnetClick, handleNoteClick, handleDragStart, handleDragEnd, handleDropOnNotebook, handleStartRename])
|
}, [rootNotebooks, childNotebooks, filteredNotebookIds, currentNotebookId, notebookNotes, draggedId, dropTarget, dropAction, expandedIds, pinnedIds, aiNotebookIds, toggleExpand, handleCarnetClick, handleDragStart, handleDragEnd, handleDropOnNotebook, handleStartRename])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -2137,9 +2047,6 @@ export function Sidebar({ className, user }: { className?: string; user?: any })
|
|||||||
const mapped = notes.map((n: Note) => ({
|
const mapped = notes.map((n: Note) => ({
|
||||||
id: n.id,
|
id: n.id,
|
||||||
title: getNoteDisplayTitle(n, t('notes.untitled')),
|
title: getNoteDisplayTitle(n, t('notes.untitled')),
|
||||||
isPinned: n.isPinned,
|
|
||||||
autoGenerated: Boolean(n.autoGenerated),
|
|
||||||
isRecent: true,
|
|
||||||
}))
|
}))
|
||||||
setNotebookNotes((prev) => ({ ...prev, [notebookId]: mapped }))
|
setNotebookNotes((prev) => ({ ...prev, [notebookId]: mapped }))
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
|
|||||||
Reference in New Issue
Block a user