diff --git a/src/components/SearchBar/SearchBar.tsx b/src/components/SearchBar/SearchBar.tsx index e2cb86ffc..652909a20 100644 --- a/src/components/SearchBar/SearchBar.tsx +++ b/src/components/SearchBar/SearchBar.tsx @@ -22,7 +22,7 @@ export const SearchBar = forwardRef((props, re const inputRef = useRef(null); const refs = useMergeRefs(inputRef, ref); const { landingFormUrl } = useLandingFormPreference(); - const { getSearchHref, show: showBackLink } = useBackToSearchResults(); + const { handleBack } = useBackToSearchResults(); useEffect(() => { if (query !== undefined) { @@ -50,16 +50,16 @@ export const SearchBar = forwardRef((props, re > Start new search - ) : showBackLinkAs === 'results' && showBackLink ? ( + ) : showBackLinkAs === 'results' ? ( ) : null} diff --git a/src/components/SearchBar/__tests__/SearchBar.test.tsx b/src/components/SearchBar/__tests__/SearchBar.test.tsx index 1b52833d9..f5a89058f 100644 --- a/src/components/SearchBar/__tests__/SearchBar.test.tsx +++ b/src/components/SearchBar/__tests__/SearchBar.test.tsx @@ -6,6 +6,7 @@ const mocks = vi.hoisted(() => ({ useRouter: vi.fn(() => ({ query: { q: '' }, events: { on: vi.fn(), off: vi.fn() }, + back: vi.fn(), })), useLandingFormPreference: vi.fn(() => ({ landingFormUrl: '/', @@ -119,7 +120,8 @@ test('selecting quickfield appends to existing query', async () => { }); test('Updates via changes to the search URL', async () => { - mocks.useRouter.mockImplementationOnce(() => ({ query: { q: 'URL_QUERY' }, events: { on: vi.fn(), off: vi.fn() } })); + const urlRouter = { query: { q: 'URL_QUERY' }, events: { on: vi.fn(), off: vi.fn() }, back: vi.fn() }; + mocks.useRouter.mockImplementationOnce(() => urlRouter).mockImplementationOnce(() => urlRouter); const { getByTestId } = render(); const input = getByTestId('search-input') as HTMLInputElement; expect(input.value).toBe('URL_QUERY'); diff --git a/src/lib/useBackToSearchResults.test.ts b/src/lib/useBackToSearchResults.test.ts new file mode 100644 index 000000000..044f8b35a --- /dev/null +++ b/src/lib/useBackToSearchResults.test.ts @@ -0,0 +1,18 @@ +import { renderHook } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; +import { useBackToSearchResults } from './useBackToSearchResults'; + +const router = { + back: vi.fn(), +}; +vi.mock('next/router', () => ({ + useRouter: () => router, +})); + +describe('useBackToSearchResults', () => { + it('handleBack calls router.back()', () => { + const { result } = renderHook(() => useBackToSearchResults()); + result.current.handleBack(); + expect(router.back).toHaveBeenCalledOnce(); + }); +}); diff --git a/src/lib/useBackToSearchResults.ts b/src/lib/useBackToSearchResults.ts index c9d828eca..e2e45b449 100644 --- a/src/lib/useBackToSearchResults.ts +++ b/src/lib/useBackToSearchResults.ts @@ -1,24 +1,9 @@ -import { calculatePage } from '@/components/ResultList/Pagination/usePagination'; -import { AppState, useStore } from '@/store'; -import { useCallback } from 'react'; -import { ISimpleLinkProps } from '@/components/SimpleLink'; -import { makeSearchParams } from '@/utils/common/search'; - -const selector = { - latestQuery: (state: AppState) => state.latestQuery, -}; +import { useRouter } from 'next/router'; export const useBackToSearchResults = () => { - const latestQuery = useStore(selector.latestQuery); - const show = latestQuery.q !== ''; - - const getSearchHref = useCallback<() => ISimpleLinkProps['href']>(() => { - const search = makeSearchParams({ ...latestQuery, p: calculatePage(latestQuery.start, latestQuery.rows) }); - return { pathname: '/search', search }; - }, [latestQuery]); + const router = useRouter(); return { - getSearchHref, - show, + handleBack: router.back, }; }; diff --git a/src/pages/search/authoraffiliations.tsx b/src/pages/search/authoraffiliations.tsx index e7b8f2f3d..c51b9fef4 100644 --- a/src/pages/search/authoraffiliations.tsx +++ b/src/pages/search/authoraffiliations.tsx @@ -3,7 +3,6 @@ import { Button, Container as Box } from '@chakra-ui/react'; import { useBackToSearchResults } from '@/lib/useBackToSearchResults'; import { NextPage } from 'next'; import { AuthorAffiliations, AuthorAffiliationsErrorMessage } from '@/components/AuthorAffiliations'; -import { SimpleLink } from '@/components/SimpleLink'; import { parseQueryFromUrl } from '@/utils/common/search'; import { useRouter } from 'next/router'; import { IADSApiSearchParams } from '@/api/search/types'; @@ -11,7 +10,7 @@ import { APP_DEFAULTS } from '@/config'; import { ErrorBoundary } from 'react-error-boundary'; const AuthorAffiliationsPage: NextPage = () => { - const { getSearchHref, show: showBackLink } = useBackToSearchResults(); + const { handleBack } = useBackToSearchResults(); const router = useRouter(); const { qid, ...query } = parseQueryFromUrl<{ qid: string; format: string }>(router.asPath, { sortPostfix: 'id asc', @@ -25,21 +24,19 @@ const AuthorAffiliationsPage: NextPage = () => { return ( <> - {showBackLink && ( - - )} + - + diff --git a/src/pages/search/citation_helper.tsx b/src/pages/search/citation_helper.tsx index fe4e78ed2..174e17c66 100644 --- a/src/pages/search/citation_helper.tsx +++ b/src/pages/search/citation_helper.tsx @@ -2,7 +2,6 @@ import { IADSApiSearchParams, IDocsEntity } from '@/api/search/types'; import { composeNextGSSP } from '@/ssr-utils'; import { SimpleLink } from '@/components/SimpleLink'; import { APP_DEFAULTS, BRAND_NAME_FULL } from '@/config'; -import { useBackToSearchResults } from '@/lib/useBackToSearchResults'; import { getFormattedNumericPubdate, unwrapStringValue } from '@/utils/common/formatters'; import { ChevronLeftIcon, ExternalLinkIcon, InfoIcon } from '@chakra-ui/icons'; import { @@ -17,10 +16,12 @@ import { Stack, useDisclosure, Button, + IconButton, Tooltip, } from '@chakra-ui/react'; import { GetServerSideProps, NextPage } from 'next'; import Head from 'next/head'; +import { useRouter } from 'next/router'; import { parseQueryFromUrl } from '@/utils/common/search'; import { dehydrate, QueryClient } from '@tanstack/react-query'; import { fetchSearch, searchKeys, useSearch } from '@/api/search/search'; @@ -54,7 +55,7 @@ interface ICitationHelperPageProps { } export const CitationHelperPage: NextPage = ({ query, bibcodes, error }) => { - const { getSearchHref, show: showSearchHref } = useBackToSearchResults(); + const router = useRouter(); const { isOpen: isAddToLibraryOpen, onClose: onCloseAddToLibrary, onOpen: onOpenAddToLibrary } = useDisclosure(); @@ -155,11 +156,12 @@ export const CitationHelperPage: NextPage = ({ query, - {showSearchHref && ( - - - - )} + } + variant="ghost" + onClick={() => router.back()} + /> Citation Helper diff --git a/src/pages/search/exportcitation/[format].tsx b/src/pages/search/exportcitation/[format].tsx index 3c6a757ab..cf6d4d336 100644 --- a/src/pages/search/exportcitation/[format].tsx +++ b/src/pages/search/exportcitation/[format].tsx @@ -7,11 +7,11 @@ import { useIsClient } from '@/lib/useIsClient'; import axios from 'axios'; import { GetServerSideProps, NextPage } from 'next'; import Head from 'next/head'; +import { useRouter } from 'next/router'; import { last, map, prop } from 'ramda'; import { dehydrate, QueryClient } from '@tanstack/react-query'; import { composeNextGSSP } from '@/ssr-utils'; import { useSettings } from '@/lib/useSettings'; -import { useBackToSearchResults } from '@/lib/useBackToSearchResults'; import { logger } from '@/logger'; import { SimpleLink } from '@/components/SimpleLink'; import { CitationExporter } from '@/components/CitationExporter'; @@ -58,8 +58,8 @@ const ExportCitationPage: NextPage = (props) => { maxauthor: parseInt(settings.bibtexMaxAuthors), }; + const router = useRouter(); const { data, fetchNextPage, hasNextPage, error } = useSearchInfinite(query); - const { getSearchHref, show: showSearchHref } = useBackToSearchResults(); // TODO: add more error handling here if (!data) { @@ -81,10 +81,14 @@ const ExportCitationPage: NextPage = (props) => { - {(referrer || showSearchHref) && ( - + {referrer ? ( + + ) : ( + )}