feat: hierarchical notebook system - trash, selectors, breadcrumb, sidebar tree
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m9s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m9s
- Schema: soft delete with trashedAt on Notebook model - API: PATCH/GET notebooks support trashedAt filtering with cascade - Sidebar: recursive tree rendering with collapse/expand, visual guides, hover actions - HierarchicalNotebookSelector: portal-based dropdown with search, breadcrumbs, dropUp support - AI chat: context selector with Toutes mes notes + notebook selector - Agent detail: flat selects replaced with HierarchicalNotebookSelector - Breadcrumb: notebook path display on home page - Trash view: card grid with countdown, restore/permanent delete - CSS: design tokens (ink, paper, blueprint, concrete, etc.) - Types: parentId, trashedAt added to Notebook interface
This commit is contained in:
@@ -11,7 +11,7 @@ import { useLanguage } from '@/lib/i18n'
|
||||
import { MarkdownContent } from '@/components/markdown-content'
|
||||
import { useWebSearchAvailable } from '@/hooks/use-web-search-available'
|
||||
import { useNotebooks } from '@/context/notebooks-context'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { HierarchicalNotebookSelector } from '@/components/hierarchical-notebook-selector'
|
||||
import { toast } from 'sonner'
|
||||
import { createConversation } from '@/app/actions/chat-actions'
|
||||
|
||||
@@ -352,29 +352,39 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
|
||||
{/* Input Area & Tone Controls (Only in Chat tab) */}
|
||||
<div className={cn("p-4 border-t border-border/40 bg-background shrink-0", activeTab !== 'chat' && "hidden")}>
|
||||
{/* Context Scope */}
|
||||
<div className="mb-3">
|
||||
<span className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground block mb-1.5 ml-1">{t('ai.discussionContextLabel')}</span>
|
||||
<Select value={chatScope} onValueChange={setChatScope}>
|
||||
<SelectTrigger className="h-8 text-xs bg-background border-border/60">
|
||||
<SelectValue placeholder={t('ai.selectNotebook')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">
|
||||
<div className="flex items-center gap-2">
|
||||
<Layers className="h-4 w-4 text-muted-foreground" />
|
||||
<span>{t('ai.allMyNotes')}</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
{notebooks && notebooks.length > 0 && notebooks.map(nb => (
|
||||
<SelectItem key={nb.id} value={nb.id}>
|
||||
<div className="flex items-center gap-2">
|
||||
<BookOpen className="h-4 w-4 text-muted-foreground" />
|
||||
<span>{nb.name}</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="mb-3 space-y-2">
|
||||
<span className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground block ml-1">Source du Contexte</span>
|
||||
<button
|
||||
onClick={() => setChatScope('all')}
|
||||
className={cn(
|
||||
'w-full p-2.5 border rounded-lg text-xs flex items-center justify-between transition-all',
|
||||
chatScope === 'all' ? 'bg-blueprint/10 border-blueprint/30' : 'bg-card border-border hover:border-foreground/20'
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Layers className="h-3.5 w-3.5 text-blueprint/60" />
|
||||
<span className={cn('font-medium', chatScope === 'all' ? 'text-blueprint' : 'text-foreground/60')}>
|
||||
{t('ai.allMyNotes') || 'Toutes mes notes'}
|
||||
</span>
|
||||
</div>
|
||||
{chatScope === 'all' && (
|
||||
<span className="text-[8px] bg-blueprint/10 text-blueprint px-1.5 py-0.5 rounded uppercase font-bold">Auto</span>
|
||||
)}
|
||||
</button>
|
||||
|
||||
<div className="flex items-center gap-2 px-2">
|
||||
<div className="h-px flex-1 bg-border/40" />
|
||||
<span className="text-[9px] font-bold text-muted-foreground uppercase tracking-widest">+ Carnet</span>
|
||||
<div className="h-px flex-1 bg-border/40" />
|
||||
</div>
|
||||
|
||||
<HierarchicalNotebookSelector
|
||||
notebooks={notebooks.filter(nb => !nb.trashedAt)}
|
||||
selectedId={chatScope !== 'all' ? chatScope : null}
|
||||
onSelect={(id) => setChatScope(id)}
|
||||
placeholder={t('ai.selectNotebook') || 'Inclure un carnet...'}
|
||||
dropUp
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Tone Selection */}
|
||||
|
||||
Reference in New Issue
Block a user