Skip to content

Commit

Permalink
feat: implement collapsed sections, icons, and hidden pages/sections. (
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity authored Mar 26, 2024
1 parent 303e974 commit a7ae862
Show file tree
Hide file tree
Showing 15 changed files with 347 additions and 139 deletions.
1 change: 1 addition & 0 deletions fern/apis/fdr/definition/docs/v1/db/__package__.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ types:
artifacts: optional<docsReadV1.ApiArtifacts>
showErrors: optional<boolean>
changelog: optional<docsReadV1.ChangelogSection>
hidden: optional<boolean>
fullSlug: optional<list<string>>

DocsSection:
Expand Down
3 changes: 3 additions & 0 deletions fern/apis/fdr/definition/docs/v1/read/__package__.yml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ types:
id: PageId
title: string
icon: optional<string>
hidden: optional<boolean>
urlSlug: string
fullSlug: optional<list<string>>

Expand Down Expand Up @@ -360,6 +361,7 @@ types:
properties:
title: string
icon: optional<string>
hidden: optional<boolean>
api: rootCommons.ApiDefinitionId
urlSlug: string
skipUrlSlug: boolean
Expand All @@ -374,6 +376,7 @@ types:
icon:
type: optional<string>
docs: Defaults to ActivityLog icon
hidden: optional<boolean>
description: optional<string>
pageId: optional<PageId>
items: list<ChangelogItem>
Expand Down
4 changes: 4 additions & 0 deletions fern/apis/fdr/definition/docs/v1/write/__package__.yml
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ types:
properties:
title: string
icon: optional<string>
hidden: optional<boolean>
id: PageId
urlSlugOverride: optional<string>
fullSlug: optional<list<string>>
Expand All @@ -319,6 +320,7 @@ types:
skipUrlSlug: optional<boolean>
showErrors: optional<boolean>
changelog: optional<ChangelogSection>
hidden: optional<boolean>
fullSlug: optional<list<string>>

ChangelogSection:
Expand All @@ -330,6 +332,7 @@ types:
icon:
type: optional<string>
docs: Defaults to ActivityLog icon
hidden: optional<boolean>
description: optional<string>
pageId:
type: optional<string>
Expand All @@ -343,6 +346,7 @@ types:
properties:
date: date
pageId: string
hidden: optional<boolean>

DocsSection:
properties:
Expand Down
1 change: 1 addition & 0 deletions packages/commons/fdr-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export * from "./slug";
export * from "./subpackage";
export * from "./traverser";
export * from "./types";
export * from "./visitSidebarNode";
export * from "./visitSidebarNodeRaw";
95 changes: 52 additions & 43 deletions packages/commons/fdr-utils/src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ function resolveSidebarNodeRawApiSection(
description: endpoint.description,
method: endpoint.method,
stream: endpoint.response?.type.type === "stream",
icon: undefined,
hidden: false,
}),
);
const websockets = subpackage.websockets.map(
Expand All @@ -59,6 +61,8 @@ function resolveSidebarNodeRawApiSection(
slug: [...slug, ...websocket.urlSlug.split("/")],
title: websocket.name != null ? websocket.name : stringifyEndpointPathParts(websocket.path.parts),
description: websocket.description,
icon: undefined,
hidden: false,
}),
);
const webhooks = subpackage.webhooks.map(
Expand All @@ -70,6 +74,8 @@ function resolveSidebarNodeRawApiSection(
slug: [...slug, ...webhook.urlSlug.split("/")],
title: webhook.name != null ? webhook.name : "/" + webhook.path.join("/"),
description: webhook.description,
icon: undefined,
hidden: false,
}),
);

Expand Down Expand Up @@ -135,6 +141,8 @@ function resolveSidebarNodeRawApiSection(
artifacts: undefined,
changelog: undefined,
description: undefined, // TODO: add description here
icon: undefined,
hidden: false,
};
}

Expand Down Expand Up @@ -218,38 +226,36 @@ export function resolveSidebarNodes(
parentSlugs: readonly string[], // parent slugs that are inherited from the parent node
fixedSlugs: readonly string[], // basepath and version slugs
): SidebarNodeRaw[] {
const SidebarNodeRaws: SidebarNodeRaw[] = [];
const sidebarNodes: SidebarNodeRaw[] = [];

function pushPageGroup(item: SidebarNodeRaw.PageGroup["pages"][0]) {
const lastSidebarNode = sidebarNodes[sidebarNodes.length - 1];
if (lastSidebarNode != null && lastSidebarNode.type === "pageGroup") {
lastSidebarNode.pages.push(item);
} else {
sidebarNodes.push({
type: "pageGroup",
slug: parentSlugs,
pages: [item],
});
}
}

for (const navigationItem of navigationItems) {
visitDiscriminatedUnion(navigationItem, "type")._visit<void>({
page: (page) => {
const lastSidebarNodeRaw = SidebarNodeRaws[SidebarNodeRaws.length - 1];
if (lastSidebarNodeRaw != null && lastSidebarNodeRaw.type === "pageGroup") {
lastSidebarNodeRaw.pages.push({
...page,
slug:
page.fullSlug != null
? [...fixedSlugs, ...page.fullSlug]
: [...parentSlugs, ...page.urlSlug.split("/")],
type: "page",
description: undefined,
});
} else {
SidebarNodeRaws.push({
type: "pageGroup",
slug: parentSlugs,
pages: [
{
...page,
slug:
page.fullSlug != null
? [...fixedSlugs, ...page.fullSlug]
: [...parentSlugs, ...page.urlSlug.split("/")],
type: "page",
description: undefined,
},
],
});
}
const resolvedPage: SidebarNodeRaw.Page = {
...page,
slug:
page.fullSlug != null
? [...fixedSlugs, ...page.fullSlug]
: [...parentSlugs, ...page.urlSlug.split("/")],
type: "page",
description: undefined,
icon: page.icon,
hidden: page.hidden ?? false,
};
pushPageGroup(resolvedPage);
},
api: async (api) => {
const definition = apis[api.api];
Expand All @@ -270,7 +276,7 @@ export function resolveSidebarNodes(
definitionSlug,
definition.navigation,
);
SidebarNodeRaws.push({
sidebarNodes.push({
type: "apiSection",
api: api.api,
id: api.api,
Expand All @@ -296,9 +302,13 @@ export function resolveSidebarNodes(
date: item.date,
pageId: item.pageId,
})),
icon: api.changelog.icon,
hidden: api.changelog.hidden ?? false,
}
: undefined,
description: undefined, // TODO: add description here
icon: api.icon,
hidden: api.hidden ?? false,
});
}
},
Expand All @@ -309,29 +319,28 @@ export function resolveSidebarNodes(
: section.skipUrlSlug
? parentSlugs
: [...parentSlugs, ...section.urlSlug.split("/")];
SidebarNodeRaws.push({
const resolvedSection: SidebarNodeRaw.Section = {
type: "section",
title: section.title,
slug: sectionSlug,
// if section.fullSlug is defined, the child slugs will be built from that, rather than from inherited parentSlugs
items: resolveSidebarNodes(section.items, apis, sectionSlug, fixedSlugs),
});
},
link: (link) => {
const lastSidebarNodeRaw = SidebarNodeRaws[SidebarNodeRaws.length - 1];
if (lastSidebarNodeRaw != null && lastSidebarNodeRaw.type === "pageGroup") {
lastSidebarNodeRaw.pages.push(link);
icon: section.icon,
hidden: section.hidden ?? false,
};

if (section.collapsed) {
pushPageGroup(resolvedSection);
} else {
SidebarNodeRaws.push({
type: "pageGroup",
slug: parentSlugs,
pages: [link],
});
sidebarNodes.push(resolvedSection);
}
},
link: (link) => {
pushPageGroup({ ...link, icon: link.icon });
},
_other: () => Promise.resolve(),
});
}

return SidebarNodeRaws;
return sidebarNodes;
}
19 changes: 15 additions & 4 deletions packages/commons/fdr-utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export declare namespace SidebarNodeRaw {
export interface PageGroup {
type: "pageGroup";
slug: readonly string[];
pages: (Page | Link)[];
pages: (Page | Link | Section)[];
}

export interface ChangelogPage extends Page {
Expand All @@ -91,13 +91,17 @@ export declare namespace SidebarNodeRaw {
showErrors: boolean;
changelog: ChangelogPage | undefined;
description: string | undefined;
icon: string | undefined;
hidden: boolean;
}

export interface Section {
type: "section";
title: string;
slug: readonly string[];
items: SidebarNodeRaw[];
icon: string | undefined;
hidden: boolean;
}

export interface Page {
Expand All @@ -106,12 +110,15 @@ export declare namespace SidebarNodeRaw {
slug: string[];
title: string;
description: string | undefined;
icon: string | undefined;
hidden: boolean;
}

export interface Link {
type: "link";
title: string;
url: string;
icon: string | undefined;
}

export interface WebSocketPage extends Page {
Expand Down Expand Up @@ -158,7 +165,7 @@ export declare namespace SidebarNode {
}

export interface PageGroup extends Omit<SidebarNodeRaw.PageGroup, "pages"> {
pages: (Page | SidebarNodeRaw.Link)[];
pages: (Page | SidebarNodeRaw.Link | Section)[];
}

export interface ChangelogPage extends Page, Omit<SidebarNodeRaw.ChangelogPage, keyof Page> {}
Expand Down Expand Up @@ -204,16 +211,20 @@ export declare namespace SidebarNode {
}

export const SidebarNode = {
isPage: (node: SidebarNode.Page | SidebarNodeRaw.Link): node is SidebarNode.Page => node.type === "page",
isPage: (node: SidebarNode.Page | SidebarNode.Section | SidebarNodeRaw.Link): node is SidebarNode.Page =>
node.type === "page",
isApiPage: (node: SidebarNode.Page | SidebarNode.ApiSection): node is SidebarNode.ApiPage => "apiType" in node,
isChangelogPage: (node: SidebarNode.Page): node is SidebarNode.ChangelogPage =>
node.type === "page" && (node as SidebarNode.ChangelogPage).pageType === "changelog",
isEndpointPage: (node: SidebarNode.Page): node is SidebarNode.EndpointPage =>
node.type === "page" && "method" in node,
isSubpackageSection: (node: SidebarNode.ApiPageOrSubpackage): node is SidebarNode.SubpackageSection =>
node.type === "apiSection",
};

export const SidebarNodeRaw = {
isPage: (node: SidebarNodeRaw.Page | SidebarNodeRaw.Link): node is SidebarNodeRaw.Page => node.type === "page",
isPage: (node: SidebarNodeRaw.Page | SidebarNodeRaw.Section | SidebarNodeRaw.Link): node is SidebarNodeRaw.Page =>
node.type === "page",
isApiPage: (node: SidebarNodeRaw.Page | SidebarNodeRaw.ApiSection): node is SidebarNodeRaw.ApiPage =>
"apiType" in node,
isChangelogPage: (node: SidebarNodeRaw.Page): node is SidebarNodeRaw.ChangelogPage =>
Expand Down
38 changes: 38 additions & 0 deletions packages/commons/fdr-utils/src/visitSidebarNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { noop, visitDiscriminatedUnion } from "@fern-ui/core-utils";
import { SidebarNode } from "./types";

export function visitSidebarNode(
node: SidebarNode | SidebarNode.Page,
visit: (node: SidebarNode | SidebarNode.Page, parents: SidebarNode[]) => void,
parentNodes: SidebarNode[] = [],
): void {
visit(node, parentNodes);
visitDiscriminatedUnion(node, "type")._visit({
pageGroup: (pageGroup) => {
pageGroup.pages.forEach((page) => {
if (SidebarNode.isPage(page)) {
visit(page, [...parentNodes, pageGroup]);
}
});
},
apiSection: (apiSection) => {
apiSection.items.forEach((item) => {
if (SidebarNode.isSubpackageSection(item)) {
visitSidebarNode(item, visit, [...parentNodes, apiSection]);
} else {
visit(item, [...parentNodes, apiSection]);
}
});
if (apiSection.changelog) {
visit(apiSection.changelog, [...parentNodes, apiSection]);
}
},
section: (section) => {
section.items.forEach((item) => {
visitSidebarNode(item, visit, [...parentNodes, section]);
});
},
page: noop,
_other: noop,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export function transformNavigationItemForDb(
return {
...writeShape,
icon: writeShape.icon,
hidden: writeShape.hidden ?? false,
fullSlug: writeShape.fullSlug,
urlSlug: kebabCase(writeShape.title),
artifacts:
Expand All @@ -185,6 +186,8 @@ export function transformNavigationItemForDb(
pageId: writeShape.changelog.pageId,
urlSlug: writeShape.changelog.urlSlug,
fullSlug: writeShape.fullSlug,
icon: writeShape.changelog.icon,
hidden: writeShape.changelog.hidden ?? false,
}
: undefined,
};
Expand All @@ -196,6 +199,7 @@ export function transformNavigationItemForDb(
icon: writeShape.icon,
urlSlug: writeShape.urlSlugOverride ?? kebabCase(writeShape.title),
fullSlug: writeShape.fullSlug,
hidden: writeShape.hidden ?? false,
};
case "section":
return {
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/app/src/next-app/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@
}
}

.fern-sidebar-heading {
@apply flex min-h-[32px] lg:min-h-[36px];
}

.fern-sidebar-group {
@apply list-none;
@apply max-lg:-mx-4;
Expand Down
Loading

0 comments on commit a7ae862

Please sign in to comment.