feat(admin-web): add folder and project creation functionality in FolderNode and FolderTree components

This commit is contained in:
2026-07-18 12:32:45 +08:00
parent b93acd8e8c
commit a12984d174
5 changed files with 95 additions and 22 deletions
@@ -8,6 +8,8 @@
folders,
projects,
slug,
onCreateFolder,
onCreateProject,
}: {
folder: ExplorerFolder;
folders: ExplorerFolder[];
@@ -19,30 +21,58 @@
binding: { chatId: string } | null;
}[];
slug: string;
onCreateFolder?: (parentId: string) => void;
onCreateProject?: (folderId: string) => void;
} = $props();
let open = $state(true);
</script>
<div>
<button
type="button"
class="flex w-full items-center gap-2.5 px-3 py-2.5 text-left text-sm transition hover:bg-surface-100"
onclick={() => (open = !open)}
>
<span class="w-3.5 text-center text-xs text-surface-600">{open ? '▾' : '▸'}</span>
<span class="flex h-7 w-7 items-center justify-center border border-warning-300 bg-warning-50 text-warning-800">
<Icon name="folder" class="h-4 w-4" />
</span>
<span class="min-w-0 flex-1 truncate font-medium text-surface-900">{folder.name}</span>
<span class="saas-badge-neutral">{folder.projectCount} 项目</span>
{#if folder.childFolderCount > 0}
<span class="saas-badge-neutral">{folder.childFolderCount} 子夹</span>
<div class="group flex w-full items-center gap-2.5 px-3 py-2.5 text-sm transition hover:bg-surface-100">
<button type="button" class="flex min-w-0 flex-1 items-center gap-2.5 text-left" onclick={() => (open = !open)}>
<span class="w-3.5 text-center text-xs text-surface-600">{open ? '▾' : '▸'}</span>
<span class="flex h-7 w-7 items-center justify-center border border-warning-300 bg-warning-50 text-warning-800">
<Icon name="folder" class="h-4 w-4" />
</span>
<span class="min-w-0 flex-1 truncate font-medium text-surface-900">{folder.name}</span>
<span class="saas-badge-neutral">{folder.projectCount} 项目</span>
{#if folder.childFolderCount > 0}
<span class="saas-badge-neutral">{folder.childFolderCount} 子夹</span>
{/if}
</button>
{#if onCreateFolder || onCreateProject}
<span
class="flex shrink-0 items-center gap-1 opacity-0 transition group-hover:opacity-100 focus-within:opacity-100"
>
{#if onCreateFolder}
<button
type="button"
class="flex h-6 w-6 items-center justify-center border border-surface-300 bg-surface-50 text-surface-600 transition hover:border-primary-400 hover:text-primary-700"
title="在此新建子文件夹"
aria-label="在 {folder.name} 内新建子文件夹"
onclick={() => onCreateFolder(folder.id)}
>
<Icon name="folder-plus" class="h-4 w-4" />
</button>
{/if}
{#if onCreateProject}
<button
type="button"
class="flex h-6 w-6 items-center justify-center border border-surface-300 bg-surface-50 text-surface-600 transition hover:border-primary-400 hover:text-primary-700"
title="在此新建项目"
aria-label="在 {folder.name} 内新建项目"
onclick={() => onCreateProject(folder.id)}
>
<Icon name="file-plus" class="h-4 w-4" />
</button>
{/if}
</span>
{/if}
</button>
</div>
{#if open}
<div class="ml-4 border-l border-surface-300 pl-2">
<FolderTree {folders} {projects} parentId={folder.id} {slug} />
<FolderTree {folders} {projects} parentId={folder.id} {slug} {onCreateFolder} {onCreateProject} />
</div>
{/if}
</div>