1
- import { ApiRequest , ApiResponses , TimeAgo , Heading , Paragraph } from '@/components' ;
1
+ import { ApiRequest , ApiResponses , TimeAgo , Heading , Paragraph , Tag , Note } from '@/components' ;
2
2
import { loadMdxInfo } from '@/lib/markdown/util' ;
3
- import { parseSchema , toOperations } from '@/lib/swagger/parse' ;
3
+ import { parseSchemas , toOperations } from '@/lib/swagger/parse' ;
4
4
import { toRouteSegments , toSlug } from '@/lib/util' ;
5
5
import { notFound } from 'next/navigation' ;
6
6
import type { Metadata } from 'next' ;
7
7
import { withMdxMetadata , withDefaultMetadata , getLastUpdated } from '@/lib/metadata/util' ;
8
+ import { getMenuItem , getActiveAncestors } from '@/lib/menu/util' ;
8
9
import WithQuicknav from '@/components/WithQuickNav' ;
10
+ import { Icon } from '@/icons' ;
11
+ import { Link } from '@/components' ;
12
+ import { cx } from 'class-variance-authority' ;
9
13
10
14
import styles from './page.module.css' ;
11
15
@@ -27,8 +31,8 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
27
31
}
28
32
29
33
// 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 ) ;
32
36
const operation = operations . find ( ( op ) => op . slug === qualifiedSlug ) ;
33
37
34
38
if ( operation ) {
@@ -55,8 +59,8 @@ export const generateStaticParams = async () => {
55
59
. map ( ( info ) => ( { slug : info . segments } ) ) ;
56
60
57
61
// Generate swagger slugs
58
- const schema = await parseSchema ( ) ;
59
- const operations = toOperations ( schema ) ;
62
+ const schemas = await parseSchemas ( ) ;
63
+ const operations = toOperations ( schemas ) ;
60
64
const operationSlugs = operations . map ( ( op ) => ( { slug : toRouteSegments ( op . slug ) } ) ) ;
61
65
62
66
return mdxSlugs . concat ( operationSlugs ) ;
@@ -70,29 +74,65 @@ const Page = async ({ params }: PageProps) => {
70
74
const content = await loadMdxInfo ( 'api' ) ;
71
75
const mdxInfo = content . find ( ( info ) => info . slug === qualifiedSlug ) ;
72
76
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
+
73
82
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 ) ;
77
85
78
86
return (
79
87
< WithQuicknav >
88
+ { parentTitle ? (
89
+ < h2 data-quick-nav-ignore className = { cx ( styles . sectionHeading , 'monoXSUppercase' ) } >
90
+ { parentTitle }
91
+ </ h2 >
92
+ ) : null }
80
93
< Post />
81
94
{ lastUpdated ? < TimeAgo date = { lastUpdated } /> : null }
82
95
</ WithQuicknav >
83
96
) ;
84
97
}
85
98
86
99
// 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 ) ;
89
102
const operation = operations . find ( ( op ) => op . slug === qualifiedSlug ) ;
90
103
91
104
if ( operation ) {
105
+ const operationParentTitle =
106
+ parentTitle ||
107
+ ( operation . menuSegments . length > 1 ? operation . menuSegments [ operation . menuSegments . length - 2 ] : null ) ;
108
+
92
109
return (
93
110
< 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 }
94
121
< 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 }
96
136
97
137
< div className = { styles . gridRoot } >
98
138
< Heading size = "h2" className = { styles . fullWidth } >
0 commit comments