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:
Alexey Pyltsyn 2020-10-22 12:22:11 +03:00 committed by GitHub
parent 44535f7555
commit 0ec5d533d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 74 deletions

View file

@ -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;

View file

@ -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>

View file

@ -14,6 +14,7 @@
padding: 0.5rem;
width: 100%;
background: #fff;
margin-bottom: 1rem;
}
.searchResultsColumn {