Files
curriculum-project-hub/hub/admin-web/src/lib/components/FolderNode.svelte
T

79 lines
2.6 KiB
Svelte

<script lang="ts">
import type { ExplorerFolder } from '$lib/api';
import Icon from './Icon.svelte';
import FolderTree from './FolderTree.svelte';
let {
folder,
folders,
projects,
slug,
onCreateFolder,
onCreateProject,
}: {
folder: ExplorerFolder;
folders: ExplorerFolder[];
projects: {
id: string;
name: string;
folderId: string | null;
createdAt: string;
binding: { chatId: string } | null;
}[];
slug: string;
onCreateFolder?: (parentId: string) => void;
onCreateProject?: (folderId: string) => void;
} = $props();
let open = $state(true);
</script>
<div>
<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}
</div>
{#if open}
<div class="ml-4 border-l border-surface-300 pl-2">
<FolderTree {folders} {projects} parentId={folder.id} {slug} {onCreateFolder} {onCreateProject} />
</div>
{/if}
</div>