зеркало из https://github.com/github/docs.git
Create landings subject folder (#37416)
This commit is contained in:
Родитель
5d9014dcd9
Коммит
cad57eeca3
|
@ -1,7 +1,10 @@
|
|||
import pick from 'lodash/pick'
|
||||
import { createContext, useContext } from 'react'
|
||||
import { LearningTrack } from './ArticleContext'
|
||||
import { FeaturedLink, getFeaturedLinksFromReq } from './ProductLandingContext'
|
||||
import {
|
||||
FeaturedLink,
|
||||
getFeaturedLinksFromReq,
|
||||
} from 'src/landings/components/ProductLandingContext'
|
||||
|
||||
export type TocItem = {
|
||||
fullPath: string
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import cx from 'classnames'
|
||||
|
||||
import { useMainContext } from 'components/context/MainContext'
|
||||
import { SidebarProduct } from './SidebarProduct'
|
||||
import { SidebarHomepage } from './SidebarHomepage'
|
||||
import { SidebarProduct } from 'src/landings/components/SidebarProduct'
|
||||
import { SidebarHomepage } from '../../src/landings/components/SidebarHomepage'
|
||||
import { AllProductsLink } from './AllProductsLink'
|
||||
import { ApiVersionPicker } from 'src/rest/components/ApiVersionPicker'
|
||||
import { Link } from 'components/Link'
|
||||
|
|
|
@ -50,7 +50,7 @@ import glossaries from './contextualizers/glossaries.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 featuredLinks from '../src/landings/middleware/featured-links.js'
|
||||
import learningTrack from './learning-track.js'
|
||||
import next from './next.js'
|
||||
import renderPage from './render-page.js'
|
||||
|
|
|
@ -1,128 +1 @@
|
|||
import { GetServerSideProps } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
// "legacy" javascript needed to maintain existing functionality
|
||||
// typically operating on elements **within** an article.
|
||||
import copyCode from 'components/lib/copy-code'
|
||||
import localization from 'components/lib/localization'
|
||||
import wrapCodeTerms from 'components/lib/wrap-code-terms'
|
||||
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
|
||||
import {
|
||||
getProductLandingContextFromRequest,
|
||||
ProductLandingContextT,
|
||||
ProductLandingContext,
|
||||
} from 'components/context/ProductLandingContext'
|
||||
import {
|
||||
getProductGuidesContextFromRequest,
|
||||
ProductGuidesContextT,
|
||||
ProductGuidesContext,
|
||||
} from 'components/context/ProductGuidesContext'
|
||||
|
||||
import {
|
||||
getArticleContextFromRequest,
|
||||
ArticleContextT,
|
||||
ArticleContext,
|
||||
} from 'components/context/ArticleContext'
|
||||
import { ArticlePage } from 'components/article/ArticlePage'
|
||||
|
||||
import { ProductLanding } from 'components/landing/ProductLanding'
|
||||
import { ProductGuides } from 'components/guides/ProductGuides'
|
||||
import { TocLanding } from 'components/landing/TocLanding'
|
||||
import {
|
||||
getTocLandingContextFromRequest,
|
||||
TocLandingContext,
|
||||
TocLandingContextT,
|
||||
} from 'components/context/TocLandingContext'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
function initiateArticleScripts() {
|
||||
copyCode()
|
||||
localization()
|
||||
wrapCodeTerms()
|
||||
}
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
productLandingContext?: ProductLandingContextT
|
||||
productGuidesContext?: ProductGuidesContextT
|
||||
tocLandingContext?: TocLandingContextT
|
||||
articleContext?: ArticleContextT
|
||||
}
|
||||
const GlobalPage = ({
|
||||
mainContext,
|
||||
productLandingContext,
|
||||
productGuidesContext,
|
||||
tocLandingContext,
|
||||
articleContext,
|
||||
}: Props) => {
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
// https://stackoverflow.com/a/67063998
|
||||
initiateArticleScripts() // on initiate page
|
||||
router.events.on('routeChangeComplete', initiateArticleScripts) // on client side route
|
||||
return () => {
|
||||
router.events.off('routeChangeComplete', initiateArticleScripts)
|
||||
}
|
||||
}, [router.events])
|
||||
|
||||
let content
|
||||
if (productLandingContext) {
|
||||
content = (
|
||||
<ProductLandingContext.Provider value={productLandingContext}>
|
||||
<ProductLanding />
|
||||
</ProductLandingContext.Provider>
|
||||
)
|
||||
} else if (productGuidesContext) {
|
||||
content = (
|
||||
<ProductGuidesContext.Provider value={productGuidesContext}>
|
||||
<ProductGuides />
|
||||
</ProductGuidesContext.Provider>
|
||||
)
|
||||
} else if (tocLandingContext) {
|
||||
content = (
|
||||
<TocLandingContext.Provider value={tocLandingContext}>
|
||||
<TocLanding />
|
||||
</TocLandingContext.Provider>
|
||||
)
|
||||
} else if (articleContext) {
|
||||
content = (
|
||||
<ArticleContext.Provider value={articleContext}>
|
||||
<ArticlePage />
|
||||
</ArticleContext.Provider>
|
||||
)
|
||||
} else {
|
||||
throw new Error('No context provided to page')
|
||||
}
|
||||
|
||||
return <MainContext.Provider value={mainContext}>{content}</MainContext.Provider>
|
||||
}
|
||||
|
||||
export default GlobalPage
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
|
||||
const props: Props = {
|
||||
mainContext: await getMainContext(req, res),
|
||||
}
|
||||
const { currentLayoutName, relativePath } = props.mainContext
|
||||
|
||||
// This looks a little funky, but it's so we only send one context's data to the client
|
||||
if (currentLayoutName === 'product-landing') {
|
||||
props.productLandingContext = await getProductLandingContextFromRequest(req)
|
||||
} else if (currentLayoutName === 'product-guides') {
|
||||
props.productGuidesContext = getProductGuidesContextFromRequest(req)
|
||||
} else if (relativePath?.endsWith('index.md')) {
|
||||
props.tocLandingContext = getTocLandingContextFromRequest(req)
|
||||
} else {
|
||||
props.articleContext = getArticleContextFromRequest(req)
|
||||
}
|
||||
|
||||
return {
|
||||
props,
|
||||
}
|
||||
}
|
||||
export { default, getServerSideProps } from 'src/landings/pages/product'
|
||||
|
|
|
@ -1,93 +1 @@
|
|||
import React from 'react'
|
||||
import type { GetServerSideProps } from 'next'
|
||||
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
|
||||
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 = {
|
||||
href: string
|
||||
title: string
|
||||
intro: string
|
||||
}
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
popularLinks: Array<FeaturedLink>
|
||||
gettingStartedLinks: Array<FeaturedLink>
|
||||
productGroups: Array<ProductGroupT>
|
||||
}
|
||||
|
||||
export default function MainHomePage({
|
||||
mainContext,
|
||||
gettingStartedLinks,
|
||||
popularLinks,
|
||||
productGroups,
|
||||
}: Props) {
|
||||
return (
|
||||
<MainContext.Provider value={mainContext}>
|
||||
<DefaultLayout>
|
||||
<HomePage
|
||||
gettingStartedLinks={gettingStartedLinks}
|
||||
popularLinks={popularLinks}
|
||||
productGroups={productGroups}
|
||||
/>
|
||||
</DefaultLayout>
|
||||
</MainContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
type HomePageProps = {
|
||||
popularLinks: Array<FeaturedLink>
|
||||
gettingStartedLinks: Array<FeaturedLink>
|
||||
productGroups: Array<ProductGroupT>
|
||||
}
|
||||
function HomePage(props: HomePageProps) {
|
||||
const { gettingStartedLinks, popularLinks, productGroups } = props
|
||||
const { t } = useTranslation(['toc'])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<HomePageHero />
|
||||
<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">
|
||||
<div className="col-12 col-lg-6 mb-md-4 mb-lg-0 float-left">
|
||||
<ArticleList title={t('toc:getting_started')} articles={gettingStartedLinks} />
|
||||
</div>
|
||||
|
||||
<div className="col-12 col-lg-6 float-left">
|
||||
<ArticleList title={t('toc:popular')} articles={popularLinks} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
|
||||
return {
|
||||
props: {
|
||||
mainContext: await getMainContext(req, res),
|
||||
productGroups: req.context.productGroups,
|
||||
gettingStartedLinks: req.context.featuredLinks.gettingStarted.map(
|
||||
({ title, href, intro }: any) => ({ title, href, intro })
|
||||
),
|
||||
popularLinks: req.context.featuredLinks.popular.map(({ title, href, intro }: any) => ({
|
||||
title,
|
||||
href,
|
||||
intro,
|
||||
})),
|
||||
},
|
||||
}
|
||||
}
|
||||
export { default, getServerSideProps } from 'src/landings/pages/home'
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# Landing pages
|
||||
|
||||
Landing pages include the Docs home page, the product landing pages, and product guides pages.
|
||||
|
||||
## What landing pages are for
|
||||
|
||||
Landing pages provide a hierarchical view of their area, making navigating the Docs easier.
|
|
@ -1,6 +1,6 @@
|
|||
import { Label } from '@primer/react'
|
||||
|
||||
import { ArticleGuide } from 'components/context/ProductGuidesContext'
|
||||
import { ArticleGuide } from 'src/landings/components/ProductGuidesContext'
|
||||
import { Link } from 'components/Link'
|
||||
|
||||
type Props = {
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { ArticleGuide, useProductGuidesContext } from 'components/context/ProductGuidesContext'
|
||||
import { ArticleGuide, useProductGuidesContext } from 'src/landings/components/ProductGuidesContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { ArticleCard } from './ArticleCard'
|
||||
import { ActionList, ActionMenu } from '@primer/react'
|
|
@ -4,7 +4,7 @@ import { ActionList } from '@primer/react'
|
|||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { Link } from 'components/Link'
|
||||
import { ArrowRightIcon } from '@primer/octicons-react'
|
||||
import { FeaturedLink } from 'components/context/ProductLandingContext'
|
||||
import { FeaturedLink } from 'src/landings/components/ProductLandingContext'
|
||||
import { useMainContext } from 'components/context/MainContext'
|
||||
import { TruncateLines } from 'components/ui/TruncateLines'
|
||||
import { BumpLink } from 'components/ui/BumpLink'
|
|
@ -1,9 +1,9 @@
|
|||
import { useState } from 'react'
|
||||
import { ArrowRightIcon } from '@primer/octicons-react'
|
||||
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { RepoCard } from 'components/landing/RepoCard'
|
||||
import { RepoCard } from 'src/landings/components/RepoCard'
|
||||
|
||||
export const CommunityExamples = () => {
|
||||
const { productCommunityExamples } = useProductLandingContext()
|
|
@ -1,8 +1,8 @@
|
|||
import cx from 'classnames'
|
||||
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { ArticleList } from 'components/landing/ArticleList'
|
||||
import { ArticleList } from 'src/landings/components/ArticleList'
|
||||
|
||||
export const FeaturedArticles = () => {
|
||||
const { featuredArticles = [], whatsNewChangelog, changelogUrl } = useProductLandingContext()
|
|
@ -1,4 +1,4 @@
|
|||
import type { FeaturedLink } from 'components/context/ProductLandingContext'
|
||||
import type { FeaturedLink } from 'src/landings/components/ProductLandingContext'
|
||||
|
||||
type Props = {
|
||||
guide: FeaturedLink
|
|
@ -4,8 +4,8 @@ import { Link } from 'components/Link'
|
|||
import { ArrowRightIcon } from '@primer/octicons-react'
|
||||
import { useMainContext } from 'components/context/MainContext'
|
||||
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { GuideCard } from 'components/landing/GuideCard'
|
||||
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
|
||||
import { GuideCard } from 'src/landings/components/GuideCard'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
|
||||
export const GuideCards = () => {
|
|
@ -1,5 +1,5 @@
|
|||
import cx from 'classnames'
|
||||
import { useProductGuidesContext } from 'components/context/ProductGuidesContext'
|
||||
import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext'
|
||||
import { ArrowRightIcon, StarFillIcon } from '@primer/octicons-react'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { Link } from 'components/Link'
|
|
@ -1,4 +1,4 @@
|
|||
import { OctocatHeader } from 'components/landing/OctocatHeader'
|
||||
import { OctocatHeader } from 'src/landings/components/OctocatHeader'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
|
||||
export const HomePageHero = () => {
|
|
@ -4,7 +4,7 @@ import { useRouter } from 'next/router'
|
|||
import { LinkExternalIcon, NoteIcon } from '@primer/octicons-react'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { useVersion } from 'components/hooks/useVersion'
|
||||
import { Lead } from 'components/ui/Lead'
|
|
@ -3,7 +3,7 @@ import { useTranslation } from 'components/hooks/useTranslation'
|
|||
import { ArrowRightIcon } from '@primer/octicons-react'
|
||||
import { ActionList } from '@primer/react'
|
||||
import { useState } from 'react'
|
||||
import { FeaturedTrack } from 'components/context/ProductGuidesContext'
|
||||
import { FeaturedTrack } from 'src/landings/components/ProductGuidesContext'
|
||||
import { TruncateLines } from 'components/ui/TruncateLines'
|
||||
import { slug } from 'github-slugger'
|
||||
import styles from './LearningTrack.module.scss'
|
|
@ -1,5 +1,5 @@
|
|||
import { useProductGuidesContext } from 'components/context/ProductGuidesContext'
|
||||
import { LearningTrack } from 'components/guides/LearningTrack'
|
||||
import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext'
|
||||
import { LearningTrack } from 'src/landings/components/LearningTrack'
|
||||
|
||||
export const LearningTracks = () => {
|
||||
const { learningTracks } = useProductGuidesContext()
|
|
@ -1,9 +1,9 @@
|
|||
import { DefaultLayout } from 'components/DefaultLayout'
|
||||
import { useProductGuidesContext } from 'components/context/ProductGuidesContext'
|
||||
import { LandingSection } from 'components/landing/LandingSection'
|
||||
import { GuidesHero } from 'components/guides/GuidesHero'
|
||||
import { LearningTracks } from 'components/guides/LearningTracks'
|
||||
import { ArticleCards } from 'components/guides/ArticleCards'
|
||||
import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext'
|
||||
import { LandingSection } from 'src/landings/components/LandingSection'
|
||||
import { GuidesHero } from 'src/landings/components/GuidesHero'
|
||||
import { LearningTracks } from 'src/landings/components/LearningTracks'
|
||||
import { ArticleCards } from 'src/landings/components/ArticleCards'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { useMainContext } from 'components/context/MainContext'
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import { DefaultLayout } from 'components/DefaultLayout'
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
|
||||
|
||||
import { LandingHero } from 'components/landing/LandingHero'
|
||||
import { FeaturedArticles } from 'components/landing/FeaturedArticles'
|
||||
import { GuideCards } from 'components/landing/GuideCards'
|
||||
import { SponsorsExamples } from 'components/landing/SponsorsExamples'
|
||||
import { CommunityExamples } from 'components/landing/CommunityExamples'
|
||||
import { LandingSection } from 'components/landing/LandingSection'
|
||||
import { LandingHero } from 'src/landings/components/LandingHero'
|
||||
import { FeaturedArticles } from 'src/landings/components/FeaturedArticles'
|
||||
import { GuideCards } from 'src/landings/components/GuideCards'
|
||||
import { SponsorsExamples } from 'src/landings/components/SponsorsExamples'
|
||||
import { CommunityExamples } from 'src/landings/components/CommunityExamples'
|
||||
import { LandingSection } from 'src/landings/components/LandingSection'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { ProductArticlesList } from 'components/landing/ProductArticlesList'
|
||||
import { ProductReleases } from 'components/landing/ProductReleases'
|
||||
import { ProductArticlesList } from 'src/landings/components/ProductArticlesList'
|
||||
import { ProductReleases } from 'src/landings/components/ProductReleases'
|
||||
import { useVersion } from 'components/hooks/useVersion'
|
||||
import { RestRedirect } from 'src/rest/components/RestRedirect'
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { ArrowRightIcon, ArrowUpIcon, FileIcon, ListUnorderedIcon } from '@primer/octicons-react'
|
||||
import { useMainContext } from 'components/context/MainContext'
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { Link } from 'components/Link'
|
||||
import { useRouter } from 'next/router'
|
|
@ -1,5 +1,5 @@
|
|||
import { ProductT, useMainContext } from 'components/context/MainContext'
|
||||
import type { ProductGroupT } from 'components/homepage/ProductSelections'
|
||||
import type { ProductGroupT } from 'src/landings/components/ProductSelections'
|
||||
|
||||
import React from 'react'
|
||||
import { useRouter } from 'next/router'
|
|
@ -7,7 +7,7 @@ import { useMainContext } from 'components/context/MainContext'
|
|||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { Link } from 'components/Link'
|
||||
import { RestCollapsibleSection } from 'src/rest/components/RestCollapsibleSection'
|
||||
import { ProductCollapsibleSection } from './ProductCollapsibleSection'
|
||||
import { ProductCollapsibleSection } from 'components/sidebar/ProductCollapsibleSection'
|
||||
|
||||
export const SidebarProduct = () => {
|
||||
const router = useRouter()
|
|
@ -1,9 +1,9 @@
|
|||
import { ArrowRightIcon } from '@primer/octicons-react'
|
||||
|
||||
import { Link } from 'components/Link'
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { UserCard } from 'components/landing/UserCard'
|
||||
import { UserCard } from 'src/landings/components/UserCard'
|
||||
|
||||
export const SponsorsExamples = () => {
|
||||
const { productUserExamples } = useProductLandingContext()
|
|
@ -3,7 +3,7 @@ import cx from 'classnames'
|
|||
|
||||
import { ActionList } from '@primer/react'
|
||||
import { Link } from 'components/Link'
|
||||
import type { TocItem } from 'components/context/ProductLandingContext'
|
||||
import type { TocItem } from 'src/landings/components/ProductLandingContext'
|
||||
|
||||
type Props = {
|
||||
items: Array<TocItem>
|
|
@ -4,10 +4,10 @@ import cx from 'classnames'
|
|||
import { useTocLandingContext } from 'components/context/TocLandingContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { DefaultLayout } from 'components/DefaultLayout'
|
||||
import { TableOfContents } from 'components/landing/TableOfContents'
|
||||
import { TableOfContents } from 'src/landings/components/TableOfContents'
|
||||
import { ArticleTitle } from 'components/article/ArticleTitle'
|
||||
import { MarkdownContent } from 'components/ui/MarkdownContent'
|
||||
import { ArticleList } from 'components/landing/ArticleList'
|
||||
import { ArticleList } from 'src/landings/components/ArticleList'
|
||||
import { ArticleGridLayout } from 'components/article/ArticleGridLayout'
|
||||
import { Callout } from 'components/ui/Callout'
|
||||
import { Lead } from 'components/ui/Lead'
|
|
@ -1,5 +1,5 @@
|
|||
import getLinkData from '../lib/get-link-data.js'
|
||||
import renderContent from '../lib/render-content/index.js'
|
||||
import getLinkData from '../../../lib/get-link-data.js'
|
||||
import renderContent from '../../../lib/render-content/index.js'
|
||||
|
||||
// this middleware adds properties to the context object
|
||||
export default async function featuredLinks(req, res, next) {
|
|
@ -0,0 +1,93 @@
|
|||
import React from 'react'
|
||||
import type { GetServerSideProps } from 'next'
|
||||
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
|
||||
import { DefaultLayout } from 'components/DefaultLayout'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { ArticleList } from 'src/landings/components/ArticleList'
|
||||
import { HomePageHero } from 'src/landings/components/HomePageHero'
|
||||
import type { ProductGroupT } from 'src/landings/components/ProductSelections'
|
||||
import { ProductSelections } from 'src/landings/components/ProductSelections'
|
||||
|
||||
type FeaturedLink = {
|
||||
href: string
|
||||
title: string
|
||||
intro: string
|
||||
}
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
popularLinks: Array<FeaturedLink>
|
||||
gettingStartedLinks: Array<FeaturedLink>
|
||||
productGroups: Array<ProductGroupT>
|
||||
}
|
||||
|
||||
export default function MainHomePage({
|
||||
mainContext,
|
||||
gettingStartedLinks,
|
||||
popularLinks,
|
||||
productGroups,
|
||||
}: Props) {
|
||||
return (
|
||||
<MainContext.Provider value={mainContext}>
|
||||
<DefaultLayout>
|
||||
<HomePage
|
||||
gettingStartedLinks={gettingStartedLinks}
|
||||
popularLinks={popularLinks}
|
||||
productGroups={productGroups}
|
||||
/>
|
||||
</DefaultLayout>
|
||||
</MainContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
type HomePageProps = {
|
||||
popularLinks: Array<FeaturedLink>
|
||||
gettingStartedLinks: Array<FeaturedLink>
|
||||
productGroups: Array<ProductGroupT>
|
||||
}
|
||||
function HomePage(props: HomePageProps) {
|
||||
const { gettingStartedLinks, popularLinks, productGroups } = props
|
||||
const { t } = useTranslation(['toc'])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<HomePageHero />
|
||||
<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">
|
||||
<div className="col-12 col-lg-6 mb-md-4 mb-lg-0 float-left">
|
||||
<ArticleList title={t('toc:getting_started')} articles={gettingStartedLinks} />
|
||||
</div>
|
||||
|
||||
<div className="col-12 col-lg-6 float-left">
|
||||
<ArticleList title={t('toc:popular')} articles={popularLinks} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
|
||||
return {
|
||||
props: {
|
||||
mainContext: await getMainContext(req, res),
|
||||
productGroups: req.context.productGroups,
|
||||
gettingStartedLinks: req.context.featuredLinks.gettingStarted.map(
|
||||
({ title, href, intro }: any) => ({ title, href, intro })
|
||||
),
|
||||
popularLinks: req.context.featuredLinks.popular.map(({ title, href, intro }: any) => ({
|
||||
title,
|
||||
href,
|
||||
intro,
|
||||
})),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
import { GetServerSideProps } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
// "legacy" javascript needed to maintain existing functionality
|
||||
// typically operating on elements **within** an article.
|
||||
import copyCode from 'components/lib/copy-code'
|
||||
import localization from 'components/lib/localization'
|
||||
import wrapCodeTerms from 'components/lib/wrap-code-terms'
|
||||
|
||||
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
|
||||
|
||||
import {
|
||||
getProductLandingContextFromRequest,
|
||||
ProductLandingContextT,
|
||||
ProductLandingContext,
|
||||
} from 'src/landings/components/ProductLandingContext'
|
||||
import {
|
||||
getProductGuidesContextFromRequest,
|
||||
ProductGuidesContextT,
|
||||
ProductGuidesContext,
|
||||
} from 'src/landings/components/ProductGuidesContext'
|
||||
|
||||
import {
|
||||
getArticleContextFromRequest,
|
||||
ArticleContextT,
|
||||
ArticleContext,
|
||||
} from 'components/context/ArticleContext'
|
||||
import { ArticlePage } from 'components/article/ArticlePage'
|
||||
|
||||
import { ProductLanding } from 'src/landings/components/ProductLanding'
|
||||
import { ProductGuides } from 'src/landings/components/ProductGuides'
|
||||
import { TocLanding } from 'src/landings/components/TocLanding'
|
||||
import {
|
||||
getTocLandingContextFromRequest,
|
||||
TocLandingContext,
|
||||
TocLandingContextT,
|
||||
} from 'components/context/TocLandingContext'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
function initiateArticleScripts() {
|
||||
copyCode()
|
||||
localization()
|
||||
wrapCodeTerms()
|
||||
}
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
productLandingContext?: ProductLandingContextT
|
||||
productGuidesContext?: ProductGuidesContextT
|
||||
tocLandingContext?: TocLandingContextT
|
||||
articleContext?: ArticleContextT
|
||||
}
|
||||
const GlobalPage = ({
|
||||
mainContext,
|
||||
productLandingContext,
|
||||
productGuidesContext,
|
||||
tocLandingContext,
|
||||
articleContext,
|
||||
}: Props) => {
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
// https://stackoverflow.com/a/67063998
|
||||
initiateArticleScripts() // on initiate page
|
||||
router.events.on('routeChangeComplete', initiateArticleScripts) // on client side route
|
||||
return () => {
|
||||
router.events.off('routeChangeComplete', initiateArticleScripts)
|
||||
}
|
||||
}, [router.events])
|
||||
|
||||
let content
|
||||
if (productLandingContext) {
|
||||
content = (
|
||||
<ProductLandingContext.Provider value={productLandingContext}>
|
||||
<ProductLanding />
|
||||
</ProductLandingContext.Provider>
|
||||
)
|
||||
} else if (productGuidesContext) {
|
||||
content = (
|
||||
<ProductGuidesContext.Provider value={productGuidesContext}>
|
||||
<ProductGuides />
|
||||
</ProductGuidesContext.Provider>
|
||||
)
|
||||
} else if (tocLandingContext) {
|
||||
content = (
|
||||
<TocLandingContext.Provider value={tocLandingContext}>
|
||||
<TocLanding />
|
||||
</TocLandingContext.Provider>
|
||||
)
|
||||
} else if (articleContext) {
|
||||
content = (
|
||||
<ArticleContext.Provider value={articleContext}>
|
||||
<ArticlePage />
|
||||
</ArticleContext.Provider>
|
||||
)
|
||||
} else {
|
||||
throw new Error('No context provided to page')
|
||||
}
|
||||
|
||||
return <MainContext.Provider value={mainContext}>{content}</MainContext.Provider>
|
||||
}
|
||||
|
||||
export default GlobalPage
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
|
||||
const req = context.req as any
|
||||
const res = context.res as any
|
||||
|
||||
const props: Props = {
|
||||
mainContext: await getMainContext(req, res),
|
||||
}
|
||||
const { currentLayoutName, relativePath } = props.mainContext
|
||||
|
||||
// This looks a little funky, but it's so we only send one context's data to the client
|
||||
if (currentLayoutName === 'product-landing') {
|
||||
props.productLandingContext = await getProductLandingContextFromRequest(req)
|
||||
} else if (currentLayoutName === 'product-guides') {
|
||||
props.productGuidesContext = getProductGuidesContextFromRequest(req)
|
||||
} else if (relativePath?.endsWith('index.md')) {
|
||||
props.tocLandingContext = getTocLandingContextFromRequest(req)
|
||||
} else {
|
||||
props.articleContext = getArticleContextFromRequest(req)
|
||||
}
|
||||
|
||||
return {
|
||||
props,
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { getDOM } from '../helpers/e2etest.js'
|
||||
import { getDOM } from '../../../tests/helpers/e2etest.js'
|
||||
import { jest } from '@jest/globals'
|
||||
|
||||
describe('curated homepage links', () => {
|
|
@ -1,7 +1,7 @@
|
|||
import { jest } from '@jest/globals'
|
||||
|
||||
import { getDOM } from '../helpers/e2etest.js'
|
||||
import enterpriseServerReleases from '../../lib/enterprise-server-releases.js'
|
||||
import { getDOM } from '../../../tests/helpers/e2etest.js'
|
||||
import enterpriseServerReleases from '../../../lib/enterprise-server-releases.js'
|
||||
|
||||
describe('featuredLinks', () => {
|
||||
jest.setTimeout(3 * 60 * 1000)
|
|
@ -14,7 +14,7 @@ import {
|
|||
TocLandingContext,
|
||||
TocLandingContextT,
|
||||
} from 'components/context/TocLandingContext'
|
||||
import { TocLanding } from 'components/landing/TocLanding'
|
||||
import { TocLanding } from 'src/landings/components/TocLanding'
|
||||
|
||||
type MinitocItemsT = {
|
||||
restOperationsMiniTocItems: MiniTocItem[]
|
||||
|
|
Загрузка…
Ссылка в новой задаче