1
0
mirror of synced 2025-12-23 11:54:18 -05:00

only include productGroups in main context on homepage (#31640)

This commit is contained in:
Peter Bengtsson
2022-10-17 22:27:19 +02:00
committed by GitHub
parent dce3db6013
commit d3fe424810
8 changed files with 100 additions and 22 deletions

View File

@@ -13,13 +13,6 @@ export type ProductT = {
versions?: Array<string>
}
export type ProductGroupT = {
name: string
icon: string
octicon: string
children: Array<ProductT>
}
type VersionItem = {
// free-pro-team@latest, enterprise-cloud@latest, enterprise-server@3.3 ...
version: string
@@ -77,7 +70,6 @@ export type MainContextT = {
article?: BreadcrumbT
}
activeProducts: Array<ProductT>
productGroups: Array<ProductGroupT>
communityRedirect: {
name: string
href: string
@@ -137,7 +129,6 @@ export const getMainContext = async (req: any, res: any): Promise<MainContextT>
return {
breadcrumbs: req.context.breadcrumbs || {},
activeProducts: req.context.activeProducts,
productGroups: req.context.productGroups,
communityRedirect: req.context.page?.communityRedirect || {},
currentProduct: req.context.productMap[req.context.currentProduct] || null,
currentLayoutName: req.context.currentLayoutName,

View File

@@ -1,4 +1,5 @@
import { ProductT, ProductGroupT, useMainContext } from 'components/context/MainContext'
import { ProductT, useMainContext } from 'components/context/MainContext'
import type { ProductGroupT } from 'components/homepage/ProductSelections'
import React from 'react'
import { useRouter } from 'next/router'

View File

@@ -1,11 +1,20 @@
import { useMainContext } from 'components/context/MainContext'
import React from 'react'
import type { ProductT } from 'components/context/MainContext'
import { ProductSelectionCard } from './ProductSelectionCard'
export const ProductSelections = () => {
const { productGroups } = useMainContext()
export type ProductGroupT = {
name: string
icon: string
octicon: string
children: Array<ProductT>
}
type Props = {
productGroups: Array<ProductGroupT>
}
export const ProductSelections = ({ productGroups }: Props) => {
return (
<section className="container-xl pb-lg-4 mt-6 px-3 px-md-6" data-testid="product">
<div className="">

View File

@@ -1,7 +1,7 @@
import languages from '../lib/languages.js'
import enterpriseServerReleases from '../lib/enterprise-server-releases.js'
import { allVersions } from '../lib/all-versions.js'
import { productMap, getProductGroups } from '../lib/all-products.js'
import { productMap } from '../lib/all-products.js'
import pathUtils from '../lib/path-utils.js'
import productNames from '../lib/product-names.js'
import warmServer from '../lib/warm-server.js'
@@ -39,7 +39,6 @@ export default async function contextualize(req, res, next) {
req.context.currentProduct = getProductStringFromPath(req.pagePath)
req.context.currentCategory = getCategoryStringFromPath(req.pagePath)
req.context.productMap = productMap
req.context.productGroups = getProductGroups(pageMap, req.language)
req.context.activeProducts = activeProducts
req.context.allVersions = allVersions
req.context.currentPathWithoutLanguage = getPathWithoutLanguage(req.pagePath)

View File

@@ -0,0 +1,32 @@
import { getProductGroups } from '../../lib/all-products.js'
import warmServer from '../../lib/warm-server.js'
import { languageKeys } from '../../lib/languages.js'
import { allVersionKeys } from '../../lib/all-versions.js'
const isHomepage = (path) => {
const split = path.split('/')
// E.g. `/foo` but not `foo/bar` or `foo/`
if (split.length === 2 && split[1] && !split[0]) {
return languageKeys.includes(split[1])
}
// E.g. `/foo/possiblyproductname` but not `foo/possiblyproductname` or
// `/foo/something/`
if (split.length === 3 && !split[0] && split[2]) {
return allVersionKeys.includes(split[2])
}
return false
}
export default async function productGroups(req, res, next) {
// It's important to use `req.pathPage` instead of `req.path` because
// the request could be the client-side routing from Next where the URL
// might be something like `/_next/data/foo/bar.json` which is translated,
// in another middleware, to what it would equate to if it wasn't
// client-side routing.
if (isHomepage(req.pagePath)) {
const { pages } = await warmServer()
req.context.productGroups = getProductGroups(pages, req.language)
}
return next()
}

View File

@@ -45,6 +45,7 @@ import genericToc from './contextualizers/generic-toc.js'
import breadcrumbs from './contextualizers/breadcrumbs.js'
import features from './contextualizers/features.js'
import productExamples from './contextualizers/product-examples.js'
import productGroups from './contextualizers/product-groups.js'
import featuredLinks from './featured-links.js'
import learningTrack from './learning-track.js'
import next from './next.js'
@@ -267,6 +268,7 @@ export default function (app) {
app.use(asyncMiddleware(instrument(breadcrumbs, './contextualizers/breadcrumbs')))
app.use(instrument(features, './contextualizers/features'))
app.use(asyncMiddleware(instrument(productExamples, './contextualizers/product-examples')))
app.use(asyncMiddleware(instrument(productGroups, './contextualizers/product-groups')))
app.use(asyncMiddleware(instrument(featuredLinks, './featured-links')))
app.use(asyncMiddleware(instrument(learningTrack, './learning-track')))

View File

@@ -1,12 +1,13 @@
import { GetServerSideProps } from 'next'
import React from 'react'
import type { GetServerSideProps } from 'next'
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
import React from 'react'
import { DefaultLayout } from 'components/DefaultLayout'
import { useTranslation } from 'components/hooks/useTranslation'
import { ArticleList } from 'components/landing/ArticleList'
import { HomePageHero } from 'components/homepage/HomePageHero'
import type { ProductGroupT } from 'components/homepage/ProductSelections'
import { ProductSelections } from 'components/homepage/ProductSelections'
type FeaturedLink = {
@@ -19,13 +20,23 @@ type Props = {
mainContext: MainContextT
popularLinks: Array<FeaturedLink>
gettingStartedLinks: Array<FeaturedLink>
productGroups: Array<ProductGroupT>
}
export default function MainHomePage({ mainContext, gettingStartedLinks, popularLinks }: Props) {
export default function MainHomePage({
mainContext,
gettingStartedLinks,
popularLinks,
productGroups,
}: Props) {
return (
<MainContext.Provider value={mainContext}>
<DefaultLayout>
<HomePage gettingStartedLinks={gettingStartedLinks} popularLinks={popularLinks} />
<HomePage
gettingStartedLinks={gettingStartedLinks}
popularLinks={popularLinks}
productGroups={productGroups}
/>
</DefaultLayout>
</MainContext.Provider>
)
@@ -34,15 +45,16 @@ export default function MainHomePage({ mainContext, gettingStartedLinks, popular
type HomePageProps = {
popularLinks: Array<FeaturedLink>
gettingStartedLinks: Array<FeaturedLink>
productGroups: Array<ProductGroupT>
}
function HomePage(props: HomePageProps) {
const { gettingStartedLinks, popularLinks } = props
const { gettingStartedLinks, popularLinks, productGroups } = props
const { t } = useTranslation(['toc'])
return (
<div>
<HomePageHero />
<ProductSelections />
<ProductSelections productGroups={productGroups} />
<div className="mt-6 px-3 px-md-6 container-xl">
<div className="container-xl">
<div className="gutter gutter-xl-spacious clearfix">
@@ -67,6 +79,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async (context) =>
return {
props: {
mainContext: await getMainContext(req, res),
productGroups: req.context.productGroups,
gettingStartedLinks: req.context.featuredLinks.gettingStarted.map(
({ title, href, intro }: any) => ({ title, href, intro })
),

View File

@@ -0,0 +1,31 @@
import { expect, jest } from '@jest/globals'
import { getDOM } from '../helpers/e2etest.js'
describe('rendering the home page(s)', () => {
jest.setTimeout(5 * 60 * 1000)
test('homepage has product links', async () => {
const $ = await getDOM('/en')
const products = $('[data-testid=product]')
expect(products.length).toBe(1)
})
test('homepage in non-default language has product links', async () => {
const $ = await getDOM('/ja')
const products = $('[data-testid=product]')
expect(products.length).toBe(1)
})
test('homepage in non-default product', async () => {
const $ = await getDOM('/en/enterprise-cloud@latest')
const products = $('[data-testid=product]')
expect(products.length).toBe(1)
})
test('homepage in non-default product in non-default language', async () => {
const $ = await getDOM('/ja/enterprise-cloud@latest')
const products = $('[data-testid=product]')
expect(products.length).toBe(1)
})
})