Unique headers for REST operation components (#34986)
This commit is contained in:
@@ -20,6 +20,7 @@ import { useVersion } from 'components/hooks/useVersion'
|
|||||||
type Props = {
|
type Props = {
|
||||||
slug: string
|
slug: string
|
||||||
operation: Operation
|
operation: Operation
|
||||||
|
heading: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const GHCLIKEY = 'ghcli'
|
const GHCLIKEY = 'ghcli'
|
||||||
@@ -41,7 +42,7 @@ function getLanguageHighlight(selectedLanguage: string) {
|
|||||||
return selectedLanguage === JSKEY ? 'javascript' : 'curl'
|
return selectedLanguage === JSKEY ? 'javascript' : 'curl'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RestCodeSamples({ operation, slug }: Props) {
|
export function RestCodeSamples({ operation, slug, heading }: Props) {
|
||||||
const { t } = useTranslation('products')
|
const { t } = useTranslation('products')
|
||||||
const { isEnterpriseServer } = useVersion()
|
const { isEnterpriseServer } = useVersion()
|
||||||
|
|
||||||
@@ -228,7 +229,7 @@ export function RestCodeSamples({ operation, slug }: Props) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="mt-0 pt-0 h4" id={`${slug}--code-samples`}>
|
<h3 className="mt-0 pt-0 h4" id={`${slug}--code-samples`}>
|
||||||
<a href={`#${slug}--code-samples`}>{`${t('rest.reference.code_samples')}`}</a>
|
<a href={`#${slug}--code-samples`}>{heading}</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{/* Display an example selector if more than one example */}
|
{/* Display an example selector if more than one example */}
|
||||||
@@ -299,11 +300,12 @@ export function RestCodeSamples({ operation, slug }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Response section */}
|
{/* Response section */}
|
||||||
<h5
|
<div
|
||||||
|
className="mt-5 mb-2 h5"
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: displayedExample.response.description || t('rest.reference.response'),
|
__html: displayedExample.response.description || t('rest.reference.response'),
|
||||||
}}
|
}}
|
||||||
></h5>
|
></div>
|
||||||
|
|
||||||
<div className="border rounded-1">
|
<div className="border rounded-1">
|
||||||
{displayedExample.response.schema ? (
|
{displayedExample.response.schema ? (
|
||||||
|
|||||||
@@ -67,7 +67,10 @@ export function RestOperation({ operation }: Props) {
|
|||||||
<ParameterTable
|
<ParameterTable
|
||||||
slug={titleSlug}
|
slug={titleSlug}
|
||||||
numPreviews={numPreviews}
|
numPreviews={numPreviews}
|
||||||
heading={t('rest.reference.parameters')}
|
heading={t('rest.reference.parameters').replace(
|
||||||
|
'{{ RESTOperationTitle }}',
|
||||||
|
operation.title
|
||||||
|
)}
|
||||||
headers={headers}
|
headers={headers}
|
||||||
parameters={operation.parameters}
|
parameters={operation.parameters}
|
||||||
bodyParameters={operation.bodyParameters}
|
bodyParameters={operation.bodyParameters}
|
||||||
@@ -75,16 +78,48 @@ export function RestOperation({ operation }: Props) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{hasStatusCodes && (
|
{hasStatusCodes && (
|
||||||
<RestStatusCodes statusCodes={operation.statusCodes} slug={titleSlug} />
|
<RestStatusCodes
|
||||||
|
statusCodes={operation.statusCodes}
|
||||||
|
slug={titleSlug}
|
||||||
|
heading={t('rest.reference.http_status_code').replace(
|
||||||
|
'{{ RESTOperationTitle }}',
|
||||||
|
operation.title
|
||||||
|
)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="col-md-12 col-lg-6 position-sticky flex-self-start"
|
className="col-md-12 col-lg-6 position-sticky flex-self-start"
|
||||||
style={{ top: '6.5em' }}
|
style={{ top: '6.5em' }}
|
||||||
>
|
>
|
||||||
{hasCodeSamples && <RestCodeSamples operation={operation} slug={titleSlug} />}
|
{hasCodeSamples && (
|
||||||
|
<RestCodeSamples
|
||||||
|
operation={operation}
|
||||||
|
slug={titleSlug}
|
||||||
|
heading={t('rest.reference.code_samples').replace(
|
||||||
|
'{{ RESTOperationTitle }}',
|
||||||
|
operation.title
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{numPreviews > 0 && <RestPreviewNotice slug={titleSlug} previews={operation.previews} />}
|
{numPreviews > 0 && (
|
||||||
|
<RestPreviewNotice
|
||||||
|
slug={titleSlug}
|
||||||
|
previews={operation.previews}
|
||||||
|
heading={
|
||||||
|
operation.previews.length > 1
|
||||||
|
? `${t('rest.reference.preview_notices').replace(
|
||||||
|
'{{ RESTOperationTitle }}',
|
||||||
|
operation.title
|
||||||
|
)}`
|
||||||
|
: `${t('rest.reference.preview_notice').replace(
|
||||||
|
'{{ RESTOperationTitle }}',
|
||||||
|
operation.title
|
||||||
|
)}`
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
import { useTranslation } from 'components/hooks/useTranslation'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
slug: string
|
slug: string
|
||||||
previews: Array<string>
|
previews: Array<string>
|
||||||
|
heading: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RestPreviewNotice({ slug, previews }: Props) {
|
export function RestPreviewNotice({ slug, previews, heading }: Props) {
|
||||||
const { t } = useTranslation('products')
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="h4" id={`${slug}-preview-notices`}>
|
<h3 className="h4" id={`${slug}-preview-notices`}>
|
||||||
<a href={`#${slug}-preview-notices`}>
|
<a href={`#${slug}-preview-notices`}>{heading}</a>
|
||||||
{previews.length > 1
|
|
||||||
? `${t('rest.reference.preview_notices')}`
|
|
||||||
: `${t('rest.reference.preview_notice')}`}
|
|
||||||
</a>
|
|
||||||
</h3>
|
</h3>
|
||||||
{previews.map((preview, index) => (
|
{previews.map((preview, index) => (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -4,15 +4,16 @@ import { StatusCode } from './types'
|
|||||||
type Props = {
|
type Props = {
|
||||||
statusCodes: Array<StatusCode>
|
statusCodes: Array<StatusCode>
|
||||||
slug: string
|
slug: string
|
||||||
|
heading: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RestStatusCodes({ statusCodes, slug }: Props) {
|
export function RestStatusCodes({ statusCodes, slug, heading }: Props) {
|
||||||
const { t } = useTranslation('products')
|
const { t } = useTranslation('products')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="mt-4 mb-3 pt-3 h4" id={`${slug}--status-codes`}>
|
<h3 className="mt-4 mb-3 pt-3 h4" id={`${slug}--status-codes`}>
|
||||||
<a href={`#${slug}--status-codes`}>{t('rest.reference.http_status_code')}</a>
|
<a href={`#${slug}--status-codes`}>{heading}</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
|
|||||||
10
data/ui.yml
10
data/ui.yml
@@ -133,15 +133,15 @@ products:
|
|||||||
in: In
|
in: In
|
||||||
description: Description
|
description: Description
|
||||||
notes: Notes
|
notes: Notes
|
||||||
parameters: Parameters
|
parameters: Parameters for "{{ RESTOperationTitle }}"
|
||||||
response: Response
|
response: Response
|
||||||
example_response: Example response
|
example_response: Example response
|
||||||
status_code: Status code
|
status_code: Status code
|
||||||
http_status_code: HTTP response status codes
|
http_status_code: HTTP response status codes for "{{ RESTOperationTitle }}"
|
||||||
code_sample: Code sample
|
code_sample: Code sample
|
||||||
code_samples: Code samples
|
code_samples: Code samples for "{{ RESTOperationTitle }}"
|
||||||
preview_notice: Preview notice
|
preview_notice: Preview notice for "{{ RESTOperationTitle }}"
|
||||||
preview_notices: Preview notices
|
preview_notices: Preview notices for "{{ RESTOperationTitle }}"
|
||||||
preview_header_is_required: This header is <strong>required</strong>
|
preview_header_is_required: This header is <strong>required</strong>
|
||||||
preview_notice_to_change: This API is under preview and subject to change
|
preview_notice_to_change: This API is under preview and subject to change
|
||||||
works_with: Works with
|
works_with: Works with
|
||||||
|
|||||||
10
tests/fixtures/data/ui.yml
vendored
10
tests/fixtures/data/ui.yml
vendored
@@ -133,15 +133,15 @@ products:
|
|||||||
in: In
|
in: In
|
||||||
description: Description
|
description: Description
|
||||||
notes: Notes
|
notes: Notes
|
||||||
parameters: Parameters
|
parameters: Parameters for "{{ RESTOperationTitle }}"
|
||||||
response: Response
|
response: Response
|
||||||
example_response: Example response
|
example_response: Example response
|
||||||
status_code: Status code
|
status_code: Status code
|
||||||
http_status_code: HTTP response status codes
|
http_status_code: HTTP response status codes for "{{ RESTOperationTitle }}"
|
||||||
code_sample: Code sample
|
code_sample: Code sample
|
||||||
code_samples: Code samples
|
code_samples: Code samples for "{{ RESTOperationTitle }}"
|
||||||
preview_notice: Preview notice
|
preview_notice: Preview notice for "{{ RESTOperationTitle }}"
|
||||||
preview_notices: Preview notices
|
preview_notices: Preview notices for "{{ RESTOperationTitle }}"
|
||||||
preview_header_is_required: This header is <strong>required</strong>
|
preview_header_is_required: This header is <strong>required</strong>
|
||||||
preview_notice_to_change: This API is under preview and subject to change
|
preview_notice_to_change: This API is under preview and subject to change
|
||||||
works_with: Works with
|
works_with: Works with
|
||||||
|
|||||||
@@ -152,6 +152,36 @@ describe('REST references docs', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('headings', () => {
|
||||||
|
test('rest pages do not render any headings with duplicate text', async () => {
|
||||||
|
const $ = await getDOM('/en/rest/actions/artifacts')
|
||||||
|
const headingText = $('body')
|
||||||
|
.find('h2, h3, h4, h5, h6')
|
||||||
|
.map((i, el) => $(el).text())
|
||||||
|
.get()
|
||||||
|
.sort()
|
||||||
|
|
||||||
|
const dupes = headingText.filter((item, index) => headingText.indexOf(item) !== index)
|
||||||
|
|
||||||
|
const message = `The following duplicate heading texts were found: ${dupes.join(', ')}`
|
||||||
|
expect(dupes.length, message).toBe(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('rest pages do not render any headings with duplicate ids', async () => {
|
||||||
|
const $ = await getDOM('/en/rest/actions/artifacts')
|
||||||
|
const headingIDs = $('body')
|
||||||
|
.find('h2, h3, h4, h5, h6')
|
||||||
|
.map((i, el) => $(el).attr('id'))
|
||||||
|
.get()
|
||||||
|
.sort()
|
||||||
|
|
||||||
|
const dupes = headingIDs.filter((item, index) => headingIDs.indexOf(item) !== index)
|
||||||
|
|
||||||
|
const message = `The following duplicate heading IDs were found: ${dupes.join(', ')}`
|
||||||
|
expect(dupes.length, message).toBe(0)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function formatErrors(differences) {
|
function formatErrors(differences) {
|
||||||
|
|||||||
Reference in New Issue
Block a user