Skip to content

Commit ae3d891

Browse files
authored
Cleanup featuredLinks usage, fix insights page, better ArticleList (github#19872)
* cleanup featuredLinks usage, fix insights page, better ArticleList component
1 parent e26a344 commit ae3d891

9 files changed

+153
-103
lines changed

Diff for: components/context/ProductLandingContext.tsx

+18-11
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export type ProductLandingContextT = {
3939
overview?: string
4040
} | null
4141
product_video?: string
42-
guideCards: Array<FeaturedLink>
42+
featuredLinks: Record<string, Array<FeaturedLink>>
4343
productCodeExamples: Array<CodeExample>
4444
productUserExamples: Array<{ username: string; description: string }>
4545
productCommunityExamples: Array<{ repo: string; description: string }>
@@ -74,6 +74,22 @@ export const useProductLandingContext = (): ProductLandingContextT => {
7474
return context
7575
}
7676

77+
export const getFeaturedLinksFromReq = (req: any): Record<string, Array<FeaturedLink>> => {
78+
return Object.fromEntries(
79+
Object.entries(req.context.featuredLinks || {}).map(([key, entries]) => {
80+
return [
81+
key,
82+
(entries as Array<any>).map((entry) => ({
83+
href: entry.href,
84+
title: entry.title,
85+
intro: entry.intro,
86+
authors: entry.page.authors || [],
87+
})),
88+
]
89+
})
90+
)
91+
}
92+
7793
export const getProductLandingContextFromRequest = (req: any): ProductLandingContextT => {
7894
const productTree = req.context.currentProductTree
7995
const page = req.context.page
@@ -113,16 +129,7 @@ export const getProductLandingContextFromRequest = (req: any): ProductLandingCon
113129
}
114130
: null,
115131

116-
guideCards: (req.context.featuredLinks ? req.context.featuredLinks.guideCards || [] : []).map(
117-
(link: any) => {
118-
return {
119-
href: link.href,
120-
title: link.title,
121-
intro: link.intro,
122-
authors: link.page.authors || [],
123-
}
124-
}
125-
),
132+
featuredLinks: getFeaturedLinksFromReq(req),
126133

127134
tocItems: req.context.tocItems || [],
128135

Diff for: components/context/TocLandingContext.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pick from 'lodash/pick'
22
import { createContext, useContext } from 'react'
3+
import { FeaturedLink, getFeaturedLinksFromReq } from './ProductLandingContext'
34

45
export type TocItem = {
56
fullPath: string
@@ -13,6 +14,7 @@ export type TocLandingContextT = {
1314
productCallout: string
1415
tocItems: Array<TocItem>
1516
variant?: 'compact' | 'expanded'
17+
featuredLinks: Record<string, Array<FeaturedLink>>
1618
}
1719

1820
export const TocLandingContext = createContext<TocLandingContextT | null>(null)
@@ -36,5 +38,7 @@ export const getTocLandingContextFromRequest = (req: any): TocLandingContextT =>
3638
pick(obj, ['fullPath', 'title', 'intro'])
3739
),
3840
variant: req.context.genericTocFlat ? 'expanded' : 'compact',
41+
42+
featuredLinks: getFeaturedLinksFromReq(req),
3943
}
4044
}

Diff for: components/landing/ArticleList.tsx

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import cx from 'classnames'
2+
import dayjs from 'dayjs'
3+
4+
import { Link } from 'components/Link'
5+
import { ArrowRightIcon } from '@primer/octicons-react'
6+
import { FeaturedLink } from 'components/context/ProductLandingContext'
7+
import { TruncateLines } from 'components/TruncateLines'
8+
9+
type Props = {
10+
title?: string
11+
viewAllHref?: string
12+
articles: Array<FeaturedLink>
13+
variant?: 'compact' | 'spaced'
14+
titleVariant?: 'large' | 'default'
15+
}
16+
export const ArticleList = ({
17+
title,
18+
viewAllHref,
19+
articles,
20+
variant = 'compact',
21+
titleVariant = 'default',
22+
}: Props) => {
23+
return (
24+
<>
25+
{title && (
26+
<div className="mb-4 d-flex flex-items-baseline">
27+
<h3
28+
className={cx(
29+
titleVariant === 'large'
30+
? 'f4 text-normal text-mono text-uppercase'
31+
: 'f5 text-normal text-mono underline-dashed color-text-secondary'
32+
)}
33+
>
34+
{title}
35+
</h3>
36+
{viewAllHref && (
37+
<Link href={viewAllHref} className="ml-4">
38+
View all <ArrowRightIcon size={14} className="v-align-middle" />
39+
</Link>
40+
)}
41+
</div>
42+
)}
43+
44+
<ul className="list-style-none">
45+
{articles.map((link) => {
46+
return (
47+
<li key={link.href} className={cx(variant === 'compact' && 'border-top')}>
48+
<Link
49+
href={link.href}
50+
className="link-with-intro Bump-link--hover no-underline d-block py-3"
51+
>
52+
<h4 className="link-with-intro-title">
53+
<span dangerouslySetInnerHTML={{ __html: link.title }} />
54+
<span className="Bump-link-symbol"></span>
55+
</h4>
56+
{!link.hideIntro && link.intro && (
57+
<TruncateLines
58+
as="p"
59+
maxLines={variant === 'spaced' ? 6 : 2}
60+
className="link-with-intro-intro color-text-secondary mb-0 mt-1"
61+
>
62+
<span dangerouslySetInnerHTML={{ __html: link.intro }} />
63+
</TruncateLines>
64+
)}
65+
{link.date && (
66+
<time
67+
className="tooltipped tooltipped-n color-text-tertiary text-mono mt-1"
68+
aria-label={dayjs(link.date).format('LLL')}
69+
>
70+
{dayjs(link.date).format('MMMM DD')}
71+
</time>
72+
)}
73+
</Link>
74+
</li>
75+
)
76+
})}
77+
</ul>
78+
</>
79+
)
80+
}

Diff for: components/landing/FeaturedArticles.tsx

+4-63
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import cx from 'classnames'
2-
import dayjs from 'dayjs'
32

4-
import { Link } from 'components/Link'
5-
import { ArrowRightIcon } from '@primer/octicons-react'
6-
import { FeaturedLink, useProductLandingContext } from 'components/context/ProductLandingContext'
3+
import { useProductLandingContext } from 'components/context/ProductLandingContext'
74
import { useTranslation } from 'components/hooks/useTranslation'
8-
import { TruncateLines } from 'components/TruncateLines'
5+
import { ArticleList } from './ArticleList'
96

107
export const FeaturedArticles = () => {
118
const { featuredArticles = [], whatsNewChangelog, changelogUrl } = useProductLandingContext()
@@ -22,6 +19,7 @@ export const FeaturedArticles = () => {
2219
>
2320
<ArticleList
2421
title={section.label}
22+
titleVariant="large"
2523
viewAllHref={section.viewAllHref}
2624
articles={section.articles}
2725
/>
@@ -33,6 +31,7 @@ export const FeaturedArticles = () => {
3331
<div className={cx('col-12 mb-4 mb-lg-0 col-lg-4')}>
3432
<ArticleList
3533
title={t('whats_new')}
34+
titleVariant="large"
3635
viewAllHref={changelogUrl}
3736
articles={(whatsNewChangelog || []).map((link) => {
3837
return {
@@ -47,61 +46,3 @@ export const FeaturedArticles = () => {
4746
</div>
4847
)
4948
}
50-
51-
type ArticleListProps = {
52-
title?: string
53-
viewAllHref?: string
54-
articles: Array<FeaturedLink>
55-
maxLines?: number
56-
}
57-
export const ArticleList = ({ title, viewAllHref, articles, maxLines = 2 }: ArticleListProps) => {
58-
return (
59-
<>
60-
{title && (
61-
<div className="featured-links-heading mb-4 d-flex flex-items-baseline">
62-
<h3 className="f4 text-normal text-mono text-uppercase">{title}</h3>
63-
{viewAllHref && (
64-
<Link href={viewAllHref} className="ml-4">
65-
View all <ArrowRightIcon size={14} className="v-align-middle" />
66-
</Link>
67-
)}
68-
</div>
69-
)}
70-
71-
<ul className="list-style-none">
72-
{articles.map((link) => {
73-
return (
74-
<li key={link.href} className="border-top">
75-
<Link
76-
href={link.href}
77-
className="link-with-intro Bump-link--hover no-underline d-block py-3"
78-
>
79-
<h4 className="link-with-intro-title">
80-
<span dangerouslySetInnerHTML={{ __html: link.title }} />
81-
<span className="Bump-link-symbol"></span>
82-
</h4>
83-
{!link.hideIntro && link.intro && (
84-
<TruncateLines
85-
as="p"
86-
maxLines={maxLines}
87-
className="link-with-intro-intro color-text-secondary mb-0 mt-1"
88-
>
89-
<span dangerouslySetInnerHTML={{ __html: link.intro }} />
90-
</TruncateLines>
91-
)}
92-
{link.date && (
93-
<time
94-
className="tooltipped tooltipped-n color-text-tertiary text-mono mt-1"
95-
aria-label={dayjs(link.date).format('LLL')}
96-
>
97-
{dayjs(link.date).format('MMMM DD')}
98-
</time>
99-
)}
100-
</Link>
101-
</li>
102-
)
103-
})}
104-
</ul>
105-
</>
106-
)
107-
}

Diff for: components/landing/GuideCards.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@ import { GuideCard } from 'components/landing/GuideCard'
1010
export const GuideCards = () => {
1111
const router = useRouter()
1212
const { currentCategory } = useMainContext()
13-
const { guideCards, hasGuidesPage } = useProductLandingContext()
13+
const { featuredLinks, hasGuidesPage } = useProductLandingContext()
14+
1415
const routePath = `/${router.locale}${router.asPath.split('?')[0]}` // remove query string
1516

16-
if (!guideCards) {
17+
if (!featuredLinks.guideCards) {
1718
return null
1819
}
1920

2021
return (
2122
<div>
2223
<div className="d-lg-flex gutter-lg flex-items-stretch">
23-
{(guideCards || []).map((guide) => {
24+
{(featuredLinks.guideCards || []).map((guide) => {
2425
return <GuideCard key={guide.href} guide={guide} />
2526
})}
2627
</div>

Diff for: components/landing/ProductArticlesList.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import cx from 'classnames'
22
import { useState } from 'react'
33

4-
import { ChevronUpIcon } from '@primer/octicons-react'
4+
import { ChevronDownIcon } from '@primer/octicons-react'
55

66
import { ProductTreeNode, useMainContext } from 'components/context/MainContext'
77
import { Link } from 'components/Link'
@@ -22,13 +22,13 @@ export const ProductArticlesList = () => {
2222
return null
2323
}
2424

25-
return <ArticleList key={treeNode.href + i} treeNode={treeNode} />
25+
return <ProductTreeNodeList key={treeNode.href + i} treeNode={treeNode} />
2626
})}
2727
</div>
2828
)
2929
}
3030

31-
const ArticleList = ({ treeNode }: { treeNode: ProductTreeNode }) => {
31+
const ProductTreeNodeList = ({ treeNode }: { treeNode: ProductTreeNode }) => {
3232
const [isShowingMore, setIsShowingMore] = useState(false)
3333

3434
return (
@@ -61,7 +61,7 @@ const ArticleList = ({ treeNode }: { treeNode: ProductTreeNode }) => {
6161
{!isShowingMore && treeNode.childPages.length > maxArticles && (
6262
<button onClick={() => setIsShowingMore(true)} className="btn-link Link--secondary">
6363
Show {treeNode.childPages.length - maxArticles} more{' '}
64-
<ChevronUpIcon className="v-align-text-bottom" />
64+
<ChevronDownIcon className="v-align-text-bottom" />
6565
</button>
6666
)}
6767
</div>

Diff for: components/landing/ProductLanding.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const ProductLanding = () => {
1919
const { isEnterpriseServer } = useVersion()
2020
const {
2121
shortTitle,
22-
guideCards,
22+
featuredLinks,
2323
productUserExamples,
2424
productCommunityExamples,
2525
productCodeExamples,
@@ -60,7 +60,7 @@ export const ProductLanding = () => {
6060
</LandingSection>
6161
)}
6262

63-
{guideCards.length > 0 && (
63+
{featuredLinks.guideCards?.length > 0 && (
6464
<div className="color-bg-tertiary py-6">
6565
<LandingSection title={t('guides')} sectionLink="guides-2" className="my-6">
6666
<GuideCards />

Diff for: components/landing/TocLanding.tsx

+29-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import { ArticleVersionPicker } from 'components/article/ArticleVersionPicker'
44
import { Breadcrumbs } from 'components/Breadcrumbs'
55
import { useTocLandingContext } from 'components/context/TocLandingContext'
66
import { ArticleTitle } from 'components/article/ArticleTitle'
7+
import { ArticleList } from 'components/landing/ArticleList'
8+
import { useTranslation } from 'components/hooks/useTranslation'
79

810
export const TocLanding = () => {
9-
const { title, introPlainText, tocItems, productCallout, variant } = useTocLandingContext()
11+
const { title, introPlainText, tocItems, productCallout, variant, featuredLinks } =
12+
useTocLandingContext()
13+
const { t } = useTranslation('toc')
14+
1015
return (
1116
<DefaultLayout>
1217
<div className="container-xl px-3 px-md-6 my-4 my-lg-4">
@@ -24,7 +29,7 @@ export const TocLanding = () => {
2429

2530
<div className="article-grid-container">
2631
<div>
27-
<div className="mt-8">
32+
<div className="mt-7">
2833
<ArticleTitle>{title}</ArticleTitle>
2934

3035
<div className="lead-mktg">
@@ -42,6 +47,28 @@ export const TocLanding = () => {
4247
<div className="border-bottom border-xl-0 pb-4 mb-5 pb-xl-0 mb-xl-0" />
4348

4449
<div className={variant === 'expanded' ? 'mt-7' : 'mt-2'}>
50+
{featuredLinks.gettingStarted && featuredLinks.popular && (
51+
<div className="pb-8 container-xl">
52+
<div className="gutter gutter-xl-spacious clearfix">
53+
<div className="col-12 col-lg-6 mb-md-4 mb-lg-0 float-left">
54+
<ArticleList
55+
title={t('getting_started')}
56+
variant="spaced"
57+
articles={featuredLinks.gettingStarted}
58+
/>
59+
</div>
60+
61+
<div className="col-12 col-lg-6 float-left">
62+
<ArticleList
63+
title={t('popular')}
64+
variant="spaced"
65+
articles={featuredLinks.popular}
66+
/>
67+
</div>
68+
</div>
69+
</div>
70+
)}
71+
4572
<TableOfContents items={tocItems} variant={variant} />
4673
</div>
4774
</div>

0 commit comments

Comments
 (0)