From b85c3f7711a7838c1eb6ea607e8e34ac36c231f7 Mon Sep 17 00:00:00 2001 From: Hossein Mehrabi Date: Tue, 6 Jun 2023 01:16:50 +0330 Subject: [PATCH] feat: add support for searching across all docs instances --- packages/logos-docusaurus-preset/src/index.ts | 42 ++++++++++--------- .../src/types/preset.ts | 5 +++ .../src/client/index.ts | 9 ++-- .../src/client/lib/string.utils.ts | 5 +++ .../src/client/lib/usePersistedHistory.ts | 7 +++- .../src/client/theme/SearchBar/SearchBar.tsx | 1 + .../hooks/useProxiedGeneratedData.ts | 5 --- .../client/theme/SearchBar/hooks/useSearch.ts | 16 ++++--- .../SearchBar/hooks/useSearchContextPath.ts | 33 +++++++++++++++ .../theme/SearchBar/hooks/useVersionUrl.ts | 27 ------------ .../src/client/theme/SearchBar/index.tsx | 9 +++- 11 files changed, 89 insertions(+), 70 deletions(-) create mode 100644 packages/logos-docusaurus-theme/src/client/lib/string.utils.ts delete mode 100644 packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useProxiedGeneratedData.ts create mode 100644 packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearchContextPath.ts delete mode 100644 packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useVersionUrl.ts diff --git a/packages/logos-docusaurus-preset/src/index.ts b/packages/logos-docusaurus-preset/src/index.ts index d5f8335..3f9d015 100644 --- a/packages/logos-docusaurus-preset/src/index.ts +++ b/packages/logos-docusaurus-preset/src/index.ts @@ -13,30 +13,32 @@ const makeSearchPluginConfig = ( plugins: PluginConfig[], options: PluginOptions, ): PluginConfig[] => { + const singleIndex = options.localSearch?.singleIndex ?? true + const docs = findDocInstances(plugins).map((plugin) => validateDocPluginOptions(plugin![1]), ) - return [ - [ - '@acid-info/logos-docusaurus-search-local', - { - hashed: true, - indexDocs: true, - indexBlog: false, - indexPages: true, - docsDir: docs.map((doc) => doc.path), - searchContextByPaths: docs.map(({ routeBasePath, path }) => - routeBasePath === '/' - ? path - : routeBasePath.startsWith('/') - ? routeBasePath.slice(1) - : routeBasePath, - ), - docsRouteBasePath: docs.map((doc) => doc.routeBasePath), - } as Partial, - ], - ] + const config = { + hashed: true, + indexDocs: true, + indexBlog: false, + indexPages: true, + docsDir: docs.map((doc) => doc.path), + docsRouteBasePath: docs.map((doc) => doc.routeBasePath), + } as Partial + + if (!singleIndex) { + config.searchContextByPaths = docs.map(({ routeBasePath, path }) => + routeBasePath === '/' + ? path + : routeBasePath.startsWith('/') + ? routeBasePath.slice(1) + : routeBasePath, + ) + } + + return [['@acid-info/logos-docusaurus-search-local', config]] } export default function logosPreset( diff --git a/packages/logos-docusaurus-preset/src/types/preset.ts b/packages/logos-docusaurus-preset/src/types/preset.ts index f1aff6e..0abaf4d 100644 --- a/packages/logos-docusaurus-preset/src/types/preset.ts +++ b/packages/logos-docusaurus-preset/src/types/preset.ts @@ -28,6 +28,10 @@ export type Contact = { export type ContactInfo = Contact[] +export type LocalSearchConfig = { + singleIndex?: boolean +} + export type PresetConfig = { businessUnit: BusinessUnits contactInfo?: string @@ -42,4 +46,5 @@ export type PresetConfig = { } customSiteConfig?: boolean docs?: Partial + localSearch?: LocalSearchConfig } diff --git a/packages/logos-docusaurus-search-local/src/client/index.ts b/packages/logos-docusaurus-search-local/src/client/index.ts index aa2e5bd..33dba3f 100644 --- a/packages/logos-docusaurus-search-local/src/client/index.ts +++ b/packages/logos-docusaurus-search-local/src/client/index.ts @@ -33,13 +33,10 @@ const findSearchContext = ({ versionUrl: string searchContextByPaths: string | string[] }): string => { - const { pathname } = window.location + let pathname = window.location.pathname + pathname = pathname.endsWith('/') ? pathname : pathname + '/' - if ( - searchContextByPaths === '' || - !Array.isArray(searchContextByPaths) || - !pathname.startsWith(versionUrl) - ) + if (!Array.isArray(searchContextByPaths) || !pathname.startsWith(versionUrl)) return '' const uri = pathname.substring(versionUrl.length) diff --git a/packages/logos-docusaurus-theme/src/client/lib/string.utils.ts b/packages/logos-docusaurus-theme/src/client/lib/string.utils.ts new file mode 100644 index 0000000..81628f2 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/lib/string.utils.ts @@ -0,0 +1,5 @@ +export const ensureTrailingString = (str: string, trail: string) => + str.endsWith(trail) ? str : str + trail + +export const ensureTrailingSlash = (str: string) => + ensureTrailingString(str, '/') diff --git a/packages/logos-docusaurus-theme/src/client/lib/usePersistedHistory.ts b/packages/logos-docusaurus-theme/src/client/lib/usePersistedHistory.ts index 9deceb0..f681087 100644 --- a/packages/logos-docusaurus-theme/src/client/lib/usePersistedHistory.ts +++ b/packages/logos-docusaurus-theme/src/client/lib/usePersistedHistory.ts @@ -5,10 +5,12 @@ export const usePersistedHistory = ( options?: { equals?: (a: T, b: T) => boolean unique?: boolean + maxItems?: number }, ) => { const unique = options?.unique ?? false const equals = options?.equals ?? ((a, b) => a === b) + const maxItems = options?.maxItems ?? null const [history, setHistory] = useLocalStorage( 'logos-docusaurus-theme-' + key, @@ -17,10 +19,11 @@ export const usePersistedHistory = ( const add = (value: T) => { const arr = history ?? [] - setHistory([ + const newHistory = [ value, ...(unique ? arr.filter((item) => !equals(item, value)) : arr), - ]) + ] + setHistory(maxItems ? newHistory.slice(0, maxItems) : newHistory) } const remove = (rm: (item: T, index: number) => boolean) => { diff --git a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/SearchBar.tsx b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/SearchBar.tsx index 2a36110..af0e88f 100644 --- a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/SearchBar.tsx +++ b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/SearchBar.tsx @@ -14,6 +14,7 @@ export const SearchBar: React.FC<{}> = ({}) => { const history = usePersistedHistory('search', { unique: true, equals: (a, b) => a.title === b.title && a.href === b.href, + maxItems: 10, }) const search = useSearch() const ref = useRef(null) diff --git a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useProxiedGeneratedData.ts b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useProxiedGeneratedData.ts deleted file mode 100644 index 9cc50ac..0000000 --- a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useProxiedGeneratedData.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const useProxiedGeneratedData = () => { - const win = window as any - - return win.getProxiedGeneratedData() -} diff --git a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearch.ts b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearch.ts index 8f65533..c981a2f 100644 --- a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearch.ts +++ b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearch.ts @@ -1,21 +1,19 @@ import { useEffect, useRef, useState } from 'react' -import { useProxiedGeneratedData } from './useProxiedGeneratedData' -import { useVersionUrl } from './useVersionUrl' +import { useSearchContextPath } from './useSearchContextPath' export const useSearch = () => { - const win = window as any + const { createSearchInstance } = window as any - const data = useProxiedGeneratedData() - const versionUrl = useVersionUrl() + const searchContextPath = useSearchContextPath() const [loaded, setLoaded] = useState(false) const search = useRef(null) const init = async () => { - search.current = await win.createSearchInstance({ + search.current = await createSearchInstance({ resultsLimit: 50, - preferredVersionPath: versionUrl, - searchContextByPaths: data.searchContextByPaths, + preferredVersionPath: searchContextPath[0], + searchContextByPaths: searchContextPath[1], }) await search.current.init() @@ -27,7 +25,7 @@ export const useSearch = () => { setLoaded(false) init() - }, [versionUrl]) + }, [searchContextPath[0], searchContextPath[1]]) return { loaded, diff --git a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearchContextPath.ts b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearchContextPath.ts new file mode 100644 index 0000000..5e8f9b2 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useSearchContextPath.ts @@ -0,0 +1,33 @@ +import { useActivePluginAndVersion } from '@docusaurus/plugin-content-docs/client' +import { ensureTrailingSlash } from '../../../lib/string.utils' + +const useProxiedData = () => { + const win = window as any + return win.getProxiedGeneratedData() +} + +const useSearchContextByPaths = () => { + return useProxiedData().searchContextByPaths +} + +export const useSearchContextPath = () => { + const separateContexts = useSearchContextByPaths() + + const activePluginData = useActivePluginAndVersion() + if (!activePluginData) return ['/', ''] + + const { + activePlugin: { + pluginData: { path: pluginPath }, + }, + activeVersion, + } = activePluginData + if (!activeVersion) return ['/', ''] + + return [ + pluginPath !== activeVersion.path + ? ensureTrailingSlash(activeVersion.path) + : '/', + separateContexts, + ] +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useVersionUrl.ts b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useVersionUrl.ts deleted file mode 100644 index ee02388..0000000 --- a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/hooks/useVersionUrl.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { useActivePlugin } from '@docusaurus/plugin-content-docs/client' -import { useDocsPreferredVersion } from '@docusaurus/theme-common/internal' -import useDocusaurusContext from '@docusaurus/useDocusaurusContext' -import { useProxiedGeneratedData } from './useProxiedGeneratedData' - -export const useVersionUrl = () => { - const { - siteConfig: { baseUrl }, - } = useDocusaurusContext() - - const { docsPluginIdForPreferredVersion } = useProxiedGeneratedData() - - let result = baseUrl - - const activePlugin = useActivePlugin() - - const { preferredVersion } = useDocsPreferredVersion( - activePlugin?.pluginId ?? docsPluginIdForPreferredVersion, - ) - - result = - preferredVersion && !preferredVersion.isLast - ? preferredVersion.path + '/' - : result - - return result -} diff --git a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/index.tsx b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/index.tsx index 69799e3..6fe190f 100644 --- a/packages/logos-docusaurus-theme/src/client/theme/SearchBar/index.tsx +++ b/packages/logos-docusaurus-theme/src/client/theme/SearchBar/index.tsx @@ -1,3 +1,4 @@ +import ErrorBoundary from '@docusaurus/ErrorBoundary' import { useActivePlugin } from '@docusaurus/plugin-content-docs/lib/client/index.js' import React from 'react' import { SearchBar } from './SearchBar' @@ -6,7 +7,13 @@ const SearchBarWrapper: React.FC = () => { const activePlugin = useActivePlugin() if (!activePlugin) return <> - return typeof window === 'undefined' ? <> : + return typeof window === 'undefined' ? ( + <> + ) : ( + <>}> + + + ) } export default SearchBarWrapper