This is an automated email from the ASF dual-hosted git repository. jeffreyh pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push: new 204f988257c fix:request when switch version (#1470) 204f988257c is described below commit 204f988257cce3dbca419e5577361897970545ae Author: yangon <2689991...@qq.com> AuthorDate: Fri Dec 6 14:41:04 2024 +0800 fix:request when switch version (#1470) Co-authored-by: liyang <liy...@selectdb.com> --- src/theme/SearchBar/SearchBar.jsx | 373 ++++++++++++++++++++++---------------- 1 file changed, 213 insertions(+), 160 deletions(-) diff --git a/src/theme/SearchBar/SearchBar.jsx b/src/theme/SearchBar/SearchBar.jsx index a82ab78e15e..f80b948d72a 100644 --- a/src/theme/SearchBar/SearchBar.jsx +++ b/src/theme/SearchBar/SearchBar.jsx @@ -1,36 +1,51 @@ -import React, { useCallback, useEffect, useRef, useState, } from "react"; -import clsx from "clsx"; -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import useIsBrowser from "@docusaurus/useIsBrowser"; -import { useHistory, useLocation } from "@docusaurus/router"; -import { translate } from "@docusaurus/Translate"; -import { ReactContextError, useDocsPreferredVersion, } from "@docusaurus/theme-common"; -import { useActivePlugin } from "@docusaurus/plugin-content-docs/client"; -import { fetchIndexes } from "./fetchIndexes"; -import { SearchSourceFactory } from "../../utils/SearchSourceFactory"; -import { SuggestionTemplate } from "./SuggestionTemplate"; -import { EmptyTemplate } from "./EmptyTemplate"; -import { searchResultLimits, Mark, searchBarShortcut, searchBarShortcutHint, searchBarPosition, docsPluginIdForPreferredVersion, indexDocs, searchContextByPaths, hideSearchBarWithNoSearchContext, useAllContextsWithNoSearchContext, } from "../../utils/proxiedGenerated"; -import LoadingRing from "../LoadingRing/LoadingRing"; -import styles from "./SearchBar.module.css"; -import { normalizeContextByPath } from "../../utils/normalizeContextByPath"; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import clsx from 'clsx'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import { useHistory, useLocation } from '@docusaurus/router'; +import { translate } from '@docusaurus/Translate'; +import { ReactContextError, useDocsPreferredVersion } from '@docusaurus/theme-common'; +import { useActivePlugin } from '@docusaurus/plugin-content-docs/client'; +import { fetchIndexes } from './fetchIndexes'; +import { SearchSourceFactory } from '../../utils/SearchSourceFactory'; +import { SuggestionTemplate } from './SuggestionTemplate'; +import { EmptyTemplate } from './EmptyTemplate'; +import { + searchResultLimits, + Mark, + searchBarShortcut, + searchBarShortcutHint, + searchBarPosition, + docsPluginIdForPreferredVersion, + indexDocs, + searchContextByPaths, + hideSearchBarWithNoSearchContext, + useAllContextsWithNoSearchContext, +} from '../../utils/proxiedGenerated'; +import LoadingRing from '../LoadingRing/LoadingRing'; +import { VERSIONS, DEFAULT_VERSION } from '@site/src/constant/common'; +import styles from './SearchBar.module.css'; +import { normalizeContextByPath } from '../../utils/normalizeContextByPath'; async function fetchAutoCompleteJS() { - const autoCompleteModule = await import("@easyops-cn/autocomplete.js"); + const autoCompleteModule = await import('@easyops-cn/autocomplete.js'); const autoComplete = autoCompleteModule.default; if (autoComplete.noConflict) { // For webpack v5 since docusaurus v2.0.0-alpha.75 autoComplete.noConflict(); - } - else if (autoCompleteModule.noConflict) { + } else if (autoCompleteModule.noConflict) { // For webpack v4 before docusaurus v2.0.0-alpha.74 autoCompleteModule.noConflict(); } return autoComplete; } -const SEARCH_PARAM_HIGHLIGHT = "_highlight"; -export default function SearchBar({ handleSearchBarToggle, }) { +const SEARCH_PARAM_HIGHLIGHT = '_highlight'; +export default function SearchBar({ handleSearchBarToggle }) { const isBrowser = useIsBrowser(); - const { siteConfig: { baseUrl }, i18n: { currentLocale }, } = useDocusaurusContext(); + const [curVersion, setCurVersion] = useState(DEFAULT_VERSION); + const { + siteConfig: { baseUrl }, + i18n: { currentLocale }, + } = useDocusaurusContext(); // It returns undefined for non-docs pages const activePlugin = useActivePlugin(); let versionUrl = baseUrl; @@ -45,15 +60,13 @@ export default function SearchBar({ handleSearchBarToggle, }) { // eslint-disable-next-line react-hooks/rules-of-hooks const { preferredVersion } = useDocsPreferredVersion(activePlugin?.pluginId ?? docsPluginIdForPreferredVersion); if (preferredVersion && !preferredVersion.isLast) { - versionUrl = preferredVersion.path + "/"; + versionUrl = preferredVersion.path + '/'; } - } - catch (e) { + } catch (e) { if (indexDocs) { if (e instanceof ReactContextError) { /* ignore, happens when website doesn't use versions */ - } - else { + } else { throw e; } } @@ -66,20 +79,20 @@ export default function SearchBar({ handleSearchBarToggle, }) { const focusAfterIndexLoaded = useRef(false); const [loading, setLoading] = useState(false); const [inputChanged, setInputChanged] = useState(false); - const [inputValue, setInputValue] = useState(""); + const [inputValue, setInputValue] = useState(''); const search = useRef(null); - const prevSearchContext = useRef(""); - const [searchContext, setSearchContext] = useState(""); + const prevSearchContext = useRef(''); + const [searchContext, setSearchContext] = useState(''); useEffect(() => { if (!Array.isArray(searchContextByPaths)) { return; } - let nextSearchContext = ""; + let nextSearchContext = ''; if (location.pathname.startsWith(versionUrl)) { const uri = location.pathname.substring(versionUrl.length); let matchedPath; for (const _path of searchContextByPaths) { - const path = typeof _path === "string" ? _path : _path.path; + const path = typeof _path === 'string' ? _path : _path.path; if (uri === path || uri.startsWith(`${path}/`)) { matchedPath = path; break; @@ -96,69 +109,76 @@ export default function SearchBar({ handleSearchBarToggle, }) { } setSearchContext(nextSearchContext); }, [location.pathname, versionUrl]); - const hidden = !!hideSearchBarWithNoSearchContext && - Array.isArray(searchContextByPaths) && - searchContext === ""; - const loadIndex = useCallback(async () => { - if (hidden || indexStateMap.current.get(searchContext)) { + const hidden = !!hideSearchBarWithNoSearchContext && Array.isArray(searchContextByPaths) && searchContext === ''; + const loadIndex = useCallback(async (forceLoad = false) => { + if ((hidden || indexStateMap.current.get(searchContext)) && !forceLoad) { // Do not load the index (again) if its already loaded or in the process of being loaded. return; } - indexStateMap.current.set(searchContext, "loading"); + indexStateMap.current.set(searchContext, 'loading'); search.current?.autocomplete.destroy(); setLoading(true); const [{ wrappedIndexes, zhDictionary }, autoComplete] = await Promise.all([ fetchIndexes(versionUrl, searchContext), fetchAutoCompleteJS(), ]); - const searchFooterLinkElement = ({ query, isEmpty, }) => { - const a = document.createElement("a"); + const searchFooterLinkElement = ({ query, isEmpty }) => { + const a = document.createElement('a'); const params = new URLSearchParams(); - params.set("q", query); + params.set('q', query); let linkText; if (searchContext) { - const detailedSearchContext = searchContext && Array.isArray(searchContextByPaths) - ? searchContextByPaths.find((item) => typeof item === "string" - ? item === searchContext - : item.path === searchContext) - : searchContext; + const detailedSearchContext = + searchContext && Array.isArray(searchContextByPaths) + ? searchContextByPaths.find(item => + typeof item === 'string' ? item === searchContext : item.path === searchContext, + ) + : searchContext; const translatedSearchContext = detailedSearchContext ? normalizeContextByPath(detailedSearchContext, currentLocale).label : searchContext; if (useAllContextsWithNoSearchContext && isEmpty) { - linkText = translate({ - id: "theme.SearchBar.seeAllOutsideContext", - message: 'See all results outside "{context}"', - }, { context: translatedSearchContext }); - } - else { - linkText = translate({ - id: "theme.SearchBar.searchInContext", - message: 'See all results within "{context}"', - }, { context: translatedSearchContext }); + linkText = translate( + { + id: 'theme.SearchBar.seeAllOutsideContext', + message: 'See all results outside "{context}"', + }, + { context: translatedSearchContext }, + ); + } else { + linkText = translate( + { + id: 'theme.SearchBar.searchInContext', + message: 'See all results within "{context}"', + }, + { context: translatedSearchContext }, + ); } - } - else { + } else { linkText = translate({ - id: "theme.SearchBar.seeAll", - message: "See all results", + id: 'theme.SearchBar.seeAll', + message: 'See all results', }); } - if (searchContext && + if ( + searchContext && Array.isArray(searchContextByPaths) && - (!useAllContextsWithNoSearchContext || !isEmpty)) { - params.set("ctx", searchContext); + (!useAllContextsWithNoSearchContext || !isEmpty) + ) { + params.set('ctx', searchContext); } if (versionUrl !== baseUrl) { if (!versionUrl.startsWith(baseUrl)) { - throw new Error(`Version url '${versionUrl}' does not start with base url '${baseUrl}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`); + throw new Error( + `Version url '${versionUrl}' does not start with base url '${baseUrl}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`, + ); } - params.set("version", versionUrl.substring(baseUrl.length)); + params.set('version', versionUrl.substring(baseUrl.length)); } const url = `${baseUrl}search/?${params.toString()}`; a.href = url; a.textContent = linkText; - a.addEventListener("click", (e) => { + a.addEventListener('click', e => { if (!e.ctrlKey && !e.metaKey) { e.preventDefault(); search.current?.autocomplete.close(); @@ -167,63 +187,66 @@ export default function SearchBar({ handleSearchBarToggle, }) { }); return a; }; - search.current = autoComplete(searchBarRef.current, { - hint: false, - autoselect: true, - openOnFocus: true, - cssClasses: { - root: clsx(styles.searchBar, { - [styles.searchBarLeft]: searchBarPosition === "left", - }), - noPrefix: true, - dropdownMenu: styles.dropdownMenu, - input: styles.input, - hint: styles.hint, - suggestions: styles.suggestions, - suggestion: styles.suggestion, - cursor: styles.cursor, - dataset: styles.dataset, - empty: styles.empty, - }, - }, [ + search.current = autoComplete( + searchBarRef.current, { - source: SearchSourceFactory(wrappedIndexes, zhDictionary, searchResultLimits), - templates: { - suggestion: SuggestionTemplate, - empty: EmptyTemplate, - footer: ({ query, isEmpty }) => { - if (isEmpty && - (!searchContext || !useAllContextsWithNoSearchContext)) { - return; - } - const a = searchFooterLinkElement({ query, isEmpty }); - const div = document.createElement("div"); - div.className = styles.hitFooter; - div.appendChild(a); - return div; - }, + hint: false, + autoselect: true, + openOnFocus: true, + cssClasses: { + root: clsx(styles.searchBar, { + [styles.searchBarLeft]: searchBarPosition === 'left', + }), + noPrefix: true, + dropdownMenu: styles.dropdownMenu, + input: styles.input, + hint: styles.hint, + suggestions: styles.suggestions, + suggestion: styles.suggestion, + cursor: styles.cursor, + dataset: styles.dataset, + empty: styles.empty, }, }, - ]) - .on("autocomplete:selected", function (event, { document: { u, h }, tokens }) { - searchBarRef.current?.blur(); - let url = u; - if (Mark && tokens.length > 0) { - const params = new URLSearchParams(); - for (const token of tokens) { - params.append(SEARCH_PARAM_HIGHLIGHT, token); + [ + { + source: SearchSourceFactory(wrappedIndexes, zhDictionary, searchResultLimits), + templates: { + suggestion: SuggestionTemplate, + empty: EmptyTemplate, + footer: ({ query, isEmpty }) => { + if (isEmpty && (!searchContext || !useAllContextsWithNoSearchContext)) { + return; + } + const a = searchFooterLinkElement({ query, isEmpty }); + const div = document.createElement('div'); + div.className = styles.hitFooter; + div.appendChild(a); + return div; + }, + }, + }, + ], + ) + .on('autocomplete:selected', function (event, { document: { u, h }, tokens }) { + searchBarRef.current?.blur(); + let url = u; + if (Mark && tokens.length > 0) { + const params = new URLSearchParams(); + for (const token of tokens) { + params.append(SEARCH_PARAM_HIGHLIGHT, token); + } + url += `?${params.toString()}`; } - url += `?${params.toString()}`; - } - if (h) { - url += h; - } - history.push(url); - }) - .on("autocomplete:closed", () => { - searchBarRef.current?.blur(); - }); - indexStateMap.current.set(searchContext, "done"); + if (h) { + url += h; + } + history.push(url); + }) + .on('autocomplete:closed', () => { + searchBarRef.current?.blur(); + }); + indexStateMap.current.set(searchContext, 'done'); setLoading(false); if (focusAfterIndexLoaded.current) { const input = searchBarRef.current; @@ -237,15 +260,13 @@ export default function SearchBar({ handleSearchBarToggle, }) { if (!Mark) { return; } - const keywords = isBrowser - ? new URLSearchParams(location.search).getAll(SEARCH_PARAM_HIGHLIGHT) - : []; + const keywords = isBrowser ? new URLSearchParams(location.search).getAll(SEARCH_PARAM_HIGHLIGHT) : []; // A workaround to fix an issue of highlighting in code blocks. // See https://github.com/easyops-cn/docusaurus-search-local/issues/92 // Code blocks will be re-rendered after this `useEffect` ran. // So we make the marking run after a macro task. setTimeout(() => { - const root = document.querySelector("article"); + const root = document.querySelector('article'); if (!root) { return; } @@ -255,8 +276,8 @@ export default function SearchBar({ handleSearchBarToggle, }) { mark.mark(keywords); } // Apply any keywords to the search input so that we can clear marks in case we loaded a page with a highlight in the url - setInputValue(keywords.join(" ")); - search.current?.autocomplete.setVal(keywords.join(" ")); + setInputValue(keywords.join(' ')); + search.current?.autocomplete.setVal(keywords.join(' ')); }); }, [isBrowser, location.search, location.pathname]); const [focused, setFocused] = useState(false); @@ -273,67 +294,99 @@ export default function SearchBar({ handleSearchBarToggle, }) { const onInputMouseEnter = useCallback(() => { loadIndex(); }, [loadIndex]); - const onInputChange = useCallback((event) => { + const onInputChange = useCallback(event => { setInputValue(event.target.value); if (event.target.value) { setInputChanged(true); } }, []); // Implement hint icons for the search shortcuts on mac and the rest operating systems. - const isMac = isBrowser - ? /mac/i.test(navigator.userAgentData?.platform ?? navigator.platform) - : false; + const isMac = isBrowser ? /mac/i.test(navigator.userAgentData?.platform ?? navigator.platform) : false; + + useEffect(() => { + const pathHaveVer = VERSIONS.some(item => location.pathname.includes(item)); + if (!pathHaveVer && curVersion !== '2.1') { + setCurVersion('2.1'); + } else { + VERSIONS.forEach(item => { + if (location.pathname.includes(item) && item !== curVersion) { + setCurVersion(item); + } + }); + } + }, [location.pathname]); + useEffect(() => { + loadIndex(true); + }, [curVersion]); useEffect(() => { if (!searchBarShortcut) { return; } // Add shortcuts command/ctrl + K - const handleShortcut = (event) => { - if ((isMac ? event.metaKey : event.ctrlKey) && - (event.key === "k" || event.key === "K")) { + const handleShortcut = event => { + if ((isMac ? event.metaKey : event.ctrlKey) && (event.key === 'k' || event.key === 'K')) { event.preventDefault(); searchBarRef.current?.focus(); onInputFocus(); } }; - document.addEventListener("keydown", handleShortcut); + document.addEventListener('keydown', handleShortcut); return () => { - document.removeEventListener("keydown", handleShortcut); + document.removeEventListener('keydown', handleShortcut); }; }, [isMac, onInputFocus]); const onClearSearch = useCallback(() => { const params = new URLSearchParams(location.search); params.delete(SEARCH_PARAM_HIGHLIGHT); const paramsStr = params.toString(); - const searchUrl = location.pathname + - (paramsStr != "" ? `?${paramsStr}` : "") + - location.hash; + const searchUrl = location.pathname + (paramsStr != '' ? `?${paramsStr}` : '') + location.hash; if (searchUrl != location.pathname + location.search + location.hash) { history.push(searchUrl); } // We always clear these here because in case no match was selected the above history push wont happen - setInputValue(""); - search.current?.autocomplete.setVal(""); + setInputValue(''); + search.current?.autocomplete.setVal(''); }, [location.pathname, location.search, location.hash, history]); - return (<div className={clsx("navbar__search", styles.searchBarContainer, { - [styles.searchIndexLoading]: loading && inputChanged, - [styles.focused]: focused, - })} hidden={hidden} - // Manually make the search bar be LTR even if in RTL - dir="ltr"> - <input placeholder={translate({ - id: "theme.SearchBar.label", - message: "Search", - description: "The ARIA label and placeholder for search button", - })} aria-label="Search" className="navbar__search-input" onMouseEnter={onInputMouseEnter} onFocus={onInputFocus} onBlur={onInputBlur} onChange={onInputChange} ref={searchBarRef} value={inputValue}/> - <LoadingRing className={styles.searchBarLoadingRing}/> - {searchBarShortcut && - searchBarShortcutHint && - (inputValue !== "" ? (<button className={styles.searchClearButton} onClick={onClearSearch}> - ✕ - </button>) : (isBrowser && (<div className={styles.searchHintContainer}> - <kbd className={styles.searchHint}>{isMac ? "⌘" : "ctrl"}</kbd> - <kbd className={styles.searchHint}>K</kbd> - </div>)))} - </div>); + return ( + <div + className={clsx('navbar__search', styles.searchBarContainer, { + [styles.searchIndexLoading]: loading && inputChanged, + [styles.focused]: focused, + })} + hidden={hidden} + // Manually make the search bar be LTR even if in RTL + dir="ltr" + > + <input + placeholder={translate({ + id: 'theme.SearchBar.label', + message: 'Search', + description: 'The ARIA label and placeholder for search button', + })} + aria-label="Search" + className="navbar__search-input" + onMouseEnter={onInputMouseEnter} + onFocus={onInputFocus} + onBlur={onInputBlur} + onChange={onInputChange} + ref={searchBarRef} + value={inputValue} + /> + <LoadingRing className={styles.searchBarLoadingRing} /> + {searchBarShortcut && + searchBarShortcutHint && + (inputValue !== '' ? ( + <button className={styles.searchClearButton} onClick={onClearSearch}> + ✕ + </button> + ) : ( + isBrowser && ( + <div className={styles.searchHintContainer}> + <kbd className={styles.searchHint}>{isMac ? '⌘' : 'ctrl'}</kbd> + <kbd className={styles.searchHint}>K</kbd> + </div> + ) + ))} + </div> + ); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org