feat: show vault root in folder tree

This commit is contained in:
lucaronin
2026-04-30 00:18:33 +02:00
parent ce859aa0e7
commit ec83e9b839
17 changed files with 442 additions and 159 deletions

View File

@@ -29,6 +29,7 @@ export function FolderContextMenu({
locale = 'en',
}: FolderContextMenuProps) {
if (!menu) return null
const canMutateFolder = menu.path.length > 0
return (
<div
@@ -61,25 +62,29 @@ export function FolderContextMenu({
{translate(locale, 'sidebar.action.copyFolderPathMenu')}
</Button>
)}
<Button
type="button"
variant="ghost"
className="h-auto w-full justify-start gap-2 px-2 py-1.5 text-sm"
onClick={() => onRename(menu.path)}
>
<PencilSimple size={14} />
{translate(locale, 'sidebar.action.renameFolderMenu')}
</Button>
<Button
type="button"
variant="ghost"
className="h-auto w-full justify-start gap-2 px-2 py-1.5 text-sm text-destructive hover:text-destructive"
onClick={() => onDelete?.(menu.path)}
data-testid="delete-folder-menu-item"
>
<Trash size={14} />
{translate(locale, 'sidebar.action.deleteFolderMenu')}
</Button>
{canMutateFolder && (
<Button
type="button"
variant="ghost"
className="h-auto w-full justify-start gap-2 px-2 py-1.5 text-sm"
onClick={() => onRename(menu.path)}
>
<PencilSimple size={14} />
{translate(locale, 'sidebar.action.renameFolderMenu')}
</Button>
)}
{canMutateFolder && (
<Button
type="button"
variant="ghost"
className="h-auto w-full justify-start gap-2 px-2 py-1.5 text-sm text-destructive hover:text-destructive"
onClick={() => onDelete?.(menu.path)}
data-testid="delete-folder-menu-item"
>
<Trash size={14} />
{translate(locale, 'sidebar.action.deleteFolderMenu')}
</Button>
)}
</div>
)
}

View File

@@ -215,7 +215,7 @@ function FolderSelectButton({
paddingLeft: hasChildren ? 0 : contentInset,
paddingRight: hasActions ? 48 : 16,
}}
title={node.path}
title={node.path || node.name}
onClick={(event) => onClick(event.detail)}
onDoubleClick={onDoubleClick}
data-testid={`folder-row:${node.path}`}

View File

@@ -17,6 +17,7 @@ interface FolderTreeRowProps {
onCancelRenameFolder?: () => void
locale?: AppLocale
renamingFolderPath?: string | null
rootPath?: string
selection: SidebarSelection
}
@@ -64,6 +65,7 @@ function FolderChildren({
onCancelRenameFolder,
locale,
renamingFolderPath,
rootPath,
selection,
}: FolderTreeRowProps) {
const isExpanded = expanded[node.path] ?? false
@@ -91,6 +93,7 @@ function FolderChildren({
onCancelRenameFolder={onCancelRenameFolder}
locale={locale}
renamingFolderPath={renamingFolderPath}
rootPath={rootPath}
selection={selection}
/>
))}
@@ -111,16 +114,18 @@ export const FolderTreeRow = memo(function FolderTreeRow({
onCancelRenameFolder,
locale = 'en',
renamingFolderPath,
rootPath,
selection,
}: FolderTreeRowProps) {
const isExpanded = expanded[node.path] ?? false
const isRenaming = renamingFolderPath === node.path
const isSelected = selection.kind === 'folder' && selection.path === node.path
const canMutateFolder = node.path.length > 0
const depthIndent = depth * 16
const contentInset = 16
const selectFolder = useCallback(() => {
onSelect({ kind: 'folder', path: node.path })
}, [node.path, onSelect])
onSelect(node.path === '' ? { kind: 'folder', path: '', rootPath } : { kind: 'folder', path: node.path })
}, [node.path, onSelect, rootPath])
const row = (
<FolderItemRow
contentInset={contentInset}
@@ -128,10 +133,10 @@ export const FolderTreeRow = memo(function FolderTreeRow({
isExpanded={isExpanded}
isSelected={isSelected}
node={node}
onDeleteFolder={onDeleteFolder}
onDeleteFolder={canMutateFolder ? onDeleteFolder : undefined}
onOpenMenu={onOpenMenu}
onSelect={selectFolder}
onStartRenameFolder={onStartRenameFolder}
onStartRenameFolder={canMutateFolder ? onStartRenameFolder : undefined}
onToggle={onToggle}
locale={locale}
/>
@@ -162,6 +167,7 @@ export const FolderTreeRow = memo(function FolderTreeRow({
onCancelRenameFolder={onCancelRenameFolder}
locale={locale}
renamingFolderPath={renamingFolderPath}
rootPath={rootPath}
selection={selection}
/>
</>

View File

@@ -24,7 +24,10 @@ function useExpandedFolders(selection: SidebarSelection, renamingFolderPath?: st
)
const toggleFolder = useCallback((path: string) => {
setManualExpanded((current) => ({ ...current, [path]: !current[path] }))
setManualExpanded((current) => {
const defaultExpanded = path === ''
return { ...current, [path]: !(current[path] ?? defaultExpanded) }
})
}, [])
return {