Skip to content

Commit

Permalink
Merge pull request github#35224 from github/repo-sync
Browse files Browse the repository at this point in the history
Repo sync
  • Loading branch information
docs-bot authored Nov 7, 2024
2 parents 6855f29 + 2d14549 commit b038972
Show file tree
Hide file tree
Showing 12 changed files with 291 additions and 78 deletions.
62 changes: 62 additions & 0 deletions src/frame/components/context/CategoryLandingContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import pick from 'lodash/pick'
import { createContext, useContext } from 'react'
import { LearningTrack } from './ArticleContext'
import {
FeaturedLink,
getFeaturedLinksFromReq,
} from 'src/landings/components/ProductLandingContext'

export type TocItem = {
fullPath: string
title: string
intro?: string
childTocItems?: Array<{
fullPath: string
title: string
intro: string
}>
}

export type CategoryLandingContextT = {
title: string
intro: string
productCallout: string
permissions: string
tocItems: Array<TocItem>
variant?: 'compact' | 'expanded'
featuredLinks: Record<string, Array<FeaturedLink>>
renderedPage: string
currentLearningTrack?: LearningTrack
currentLayout: string
}

export const CategoryLandingContext = createContext<CategoryLandingContextT | null>(null)

export const useCategoryLandingContext = (): CategoryLandingContextT => {
const context = useContext(CategoryLandingContext)

if (!context) {
throw new Error(
'"useCategoryLandingContext" may only be used inside "CategoryLandingContext.Provider"',
)
}

return context
}

export const getCategoryLandingContextFromRequest = (req: any): CategoryLandingContextT => {
return {
title: req.context.page.title,
productCallout: req.context.page.product || '',
permissions: req.context.page.permissions || '',
intro: req.context.page.intro,
tocItems: (req.context.genericTocFlat || req.context.genericTocNested || []).map((obj: any) =>
pick(obj, ['fullPath', 'title', 'intro', 'childTocItems']),
),
variant: req.context.genericTocFlat ? 'expanded' : 'compact',
featuredLinks: getFeaturedLinksFromReq(req),
renderedPage: req.context.renderedPage,
currentLearningTrack: req.context.currentLearningTrack,
currentLayout: req.context.currentLayoutName,
}
}
1 change: 1 addition & 0 deletions src/frame/lib/frontmatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const layoutNames = [
'product-guides',
'release-notes',
'inline',
'category-landing',
false,
]

Expand Down
14 changes: 11 additions & 3 deletions src/frame/middleware/context/generic-toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import findPageInSiteTree from '@/frame/lib/find-page-in-site-tree.js'
export default async function genericToc(req: ExtendedRequest, res: Response, next: NextFunction) {
if (!req.context) throw new Error('request not contextualized')
if (!req.context.page) return next()
if (req.context.currentLayoutName !== 'default') return next()
if (
req.context.currentLayoutName !== 'default' &&
req.context.currentLayoutName !== 'category-landing'
)
return next()
// This middleware can only run on product, category, and map topics.
if (
req.context.page.documentType === 'homepage' ||
Expand Down Expand Up @@ -92,7 +96,7 @@ export default async function genericToc(req: ExtendedRequest, res: Response, ne
renderIntros = false
req.context.genericTocNested = await getTocItems(treePage, req.context, {
recurse: isRecursive,
renderIntros,
renderIntros: req.context.currentLayoutName === 'category-landing' ? true : false,
includeHidden,
})
}
Expand Down Expand Up @@ -127,7 +131,11 @@ async function getTocItems(node: Tree, context: Context, opts: Options): Promise
// Deliberately don't use `textOnly:true` here because we intend
// to display the intro, in a table of contents component,
// with the HTML (dangerouslySetInnerHTML).
intro = await page.renderProp('rawIntro', context)
intro = await page.renderProp(
'rawIntro',
context,
context.currentLayoutName === 'category-landing' ? { textOnly: true } : {},
)
}
}

Expand Down
67 changes: 67 additions & 0 deletions src/landings/components/CategoryLanding.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useRouter } from 'next/router'
import cx from 'classnames'

import { useCategoryLandingContext } from 'src/frame/components/context/CategoryLandingContext'
import { DefaultLayout } from 'src/frame/components/DefaultLayout'
import { ArticleTitle } from 'src/frame/components/article/ArticleTitle'
import { Lead } from 'src/frame/components/ui/Lead'
import { ClientSideRedirects } from 'src/rest/components/ClientSideRedirects'
import { RestRedirect } from 'src/rest/components/RestRedirect'
import { Breadcrumbs } from 'src/frame/components/page-header/Breadcrumbs'

export const CategoryLanding = () => {
const router = useRouter()
const { title, intro, tocItems } = useCategoryLandingContext()

// tocItems contains directories and its children, we only want the child articles
const onlyFlatItems = tocItems.flatMap((item) => item.childTocItems || [])

return (
<DefaultLayout>
{router.route === '/[versionId]/rest/[category]' && <RestRedirect />}
{/* Doesn't matter *where* this is included because it will
never render anything. It always just return null. */}
<ClientSideRedirects />

<div className="container-xl px-3 px-md-6 my-4">
<div className={cx('d-none d-xl-block mt-3 mr-auto width-full')}>
<Breadcrumbs />
</div>
<ArticleTitle>{title}</ArticleTitle>

{intro && <Lead data-search="lead">{intro}</Lead>}

<h2 className="py-5">Spotlight</h2>
<div className="container-lg clearfix">
<div className="col-4 float-left border p-4">Spotlight 1</div>
<div className="col-4 float-left border p-4">Spotlight 2</div>
<div className="col-4 float-left border p-4">Spotlight 3</div>
</div>

<div className="pt-8">
<div className="py-5 clearfix border-bottom">
<div className="col-5 float-left p-3">
<h2>Explore {onlyFlatItems.length} prompt articles</h2>
</div>
<div className="col-3 float-left p-4">Searchbar</div>
<div className="col-1 float-left p-4">Category</div>
<div className="col-1 float-left p-4">Complexity</div>
<div className="col-1 float-left p-4">Industry</div>
<div className="col-1 float-left p-4">Reset</div>
</div>
<div className="clearfix gutter-md-spacious">
{/* TODO: replace with card components */}
{onlyFlatItems.map((item, index) => (
<div key={index} className="col-4 float-left p-4">
<div className="px-3 pb-3 border-bottom">
<div>{item.title}</div>
<div>{item.intro}</div>
</div>
</div>
))}
</div>
</div>
</div>
</DefaultLayout>
)
}
24 changes: 21 additions & 3 deletions src/landings/pages/product.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ import { ArticlePage } from 'src/frame/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 { CategoryLanding } from 'src/landings/components/CategoryLanding'
import {
getTocLandingContextFromRequest,
TocLandingContext,
TocLandingContextT,
} from 'src/frame/components/context/TocLandingContext'
import {
getCategoryLandingContextFromRequest,
CategoryLandingContext,
CategoryLandingContextT,
} from 'src/frame/components/context/CategoryLandingContext'
import { useEffect } from 'react'

function initiateArticleScripts() {
Expand All @@ -54,13 +60,15 @@ type Props = {
productGuidesContext?: ProductGuidesContextT
tocLandingContext?: TocLandingContextT
articleContext?: ArticleContextT
categoryLandingContext?: CategoryLandingContextT
}
const GlobalPage = ({
mainContext,
productLandingContext,
productGuidesContext,
tocLandingContext,
articleContext,
categoryLandingContext,
}: Props) => {
const router = useRouter()

Expand All @@ -86,6 +94,12 @@ const GlobalPage = ({
<ProductGuides />
</ProductGuidesContext.Provider>
)
} else if (categoryLandingContext) {
content = (
<CategoryLandingContext.Provider value={categoryLandingContext}>
<CategoryLanding />
</CategoryLandingContext.Provider>
)
} else if (tocLandingContext) {
content = (
<TocLandingContext.Provider value={tocLandingContext}>
Expand Down Expand Up @@ -133,9 +147,13 @@ export const getServerSideProps: GetServerSideProps<Props> = async (context) =>
props.productGuidesContext = getProductGuidesContextFromRequest(req)
additionalUINamespaces.push('product_guides')
} else if (relativePath?.endsWith('index.md')) {
props.tocLandingContext = getTocLandingContextFromRequest(req)
if (props.tocLandingContext.currentLearningTrack?.trackName) {
additionalUINamespaces.push('learning_track_nav')
if (currentLayoutName === 'category-landing') {
props.categoryLandingContext = getCategoryLandingContextFromRequest(req)
} else {
props.tocLandingContext = getTocLandingContextFromRequest(req)
if (props.tocLandingContext.currentLearningTrack?.trackName) {
additionalUINamespaces.push('learning_track_nav')
}
}
} else if (props.mainContext.page) {
// All articles that might have hover cards needs this
Expand Down
5 changes: 5 additions & 0 deletions src/search/lib/elasticsearch-versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ for (const versionSource of Object.values(allVersions)) {
}
}

// Add the values to the keys as well so that the map value -> value works for versions that are already conformed to the indexVersion syntax
for (const [, value] of Object.entries(versionToIndexVersionMap)) {
versionToIndexVersionMap[value] = value
}

// All of the possible keys that can be input to access a version
export const allIndexVersionKeys = Array.from(
new Set([...Object.keys(versionToIndexVersionMap), ...Object.keys(allVersions)]),
Expand Down
40 changes: 34 additions & 6 deletions src/search/scripts/index/index-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { indexGeneralAutocomplete } from './lib/index-general-autocomplete'
import { indexGeneralSearch } from './lib/index-general-search'
import {
allIndexVersionKeys,
allIndexVersionOptions,
supportedAutocompletePlanVersions,
versionToIndexVersionMap,
} from '@/search/lib/elasticsearch-versions'
import { indexAISearchAutocomplete } from './lib/index-ai-search-autocomplete'

Expand All @@ -17,25 +17,40 @@ dotenv.config()

program.name('index').description('CLI scripts for indexing Docs data into Elasticsearch')

const allVersionKeysWithAll = [...allIndexVersionKeys, 'all']

const generalAutoCompleteCommand = new Command('general-autocomplete')
.description('Index for general search autocomplete')
.addOption(
new Option('-l, --language <language...>', 'Specific languages(s)').choices(languageKeys),
)
.addOption(
new Option('-v, --version <version...>', 'Specific versions').choices(allIndexVersionKeys),
new Option('-v, --version <version...>', 'Specific versions').choices(allVersionKeysWithAll),
)
.option('--verbose', 'Verbose output')
.option('--index-prefix <prefix>', 'Prefix for the index names', '')
.argument('<data-root>', 'path to the docs-internal-data repo')
.action(async (dataRepoRoot: string, options) => {
const languages = options.language ? options.language : languageKeys
const indexPrefix = options.indexPrefix || ''
if (!Array.isArray(options.version)) {
if (typeof options.version === 'undefined') {
options.version = ['all']
} else {
options.version = [options.version]
}
}
let versions = options.version
if (!versions.length || versions[0] === 'all') {
versions = supportedAutocompletePlanVersions
} else {
versions = versions.map((version: string) => versionToIndexVersionMap[version])
}
try {
await indexGeneralAutocomplete({
dataRepoRoot,
languages,
versions: options.version || supportedAutocompletePlanVersions,
versions,
indexPrefix,
})
} catch (error: any) {
Expand All @@ -55,7 +70,7 @@ const generalSearchCommand = new Command('general-search')
)
.option('-v, --verbose', 'Verbose outputs')
.addOption(
new Option('-V, --version [VERSION...]', 'Specific versions').choices(allIndexVersionOptions),
new Option('-V, --version [VERSION...]', 'Specific versions').choices(allVersionKeysWithAll),
)
.addOption(
new Option('-l, --language <LANGUAGE...>', 'Which languages to focus on').choices(languageKeys),
Expand Down Expand Up @@ -123,7 +138,7 @@ const aiSearchAutocompleteCommand = new Command('ai-search-autocomplete')
).choices(['en']),
)
.addOption(
new Option('-v, --version <version...>', 'Specific versions').choices(allIndexVersionKeys),
new Option('-v, --version <version...>', 'Specific versions').choices(allVersionKeysWithAll),
)
.option('--verbose', 'Verbose output')
.option('--index-prefix <prefix>', 'Prefix for the index names', '')
Expand All @@ -133,11 +148,24 @@ const aiSearchAutocompleteCommand = new Command('ai-search-autocomplete')
// Currently (since this is an experiment), we only support english
const languages = ['en']
const indexPrefix = options.indexPrefix || ''
if (!Array.isArray(options.version)) {
if (typeof options.version === 'undefined') {
options.version = ['all']
} else {
options.version = [options.version]
}
}
let versions = options.version
if (!versions.length || versions[0] === 'all') {
versions = supportedAutocompletePlanVersions
} else {
versions = versions.map((version: string) => versionToIndexVersionMap[version])
}
try {
await indexAISearchAutocomplete({
dataRepoRoot,
languages,
versions: options.version || supportedAutocompletePlanVersions,
versions,
indexPrefix,
})
} catch (error: any) {
Expand Down
6 changes: 6 additions & 0 deletions src/search/scripts/index/lib/index-ai-search-autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export async function indexAISearchAutocomplete(options: Options) {
const client = getElasticsearchClient(undefined, options.verbose)
await client.ping() // Will throw if not available

console.log(
'Indexing AI search autocomplete for languages: %O and versions: %O',
options.languages,
options.versions,
)

const { dataRepoRoot, languages, versions } = options
for (const language of languages) {
for (const version of versions) {
Expand Down
6 changes: 6 additions & 0 deletions src/search/scripts/index/lib/index-general-autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export async function indexGeneralAutocomplete(options: Options) {
const client = getElasticsearchClient(undefined, options.verbose)
await client.ping() // Will throw if not available

console.log(
'Indexing general autocomplete for languages: %O and versions: %O',
options.languages,
options.versions,
)

const { dataRepoRoot, versions, languages } = options
for (const language of languages) {
for (const version of versions) {
Expand Down
Loading

0 comments on commit b038972

Please sign in to comment.