diff --git a/src/components/AbstractSearchForm/AbstractSearchForm.tsx b/src/components/AbstractSearchForm/AbstractSearchForm.tsx new file mode 100644 index 000000000..49db29c85 --- /dev/null +++ b/src/components/AbstractSearchForm/AbstractSearchForm.tsx @@ -0,0 +1,79 @@ +import { useStore } from '@/store'; +import { SearchBar } from '../SearchBar'; +import { ChangeEventHandler, useCallback } from 'react'; +import { makeSearchParams } from '@/utils/common/search'; +import { useSettings } from '@/lib/useSettings'; +import { IADSApiSearchParams } from '@/api/search/types'; +import router from 'next/router'; +import { applyFiltersToQuery } from '../SearchFacet/helpers'; +import { DatabaseEnum, IADSApiUserDataResponse } from '@/api/user/types'; +import { SolrSort } from '@/api/models'; + +export const AbstractSearchForm = () => { + const { settings } = useSettings(); + const submitQuery = useStore((state) => state.submitQuery); + const sort = [`${settings.preferredSearchSort} desc` as SolrSort]; + const query = useStore((state) => state.query.q); + + /** + * Take in a query object and apply any FQ filters + * These will either be any default ON filters or whatever has been set by the user in the preferences + */ + const applyDefaultFilters = useCallback( + (query: IADSApiSearchParams) => { + const defaultDatabases = getListOfAppliedDefaultDatabases(settings.defaultDatabase); + if (Array.isArray(defaultDatabases) && defaultDatabases.length > 0) { + return applyFiltersToQuery({ + query, + values: defaultDatabases, + field: 'database', + logic: 'or', + }); + } + return query; + }, + [settings.defaultDatabase], + ); + + /** + * Get a list of default databases that have been applied + * @param databases + */ + const getListOfAppliedDefaultDatabases = (databases: IADSApiUserDataResponse['defaultDatabase']): Array => { + const defaultDatabases = []; + for (const db of databases) { + // if All is selected, exit early here and return an empty array (no filters to apply) + if (db.name === DatabaseEnum.All && db.value) { + return []; + } + + if (db.value) { + defaultDatabases.push(db.name); + } + } + return defaultDatabases; + }; + + const handleOnSubmit: ChangeEventHandler = useCallback( + (e) => { + e.preventDefault(); + const query = new FormData(e.currentTarget).get('q') as string; + + if (query && query.trim().length > 0) { + submitQuery(); + const defaultedQuery = applyDefaultFilters({ q: query, sort, p: 1 }) as IADSApiSearchParams; + void router.push({ + pathname: '/search', + search: makeSearchParams(defaultedQuery), + }); + } + }, + [applyDefaultFilters, sort, submitQuery], + ); + + return ( +
+ + + ); +}; diff --git a/src/components/AbstractSearchForm/index.ts b/src/components/AbstractSearchForm/index.ts new file mode 100644 index 000000000..668ba010c --- /dev/null +++ b/src/components/AbstractSearchForm/index.ts @@ -0,0 +1 @@ +export * from './AbstractSearchForm'; diff --git a/src/components/AbstractSideNav/AbstractSideNav.tsx b/src/components/AbstractSideNav/AbstractSideNav.tsx index e1b50492b..bf916f299 100644 --- a/src/components/AbstractSideNav/AbstractSideNav.tsx +++ b/src/components/AbstractSideNav/AbstractSideNav.tsx @@ -172,12 +172,7 @@ export const AbstractSideNav = (props: IAbstractSideNavProps): ReactElement => { /> {/* Small viewports */} - + ); }; diff --git a/src/components/Layout/AbsLayout.tsx b/src/components/Layout/AbsLayout.tsx index 51a306c8e..ea59c0d6a 100644 --- a/src/components/Layout/AbsLayout.tsx +++ b/src/components/Layout/AbsLayout.tsx @@ -1,17 +1,15 @@ -import { ArrowLeftIcon } from '@chakra-ui/icons'; -import { Box, Button, Flex, Heading, Stack, Text } from '@chakra-ui/react'; +import { Box, Heading, Stack, Text } from '@chakra-ui/react'; -import { useBackToSearchResults } from '@/lib/useBackToSearchResults'; import { MathJax } from 'better-react-mathjax'; import Head from 'next/head'; import { FC } from 'react'; import { BRAND_NAME_FULL } from '@/config'; import { Metatags } from '@/components/Metatags'; -import { SimpleLink } from '@/components/SimpleLink'; import { AbstractSources } from '@/components/AbstractSources'; import { AbstractSideNav } from '@/components/AbstractSideNav'; import { stripHtml, unwrapStringValue } from '@/utils/common/formatters'; import { IDocsEntity } from '@/api/search/types'; +import { AbstractSearchForm } from '@/components/AbstractSearchForm'; interface IAbsLayoutProps { doc?: IDocsEntity; @@ -20,15 +18,13 @@ interface IAbsLayoutProps { } export const AbsLayout: FC = ({ children, doc, titleDescription, label }) => { - const { getSearchHref, show: showBackLink } = useBackToSearchResults(); - const rawTitle = doc ? unwrapStringValue(doc.title) : ''; const title = stripHtml(rawTitle); const suffix = `${BRAND_NAME_FULL} ${label}`; const pageTitle = title ? `${title} - ${suffix}` : suffix; return ( - + {pageTitle} {doc && } @@ -37,20 +33,7 @@ export const AbsLayout: FC = ({ children, doc, titleDescription children ) : ( <> - {showBackLink && ( - - - - )} + diff --git a/src/components/Libraries/DocumentList/ItemAnnotation.tsx b/src/components/Libraries/DocumentList/ItemAnnotation.tsx index 7fe376d7d..99c10da6d 100644 --- a/src/components/Libraries/DocumentList/ItemAnnotation.tsx +++ b/src/components/Libraries/DocumentList/ItemAnnotation.tsx @@ -73,6 +73,7 @@ export const ItemAnnotation = ({ (open ? onClose() : onOpen())} disabled={false} variant="unstyled" diff --git a/src/components/ResultList/Item/AbstractPreview.tsx b/src/components/ResultList/Item/AbstractPreview.tsx index 948e0d0d4..793c8e7c9 100644 --- a/src/components/ResultList/Item/AbstractPreview.tsx +++ b/src/components/ResultList/Item/AbstractPreview.tsx @@ -47,6 +47,7 @@ export const AbstractPreview = ({ bibcode }: IAbstractPreviewProps): ReactElemen setShow(!show)} disabled={false} variant="unstyled" diff --git a/src/components/SearchBar/SearchBar.tsx b/src/components/SearchBar/SearchBar.tsx index e807b89cc..e2cb86ffc 100644 --- a/src/components/SearchBar/SearchBar.tsx +++ b/src/components/SearchBar/SearchBar.tsx @@ -7,20 +7,22 @@ import { initialState, reducer } from '@/components/SearchBar/searchInputReducer import { QuickFields } from '@/components/SearchBar/QuickFields'; import { SimpleLink } from '@/components/SimpleLink'; import { useLandingFormPreference } from '@/lib/useLandingFormPreference'; +import { useBackToSearchResults } from '@/lib/useBackToSearchResults'; interface SearchBarProps extends Omit { query?: string; isLoading?: boolean; queryAddition?: string; - showStartNewSearchLink?: boolean; + showBackLinkAs?: 'new_search' | 'results' | 'none'; } export const SearchBar = forwardRef((props, ref) => { - const { query, queryAddition, isLoading, showStartNewSearchLink = false, ...rest } = props; + const { query, queryAddition, isLoading, showBackLinkAs = 'none', ...rest } = props; const [state, dispatch] = useReducer(reducer, initialState); const inputRef = useRef(null); const refs = useMergeRefs(inputRef, ref); const { landingFormUrl } = useLandingFormPreference(); + const { getSearchHref, show: showBackLink } = useBackToSearchResults(); useEffect(() => { if (query !== undefined) { @@ -36,7 +38,7 @@ export const SearchBar = forwardRef((props, re return ( - {showStartNewSearchLink ? ( + {showBackLinkAs === 'new_search' ? ( + ) : showBackLinkAs === 'results' && showBackLink ? ( + ) : null} diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index ef3685917..e4217da08 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -301,11 +301,11 @@ const SearchPage: NextPage = () => { {`${params.q} - ${BRAND_NAME_FULL} Search`} - +
- +