Skip to content

Commit 467459a

Browse files
authored
Reactify graphql pages (github#28547)
1 parent b5f8a60 commit 467459a

File tree

79 files changed

+5514
-47987
lines changed

Some content is hidden

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

79 files changed

+5514
-47987
lines changed

Dockerfile

-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ ENV BUILD_SHA=$BUILD_SHA
8787
# Copy only what's needed to run the server
8888
COPY --chown=node:node package.json ./
8989
COPY --chown=node:node assets ./assets
90-
COPY --chown=node:node includes ./includes
9190
COPY --chown=node:node content ./content
9291
COPY --chown=node:node lib ./lib
9392
COPY --chown=node:node middleware ./middleware
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React from 'react'
2+
import GithubSlugger from 'github-slugger'
3+
import cx from 'classnames'
4+
import { LinkIcon } from '@primer/octicons-react'
5+
6+
import { BreakingChangesT } from 'components/graphql/types'
7+
import styles from 'components/ui/MarkdownContent/MarkdownContent.module.scss'
8+
9+
type Props = {
10+
schema: BreakingChangesT
11+
}
12+
const slugger = new GithubSlugger()
13+
14+
export function BreakingChanges({ schema }: Props) {
15+
const changes = Object.keys(schema).map((date) => {
16+
const items = schema[date]
17+
const heading = `Changes scheduled for ${date}`
18+
const slug = slugger.slug(heading)
19+
20+
return (
21+
<div className={cx(styles.markdownBody, styles.automatedPages)} key={date}>
22+
<h2 id={slug}>
23+
<a className="doctocat-link" href={`#${slug}`}>
24+
<LinkIcon className="octicon-link" size="small" />
25+
</a>
26+
{heading}
27+
</h2>
28+
{items.map((item) => {
29+
const criticalityStyles =
30+
item.criticality === 'breaking'
31+
? 'color-border-danger color-bg-danger'
32+
: 'color-border-accent-emphasis color-bg-accent'
33+
const criticality = item.criticality === 'breaking' ? 'Breaking' : 'Dangerous'
34+
35+
return (
36+
<ul key={item.location}>
37+
<li>
38+
<span className={cx(criticalityStyles, 'border rounded-1 m-1 p-1')}>
39+
{criticality}
40+
</span>{' '}
41+
A change will be made to <code>{item.location}</code>.
42+
<p>
43+
<b>Description: </b>
44+
<span dangerouslySetInnerHTML={{ __html: item.description }} />
45+
</p>
46+
<p>
47+
<b>Reason: </b> <span dangerouslySetInnerHTML={{ __html: item.reason }} />
48+
</p>
49+
</li>
50+
</ul>
51+
)
52+
})}
53+
</div>
54+
)
55+
})
56+
57+
return <div>{changes}</div>
58+
}

components/graphql/Changelog.tsx

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react'
2+
import GithubSlugger from 'github-slugger'
3+
import cx from 'classnames'
4+
import { LinkIcon } from '@primer/octicons-react'
5+
6+
import { ChangelogItemT } from 'components/graphql/types'
7+
import styles from 'components/ui/MarkdownContent/MarkdownContent.module.scss'
8+
9+
type Props = {
10+
changelogItems: ChangelogItemT[]
11+
}
12+
13+
export function Changelog({ changelogItems }: Props) {
14+
const changes = changelogItems.map((item) => {
15+
const heading = `Schema changes for ${item.date}`
16+
const slugger = new GithubSlugger()
17+
const slug = slugger.slug(heading)
18+
19+
return (
20+
<div className={cx(styles.markdownBody, styles.automatedPages)} key={item.date}>
21+
<h2 id={slug}>
22+
<a className="doctocat-link" href={`#${slug}`}>
23+
<LinkIcon className="octicon-link" size="small" />
24+
</a>
25+
{heading}
26+
</h2>
27+
{item.schemaChanges &&
28+
item.schemaChanges.map((change, index) => (
29+
<React.Fragment key={`${item.date}-schema-changes-${index}`}>
30+
<p>{change.title}</p>
31+
<ul>
32+
{change.changes.map((change) => (
33+
<li key={`${item.date}-${change}`}>
34+
<span dangerouslySetInnerHTML={{ __html: change }} />
35+
</li>
36+
))}
37+
</ul>
38+
</React.Fragment>
39+
))}
40+
{item.previewChanges &&
41+
item.previewChanges.map((change, index) => (
42+
<React.Fragment key={`${item.date}-preview-changes-${index}`}>
43+
<p>{change.title}</p>
44+
<ul>
45+
{change.changes.map((change) => (
46+
<li key={`${item.date}-${change}`}>
47+
<span dangerouslySetInnerHTML={{ __html: change }} />
48+
</li>
49+
))}
50+
</ul>
51+
</React.Fragment>
52+
))}
53+
{item.upcomingChanges &&
54+
item.upcomingChanges.map((change, index) => (
55+
<React.Fragment key={`${item.date}-upcoming-changes-${index}`}>
56+
<p>{change.title}</p>
57+
{change.changes.map((change) => (
58+
<li key={`${item.date}-${change}`}>
59+
<span dangerouslySetInnerHTML={{ __html: change }} />
60+
</li>
61+
))}
62+
</React.Fragment>
63+
))}
64+
</div>
65+
)
66+
})
67+
68+
return <div>{changes}</div>
69+
}

components/graphql/Enum.tsx

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React from 'react'
2+
3+
import { useTranslation } from 'components/hooks/useTranslation'
4+
import { GraphqlItem } from './GraphqlItem'
5+
import type { EnumT } from './types'
6+
7+
type Props = {
8+
item: EnumT
9+
}
10+
11+
export function Enum({ item }: Props) {
12+
const { t } = useTranslation('products')
13+
const heading = t('graphql.reference.values')
14+
15+
return (
16+
<GraphqlItem item={item} heading={heading}>
17+
{item.values.map((value) => (
18+
<React.Fragment key={`${value.name}-${value.description}`}>
19+
<p>
20+
<strong>{value.name}</strong>
21+
</p>
22+
<div
23+
dangerouslySetInnerHTML={{
24+
__html: value.description,
25+
}}
26+
/>
27+
</React.Fragment>
28+
))}
29+
</GraphqlItem>
30+
)
31+
}

components/graphql/GraphqlItem.tsx

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { LinkIcon } from '@primer/octicons-react'
2+
3+
import type { GraphqlT } from './types'
4+
import { Notice } from './Notice'
5+
6+
type Props = {
7+
item: GraphqlT
8+
heading?: string
9+
headingLevel?: number
10+
children?: React.ReactNode
11+
}
12+
13+
export function GraphqlItem({ item, heading, children, headingLevel = 2 }: Props) {
14+
const lowerCaseName = item.name.toLowerCase()
15+
return (
16+
<>
17+
{headingLevel === 2 && (
18+
<h2 id={lowerCaseName}>
19+
<a className="doctocat-link" href={`#${lowerCaseName}`}>
20+
<LinkIcon className="octicon-link" size="small" />
21+
</a>
22+
{item.name}
23+
</h2>
24+
)}
25+
{headingLevel === 3 && (
26+
<h3 id={lowerCaseName}>
27+
<a className="doctocat-link" href={`#${lowerCaseName}`}>
28+
<LinkIcon className="octicon-link" size="small" />
29+
</a>
30+
{item.name}
31+
</h3>
32+
)}
33+
<p
34+
dangerouslySetInnerHTML={{
35+
__html: item.description,
36+
}}
37+
/>
38+
<div>
39+
{item.preview && <Notice item={item} variant="preview" />}
40+
{item.isDeprecated && <Notice item={item} variant="deprecation" />}
41+
</div>
42+
<div>
43+
{heading && <h4>{heading}</h4>}
44+
{children}
45+
</div>
46+
</>
47+
)
48+
}

components/graphql/GraphqlPage.tsx

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import React from 'react'
2+
import cx from 'classnames'
3+
import { LinkIcon } from '@primer/octicons-react'
4+
5+
import { Enum } from 'components/graphql/Enum'
6+
import { InputObject } from 'components/graphql/InputObject'
7+
import { Interface } from 'components/graphql/Interface'
8+
import { Scalar } from 'components/graphql/Scalar'
9+
import { Mutation } from 'components/graphql/Mutation'
10+
import { Object } from 'components/graphql/Object'
11+
import { Query } from 'components/graphql/Query'
12+
import { Union } from 'components/graphql/Union'
13+
import type {
14+
EnumT,
15+
InputObjectT,
16+
InterfaceT,
17+
MutationT,
18+
ObjectT,
19+
QueryT,
20+
ScalarT,
21+
UnionT,
22+
} from 'components/graphql/types'
23+
import styles from 'components/ui/MarkdownContent/MarkdownContent.module.scss'
24+
25+
type Props = {
26+
schema: Object
27+
pageName: string
28+
objects?: ObjectT[]
29+
}
30+
31+
export const GraphqlPage = ({ schema, pageName, objects }: Props) => {
32+
const graphqlItems: JSX.Element[] = [] // In the case of the H2s for Queries
33+
34+
// The queries page has two heading sections (connections and fields)
35+
// So we need to add the heading component and the children under it
36+
// for each section.
37+
if (pageName === 'queries') {
38+
graphqlItems.push(
39+
<h2 id="connections" key="query-connections-heading">
40+
<a className="doctocat-link" href="#connections">
41+
<LinkIcon className="octicon-link" size="small" />
42+
</a>
43+
Connections
44+
</h2>
45+
)
46+
graphqlItems.push(
47+
...(schema as QueryT).connections.map((item) => (
48+
<Query item={item} key={item.id + item.name} />
49+
))
50+
)
51+
graphqlItems.push(
52+
<h2 id="fields" key="query-fields-heading">
53+
<a className="doctocat-link" href="#fields">
54+
<LinkIcon className="octicon-link" size="small" />
55+
</a>
56+
Fields
57+
</h2>
58+
)
59+
60+
graphqlItems.push(
61+
...(schema as QueryT).fields.map((item) => <Query item={item} key={item.id + item.name} />)
62+
)
63+
} else if (pageName === 'enums') {
64+
graphqlItems.push(
65+
...(schema as EnumT[]).map((item) => {
66+
return <Enum key={item.id} item={item} />
67+
})
68+
)
69+
} else if (pageName === 'inputObjects') {
70+
graphqlItems.push(
71+
...(schema as InputObjectT[]).map((item) => {
72+
return <InputObject key={item.id} item={item} />
73+
})
74+
)
75+
} else if (pageName === 'interfaces' && objects) {
76+
graphqlItems.push(
77+
...(schema as InterfaceT[]).map((item) => {
78+
return <Interface key={item.id} item={item} objects={objects} />
79+
})
80+
)
81+
} else if (pageName === 'mutations') {
82+
graphqlItems.push(
83+
...(schema as MutationT[]).map((item) => {
84+
return <Mutation key={item.id} item={item} />
85+
})
86+
)
87+
} else if (pageName === 'objects') {
88+
graphqlItems.push(
89+
...(schema as ObjectT[]).map((item) => {
90+
return <Object key={item.id} item={item} />
91+
})
92+
)
93+
} else if (pageName === 'scalars') {
94+
graphqlItems.push(
95+
...(schema as ScalarT[]).map((item) => {
96+
return <Scalar key={item.id} item={item} />
97+
})
98+
)
99+
} else if (pageName === 'unions') {
100+
graphqlItems.push(
101+
...(schema as UnionT[]).map((item) => {
102+
return <Union key={item.id} item={item} />
103+
})
104+
)
105+
}
106+
107+
return <div className={cx(styles.automatedPages, styles.markdownBody)}>{graphqlItems}</div>
108+
}

components/graphql/InputObject.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { GraphqlItem } from './GraphqlItem'
2+
import { Table } from './Table'
3+
import { useTranslation } from 'components/hooks/useTranslation'
4+
import type { InputObjectT } from './types'
5+
6+
type Props = {
7+
item: InputObjectT
8+
}
9+
10+
export function InputObject({ item }: Props) {
11+
const { t } = useTranslation('products')
12+
const heading = t('graphql.reference.input_fields')
13+
return (
14+
<GraphqlItem item={item} heading={heading}>
15+
<Table fields={item.inputFields} />
16+
</GraphqlItem>
17+
)
18+
}

components/graphql/Interface.tsx

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { useRouter } from 'next/router'
2+
3+
import { Link } from 'components/Link'
4+
import { GraphqlItem } from './GraphqlItem'
5+
import { Table } from './Table'
6+
import { useTranslation } from 'components/hooks/useTranslation'
7+
import type { ObjectT, InterfaceT } from './types'
8+
9+
type Props = {
10+
item: InterfaceT
11+
objects: ObjectT[]
12+
}
13+
14+
export function Interface({ item, objects }: Props) {
15+
const { locale } = useRouter()
16+
const { t } = useTranslation('products')
17+
const heading = t('graphql.reference.implemented_by')
18+
const heading2 = t('graphql.reference.fields')
19+
20+
const implementedBy = objects.filter(
21+
(object) =>
22+
object.implements &&
23+
object.implements.some((implementsItem) => implementsItem.name === item.name)
24+
)
25+
26+
return (
27+
<GraphqlItem item={item} heading={heading}>
28+
<ul>
29+
{implementedBy.map((object) => (
30+
<li key={`${item.id}-${item.name}-${object.href}-${object.name}`}>
31+
<code>
32+
<Link href={object.href} locale={locale}>
33+
{object.name}
34+
</Link>
35+
</code>
36+
</li>
37+
))}
38+
</ul>
39+
{item.fields && (
40+
<>
41+
<h4>{heading2}</h4>
42+
<Table fields={item.fields} />
43+
</>
44+
)}
45+
</GraphqlItem>
46+
)
47+
}

0 commit comments

Comments
 (0)