1- import { ApiRequest , ApiResponses , TimeAgo , Heading , Paragraph } from '@/components' ;
1+ import { ApiRequest , ApiResponses , TimeAgo , Heading , Paragraph , Tag , Note } from '@/components' ;
22import { loadMdxInfo } from '@/lib/markdown/util' ;
3- import { parseSchema , toOperations } from '@/lib/swagger/parse' ;
3+ import { parseSchemas , toOperations } from '@/lib/swagger/parse' ;
44import { toRouteSegments , toSlug } from '@/lib/util' ;
55import { notFound } from 'next/navigation' ;
66import type { Metadata } from 'next' ;
77import { withMdxMetadata , withDefaultMetadata , getLastUpdated } from '@/lib/metadata/util' ;
8+ import { getMenuItem , getActiveAncestors } from '@/lib/menu/util' ;
89import WithQuicknav from '@/components/WithQuickNav' ;
10+ import { Icon } from '@/icons' ;
11+ import { Link } from '@/components' ;
12+ import { cx } from 'class-variance-authority' ;
913
1014import styles from './page.module.css' ;
1115
@@ -27,8 +31,8 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
2731 }
2832
2933 // For Swagger operations, use the operation details
30- const schema = await parseSchema ( ) ;
31- const operations = toOperations ( schema ) ;
34+ const schemas = await parseSchemas ( ) ;
35+ const operations = toOperations ( schemas ) ;
3236 const operation = operations . find ( ( op ) => op . slug === qualifiedSlug ) ;
3337
3438 if ( operation ) {
@@ -55,8 +59,8 @@ export const generateStaticParams = async () => {
5559 . map ( ( info ) => ( { slug : info . segments } ) ) ;
5660
5761 // Generate swagger slugs
58- const schema = await parseSchema ( ) ;
59- const operations = toOperations ( schema ) ;
62+ const schemas = await parseSchemas ( ) ;
63+ const operations = toOperations ( schemas ) ;
6064 const operationSlugs = operations . map ( ( op ) => ( { slug : toRouteSegments ( op . slug ) } ) ) ;
6165
6266 return mdxSlugs . concat ( operationSlugs ) ;
@@ -70,29 +74,65 @@ const Page = async ({ params }: PageProps) => {
7074 const content = await loadMdxInfo ( 'api' ) ;
7175 const mdxInfo = content . find ( ( info ) => info . slug === qualifiedSlug ) ;
7276
77+ const pathname = `${ qualifiedSlug } ` ;
78+ const menuData = getMenuItem ( 'api' ) ;
79+ const ancestors = getActiveAncestors ( pathname , [ menuData ] ) ;
80+ const parentTitle = ancestors . length > 1 ? ancestors [ ancestors . length - 2 ] . title : null ;
81+
7382 if ( mdxInfo ) {
74- const mdxModule = await import ( `@/content/${ mdxInfo . file } ` ) ;
75- const { default : Post } = mdxModule ;
76- const lastUpdated = getLastUpdated ( mdxModule ) ;
83+ const { default : Post } = await import ( `@/content/${ mdxInfo . file } ` ) ;
84+ const lastUpdated = await getLastUpdated ( mdxInfo ) ;
7785
7886 return (
7987 < WithQuicknav >
88+ { parentTitle ? (
89+ < h2 data-quick-nav-ignore className = { cx ( styles . sectionHeading , 'monoXSUppercase' ) } >
90+ { parentTitle }
91+ </ h2 >
92+ ) : null }
8093 < Post />
8194 { lastUpdated ? < TimeAgo date = { lastUpdated } /> : null }
8295 </ WithQuicknav >
8396 ) ;
8497 }
8598
8699 // Otherwise render as an operation
87- const schema = await parseSchema ( ) ;
88- const operations = toOperations ( schema ) ;
100+ const schemas = await parseSchemas ( ) ;
101+ const operations = toOperations ( schemas ) ;
89102 const operation = operations . find ( ( op ) => op . slug === qualifiedSlug ) ;
90103
91104 if ( operation ) {
105+ const operationParentTitle =
106+ parentTitle ||
107+ ( operation . menuSegments . length > 1 ? operation . menuSegments [ operation . menuSegments . length - 2 ] : null ) ;
108+
92109 return (
93110 < div className = { styles . root } >
111+ { operationParentTitle ? (
112+ < h2 data-quick-nav-ignore className = { cx ( styles . sectionHeading , 'monoXSUppercase' ) } >
113+ { operationParentTitle }
114+ </ h2 >
115+ ) : null }
116+ { operation . experimental ? (
117+ < Tag variant = "lightyellow" className = { styles . experimentalTag } >
118+ Early access
119+ </ Tag >
120+ ) : null }
94121 < Heading size = "h1" > { operation . title } </ Heading >
95- { operation . description ? < Paragraph > { operation . description } </ Paragraph > : null }
122+ < div className = { styles . description } >
123+ { operation . description && < Paragraph > { operation . description } </ Paragraph > }
124+ { operation . sandboxLink && (
125+ < Link href = { operation . sandboxLink } className = { cx ( styles . sandboxLink , 'bodyS' ) } target = "_blank" >
126+ < span > Open API Sandbox</ span >
127+ < Icon name = "external" title = "Open API Sandbox" />
128+ </ Link >
129+ ) }
130+ </ div >
131+ { operation . experimental ? (
132+ < Note variant = "warning" noHeadline >
133+ This endpoint is in early access, and may not be available to you. Contact us to request access
134+ </ Note >
135+ ) : null }
96136
97137 < div className = { styles . gridRoot } >
98138 < Heading size = "h2" className = { styles . fullWidth } >
0 commit comments