/** * 侧栏画布树显示组件,使用业务目录库派生结构/搜索路径,只保存哪些目录项被用户折叠。 * 不重写board父子归属;活动路径和搜索可临时展开祖先,路由Link负责进入真实画布页面。 */ "use client"; import { useEffect, useMemo, useState } from "react"; import Link from "next/link"; import { ChevronRight, Network } from "lucide-react"; import { activeBoardAncestors, boardDirectory, filterBoardDirectory, type BoardBranch } from "@/lib/board-directory"; import { boardHref, matchesRef, type Board } from "@/lib/workspace"; import styles from "./workspace.module.css"; /** branches只随boards/query重算,closed是当前挂载视图局部状态,宿主切工作区可用key重建。 */ export function BoardDirectory({ boards, workspace, active, query, demo }: { boards: Board[]; workspace: string; active?: string; query: string; demo: boolean }) { const [closed, setClosed] = useState(new Set()); // memo 按 boards 引用重算;宿主更新条目须提供新数组,不能只原地改标题/父链再期待重新派生。 const branches = useMemo(() => filterBoardDirectory(boardDirectory(boards), query), [boards, query]); /** 活动画布或目录刷新时展开其祖先路径,防当前页藏在折叠树下。 */ useEffect(() => { const path = activeBoardAncestors(boards, active); setClosed((previous) => { const next = new Set(previous); for (const id of path) next.delete(id); return next; }); }, [active, boards]); /** 递归渲染树,视觉缩进最多8层但不裁掉更深子项;搜索时强制展开匹配路径而不清空用户closed记录。 */ function render(items: BoardBranch[], depth = 0) { return ; } // 有结果显示树;仅搜索无命中给提示,原始目录空时不伪造一条默认页面。 return branches.length ? render(branches) : query ?

没有找到相关页面

: null; }