From 21a3604235943ed07cbfa1fddee54be5a4de6910 Mon Sep 17 00:00:00 2001 From: Paul Gottschling Date: Tue, 2 Jul 2024 13:14:31 -0400 Subject: [PATCH] Improve the sidebar generator Improve the sidebar generator to accommodate the reorganized docs site. - Alphabetize auto-generated sidebar entries. The exception is any page that includes "Introduction" or "introduction" in the title. Elevate these to the first entry to avoid a confusing sidebar order. - Show third-level category pages in the sidebar without showing their contents. This way, we can add content one level beyond the level permitted in the sidebar while still showing the category page for that content in the sidebar. --- server/pages-helpers.ts | 24 +++++- uvu-tests/config-docs.test.ts | 155 ++++++++++++++++++++++++++++++++-- 2 files changed, 169 insertions(+), 10 deletions(-) diff --git a/server/pages-helpers.ts b/server/pages-helpers.ts index b755648f09..ed7052f2f7 100644 --- a/server/pages-helpers.ts +++ b/server/pages-helpers.ts @@ -72,6 +72,19 @@ const getEntryForPath = (fs, filePath) => { }; }; +const sortByTitle = (a, b) => { + switch (true) { + case a.title.toLowerCase().includes("introduction"): + return -1; + break; + case b.title.toLowerCase().includes("introduction"): + return 1; + break; + default: + return a.title < b.title ? -1 : 1; + } +}; + export const generateNavPaths = (fs, dirPath) => { const firstLvl = fs.readdirSync(dirPath, "utf8"); let result = []; @@ -124,15 +137,22 @@ export const generateNavPaths = (fs, dirPath) => { return; } - const fullPath2 = join(sectionDir, f2); + let fullPath2 = join(sectionDir, f2); const stat = fs.statSync(fullPath2); if (stat.isDirectory()) { - return; + const possibleCategoryPage = join(fullPath2, name + ".mdx"); + if (fs.existsSync(possibleCategoryPage)) { + fullPath2 = possibleCategoryPage; + } else { + return; + } } section.entries.push(getEntryForPath(fs, fullPath2)); }); + section.entries.sort(sortByTitle); result.push(section); }); + result.sort(sortByTitle); return result; }; diff --git a/uvu-tests/config-docs.test.ts b/uvu-tests/config-docs.test.ts index 7db74aa009..292b0f40e3 100644 --- a/uvu-tests/config-docs.test.ts +++ b/uvu-tests/config-docs.test.ts @@ -139,10 +139,6 @@ title: Database RBAC Reference }; const expected = [ - { - title: "Protect Databases with Teleport", - slug: "/database-access/introduction/", - }, { title: "Database Access Guides", slug: "/database-access/guides/guides/", @@ -161,16 +157,20 @@ title: Database RBAC Reference title: "Database Access RBAC", slug: "/database-access/rbac/rbac/", entries: [ - { - title: "Get Started with DB RBAC", - slug: "/database-access/rbac/get-started/", - }, { title: "Database RBAC Reference", slug: "/database-access/rbac/reference/", }, + { + title: "Get Started with DB RBAC", + slug: "/database-access/rbac/get-started/", + }, ], }, + { + title: "Protect Databases with Teleport", + slug: "/database-access/introduction/", + }, ]; const vol = Volume.fromJSON(files); @@ -179,6 +179,96 @@ title: Database RBAC Reference assert.equal(actual, expected); }); +Suite( + "generateNavPaths alphabetizes second-level links except 'Introduction'", + () => { + const files = { + "/docs/pages/database-access/mongodb.mdx": `--- +title: MongoDB +---`, + "/docs/pages/database-access/azure-dbs.mdx": `--- +title: Azure +---`, + "/docs/pages/database-access/introduction.mdx": `--- +title: Introduction to Database Access +---`, + }; + + const expected = [ + { + title: "Introduction to Database Access", + slug: "/database-access/introduction/", + }, + { + title: "Azure", + slug: "/database-access/azure-dbs/", + }, + { + title: "MongoDB", + slug: "/database-access/mongodb/", + }, + ]; + + const vol = Volume.fromJSON(files); + const fs = createFsFromVolume(vol); + const actual = generateNavPaths(fs, "/docs/pages/database-access"); + assert.equal(actual, expected); + } +); + +Suite( + "generateNavPaths alphabetizes third-level links except 'Introduction'", + () => { + const files = { + "/docs/pages/database-access/guides/guides.mdx": `--- +title: Database Access Guides +---`, + "/docs/pages/database-access/guides/postgres.mdx": `--- +title: Postgres Guide +---`, + "/docs/pages/database-access/guides/mysql.mdx": `--- +title: MySQL Guide +---`, + "/docs/pages/database-access/guides/get-started.mdx": `--- +title: Introduction to Database RBAC +---`, + "/docs/pages/database-access/guides/reference.mdx": `--- +title: Database RBAC Reference +---`, + }; + + const expected = [ + { + title: "Database Access Guides", + slug: "/database-access/guides/guides/", + entries: [ + { + title: "Introduction to Database RBAC", + slug: "/database-access/guides/get-started/", + }, + { + title: "Database RBAC Reference", + slug: "/database-access/guides/reference/", + }, + { + title: "MySQL Guide", + slug: "/database-access/guides/mysql/", + }, + { + title: "Postgres Guide", + slug: "/database-access/guides/postgres/", + }, + ], + }, + ]; + + const vol = Volume.fromJSON(files); + const fs = createFsFromVolume(vol); + const actual = generateNavPaths(fs, "/docs/pages/database-access"); + assert.equal(actual, expected); + } +); + Suite( "generateNavPaths throws if there is no category page in a subdirectory", () => { @@ -199,4 +289,53 @@ title: MySQL Guide } ); +Suite( + "generateNavPaths shows third-level category pages on the sidebar", + () => { + const files = { + "/docs/pages/database-access/guides/guides.mdx": `--- +title: Database Access Guides +---`, + "/docs/pages/database-access/guides/postgres.mdx": `--- +title: Postgres Guide +---`, + "/docs/pages/database-access/guides/mysql.mdx": `--- +title: MySQL Guide +---`, + "/docs/pages/database-access/guides/rbac/rbac.mdx": `--- +title: Database Access RBAC +---`, + "/docs/pages/database-access/guides/rbac/get-started.mdx": `--- +title: Get Started with DB RBAC +---`, + }; + + const expected = [ + { + title: "Database Access Guides", + slug: "/database-access/guides/guides/", + entries: [ + { + title: "Database Access RBAC", + slug: "/database-access/guides/rbac/rbac/", + }, + { + title: "MySQL Guide", + slug: "/database-access/guides/mysql/", + }, + { + title: "Postgres Guide", + slug: "/database-access/guides/postgres/", + }, + ], + }, + ]; + + const vol = Volume.fromJSON(files); + const fs = createFsFromVolume(vol); + const actual = generateNavPaths(fs, "/docs/pages/database-access"); + assert.equal(actual, expected); + } +); + Suite.run();