inline-expand knowledge folders via hover chevron

This commit is contained in:
Arjun 2026-04-18 12:22:54 +05:30
parent acc655172d
commit 5aedec2db9
2 changed files with 55 additions and 5 deletions

View file

@ -3390,9 +3390,9 @@ function App() {
return return
} }
// Top-level knowledge folders (except Notes) open as a bases view with folder filter // Top-level knowledge folders open as a bases view with folder filter
const parts = path.split('/') const parts = path.split('/')
if (parts.length === 2 && parts[0] === 'knowledge' && parts[1] !== 'Notes') { if (parts.length === 2 && parts[0] === 'knowledge') {
const folderName = parts[1] const folderName = parts[1]
const folderCfg = FOLDER_BASE_CONFIGS[folderName] const folderCfg = FOLDER_BASE_CONFIGS[folderName]
setBaseConfigByPath((prev) => ({ setBaseConfigByPath((prev) => ({
@ -4141,6 +4141,14 @@ function App() {
selectedPath={selectedPath} selectedPath={selectedPath}
expandedPaths={expandedPaths} expandedPaths={expandedPaths}
onSelectFile={toggleExpand} onSelectFile={toggleExpand}
onToggleFolder={(path) => {
setExpandedPaths((prev) => {
const next = new Set(prev)
if (next.has(path)) next.delete(path)
else next.add(path)
return next
})
}}
knowledgeActions={knowledgeActions} knowledgeActions={knowledgeActions}
onVoiceNoteCreated={handleVoiceNoteCreated} onVoiceNoteCreated={handleVoiceNoteCreated}
runs={runs} runs={runs}

View file

@ -63,6 +63,7 @@ import {
SidebarGroupContent, SidebarGroupContent,
SidebarHeader, SidebarHeader,
SidebarMenu, SidebarMenu,
SidebarMenuAction,
SidebarMenuButton, SidebarMenuButton,
SidebarMenuItem, SidebarMenuItem,
SidebarMenuSub, SidebarMenuSub,
@ -170,6 +171,7 @@ type SidebarContentPanelProps = {
selectedPath: string | null selectedPath: string | null
expandedPaths: Set<string> expandedPaths: Set<string>
onSelectFile: (path: string, kind: "file" | "dir") => void onSelectFile: (path: string, kind: "file" | "dir") => void
onToggleFolder?: (path: string) => void
knowledgeActions: KnowledgeActions knowledgeActions: KnowledgeActions
onVoiceNoteCreated?: (path: string) => void onVoiceNoteCreated?: (path: string) => void
runs?: RunListItem[] runs?: RunListItem[]
@ -403,6 +405,7 @@ export function SidebarContentPanel({
selectedPath, selectedPath,
expandedPaths, expandedPaths,
onSelectFile, onSelectFile,
onToggleFolder,
knowledgeActions, knowledgeActions,
onVoiceNoteCreated, onVoiceNoteCreated,
runs = [], runs = [],
@ -605,6 +608,7 @@ export function SidebarContentPanel({
selectedPath={selectedPath} selectedPath={selectedPath}
expandedPaths={expandedPaths} expandedPaths={expandedPaths}
onSelectFile={onSelectFile} onSelectFile={onSelectFile}
onToggleFolder={onToggleFolder}
actions={knowledgeActions} actions={knowledgeActions}
onVoiceNoteCreated={onVoiceNoteCreated} onVoiceNoteCreated={onVoiceNoteCreated}
/> />
@ -993,6 +997,7 @@ function KnowledgeSection({
selectedPath, selectedPath,
expandedPaths, expandedPaths,
onSelectFile, onSelectFile,
onToggleFolder,
actions, actions,
onVoiceNoteCreated, onVoiceNoteCreated,
}: { }: {
@ -1000,6 +1005,7 @@ function KnowledgeSection({
selectedPath: string | null selectedPath: string | null
expandedPaths: Set<string> expandedPaths: Set<string>
onSelectFile: (path: string, kind: "file" | "dir") => void onSelectFile: (path: string, kind: "file" | "dir") => void
onToggleFolder?: (path: string) => void
actions: KnowledgeActions actions: KnowledgeActions
onVoiceNoteCreated?: (path: string) => void onVoiceNoteCreated?: (path: string) => void
}) { }) {
@ -1089,6 +1095,7 @@ function KnowledgeSection({
selectedPath={selectedPath} selectedPath={selectedPath}
expandedPaths={expandedPaths} expandedPaths={expandedPaths}
onSelect={onSelectFile} onSelect={onSelectFile}
onToggleFolder={onToggleFolder}
actions={actions} actions={actions}
/> />
))} ))}
@ -1125,12 +1132,14 @@ function Tree({
selectedPath, selectedPath,
expandedPaths, expandedPaths,
onSelect, onSelect,
onToggleFolder,
actions, actions,
}: { }: {
item: TreeNode item: TreeNode
selectedPath: string | null selectedPath: string | null
expandedPaths: Set<string> expandedPaths: Set<string>
onSelect: (path: string, kind: "file" | "dir") => void onSelect: (path: string, kind: "file" | "dir") => void
onToggleFolder?: (path: string) => void
actions: KnowledgeActions actions: KnowledgeActions
}) { }) {
const isDir = item.kind === 'dir' const isDir = item.kind === 'dir'
@ -1267,15 +1276,15 @@ function Tree({
) )
} }
// Top-level knowledge folders (except Notes) open bases view — render as flat items // Top-level knowledge folders open bases view — render as flat items
const parts = item.path.split('/') const parts = item.path.split('/')
const isBasesFolder = isDir && parts.length === 2 && parts[0] === 'knowledge' && parts[1] !== 'Notes' const isBasesFolder = isDir && parts.length === 2 && parts[0] === 'knowledge'
if (isBasesFolder) { if (isBasesFolder) {
return ( return (
<ContextMenu> <ContextMenu>
<ContextMenuTrigger asChild> <ContextMenuTrigger asChild>
<SidebarMenuItem> <SidebarMenuItem className="group/file-item">
<SidebarMenuButton onClick={() => onSelect(item.path, item.kind)}> <SidebarMenuButton onClick={() => onSelect(item.path, item.kind)}>
<Folder className="size-4 shrink-0" /> <Folder className="size-4 shrink-0" />
<div className="flex w-full items-center gap-1 min-w-0"> <div className="flex w-full items-center gap-1 min-w-0">
@ -1283,6 +1292,38 @@ function Tree({
<span className="text-xs text-sidebar-foreground/50 tabular-nums shrink-0">{countFiles(item)}</span> <span className="text-xs text-sidebar-foreground/50 tabular-nums shrink-0">{countFiles(item)}</span>
</div> </div>
</SidebarMenuButton> </SidebarMenuButton>
{onToggleFolder && (item.children?.length ?? 0) > 0 && (
<SidebarMenuAction
showOnHover
aria-label={isExpanded ? "Collapse folder" : "Expand folder"}
onClick={(e) => {
e.stopPropagation()
onToggleFolder(item.path)
}}
>
<ChevronRight
className={cn(
"transition-transform",
isExpanded && "rotate-90",
)}
/>
</SidebarMenuAction>
)}
{isExpanded && (
<SidebarMenuSub>
{(item.children ?? []).map((subItem, index) => (
<Tree
key={index}
item={subItem}
selectedPath={selectedPath}
expandedPaths={expandedPaths}
onSelect={onSelect}
onToggleFolder={onToggleFolder}
actions={actions}
/>
))}
</SidebarMenuSub>
)}
</SidebarMenuItem> </SidebarMenuItem>
</ContextMenuTrigger> </ContextMenuTrigger>
{contextMenuContent} {contextMenuContent}
@ -1347,6 +1388,7 @@ function Tree({
selectedPath={selectedPath} selectedPath={selectedPath}
expandedPaths={expandedPaths} expandedPaths={expandedPaths}
onSelect={onSelect} onSelect={onSelect}
onToggleFolder={onToggleFolder}
actions={actions} actions={actions}
/> />
))} ))}