1
0
mirror of synced 2025-12-23 03:44:00 -05:00
Files
docs/components/sidebar/ApiVersionPicker.tsx
Grace Park baa53b778f Picker refactor (#33113)
Co-authored-by: Peter Bengtsson <peterbe@github.com>
2022-12-07 23:17:06 +00:00

134 lines
4.3 KiB
TypeScript

import { useRouter } from 'next/router'
import cx from 'classnames'
import Cookies from 'js-cookie'
import { InfoIcon } from '@primer/octicons-react'
import { useMainContext } from 'components/context/MainContext'
import { DEFAULT_VERSION, useVersion } from 'components/hooks/useVersion'
import { Picker } from 'components/ui/Picker'
import { useTranslation } from 'components/hooks/useTranslation'
import { API_VERSION_COOKIE_NAME } from 'components/RestRedirect'
import styles from './SidebarProduct.module.scss'
const API_VERSION_SUFFIX = ' (latest)'
type Props = {
variant: 'inline' | 'header'
width?: number
}
function rememberApiVersion(apiVersion: string) {
try {
// We use this cookie to remember which API Version a user chooses
// when they navigate the REST docs.
const apiVersionNormalized = apiVersion.replace(API_VERSION_SUFFIX, '')
Cookies.set(API_VERSION_COOKIE_NAME, apiVersionNormalized, {
expires: 365,
secure: document.location.protocol !== 'http:',
})
} catch (err) {
// You can never be too careful because setting a cookie
// can fail. For example, some browser
// extensions disallow all setting of cookies and attempts
// at the `document.cookie` setter could throw. Just swallow
// and move on.
console.warn('Unable to set preferred api version cookie', err)
}
}
export const ApiVersionPicker = ({ variant, width }: Props) => {
const router = useRouter()
const { currentVersion } = useVersion()
const { allVersions } = useMainContext()
const { t } = useTranslation(['products'])
const basePath = router.asPath.split('#')[0].split('?')[0]
// Get current date from cookie, query path, or lastly set it to latest rest version date
const isValidApiVersion =
(router.query.apiVersion &&
typeof router.query.apiVersion === 'string' &&
allVersions[currentVersion].apiVersions.includes(router.query.apiVersion)) ||
false
const currentDate = (
isValidApiVersion ? router.query.apiVersion : allVersions[currentVersion].latestApiVersion
) as string
const currentDateDisplayText =
currentDate === allVersions[currentVersion].latestApiVersion
? currentDate + API_VERSION_SUFFIX
: currentDate
const apiVersionLinks = allVersions[currentVersion].apiVersions.map((date) => {
const itemLink = `/${router.locale}${basePath}?apiVersion=${date}`
const dateDisplayText =
date === allVersions[currentVersion].latestApiVersion ? date + API_VERSION_SUFFIX : date
return {
text: dateDisplayText,
selected: router.query.apiVersion === date,
href: itemLink,
extra: {
info: false,
currentDate,
},
}
})
apiVersionLinks.push({
text: t('rest.versioning.about_versions'),
selected: false,
href: `/${router.locale}${
currentVersion === DEFAULT_VERSION ? '' : `/${currentVersion}`
}/rest/overview/api-versions`,
extra: {
info: true,
currentDate,
},
})
// This only shows the REST Version picker if it's calendar date versioned
return allVersions[currentVersion].apiVersions.length > 0 ? (
<div
className={
variant === 'inline'
? 'border-top my-2 pt-2'
: cx(
'pt-4 px-4 d-flex flex-justify-center pb-4 border-bottom',
styles.apiVersionPicker,
styles.apiFixedHeader
)
}
style={{ width: `${width}px` }}
>
<div data-testid="api-version-picker" className="width-full">
<Picker
variant={variant}
defaultText={currentDateDisplayText}
items={apiVersionLinks}
pickerLabel="Version"
alignment="center"
buttonBorder={true}
dataTestId="version"
ariaLabel="Select API Version"
onSelect={(item) => {
if (item.extra?.currentDate) rememberApiVersion(item.extra.currentDate)
}}
renderItem={(item) => {
return item.extra?.info ? (
<div className="f6">
{item.text}
<InfoIcon verticalAlign="middle" size={15} className="ml-1" />
</div>
) : (
item.text
)
}}
/>
</div>
</div>
) : (
<div className={cx(styles.noApiVersion)}></div>
)
}