|
2 | 2 | import { z } from "astro:schema";
|
3 | 3 | import { getCollection } from "astro:content";
|
4 | 4 | import { sortBySidebarOrder } from "~/util/sidebar";
|
5 |
| -import { marked } from "marked"; |
| 5 | +import DirectoryListingItem from "./DirectoryListingItem.astro"; |
| 6 | +
|
| 7 | +interface PageNode { |
| 8 | + page: (typeof allPages)[0]; |
| 9 | + children: PageNode[]; |
| 10 | +} |
6 | 11 |
|
7 | 12 | type Props = z.infer<typeof props>;
|
8 | 13 |
|
9 | 14 | const props = z.object({
|
10 | 15 | descriptions: z.boolean().default(false),
|
11 | 16 | folder: z.string().optional(),
|
| 17 | + maxDepth: z.number().default(1), |
12 | 18 | });
|
13 | 19 |
|
14 |
| -let { descriptions, folder } = props.parse(Astro.props); |
| 20 | +let { descriptions, folder, maxDepth } = props.parse(Astro.props); |
15 | 21 |
|
16 | 22 | if (!folder) folder = Astro.params.slug!;
|
17 | 23 |
|
18 |
| -const depth = folder.split("/").length + 1; |
| 24 | +const baseDepth = folder.split("/").length; |
19 | 25 |
|
20 |
| -let pages = await getCollection("docs", (page) => { |
21 |
| - return ( |
22 |
| - page.id.startsWith(`${folder}/`) && page.id.split("/").length === depth |
23 |
| - ); |
| 26 | +let allPages = await getCollection("docs", (page) => { |
| 27 | + const pageDepth = page.id.split("/").length; |
| 28 | + return page.id.startsWith(`${folder}/`) && pageDepth <= baseDepth + maxDepth; |
24 | 29 | });
|
25 | 30 |
|
26 |
| -pages.sort(sortBySidebarOrder); |
| 31 | +allPages.sort(sortBySidebarOrder); |
| 32 | +
|
| 33 | +function getChildren(parentPath: string, depth: number) { |
| 34 | + return allPages.filter((page) => { |
| 35 | + const pagePath = page.id; |
| 36 | + const pageDepth = pagePath.split("/").length; |
| 37 | + return pageDepth === depth && pagePath.startsWith(parentPath); |
| 38 | + }); |
| 39 | +} |
| 40 | +
|
| 41 | +function buildPageTree(parentPath: string, currentDepth: number): PageNode[] { |
| 42 | + const children = getChildren(parentPath, currentDepth); |
| 43 | + return children.map((page) => ({ |
| 44 | + page, |
| 45 | + children: |
| 46 | + currentDepth < baseDepth + maxDepth |
| 47 | + ? buildPageTree(page.id, currentDepth + 1) |
| 48 | + : [], |
| 49 | + })); |
| 50 | +} |
| 51 | +
|
| 52 | +const pageTree = buildPageTree(folder, baseDepth + 1); |
27 | 53 | ---
|
28 | 54 |
|
29 | 55 | <ul>
|
30 | 56 | {
|
31 |
| - pages.map((page) => { |
32 |
| - const description = descriptions && page.data.description; |
33 |
| - const href = page.data.external_link ?? "/" + page.id + "/"; |
34 |
| - return ( |
35 |
| - <li> |
36 |
| - <a href={href}>{page.data.title}</a> |
37 |
| - {description && ( |
38 |
| - <> |
39 |
| - <span>: </span> |
40 |
| - <Fragment set:html={marked.parseInline(description)} /> |
41 |
| - </> |
42 |
| - )} |
43 |
| - </li> |
44 |
| - ); |
45 |
| - }) |
| 57 | + pageTree.map((node) => ( |
| 58 | + <DirectoryListingItem node={node} descriptions={descriptions} /> |
| 59 | + )) |
46 | 60 | }
|
47 | 61 | </ul>
|
0 commit comments