mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-03 11:22:30 +02:00
refactor(v2): use new way to get versions for search page (#3604)
* refactor(v2): use new way to get versions for search page * search page: support docs multi-instance Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
parent
44535f7555
commit
0ec5d533d6
3 changed files with 94 additions and 74 deletions
|
@ -1,30 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
let versions: string[];
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line global-require
|
||||
versions = require('@site/versions.json');
|
||||
} catch {
|
||||
versions = [];
|
||||
}
|
||||
|
||||
// TODO deprecate in favor of useDocs.ts instead
|
||||
function useVersioning(): {
|
||||
versioningEnabled: boolean;
|
||||
versions: string[];
|
||||
latestVersion: string;
|
||||
} {
|
||||
return {
|
||||
versioningEnabled: versions.length > 0,
|
||||
versions,
|
||||
latestVersion: versions[0],
|
||||
};
|
||||
}
|
||||
|
||||
export default useVersioning;
|
|
@ -16,7 +16,7 @@ import clsx from 'clsx';
|
|||
import Head from '@docusaurus/Head';
|
||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import useVersioning from '@theme/hooks/useVersioning';
|
||||
import {useAllDocsData} from '@theme/hooks/useDocs';
|
||||
import useSearchQuery from '@theme/hooks/useSearchQuery';
|
||||
import Link from '@docusaurus/Link';
|
||||
import Layout from '@theme/Layout';
|
||||
|
@ -27,15 +27,85 @@ function pluralize(count, word) {
|
|||
return count > 1 ? `${word}s` : word;
|
||||
}
|
||||
|
||||
function useDocsSearchVersionsHelpers() {
|
||||
const allDocsData = useAllDocsData();
|
||||
|
||||
// State of the version select menus / algolia facet filters
|
||||
// docsPluginId -> versionName map
|
||||
const [searchVersions, setSearchVersions] = useState(() => {
|
||||
return Object.entries(allDocsData).reduce((acc, [pluginId, pluginData]) => {
|
||||
return {...acc, [pluginId]: pluginData.versions[0].name};
|
||||
}, {});
|
||||
});
|
||||
|
||||
// Set the value of a single select menu
|
||||
const setSearchVersion = (pluginId, searchVersion) =>
|
||||
setSearchVersions((s) => ({...s, [pluginId]: searchVersion}));
|
||||
|
||||
const versioningEnabled = Object.values(allDocsData).some(
|
||||
(docsData) => docsData.versions.length > 1,
|
||||
);
|
||||
|
||||
return {
|
||||
allDocsData,
|
||||
versioningEnabled,
|
||||
searchVersions,
|
||||
setSearchVersion,
|
||||
};
|
||||
}
|
||||
|
||||
// We want to display one select per versioned docs plugin instance
|
||||
const SearchVersionSelectList = ({docsSearchVersionsHelpers}) => {
|
||||
const versionedPluginEntries = Object.entries(
|
||||
docsSearchVersionsHelpers.allDocsData,
|
||||
)
|
||||
// Do not show a version select for unversioned docs plugin instances
|
||||
.filter(([, docsData]) => docsData.versions.length > 1);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'col',
|
||||
'col--3',
|
||||
'padding-left--none',
|
||||
styles.searchVersionColumn,
|
||||
)}>
|
||||
{versionedPluginEntries.map(([pluginId, docsData]) => {
|
||||
const labelPrefix =
|
||||
versionedPluginEntries.length > 1 ? `${pluginId}: ` : '';
|
||||
return (
|
||||
<select
|
||||
key={pluginId}
|
||||
onChange={(e) =>
|
||||
docsSearchVersionsHelpers.setSearchVersion(
|
||||
pluginId,
|
||||
e.target.value,
|
||||
)
|
||||
}
|
||||
defaultValue={docsSearchVersionsHelpers.searchVersions[pluginId]}
|
||||
className={styles.searchVersionInput}>
|
||||
{docsData.versions.map((version, i) => (
|
||||
<option
|
||||
key={i}
|
||||
label={`${labelPrefix}${version.label}`}
|
||||
value={version.name}
|
||||
/>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function Search() {
|
||||
const {
|
||||
siteConfig: {
|
||||
themeConfig: {algolia: {appId = 'BH4D9OD16A', apiKey, indexName} = {}},
|
||||
} = {},
|
||||
} = useDocusaurusContext();
|
||||
const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
|
||||
const {searchValue, updateSearchPath} = useSearchQuery();
|
||||
const {versioningEnabled, versions, latestVersion} = useVersioning();
|
||||
const [searchVersion, setSearchVersion] = useState(latestVersion);
|
||||
const [searchQuery, setSearchQuery] = useState(searchValue);
|
||||
const initialSearchResultState = {
|
||||
items: [],
|
||||
|
@ -87,7 +157,7 @@ function Search() {
|
|||
const algoliaHelper = algoliaSearchHelper(algoliaClient, indexName, {
|
||||
hitsPerPage: 15,
|
||||
advancedSyntax: true,
|
||||
facets: searchVersion ? ['version'] : [],
|
||||
disjunctiveFacets: ['docusaurus_tag'],
|
||||
});
|
||||
|
||||
algoliaHelper.on(
|
||||
|
@ -169,25 +239,19 @@ function Search() {
|
|||
: 'Search the documentation';
|
||||
|
||||
const makeSearch = (page = 0) => {
|
||||
if (searchVersion) {
|
||||
algoliaHelper
|
||||
.setQuery(searchQuery)
|
||||
.addFacetRefinement('version', searchVersion)
|
||||
.setPage(page)
|
||||
.search();
|
||||
} else {
|
||||
algoliaHelper.setQuery(searchQuery).setPage(page).search();
|
||||
}
|
||||
};
|
||||
algoliaHelper.setQuery(searchQuery).setPage(page);
|
||||
|
||||
const handleSearchInputChange = (e) => {
|
||||
const searchInputValue = e.target.value;
|
||||
algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default');
|
||||
Object.entries(docsSearchVersionsHelpers.searchVersions).forEach(
|
||||
([pluginId, searchVersion]) => {
|
||||
algoliaHelper.addDisjunctiveFacetRefinement(
|
||||
'docusaurus_tag',
|
||||
`docs-${pluginId}-${searchVersion}`,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (e.target.tagName === 'SELECT') {
|
||||
setSearchVersion(searchInputValue);
|
||||
} else {
|
||||
setSearchQuery(searchInputValue);
|
||||
}
|
||||
algoliaHelper.search();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -214,7 +278,7 @@ function Search() {
|
|||
makeSearch();
|
||||
}, 300);
|
||||
}
|
||||
}, [searchQuery, searchVersion]);
|
||||
}, [searchQuery, docsSearchVersionsHelpers.searchVersions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchResultState.lastPage || searchResultState.lastPage === 0) {
|
||||
|
@ -246,8 +310,8 @@ function Search() {
|
|||
<form className="row" onSubmit={(e) => e.preventDefault()}>
|
||||
<div
|
||||
className={clsx('col', styles.searchQueryColumn, {
|
||||
'col--9': versioningEnabled,
|
||||
'col--12': !versioningEnabled,
|
||||
'col--9': docsSearchVersionsHelpers.versioningEnabled,
|
||||
'col--12': !docsSearchVersionsHelpers.versioningEnabled,
|
||||
})}>
|
||||
<input
|
||||
type="search"
|
||||
|
@ -255,32 +319,17 @@ function Search() {
|
|||
className={styles.searchQueryInput}
|
||||
placeholder="Type your search here"
|
||||
aria-label="Search"
|
||||
onChange={handleSearchInputChange}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
value={searchQuery}
|
||||
autoComplete="off"
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
{versioningEnabled && (
|
||||
<div
|
||||
className={clsx(
|
||||
'col',
|
||||
'col--3',
|
||||
'padding-left--none',
|
||||
styles.searchVersionColumn,
|
||||
)}>
|
||||
<select
|
||||
onChange={handleSearchInputChange}
|
||||
defaultValue={searchVersion}
|
||||
className={styles.searchVersionInput}>
|
||||
{versions.map((version, i) => (
|
||||
<option key={i} value={version}>
|
||||
{version}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{docsSearchVersionsHelpers.versioningEnabled && (
|
||||
<SearchVersionSelectList
|
||||
docsSearchVersionsHelpers={docsSearchVersionsHelpers}
|
||||
/>
|
||||
)}
|
||||
</form>
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.searchResultsColumn {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue