Skip to content

Commit

Permalink
Redirect to advanced search if search string is enclosed in doublequotes
Browse files Browse the repository at this point in the history
  • Loading branch information
Adamik10 committed Oct 9, 2023
1 parent cdae5dc commit 3190b7d
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 24 deletions.
4 changes: 2 additions & 2 deletions src/apps/search-header/search-header.dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ export default {
defaultValue: "/advanced-search",
control: { type: "text" }
},
searchHeaderAdvancedSearchIconText: {
searchHeaderDropdownText: {
name: "Search header advanced search icon label",
defaultValue: "Advanced search",
defaultValue: "Dropdown with additional search functions",
control: { type: "text" }
},
materialUrl: {
Expand Down
2 changes: 1 addition & 1 deletion src/apps/search-header/search-header.entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface SearchHeaderTextProps {
stringSuggestionAuthorText?: string;
stringSuggestionWorkText?: string;
stringSuggestionTopicText?: string;
searchHeaderAdvancedSearchIconText: string;
searchHeaderDropdownText: string;
etAlText?: string;
autosuggestBookCategoryText: string;
autosuggestEbookCategoryText: string;
Expand Down
64 changes: 54 additions & 10 deletions src/apps/search-header/search-header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react";
import { useCombobox, UseComboboxStateChange } from "downshift";
import { useClickAway } from "react-use";
import {
SuggestionsFromQueryStringQuery,
SuggestionType,
Expand All @@ -10,6 +11,7 @@ import { Autosuggest } from "../../components/autosuggest/autosuggest";
import { Suggestion } from "../../core/utils/types/autosuggest";
import { useUrls } from "../../core/utils/url";
import {
constructAdvancedSearchUrl,
constructMaterialUrl,
constructSearchUrl,
constructSearchUrlWithFilter,
Expand Down Expand Up @@ -324,19 +326,48 @@ const SearchHeader: React.FC = () => {
onHighlightedIndexChange: handleHighlightedIndexChange
});

const headerDropdownRef = React.useRef<HTMLButtonElement>(null);

useClickAway(headerDropdownRef, () => {
// We use a timeout so that when the user clicks on the dropdown arrow as
// the dropdown is open, the state first needs to change through the
// dropdown arrow button (icon in the search bar component)
setTimeout(() => {
setIsHeaderDropdownOpen(false);
}, 100);
});

const [redirectUrl, setRedirectUrl] = useState<URL>(
constructSearchUrl(searchUrl, q)
);

useEffect(() => {
if (
q.trim().charAt(0) === '"' &&
q.trim().charAt(q.length - 1) === '"' &&
q.trim() !== '""' &&
q.trim() !== '"'
) {
setRedirectUrl(constructAdvancedSearchUrl(advancedSearchUrl, q));
} else {
setRedirectUrl(constructSearchUrl(searchUrl, q));
}
}, [q, advancedSearchUrl, searchUrl]);

return (
<form
className="header__menu-second"
action={String(constructSearchUrl(searchUrl, qWithoutQuery))}
>
<div className="header__menu-second">
{/* The downshift combobox uses prop spreading by design */}
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<div className="header__menu-search">
<SearchBar
q={q}
getInputProps={getInputProps}
getLabelProps={getLabelProps}
qWithoutQuery={qWithoutQuery}
setQWithoutQuery={setQWithoutQuery}
isHeaderDropdownOpen={isHeaderDropdownOpen}
setIsHeaderDropdownOpen={setIsHeaderDropdownOpen}
redirectUrl={redirectUrl}
/>
<Autosuggest
textData={textData}
Expand All @@ -356,14 +387,27 @@ const SearchHeader: React.FC = () => {
data-cy="search-header-dropdown"
>
<ul>
<li className="header__menu-dropdown-item">
<li>
<button
className="cursor-pointer"
ref={headerDropdownRef}
type="button"
role="menuitem"
className="header__menu-dropdown-item cursor-pointer"
onClick={() => redirectTo(advancedSearchUrl)}
onKeyUp={(e) =>
e.key === "Enter" && redirectTo(advancedSearchUrl)
}
onKeyUp={(e) => {
if (e.key === "Enter") {
return redirectTo(advancedSearchUrl);
}
if (
e.key === "ArrowDown" ||
e.key === "ArrowUp" ||
e.key === "Escape"
) {
return setIsHeaderDropdownOpen(false);
}
return null;
}}
onBlur={() => setIsHeaderDropdownOpen(false)}
>
{t("headerDropdownItemAdvancedSearchText")}
</button>
Expand All @@ -372,7 +416,7 @@ const SearchHeader: React.FC = () => {
</div>
)}
</div>
</form>
</div>
);
};

Expand Down
49 changes: 39 additions & 10 deletions src/components/search-bar/search-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,41 @@ import searchIcon from "@danskernesdigitalebibliotek/dpl-design-system/build/ico
import expandIcon from "@danskernesdigitalebibliotek/dpl-design-system/build/icons/collection/ExpandMore.svg";
import { UseComboboxPropGetters } from "downshift";
import { useText } from "../../core/utils/text";
import { redirectTo } from "../../core/utils/helpers/url";

export interface SearchBarProps {
q: string;
getInputProps: UseComboboxPropGetters<unknown>["getInputProps"];
getLabelProps: UseComboboxPropGetters<unknown>["getLabelProps"];
dataCy?: string;
qWithoutQuery: string;
setQWithoutQuery: (value: string) => void;
isHeaderDropdownOpen: boolean;
setIsHeaderDropdownOpen: (
value: boolean | ((prevState: boolean) => boolean)
) => void;
redirectUrl: URL;
}

const SearchBar: React.FC<SearchBarProps> = ({
q,
getInputProps,
getLabelProps,
dataCy = "search-header-input",
qWithoutQuery,
setQWithoutQuery,
setIsHeaderDropdownOpen
isHeaderDropdownOpen,
setIsHeaderDropdownOpen,
redirectUrl
}) => {
const t = useText();
const handleDropdownMenu = () => {
setIsHeaderDropdownOpen((prev: boolean) => !prev);
setIsHeaderDropdownOpen(!isHeaderDropdownOpen);
};

return (
<>
{/* The downshift combobox uses prop spreading by design & associated control is desctructured too */}
{/* The downshift combobox uses prop spreading by design & associated control is destructured too */}
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control, react/jsx-props-no-spreading */}
<label className="hide-visually" {...getLabelProps()}>
{t("searchHeaderInputLabelText")}
Expand All @@ -44,6 +53,11 @@ const SearchBar: React.FC<SearchBarProps> = ({
type="text"
placeholder={t("inputPlaceholderText")}
aria-label={t("inputPlaceholderText")}
onKeyUp={(e) => {
if (e.key === "Enter" && qWithoutQuery === q && q.length > 0) {
redirectTo(redirectUrl);
}
}}
{...getInputProps({
onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
setQWithoutQuery(e.target.value);
Expand All @@ -52,27 +66,42 @@ const SearchBar: React.FC<SearchBarProps> = ({
/>
{/* eslint-enable react/jsx-props-no-spreading */}
<input
required
type="image"
src={searchIcon}
alt={t("searchHeaderIconAltText")}
className="header__menu-search-icon"
onClick={() => {
// Only redirect if there is no selected item in autosuggest
if (qWithoutQuery === q && q.length > 0) {
redirectTo(redirectUrl);
}
}}
onKeyUp={(e) => {
// Only redirect if there is no selected item in autosuggest
if (e.key === "Enter" && qWithoutQuery === q && q.length > 0) {
redirectTo(redirectUrl);
}
}}
/>
<input
required
type="image"
src={expandIcon}
alt={t("searchHeaderAdvancedSearchIconText")}
alt={t("searchHeaderDropdownText")}
className="header__menu-dropdown-icon"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handleDropdownMenu();
}}
onKeyUp={(e) =>
(e.key === "Enter" || e.key === "ArrowDown") && handleDropdownMenu()
}
onKeyUp={(e) => {
if (e.key === "Enter" || e.key === "ArrowDown") {
e.preventDefault();
e.stopPropagation();
handleDropdownMenu();
}
}}
tabIndex={0}
aria-label={t("searchHeaderAdvancedSearchIconText")}
aria-label={t("searchHeaderDropdownText")}
data-cy="search-header-dropdown-icon"
/>
</>
Expand Down
2 changes: 1 addition & 1 deletion src/core/utils/helpers/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const constructSearchUrl = (searchUrl: URL, q: string) =>

export const constructAdvancedSearchUrl = (advancedSearchUrl: URL, q: string) =>
appendQueryParametersToUrl(advancedSearchUrl, {
q
advancedSearchCql: q
});

export const constructSearchUrlWithFilter = (args: {
Expand Down

0 comments on commit 3190b7d

Please sign in to comment.