Skip to content

Commit 2ade7d8

Browse files
authored
reactify rest pages (#25005)
1 parent 9c8ab14 commit 2ade7d8

File tree

204 files changed

+539771
-593170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

204 files changed

+539771
-593170
lines changed

Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ COPY stylesheets ./stylesheets
4646
COPY pages ./pages
4747
COPY components ./components
4848
COPY lib ./lib
49-
5049
# One part of the build relies on this content file to pull all-products
5150
COPY content/index.md ./content/index.md
5251

components/article/ArticlePage.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect } from 'react'
1+
import { useState, useEffect, ReactNode } from 'react'
22
import { useRouter } from 'next/router'
33
import dynamic from 'next/dynamic'
44
import cx from 'classnames'
@@ -50,7 +50,11 @@ const interactiveAlternatives: Record<string, { href: string }> = {
5050
},
5151
}
5252

53-
export const ArticlePage = () => {
53+
export type StructuredContentT = {
54+
structuredContent?: ReactNode
55+
}
56+
57+
export const ArticlePage = ({ structuredContent }: StructuredContentT) => {
5458
const { asPath } = useRouter()
5559
const {
5660
title,
@@ -65,6 +69,7 @@ export const ArticlePage = () => {
6569
miniTocItems,
6670
currentLearningTrack,
6771
} = useArticleContext()
72+
const renderedContent = structuredContent || renderedPage
6873
const { t } = useTranslation('pages')
6974
const currentPath = asPath.split('?')[0]
7075

@@ -236,7 +241,7 @@ export const ArticlePage = () => {
236241
}
237242
>
238243
<div id="article-contents">
239-
<MarkdownContent>{renderedPage}</MarkdownContent>
244+
<MarkdownContent>{renderedContent}</MarkdownContent>
240245
{effectiveDate && (
241246
<div className="mt-4" id="effectiveDate">
242247
Effective as of:{' '}

components/context/ArticleContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export type ArticleContextT = {
1717
title: string
1818
intro: string
1919
effectiveDate: string
20-
renderedPage: string
20+
renderedPage: string | JSX.Element[]
2121
miniTocItems: Array<MiniTocItem>
2222
contributor: { name: string; URL: string } | null
2323
permissions?: string

components/context/MainContext.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@ export type ProductGroupT = {
2121
}
2222

2323
type VersionItem = {
24+
// free-pro-team@latest, enterprise-cloud@latest, enterprise-server@3.3 ...
2425
version: string
2526
versionTitle: string
2627
currentRelease: string
2728
latestVersion: string
2829
shortName: string
30+
// api.github.com, ghes-3.3, github.ae
31+
openApiVersionName: string
32+
// api.github.com, ghes-, github.ae
33+
openApiBaseName: string
2934
}
3035

3136
export type ProductTreeNode = {

components/page-header/RestBanner.tsx

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import { useRouter } from 'next/router'
44
import { Link } from 'components/Link'
55

66
const restRepoDisplayPages = [
7-
'/rest/reference/branches',
8-
'/rest/reference/collaborators',
9-
'/rest/reference/commits',
10-
'/rest/reference/deployments',
11-
'/rest/reference/pages',
12-
'/rest/reference/releases',
13-
'/rest/reference/repos',
14-
'/rest/reference/metrics',
15-
'/rest/reference/webhooks',
7+
'branches',
8+
'collaborators',
9+
'commits',
10+
'deployments',
11+
'pages',
12+
'releases',
13+
'repos',
14+
'metrics',
15+
'webhooks',
1616
]
17-
const restEnterpriseDisplayPages = ['/rest/reference/enterprise-admin']
17+
const restEnterpriseDisplayPages = ['enterprise-admin']
1818
const restRepoCategoryExceptionsTitles = {
1919
branches: 'Branches',
2020
collaborators: 'Collaborators',
@@ -28,18 +28,14 @@ const restRepoCategoryExceptionsTitles = {
2828

2929
export const RestBanner = () => {
3030
const router = useRouter()
31-
const restPage = (router.query.restPage as string[]) || []
32-
const asPathRoot = `/${router.query.productId}/${restPage.join('/')}`
33-
if (
34-
!restRepoDisplayPages.includes(asPathRoot) &&
35-
!restEnterpriseDisplayPages.includes(asPathRoot)
36-
) {
31+
const restPage = router.query.category as string
32+
if (!restRepoDisplayPages.includes(restPage) && !restEnterpriseDisplayPages.includes(restPage)) {
3733
return null
3834
}
3935

4036
let noticeString
4137

42-
if (restRepoDisplayPages.includes(asPathRoot)) {
38+
if (restRepoDisplayPages.includes(restPage)) {
4339
const pages = Object.keys(restRepoCategoryExceptionsTitles) as Array<
4440
keyof typeof restRepoCategoryExceptionsTitles
4541
>
@@ -58,7 +54,7 @@ export const RestBanner = () => {
5854
pages.
5955
</React.Fragment>
6056
)
61-
} else if (restEnterpriseDisplayPages.includes(asPathRoot)) {
57+
} else if (restEnterpriseDisplayPages.includes(restPage)) {
6258
noticeString = (
6359
<React.Fragment>
6460
If you can't find what you're looking for, you might try the{' '}

components/rest/CodeBlock.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.codeBlock {
2+
pre {
3+
margin-bottom: 0;
4+
border: 1px solid var(--color-border-default);
5+
max-height: 32rem;
6+
overflow: auto;
7+
}
8+
}

components/rest/CodeBlock.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import cx from 'classnames'
2+
3+
import styles from './CodeBlock.module.scss'
4+
5+
type Props = {
6+
verb?: string
7+
codeBlock: string
8+
setHTML?: boolean
9+
}
10+
11+
export function CodeBlock({ verb, codeBlock, setHTML = false }: Props) {
12+
return setHTML ? (
13+
<div
14+
className={cx(styles.codeBlock, 'rounded')}
15+
dangerouslySetInnerHTML={{ __html: codeBlock }}
16+
/>
17+
) : (
18+
<pre className={cx(styles.methodCodeBlock, 'mb-3 rounded-1 border')}>
19+
<code>
20+
{verb && (
21+
<span className="color-bg-accent-emphasis color-fg-on-emphasis rounded-1 px-2 py-1 text-uppercase">
22+
{verb}
23+
</span>
24+
)}{' '}
25+
{codeBlock}
26+
</code>
27+
</pre>
28+
)
29+
}

components/rest/RestCodeSamples.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { xCodeSample } from './types'
2+
import { useTranslation } from 'components/hooks/useTranslation'
3+
import { CodeBlock } from './CodeBlock'
4+
5+
type Props = {
6+
slug: string
7+
xCodeSamples: Array<xCodeSample>
8+
}
9+
10+
export function RestCodeSamples({ slug, xCodeSamples }: Props) {
11+
const { t } = useTranslation('products')
12+
13+
return (
14+
<>
15+
<h4 className="pt-3 my-4" id={`${slug}--code-samples`}>
16+
<a href={`#${slug}--code-samples`}>{`${t('rest.reference.code_samples')}`}</a>
17+
</h4>
18+
{xCodeSamples.map((sample: xCodeSample, index: number) => {
19+
const sampleElements: JSX.Element[] = []
20+
if (sample.lang !== 'Ruby') {
21+
sampleElements.push(
22+
sample.lang === 'JavaScript' ? (
23+
<h5 key={`${sample.lang}-${index}`} className="pt-3">
24+
{sample.lang} (
25+
<a className="text-underline" href="https://github.com/octokit/core.js#readme">
26+
@octokit/core.js
27+
</a>
28+
)
29+
</h5>
30+
) : (
31+
<h5 key={`${sample.lang}-${index}`} className="pt-3">
32+
{sample.lang}
33+
</h5>
34+
)
35+
)
36+
sampleElements.push(
37+
<CodeBlock
38+
key={sample.lang + index}
39+
codeBlock={sample.sourceHTML}
40+
setHTML={true}
41+
></CodeBlock>
42+
)
43+
}
44+
return sampleElements
45+
})}
46+
</>
47+
)
48+
}

components/rest/RestHTTPMethod.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { CodeBlock } from './CodeBlock'
2+
3+
type Props = {
4+
verb: string
5+
requestPath: string
6+
}
7+
8+
export function RestHTTPMethod({ verb, requestPath }: Props) {
9+
return <CodeBlock verb={verb} codeBlock={requestPath}></CodeBlock>
10+
}

components/rest/RestNotes.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { useTranslation } from 'components/hooks/useTranslation'
2+
3+
type Props = {
4+
notes: Array<string>
5+
enabledForGitHubApps: boolean
6+
}
7+
8+
export function RestNotes({ notes, enabledForGitHubApps }: Props) {
9+
const { t } = useTranslation('products')
10+
11+
return (
12+
<>
13+
<h4 className="pt-4">{t('rest.reference.notes')}</h4>
14+
<ul className="mt-2 pl-3 pb-2">
15+
{enabledForGitHubApps && (
16+
<li>
17+
<a href="/developers/apps">Works with GitHub Apps</a>
18+
</li>
19+
)}
20+
{notes.map((note: string) => {
21+
return <li>{note}</li>
22+
})}
23+
</ul>
24+
</>
25+
)
26+
}

components/rest/RestOperation.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { RestOperationHeading } from './RestOperationHeading'
2+
import { RestHTTPMethod } from './RestHTTPMethod'
3+
import { RestParameterTable } from './RestParameterTable'
4+
import { RestCodeSamples } from './RestCodeSamples'
5+
import { RestResponse } from './RestResponse'
6+
import { Operation } from './types'
7+
import { RestNotes } from './RestNotes'
8+
import { RestPreviewNotice } from './RestPreviewNotice'
9+
10+
type Props = {
11+
operation: Operation
12+
index: number
13+
}
14+
15+
export function RestOperation({ operation }: Props) {
16+
const previews = operation['x-github'].previews
17+
const hasRequiredPreviews = previews
18+
? previews.filter((preview) => preview.required).length > 0
19+
: false
20+
21+
return (
22+
<div>
23+
<RestOperationHeading
24+
slug={operation.slug}
25+
summary={operation.summary}
26+
descriptionHTML={operation.descriptionHTML}
27+
/>
28+
<RestHTTPMethod verb={operation.verb} requestPath={operation.requestPath} />
29+
{operation.parameters && (
30+
<RestParameterTable
31+
slug={operation.slug}
32+
hasRequiredPreviews={hasRequiredPreviews}
33+
xGitHub={operation['x-github']}
34+
parameters={operation.parameters}
35+
bodyParameters={operation.bodyParameters}
36+
/>
37+
)}
38+
{operation['x-codeSamples'] && operation['x-codeSamples'].length > 0 && (
39+
<RestCodeSamples slug={operation.slug} xCodeSamples={operation['x-codeSamples']} />
40+
)}
41+
<RestResponse responses={operation.responses} />
42+
{(operation.notes.length > 0 || operation['x-github'].enabledForGitHubApps) && (
43+
<RestNotes
44+
notes={operation.notes}
45+
enabledForGitHubApps={operation['x-github'].enabledForGitHubApps}
46+
/>
47+
)}
48+
{previews && (
49+
<RestPreviewNotice slug={operation.slug} previews={operation['x-github'].previews} />
50+
)}
51+
</div>
52+
)
53+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { LinkIcon } from '@primer/octicons-react'
2+
3+
type Props = {
4+
slug: string
5+
summary: string
6+
descriptionHTML: string
7+
}
8+
9+
export function RestOperationHeading({ slug, summary, descriptionHTML }: Props) {
10+
return (
11+
<>
12+
<h3 id={slug}>
13+
<a href={`#${slug}`}>
14+
<LinkIcon size={16} className="m-1" />
15+
</a>
16+
{summary}
17+
</h3>
18+
<div dangerouslySetInnerHTML={{ __html: descriptionHTML }} />
19+
</>
20+
)
21+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.parameterTable {
2+
display: table;
3+
border-collapse: collapse;
4+
position: relative;
5+
width: 100%;
6+
line-height: 1.5;
7+
table-layout: auto;
8+
9+
thead {
10+
tr {
11+
border-top: none;
12+
13+
th {
14+
border: 0;
15+
font-weight: normal;
16+
}
17+
}
18+
}
19+
20+
tr:nth-child(2n) {
21+
background: none !important;
22+
}
23+
24+
td {
25+
padding: 0.75rem 0.5rem !important;
26+
border: 0 !important;
27+
vertical-align: top;
28+
}
29+
30+
tbody {
31+
tr td:first-child {
32+
font-weight: bold;
33+
}
34+
35+
table tr td:not(:first-child) {
36+
font-weight: normal;
37+
}
38+
}
39+
40+
code {
41+
background-color: var(--color-canvas-subtle);
42+
}
43+
}

0 commit comments

Comments
 (0)