Isolate document collection navigation and search
Verify and deploy Tabularium / verify-and-deploy (push) Successful in 6m8s
Verify and deploy Tabularium / verify-and-deploy (push) Successful in 6m8s
This commit is contained in:
@@ -29,7 +29,10 @@ export function Navigation({
|
||||
current?: string;
|
||||
onNavigate?: () => void;
|
||||
}) {
|
||||
const groups = [...new Set(docs.map((d) => d.group))];
|
||||
const collection = docs.find((d) => d.slug === current)?.collection;
|
||||
const scopedDocs = docs.filter((d) => d.collection === collection);
|
||||
const groups = [...new Set(scopedDocs.map((d) => d.group))];
|
||||
const collections = [...new Set(docs.map((d) => d.collection))];
|
||||
return (
|
||||
<nav aria-label="文档导航">
|
||||
<Link
|
||||
@@ -39,10 +42,21 @@ export function Navigation({
|
||||
>
|
||||
<Icon name="book" size={17} /> <span>资料库</span>
|
||||
</Link>
|
||||
{!current && collections.map((name) => (
|
||||
<Link
|
||||
onClick={onNavigate}
|
||||
className="nav-item"
|
||||
href={`/docs/${docs.find((d) => d.collection === name)!.slug}`}
|
||||
key={name}
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
))}
|
||||
{collection && !groups.includes(collection) && <p className="eyebrow">{collection}</p>}
|
||||
{groups.map((group) => (
|
||||
<div className="nav-group" key={group}>
|
||||
<p>{group}</p>
|
||||
{docs
|
||||
{scopedDocs
|
||||
.filter((d) => d.group === group)
|
||||
.map((d) => (
|
||||
<Link
|
||||
@@ -81,7 +95,9 @@ export function Shell({
|
||||
const [searchStatus, setSearchStatus] = useState("");
|
||||
const [selected, setSelected] = useState(0);
|
||||
const [menu, setMenu] = useState(false);
|
||||
const collection = docs.find((d) => d.slug === current)?.collection;
|
||||
const results = searchDocs.filter((d) =>
|
||||
(!collection || d.collection === collection) &&
|
||||
`${d.title} ${d.description} ${d.searchText ?? ""}`
|
||||
.toLocaleLowerCase()
|
||||
.includes(query.trim().toLocaleLowerCase()),
|
||||
|
||||
@@ -4,7 +4,7 @@ import catalog from "../../../../content/catalog.json";
|
||||
|
||||
const directory = path.resolve(process.cwd(), "../../content/docs");
|
||||
const validSlug = /^[a-z0-9]+(?:-[a-z0-9]+)*(?:\/[a-z0-9]+(?:-[a-z0-9]+)*)*$/;
|
||||
type Metadata = { group?: string; description?: string; draft?: boolean; featured?: boolean };
|
||||
type Metadata = { collection?: string; group?: string; description?: string; draft?: boolean; featured?: boolean };
|
||||
export type DocLink = {
|
||||
slug: string; title: string; searchText?: string;
|
||||
group: string; collection: string; description: string; draft: boolean; featured: boolean;
|
||||
@@ -18,7 +18,7 @@ export async function readDoc(slug: string): Promise<Doc> {
|
||||
const collection = catalog.collections.find((c) => !c.path || slug.startsWith(`${c.path}/`))!;
|
||||
const metadata: Metadata = (catalog.documents as Record<string, Metadata>)[slug] ?? {};
|
||||
return { slug, title, content, searchText: content,
|
||||
group: metadata.group ?? collection.title, collection: collection.title,
|
||||
group: metadata.group ?? collection.title, collection: metadata.collection ?? collection.title,
|
||||
description: metadata.description ?? collection.description,
|
||||
draft: metadata.draft ?? false, featured: metadata.featured ?? false,
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"draft": true
|
||||
},
|
||||
"05-object-graphs-gc": {
|
||||
"collection": "对象关系与垃圾回收",
|
||||
"group": "运行时基础",
|
||||
"description": "从对象引用环到标记清除、分代回收与跨代引用,记录内存管理讨论。"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user