Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d3fe424

Browse files
author
Peter Bengtsson
authored
only include productGroups in main context on homepage (#31640)
1 parent dce3db6 commit d3fe424

8 files changed

Lines changed: 100 additions & 22 deletions

File tree

components/context/MainContext.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@ export type ProductT = {
1313
versions?: Array<string>
1414
}
1515

16-
export type ProductGroupT = {
17-
name: string
18-
icon: string
19-
octicon: string
20-
children: Array<ProductT>
21-
}
22-
2316
type VersionItem = {
2417
// free-pro-team@latest, enterprise-cloud@latest, [email protected] ...
2518
version: string
@@ -77,7 +70,6 @@ export type MainContextT = {
7770
article?: BreadcrumbT
7871
}
7972
activeProducts: Array<ProductT>
80-
productGroups: Array<ProductGroupT>
8173
communityRedirect: {
8274
name: string
8375
href: string
@@ -137,7 +129,6 @@ export const getMainContext = async (req: any, res: any): Promise<MainContextT>
137129
return {
138130
breadcrumbs: req.context.breadcrumbs || {},
139131
activeProducts: req.context.activeProducts,
140-
productGroups: req.context.productGroups,
141132
communityRedirect: req.context.page?.communityRedirect || {},
142133
currentProduct: req.context.productMap[req.context.currentProduct] || null,
143134
currentLayoutName: req.context.currentLayoutName,

components/homepage/ProductSelectionCard.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { ProductT, ProductGroupT, useMainContext } from 'components/context/MainContext'
1+
import { ProductT, useMainContext } from 'components/context/MainContext'
2+
import type { ProductGroupT } from 'components/homepage/ProductSelections'
23

34
import React from 'react'
45
import { useRouter } from 'next/router'

components/homepage/ProductSelections.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
import { useMainContext } from 'components/context/MainContext'
2-
31
import React from 'react'
2+
3+
import type { ProductT } from 'components/context/MainContext'
44
import { ProductSelectionCard } from './ProductSelectionCard'
55

6-
export const ProductSelections = () => {
7-
const { productGroups } = useMainContext()
6+
export type ProductGroupT = {
7+
name: string
8+
icon: string
9+
octicon: string
10+
children: Array<ProductT>
11+
}
12+
13+
type Props = {
14+
productGroups: Array<ProductGroupT>
15+
}
816

17+
export const ProductSelections = ({ productGroups }: Props) => {
918
return (
1019
<section className="container-xl pb-lg-4 mt-6 px-3 px-md-6" data-testid="product">
1120
<div className="">

middleware/context.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import languages from '../lib/languages.js'
22
import enterpriseServerReleases from '../lib/enterprise-server-releases.js'
33
import { allVersions } from '../lib/all-versions.js'
4-
import { productMap, getProductGroups } from '../lib/all-products.js'
4+
import { productMap } from '../lib/all-products.js'
55
import pathUtils from '../lib/path-utils.js'
66
import productNames from '../lib/product-names.js'
77
import warmServer from '../lib/warm-server.js'
@@ -39,7 +39,6 @@ export default async function contextualize(req, res, next) {
3939
req.context.currentProduct = getProductStringFromPath(req.pagePath)
4040
req.context.currentCategory = getCategoryStringFromPath(req.pagePath)
4141
req.context.productMap = productMap
42-
req.context.productGroups = getProductGroups(pageMap, req.language)
4342
req.context.activeProducts = activeProducts
4443
req.context.allVersions = allVersions
4544
req.context.currentPathWithoutLanguage = getPathWithoutLanguage(req.pagePath)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { getProductGroups } from '../../lib/all-products.js'
2+
import warmServer from '../../lib/warm-server.js'
3+
import { languageKeys } from '../../lib/languages.js'
4+
import { allVersionKeys } from '../../lib/all-versions.js'
5+
6+
const isHomepage = (path) => {
7+
const split = path.split('/')
8+
// E.g. `/foo` but not `foo/bar` or `foo/`
9+
if (split.length === 2 && split[1] && !split[0]) {
10+
return languageKeys.includes(split[1])
11+
}
12+
// E.g. `/foo/possiblyproductname` but not `foo/possiblyproductname` or
13+
// `/foo/something/`
14+
if (split.length === 3 && !split[0] && split[2]) {
15+
return allVersionKeys.includes(split[2])
16+
}
17+
return false
18+
}
19+
20+
export default async function productGroups(req, res, next) {
21+
// It's important to use `req.pathPage` instead of `req.path` because
22+
// the request could be the client-side routing from Next where the URL
23+
// might be something like `/_next/data/foo/bar.json` which is translated,
24+
// in another middleware, to what it would equate to if it wasn't
25+
// client-side routing.
26+
if (isHomepage(req.pagePath)) {
27+
const { pages } = await warmServer()
28+
req.context.productGroups = getProductGroups(pages, req.language)
29+
}
30+
31+
return next()
32+
}

middleware/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import genericToc from './contextualizers/generic-toc.js'
4545
import breadcrumbs from './contextualizers/breadcrumbs.js'
4646
import features from './contextualizers/features.js'
4747
import productExamples from './contextualizers/product-examples.js'
48+
import productGroups from './contextualizers/product-groups.js'
4849
import featuredLinks from './featured-links.js'
4950
import learningTrack from './learning-track.js'
5051
import next from './next.js'
@@ -267,6 +268,7 @@ export default function (app) {
267268
app.use(asyncMiddleware(instrument(breadcrumbs, './contextualizers/breadcrumbs')))
268269
app.use(instrument(features, './contextualizers/features'))
269270
app.use(asyncMiddleware(instrument(productExamples, './contextualizers/product-examples')))
271+
app.use(asyncMiddleware(instrument(productGroups, './contextualizers/product-groups')))
270272

271273
app.use(asyncMiddleware(instrument(featuredLinks, './featured-links')))
272274
app.use(asyncMiddleware(instrument(learningTrack, './learning-track')))

pages/index.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { GetServerSideProps } from 'next'
1+
import React from 'react'
2+
import type { GetServerSideProps } from 'next'
23

34
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
45

5-
import React from 'react'
66
import { DefaultLayout } from 'components/DefaultLayout'
77
import { useTranslation } from 'components/hooks/useTranslation'
88
import { ArticleList } from 'components/landing/ArticleList'
99
import { HomePageHero } from 'components/homepage/HomePageHero'
10+
import type { ProductGroupT } from 'components/homepage/ProductSelections'
1011
import { ProductSelections } from 'components/homepage/ProductSelections'
1112

1213
type FeaturedLink = {
@@ -19,13 +20,23 @@ type Props = {
1920
mainContext: MainContextT
2021
popularLinks: Array<FeaturedLink>
2122
gettingStartedLinks: Array<FeaturedLink>
23+
productGroups: Array<ProductGroupT>
2224
}
2325

24-
export default function MainHomePage({ mainContext, gettingStartedLinks, popularLinks }: Props) {
26+
export default function MainHomePage({
27+
mainContext,
28+
gettingStartedLinks,
29+
popularLinks,
30+
productGroups,
31+
}: Props) {
2532
return (
2633
<MainContext.Provider value={mainContext}>
2734
<DefaultLayout>
28-
<HomePage gettingStartedLinks={gettingStartedLinks} popularLinks={popularLinks} />
35+
<HomePage
36+
gettingStartedLinks={gettingStartedLinks}
37+
popularLinks={popularLinks}
38+
productGroups={productGroups}
39+
/>
2940
</DefaultLayout>
3041
</MainContext.Provider>
3142
)
@@ -34,15 +45,16 @@ export default function MainHomePage({ mainContext, gettingStartedLinks, popular
3445
type HomePageProps = {
3546
popularLinks: Array<FeaturedLink>
3647
gettingStartedLinks: Array<FeaturedLink>
48+
productGroups: Array<ProductGroupT>
3749
}
3850
function HomePage(props: HomePageProps) {
39-
const { gettingStartedLinks, popularLinks } = props
51+
const { gettingStartedLinks, popularLinks, productGroups } = props
4052
const { t } = useTranslation(['toc'])
4153

4254
return (
4355
<div>
4456
<HomePageHero />
45-
<ProductSelections />
57+
<ProductSelections productGroups={productGroups} />
4658
<div className="mt-6 px-3 px-md-6 container-xl">
4759
<div className="container-xl">
4860
<div className="gutter gutter-xl-spacious clearfix">
@@ -67,6 +79,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async (context) =>
6779
return {
6880
props: {
6981
mainContext: await getMainContext(req, res),
82+
productGroups: req.context.productGroups,
7083
gettingStartedLinks: req.context.featuredLinks.gettingStarted.map(
7184
({ title, href, intro }: any) => ({ title, href, intro })
7285
),

tests/rendering/homepage.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { expect, jest } from '@jest/globals'
2+
3+
import { getDOM } from '../helpers/e2etest.js'
4+
5+
describe('rendering the home page(s)', () => {
6+
jest.setTimeout(5 * 60 * 1000)
7+
8+
test('homepage has product links', async () => {
9+
const $ = await getDOM('/en')
10+
const products = $('[data-testid=product]')
11+
expect(products.length).toBe(1)
12+
})
13+
14+
test('homepage in non-default language has product links', async () => {
15+
const $ = await getDOM('/ja')
16+
const products = $('[data-testid=product]')
17+
expect(products.length).toBe(1)
18+
})
19+
20+
test('homepage in non-default product', async () => {
21+
const $ = await getDOM('/en/enterprise-cloud@latest')
22+
const products = $('[data-testid=product]')
23+
expect(products.length).toBe(1)
24+
})
25+
26+
test('homepage in non-default product in non-default language', async () => {
27+
const $ = await getDOM('/ja/enterprise-cloud@latest')
28+
const products = $('[data-testid=product]')
29+
expect(products.length).toBe(1)
30+
})
31+
})

0 commit comments

Comments
 (0)