1
0
mirror of synced 2026-01-28 18:03:28 -05:00

Merge pull request #7551 from github/repo-sync

repo sync
This commit is contained in:
Octomerger Bot
2021-06-22 06:41:56 +10:00
committed by GitHub
17 changed files with 86 additions and 68 deletions

View File

@@ -23,7 +23,8 @@ type Props = {
// Homepage and 404 should be `isStandalone`, all others not
// `updateSearchParams` should be false on the GraphQL explorer page
export function Search({ isStandalone = false, updateSearchParams = true, children }: Props) {
const [query, setQuery] = useState('')
const router = useRouter()
const [query, setQuery] = useState(router.query.query || '')
const [results, setResults] = useState<Array<SearchResult>>([])
const [activeHit, setActiveHit] = useState(0)
const inputRef = useRef<HTMLInputElement>(null)
@@ -32,18 +33,14 @@ export function Search({ isStandalone = false, updateSearchParams = true, childr
// Figure out language and version for index
const { languages, searchVersions, nonEnterpriseDefaultVersion } = useMainContext()
const router = useRouter()
// fall back to the non-enterprise default version (FPT currently) on the homepage, 404 page, etc.
const version = searchVersions[currentVersion] || searchVersions[nonEnterpriseDefaultVersion]
const language = (Object.keys(languages).includes(router.locale || '') && router.locale) || 'en'
// If the user shows up with a query in the URL, go ahead and search for it
useEffect(() => {
const params = new URLSearchParams(location.search)
if (params.has('query')) {
const xquery = params.get('query')?.trim() || ''
setQuery(xquery)
/* await */ fetchSearchResults(xquery)
if (router.query.query) {
/* await */ fetchSearchResults((router.query.query as string).trim())
}
}, [])
@@ -183,7 +180,7 @@ export function Search({ isStandalone = false, updateSearchParams = true, childr
</div>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
<div
className={'search-overlay-desktop' + (!isStandalone && query ? ' js-open' : '')}
className={cx('search-overlay-desktop', !isStandalone && query ? 'js-open' : '')}
onClick={closeSearch}
></div>
</>

View File

@@ -35,7 +35,7 @@ export const Survey = () => {
}
return (
<form className="f5" onSubmit={submit} ref={formRef}>
<form className="f5" onSubmit={submit} ref={formRef} data-testid="survey-form">
<h2 className="mb-1 f4">
{t`able_to_find`}
@@ -128,7 +128,7 @@ export const Survey = () => {
</>
)}
{state === ViewState.END && <p className="color-text-secondary f6">{t`feedback`}</p>}
{state === ViewState.END && <p className="color-text-secondary f6" data-testid="survey-end">{t`feedback`}</p>}
</form>
)
}

View File

@@ -5,7 +5,7 @@ export type FeaturedTrack = {
trackName: string
title: string
description: string
guides?: Array<{ href: string; page: { type: string }; title: string; intro: string }>
guides?: Array<{ href: string; page?: { type: string }; title: string; intro: string }>
} | null
export type ArticleGuide = {

View File

@@ -36,7 +36,7 @@ export function GHESReleaseNotes({ context }: Props) {
{prevRelease ? (
<Link
className="btn btn-outline"
href={`/${currentLanguage}/${currentVersion.plan}@${prevRelease}/${currentProduct}/release-notes`}
href={`/${currentLanguage}/${currentVersion.plan}@${prevRelease}/${currentProduct?.id}/release-notes`}
>
<ChevronLeftIcon /> {prevRelease}
</Link>
@@ -51,7 +51,7 @@ export function GHESReleaseNotes({ context }: Props) {
{nextRelease ? (
<Link
className="btn btn-outline"
href={`/${currentLanguage}/${currentVersion.plan}@${nextRelease}/${currentProduct}/release-notes`}
href={`/${currentLanguage}/${currentVersion.plan}@${nextRelease}/${currentProduct?.id}/release-notes`}
>
{nextRelease} <ChevronRightIcon />
</Link>

View File

@@ -7,16 +7,17 @@ type Props = {
export const ArticleCard = ({ card, typeLabel }: Props) => {
return (
<div className="d-flex col-12 col-md-4 pr-0 pr-md-6 pr-lg-8">
<div data-testid="article-card" className="d-flex col-12 col-md-4 pr-0 pr-md-6 pr-lg-8">
<a className="no-underline d-flex flex-column py-3 border-bottom" href={card.href}>
<h4 className="h4 color-text-primary mb-1">{card.title}</h4>
<div className="h6 text-uppercase">{typeLabel}</div>
<div className="h6 text-uppercase" data-testid="article-card-type">{typeLabel}</div>
<p className="color-text-secondary my-3">{card.intro}</p>
{card.topics.length > 0 && (
<div>
{card.topics.map((topic) => {
return (
<span
data-testid="article-card-topic"
key={topic}
className="IssueLabel bg-gradient--pink-blue color-text-inverse mr-1"
>

View File

@@ -50,6 +50,7 @@ export const ArticleCards = () => {
className="form-select f4 text-bold border-0 rounded-0 border-top box-shadow-none pl-0"
name="type"
aria-label="guide types"
data-testid="card-filter-dropdown"
onChange={onChangeTypeFilter}
>
<option value="">{t('filters.all')}</option>
@@ -70,6 +71,7 @@ export const ArticleCards = () => {
value={topicFilter}
className="form-select f4 text-bold border-0 rounded-0 border-top box-shadow-none pl-0"
name="topics"
data-testid="card-filter-dropdown"
aria-label="guide topics"
onChange={onChangeTopicFilter}
>

View File

@@ -53,7 +53,7 @@ export const LearningTrack = ({ track }: Props) => {
</div>
<h5 className="flex-auto pr-2">{guide.title}</h5>
<div className="color-text-tertiary h6 text-uppercase flex-shrink-0">
{t('guide_types')[guide.page.type]}
{t('guide_types')[guide.page?.type || '']}
</div>
</a>
{track?.guides && track?.guides?.indexOf(guide) + 1 === MAX_VISIBLE_GUIDES ? (

View File

@@ -26,7 +26,7 @@ export const SubLandingHero = () => {
)}
</div>
<div className="color-text-tertiary h6 text-uppercase">
{t('guide_types')[guide.page.type]}
{t('guide_types')[guide.page?.type || '']}
</div>
</div>
<h3 className="font-mktg h3-mktg my-4 color-text-primary">{guide.title}</h3>

View File

@@ -9,7 +9,7 @@ topics:
{% data reusables.codespaces.release-stage %}
When you enable access and security for a repository owned by your user account, any codespaces that are created for that repository will have read and write permissions to all other repositories you own. If you want to restrict the repositories a codespace can access, you can limit to it to either the repository the codespace was opened for or specific repositories. You should only enable access and security for repositories you trust.
When you enable access and security for a repository owned by your user account, any codespaces that are created for that repository will have read permissions to all other repositories you own. If you want to restrict the repositories a codespace can access, you can limit to it to either the repository the codespace was opened for or specific repositories. You should only enable access and security for repositories you trust.
{% data reusables.user_settings.access_settings %}
{% data reusables.user_settings.codespaces-tab %}

View File

@@ -73494,6 +73494,16 @@
},
"descriptionHTML": "<p>Set to <code>open</code> or <code>resolved</code> to only list secret scanning alerts in a specific state.</p>"
},
{
"name": "secret_types",
"in": "query",
"description": "Set to a comma seperate list of secret_types to only list secret scanning alerts in for those types. Set to `all` to list all the secret scanning alerts. Default is `all`",
"required": false,
"schema": {
"type": "string"
},
"descriptionHTML": "<p>Set to a comma seperate list of secret_types to only list secret scanning alerts in for those types. Set to <code>all</code> to list all the secret scanning alerts. Default is <code>all</code></p>"
},
{
"name": "page",
"description": "Page number of the results to fetch.",

View File

@@ -71285,6 +71285,16 @@
},
"descriptionHTML": "<p>Set to <code>open</code> or <code>resolved</code> to only list secret scanning alerts in a specific state.</p>"
},
{
"name": "secret_types",
"in": "query",
"description": "Set to a comma seperate list of secret_types to only list secret scanning alerts in for those types. Set to `all` to list all the secret scanning alerts. Default is `all`",
"required": false,
"schema": {
"type": "string"
},
"descriptionHTML": "<p>Set to a comma seperate list of secret_types to only list secret scanning alerts in for those types. Set to <code>all</code> to list all the secret scanning alerts. Default is <code>all</code></p>"
},
{
"name": "page",
"description": "Page number of the results to fetch.",

View File

@@ -323443,6 +323443,15 @@
]
}
},
{
"name": "secret_types",
"in": "query",
"description": "Set to a comma seperate list of secret_types to only list secret scanning alerts in for those types. Set to `all` to list all the secret scanning alerts. Default is `all`",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "page",
"description": "Page number of the results to fetch.",

View File

@@ -307187,6 +307187,15 @@
]
}
},
{
"name": "secret_types",
"in": "query",
"description": "Set to a comma seperate list of secret_types to only list secret scanning alerts in for those types. Set to `all` to list all the secret scanning alerts. Default is `all`",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "page",
"description": "Page number of the results to fetch.",

View File

@@ -5,29 +5,6 @@ const versionIds = Object.keys(require('../lib/all-versions'))
const { FEATURE_NEXTJS } = process.env;
const enabledSubSections = [
// 'actions',
// 'admin',
"billing",
// "code-security",
// "codespaces",
"communities",
"desktop",
// "developers",
"discussions",
// 'early-access',
"education",
// 'github',
// "graphql",
// 'insights',
// "issues",
"organizations",
'packages',
"pages",
"rest",
"sponsors",
];
const homePageExp = pathToRegexp('/:locale/:versionId?')
const productPageExp = pathToRegexp('/:locale/:versionId?/:productId')
const subSectionExp = pathToRegexp('/:locale/:versionId?/:productId/:subSection*')
@@ -53,8 +30,7 @@ module.exports = function isNextRequest(req, res, next) {
} else if (productPageMatch && productIds.includes(productPageMatch[3])) {
req.renderWithNextjs = true
} else if (subSectionMatch) {
// depending on whether versionId is included the productId is in a different place
req.renderWithNextjs = enabledSubSections.includes(subSectionMatch[2]) || enabledSubSections.includes(subSectionMatch[3])
req.renderWithNextjs = true
}
}
}

View File

@@ -86,7 +86,7 @@ header {
margin-bottom: 0;
}
@include breakpoint(md) {
@include breakpoint(lg) {
#search-results-container {
display: none;
position: absolute;

View File

@@ -43,7 +43,7 @@ describe('browser search', () => {
await page.waitForSelector('.ais-Hits')
const hits = await page.$$('.ais-Hits-item')
expect(hits.length).toBeGreaterThan(5)
page.setViewport(initialViewport)
await page.setViewport(initialViewport)
})
it('works on 404 error page', async () => {
@@ -71,8 +71,10 @@ describe('browser search', () => {
interceptedRequest.continue()
})
await newPage.click('#search-input-container input[type="search"]')
await newPage.type('#search-input-container input[type="search"]', 'test')
await newPage.click('[data-testid=mobile-menu-button]')
const searchInput = await newPage.$('[data-testid=mobile-header] [data-testid=site-search-input]')
await searchInput.click()
await searchInput.type('test')
await newPage.waitForSelector('.search-result')
})
@@ -92,8 +94,10 @@ describe('browser search', () => {
interceptedRequest.continue()
})
await newPage.click('#search-input-container input[type="search"]')
await newPage.type('#search-input-container input[type="search"]', 'test')
await newPage.click('[data-testid=mobile-menu-button]')
const searchInput = await newPage.$('[data-testid=mobile-header] [data-testid=site-search-input]')
await searchInput.click()
await searchInput.type('test')
await newPage.waitForSelector('.search-result')
})
})
@@ -117,20 +121,20 @@ describe('survey', () => {
})
// When I click the "Yes" button
await page.click('.js-survey [for=survey-yes]')
await page.click('[data-testid=survey-form] [for=survey-yes]')
// (sent a POST request to /events)
// I see the request for my email
await page.waitForSelector('.js-survey [type="email"]')
await page.waitForSelector('[data-testid=survey-form] [type="email"]')
// When I fill in my email and submit the form
await page.type('.js-survey [type="email"]', 'test@example.com')
await page.type('[data-testid=survey-form] [type="email"]', 'test@example.com')
await sleep(1000)
await page.click('.js-survey [type="submit"]')
await page.click('[data-testid=survey-form] [type="submit"]')
// (sent a PUT request to /events/{id})
// I see the feedback
await page.waitForSelector('.js-survey [data-help-end]')
await page.waitForSelector('[data-testid=survey-end]')
})
})
@@ -257,23 +261,23 @@ describe('code examples', () => {
describe('filter cards', () => {
it('works with select input', async () => {
await page.goto('http://localhost:4001/en/actions/guides')
await page.select('.js-filter-card-filter-dropdown[name="type"]', 'overview')
const shownCards = await page.$$('.js-filter-card:not(.d-none)')
const shownCardsAttrib = await page.$$eval('.js-filter-card:not(.d-none)', cards =>
cards.map(card => card.dataset.type)
await page.select('[data-testid=card-filter-dropdown][name="type"]', 'overview')
const shownCards = await page.$$('[data-testid=article-card]')
const shownCardTypes = await page.$$eval('[data-testid=article-card-type]', cardTypes =>
cardTypes.map(cardType => cardType.textContent)
)
shownCardsAttrib.map(attrib => expect(attrib).toBe('overview'))
shownCardTypes.map(type => expect(type).toBe('Overview'))
expect(shownCards.length).toBeGreaterThan(0)
})
it('works with select input on an Enterprise version', async () => {
await page.goto(`http://localhost:4001/en/enterprise-server@${latest}/actions/guides`)
await page.select('.js-filter-card-filter-dropdown[name="type"]', 'overview')
const shownCards = await page.$$('.js-filter-card:not(.d-none)')
const shownCardsAttrib = await page.$$eval('.js-filter-card:not(.d-none)', cards =>
cards.map(card => card.dataset.type)
await page.select('[data-testid=card-filter-dropdown][name="type"]', 'overview')
const shownCards = await page.$$('[data-testid=article-card]')
const shownCardTypes = await page.$$eval('[data-testid=article-card-type]', cardTypes =>
cardTypes.map(cardType => cardType.textContent)
)
shownCardsAttrib.map(attrib => expect(attrib).toBe('overview'))
shownCardTypes.map(type => expect(type).toBe('Overview'))
expect(shownCards.length).toBeGreaterThan(0)
})
})

View File

@@ -34,12 +34,12 @@ describe('sidebar', () => {
test('adds an `is-current-page` class to the sidebar link to the current page', async () => {
const url = '/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings'
const $ = await getDOM(url)
expect($('.sidebar .is-current-page').length).toBe(1)
expect($('.sidebar .is-current-page a').attr('href')).toContain(url)
expect($('.sidebar-products .is-current-page').length).toBe(1)
expect($('.sidebar-products .is-current-page a').attr('href')).toContain(url)
})
test('does not display Early Access as a product', async () => {
expect($homePage('.sidebar li.sidebar-product[title*="Early"]').length).toBe(0)
expect($homePage('.sidebar li.sidebar-product[title*="early"]').length).toBe(0)
expect($homePage('.sidebar-products li.sidebar-product[title*="Early"]').length).toBe(0)
expect($homePage('.sidebar-products li.sidebar-product[title*="early"]').length).toBe(0)
})
})