Skip to content

Commit 4ac87a8

Browse files
authored
Merge branch 'main' into patch-2
2 parents e858941 + a6413f6 commit 4ac87a8

File tree

149 files changed

+1250
-1164
lines changed

Some content is hidden

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

149 files changed

+1250
-1164
lines changed

.github/workflows/azure-preview-env-deploy.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,10 @@ jobs:
163163
rsync -rptovR ./user-code/assets/./**/*.png ./assets
164164
rsync -rptovR ./user-code/data/./**/*.{yml,md} ./data
165165
rsync -rptovR ./user-code/components/./**/*.{ts,tsx} ./components
166-
rsync -rptovR ./user-code/lib/./**/*.{js,ts,json} ./lib
167-
rsync -rptovR ./user-code/middleware/./**/*.{js,ts} ./middleware
168-
rsync -rptovR ./user-code/pages/./**/*.{tsx} ./pages
169-
rsync -rptovR ./user-code/stylesheets/./**/*.{scss} ./stylesheets
166+
rsync -rptovR --ignore-missing-args ./user-code/lib/./**/*.{js,ts} ./lib
167+
rsync -rptovR --ignore-missing-args ./user-code/middleware/./**/*.{js,ts} ./middleware
168+
rsync -rptovR ./user-code/pages/./**/*.tsx ./pages
169+
rsync -rptovR ./user-code/stylesheets/./**/*.scss ./stylesheets
170170
171171
# In addition to making the final image smaller, we also save time by not sending unnecessary files to the docker build context
172172
- name: 'Prune for preview env'

.github/workflows/move-ready-to-merge-pr.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: move PR
2525
uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
2626
with:
27-
project: Docs team reviews
27+
project: Docs open source board
2828
column: Triage
2929
repo-token: ${{ secrets.DOCUBOT_READORG_REPO_WORKFLOW_SCOPES }}
3030

.github/workflows/test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ jobs:
132132
- name: Run build script
133133
run: npm run build
134134

135+
- name: Warm possible disk caching
136+
env:
137+
NODE_ENV: test
138+
run: ./script/warm-before-tests.mjs
139+
135140
- name: Run tests
136141
env:
137142
DIFF_FILE: get_diff_files.txt

components/article/ArticlePage.tsx

Lines changed: 8 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
1-
import { useState, useEffect, ReactNode } from 'react'
1+
import { useState, useEffect } from 'react'
22
import { useRouter } from 'next/router'
33
import dynamic from 'next/dynamic'
4-
import cx from 'classnames'
5-
import { ActionList, Heading } from '@primer/react'
64

75
import { ZapIcon, InfoIcon, ShieldLockIcon } from '@primer/octicons-react'
86
import { Callout } from 'components/ui/Callout'
97

108
import { Link } from 'components/Link'
119
import { DefaultLayout } from 'components/DefaultLayout'
1210
import { ArticleTitle } from 'components/article/ArticleTitle'
13-
import { MiniTocItem, useArticleContext } from 'components/context/ArticleContext'
11+
import { useArticleContext } from 'components/context/ArticleContext'
1412
import { useTranslation } from 'components/hooks/useTranslation'
1513
import { LearningTrackNav } from './LearningTrackNav'
1614
import { MarkdownContent } from 'components/ui/MarkdownContent'
1715
import { Lead } from 'components/ui/Lead'
1816
import { ArticleGridLayout } from './ArticleGridLayout'
1917
import { PlatformPicker } from 'components/article/PlatformPicker'
2018
import { ToolPicker } from 'components/article/ToolPicker'
19+
import { MiniTocs } from 'components/ui/MiniTocs'
2120

22-
const ClientSideRedirectExceptions = dynamic(() => import('./ClientsideRedirectExceptions'), {
23-
ssr: false,
24-
})
2521
const ClientSideHighlightJS = dynamic(() => import('./ClientSideHighlightJS'), { ssr: false })
2622

2723
// Mapping of a "normal" article to it's interactive counterpart
@@ -49,12 +45,11 @@ const interactiveAlternatives: Record<string, { href: string }> = {
4945
href: '/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces?langId=py',
5046
},
5147
}
52-
53-
export type StructuredContentT = {
54-
structuredContent?: ReactNode
48+
type Props = {
49+
children?: React.ReactNode
5550
}
5651

57-
export const ArticlePage = ({ structuredContent }: StructuredContentT) => {
52+
export const ArticlePage = ({ children }: Props) => {
5853
const { asPath } = useRouter()
5954
const {
6055
title,
@@ -69,58 +64,9 @@ export const ArticlePage = ({ structuredContent }: StructuredContentT) => {
6964
miniTocItems,
7065
currentLearningTrack,
7166
} = useArticleContext()
72-
const renderedContent = structuredContent || renderedPage
7367
const { t } = useTranslation('pages')
7468
const currentPath = asPath.split('?')[0]
7569

76-
const renderTocItem = (item: MiniTocItem) => {
77-
return (
78-
<ActionList.Item
79-
as="li"
80-
key={item.contents}
81-
className={item.platform}
82-
sx={{ listStyle: 'none', padding: '2px' }}
83-
>
84-
<div className={cx('lh-condensed d-block width-full')}>
85-
<div dangerouslySetInnerHTML={{ __html: item.contents }} />
86-
{item.items && item.items.length > 0 ? (
87-
<ul className="ml-3">{item.items.map(renderTocItem)}</ul>
88-
) : null}
89-
</div>
90-
</ActionList.Item>
91-
)
92-
}
93-
94-
// We have some one-off redirects for rest api docs
95-
// currently those are limited to the repos page, but
96-
// that will grow soon as we restructure the rest api docs.
97-
// This is a workaround to updating the hardcoded links
98-
// directly in the REST API code in a separate repo, which
99-
// requires many file changes and teams to sign off.
100-
// While the organization is turbulent, we can do this.
101-
// Once it's more settled, we can refactor the rest api code
102-
// to leverage the OpenAPI urls rather than hardcoded urls.
103-
// The code below determines if we should bother loading this redirecting
104-
// component at all.
105-
// The reason this isn't done at the server-level is because there you
106-
// can't possibly access the URL hash. That's only known in client-side
107-
// code.
108-
const [loadClientsideRedirectExceptions, setLoadClientsideRedirectExceptions] = useState(false)
109-
useEffect(() => {
110-
const { hash, pathname } = window.location
111-
// Today, Jan 2022, it's known explicitly what the pathname.
112-
// In the future there might be more.
113-
// Hopefully, we can some day delete all of this and no longer
114-
// be dependent on the URL hash to do the redirect.
115-
if (
116-
hash &&
117-
(pathname.endsWith('/rest/reference/repos') ||
118-
pathname.endsWith('/rest/reference/enterprise-admin'))
119-
) {
120-
setLoadClientsideRedirectExceptions(true)
121-
}
122-
}, [])
123-
12470
// If the page contains `[data-highlight]` blocks, these pages need
12571
// syntax highlighting. But not every page needs it, so it's conditionally
12672
// lazy-loaded on the client.
@@ -139,29 +85,8 @@ export const ArticlePage = ({ structuredContent }: StructuredContentT) => {
13985
// consecutive one does.
14086
}, [asPath])
14187

142-
// Scrollable code blocks in our REST API docs and elsewhere aren't accessible
143-
// via keyboard navigation without setting tabindex="0". But we don't want to set
144-
// this attribute on every `<pre>` code block, only the ones where there are scroll
145-
// bars because the content isn't all visible.
146-
useEffect(() => {
147-
const codeBlocks = document.querySelectorAll<HTMLPreElement>('pre')
148-
149-
codeBlocks.forEach((codeBlock) => {
150-
if (
151-
codeBlock.scrollWidth > codeBlock.clientWidth ||
152-
codeBlock.scrollHeight > codeBlock.clientHeight
153-
) {
154-
codeBlock.setAttribute('tabindex', '0')
155-
}
156-
})
157-
}, [])
158-
15988
return (
16089
<DefaultLayout>
161-
{/* Doesn't matter *where* this is included because it will
162-
never render anything. It always just return null. */}
163-
{loadClientsideRedirectExceptions && <ClientSideRedirectExceptions />}
164-
16590
{/* Doesn't matter *where* this is included because it will
16691
never render anything. It always just return null. */}
16792
{lazyLoadHighlightJS && <ClientSideHighlightJS />}
@@ -220,28 +145,13 @@ export const ArticlePage = ({ structuredContent }: StructuredContentT) => {
220145
</div>
221146
)}
222147
{miniTocItems.length > 1 && (
223-
<>
224-
<Heading as="h2" id="in-this-article" className="mb-1" sx={{ fontSize: 1 }}>
225-
<Link href="#in-this-article">{t('miniToc')}</Link>
226-
</Heading>
227-
228-
<ActionList
229-
key={title}
230-
items={miniTocItems.map((items, i) => {
231-
return {
232-
key: title + i,
233-
text: title,
234-
renderItem: () => <ul>{renderTocItem(items)}</ul>,
235-
}
236-
})}
237-
/>
238-
</>
148+
<MiniTocs pageTitle={title} miniTocItems={miniTocItems} />
239149
)}
240150
</>
241151
}
242152
>
243153
<div id="article-contents">
244-
<MarkdownContent>{renderedContent}</MarkdownContent>
154+
<MarkdownContent>{children || renderedPage}</MarkdownContent>
245155
{effectiveDate && (
246156
<div className="mt-4" id="effectiveDate">
247157
Effective as of:{' '}

components/lib/events.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,15 @@ function initClipboardEvent() {
245245
})
246246
}
247247

248+
function initCopyButtonEvent() {
249+
document.documentElement.addEventListener('click', (evt) => {
250+
const target = evt.target as HTMLElement
251+
const button = target.closest('.js-btn-copy') as HTMLButtonElement
252+
if (!button) return
253+
sendEvent({ type: EventType.navigate, navigate_label: 'copy icon button' })
254+
})
255+
}
256+
248257
function initLinkEvent() {
249258
document.documentElement.addEventListener('click', (evt) => {
250259
const target = evt.target as HTMLElement
@@ -267,6 +276,7 @@ export default function initializeEvents() {
267276
initPageAndExitEvent() // must come first
268277
initLinkEvent()
269278
initClipboardEvent()
279+
initCopyButtonEvent()
270280
initPrintEvent()
271281
// survey event in ./survey.js
272282
// experiment event in ./experiment.js

components/page-header/Breadcrumbs.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import styles from './Breadcrumbs.module.scss'
66

77
export type BreadcrumbT = {
88
title: string
9-
documentType?: string
109
href?: string
1110
}
1211

components/rest/CodeBlock.tsx

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,62 @@
11
import cx from 'classnames'
2+
import { CheckIcon, CopyIcon } from '@primer/octicons-react'
3+
import { Tooltip } from '@primer/react'
4+
5+
import useClipboard from 'components/hooks/useClipboard'
26

37
import styles from './CodeBlock.module.scss'
48

59
type Props = {
610
verb?: string
11+
// Only Code samples should have a copy icon - if there's a headingLang it's a code sample
12+
headingLang?: string
713
codeBlock: string
814
highlight?: string
915
}
1016

11-
export function CodeBlock({ verb, codeBlock, highlight }: Props) {
17+
export function CodeBlock({ verb, headingLang, codeBlock, highlight }: Props) {
18+
const [isCopied, setCopied] = useClipboard(codeBlock, {
19+
successDuration: 1400,
20+
})
21+
1222
return (
13-
<pre className={cx(styles.methodCodeBlock, 'rounded-1 border')} data-highlight={highlight}>
14-
<code>
15-
{verb && (
16-
<span className="color-bg-accent-emphasis color-fg-on-emphasis rounded-1 text-uppercase">
17-
{verb}
18-
</span>
19-
)}{' '}
20-
{codeBlock}
21-
</code>
22-
</pre>
23+
<div className="code-extra">
24+
{headingLang && (
25+
<header className="d-flex flex-justify-between flex-items-center p-2 text-small rounded-top-1 border">
26+
{headingLang === 'JavaScript' ? (
27+
<span>
28+
{headingLang} (
29+
<a className="text-underline" href="https://github.com/octokit/core.js#readme">
30+
@octokit/core.js
31+
</a>
32+
)
33+
</span>
34+
) : (
35+
`${headingLang}`
36+
)}
37+
<Tooltip direction="w" aria-label={isCopied ? 'Copied!' : 'Copy to clipboard'}>
38+
<button className="js-btn-copy btn-octicon" onClick={() => setCopied()}>
39+
{isCopied ? <CheckIcon /> : <CopyIcon />}
40+
</button>
41+
</Tooltip>
42+
</header>
43+
)}
44+
<pre
45+
className={cx(
46+
styles.methodCodeBlock,
47+
'd-flex flex-justify-between flex-items-center rounded-1 border'
48+
)}
49+
data-highlight={highlight}
50+
>
51+
<code>
52+
{verb && (
53+
<span className="color-bg-accent-emphasis color-fg-on-emphasis rounded-1 text-uppercase">
54+
{verb}
55+
</span>
56+
)}{' '}
57+
{codeBlock}
58+
</code>
59+
</pre>
60+
</div>
2361
)
2462
}

components/rest/RestCodeSamples.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,10 @@ export function RestCodeSamples({ slug, xCodeSamples }: Props) {
1818
{xCodeSamples.map((sample, index) => {
1919
const sampleElements: JSX.Element[] = []
2020
if (sample.lang !== 'Ruby') {
21-
sampleElements.push(
22-
sample.lang === 'JavaScript' ? (
23-
<h5 key={`${sample.lang}-${index}`}>
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}`}>{sample.lang}</h5>
32-
)
33-
)
3421
sampleElements.push(
3522
<CodeBlock
3623
key={sample.lang + index}
24+
headingLang={sample.lang}
3725
codeBlock={sample.source}
3826
highlight={sample.lang === 'JavaScript' ? 'javascript' : 'curl'}
3927
></CodeBlock>

components/rest/RestParameterTable.module.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
}
2525

2626
tbody {
27+
tr td {
28+
width: auto;
29+
}
30+
2731
tr td:first-child {
2832
font-weight: bold;
2933
}

0 commit comments

Comments
 (0)