Skip to content

Commit

Permalink
Merge pull request #488 from diggsweden/DIGG-362
Browse files Browse the repository at this point in the history
Digg 362
  • Loading branch information
MikaMunterud authored Nov 4, 2024
2 parents b91214d + e4c7f29 commit f8448b7
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { SettingsContext } from "@/providers/SettingsProvider";

export interface SearchFilterProps {
title: string | null;
usedFilters?: string;
defaultValue?: boolean;
}

export const SearchFilter: FC<PropsWithChildren<SearchFilterProps>> = ({
title,
usedFilters,
defaultValue,
children,
}) => {
Expand Down Expand Up @@ -42,12 +44,17 @@ export const SearchFilter: FC<PropsWithChildren<SearchFilterProps>> = ({
<button
aria-haspopup={true}
aria-expanded={open}
aria-label={`${
open ? t("close-filter") : t("open-filter")
} ${title} ${
usedFilters ? ` - ${usedFilters} ${t("active-filters")}` : ""
}`}
onClick={() => handleOpen(!open)}
className={`${
open && "active"
} button button--secondary button--large md:button--small w-full justify-between md:justify-start md:py-[0.25rem]`}
>
{title || t("open")}
{`${title} ${usedFilters || ""}` || t("open")}
<ChevronDownIcon
height={iconSize * 1.5}
width={iconSize * 1.5}
Expand Down
114 changes: 65 additions & 49 deletions components/content/Search/SearchFilters/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const FilterSearch: React.FC<FilterSearchProps> = ({
height={24}
width={24}
className="absolute right-sm [&_path]:fill-brown-500"
aria-hidden="true"
/>
</div>
);
Expand Down Expand Up @@ -205,7 +206,7 @@ export const SearchFilters: React.FC<SearchFilterProps> = ({
}

return (
<div id="SearchFilters">
<div id="SearchFilters" role="region" aria-label={t("common|filter")}>
<Button
variant="plain"
size="sm"
Expand All @@ -214,12 +215,18 @@ export const SearchFilters: React.FC<SearchFilterProps> = ({
aria-label={
showFilter ? t("common|hide-filter") : t("common|show-filter")
}
aria-expanded={showFilter}
aria-controls="filter-content"
onClick={() => updateFilters()}
label={showFilter ? t("common|hide-filter") : t("common|show-filter")}
/>

<div className={showFilter ? "block" : "hidden"}>
<ul className="mb-lg mt-md flex flex-col flex-wrap gap-md md:flex-row">
<div id="filter-content" className={showFilter ? "block" : "hidden"}>
<ul
className="mb-lg mt-md flex flex-col flex-wrap gap-md md:flex-row"
role="list"
aria-label={t("common|available-filters")}
>
{search.allFacets &&
Object.entries(search.allFacets)
.sort((a, b) => (a[1].indexOrder > b[1].indexOrder ? 1 : -1))
Expand All @@ -238,60 +245,65 @@ export const SearchFilters: React.FC<SearchFilterProps> = ({

if (key !== hvd) {
return (
<li key={"box" + value.title + idx}>
<li key={"box" + value.title + idx} role="listitem">
<SearchFilter
title={
value.title +
FindFilters(
value.facetValues,
search.request.facetValues,
)
}
title={value.title}
usedFilters={FindFilters(
value.facetValues,
search.request.facetValues,
)}
>
<div className="absolute z-10 mr-lg mt-sm max-h-[600px] w-full overflow-y-auto bg-white shadow-md md:max-w-[20.625rem]">
{searchMode == "datasets" ||
(searchMode == "specifications" && (
//only render on searchpage
<>
{isLicense ? (
<MarkAll
search={search}
toggleKey={key}
title={t(`filters|allchecktext$${key}`)}
/>
) : (
<FilterSearch
filterKey={key}
filter={inputFilter}
setFilter={setInputFilter}
title={value.title}
fetchMore={() =>
shouldFetchMore &&
search.fetchMoreFacets(key)
}
/>
)}
</>
))}

{facetValues.map(
(facetValue: SearchFacetValue, index: number) => {
if (facetValue.count > 0)
return (
{(searchMode == "datasets" ||
searchMode == "specifications") && (
//only render on searchpage
<>
{isLicense ? (
<MarkAll
search={search}
toggleKey={key}
title={t(`filters|allchecktext$${key}`)}
/>
) : (
<FilterSearch
filterKey={key}
filter={inputFilter}
setFilter={setInputFilter}
title={value.title}
fetchMore={() =>
shouldFetchMore &&
search.fetchMoreFacets(key)
}
/>
)}
</>
)}
{/* List of filter options within this category */}
<ul role="listbox" aria-multiselectable="true">
{facetValues.map(
(facetValue: SearchFacetValue, index: number) => (
<li
key={index}
role="option"
aria-selected={selected(key, facetValue)}
>
<button
aria-pressed={selected(key, facetValue)}
key={index}
className={`group relative flex w-full items-center break-all py-md pl-md pr-xl text-left hover:bg-brown-100 ${
className={`focus--in group relative flex w-full items-center break-all py-md pl-md pr-[3rem] text-left hover:bg-brown-100 ${
selected(key, facetValue) && "font-strong"
}`}
onClick={() => {
doSearch(key, facetValue);
}}
role="checkbox"
aria-checked={selected(key, facetValue)}
>
{facetValue.title || facetValue.resource} (
{facetValue.count}){" "}
{selected(key, facetValue)}
<span className="absolute right-md">
{facetValue.count})
{/* Decorative checkbox icon */}
<span
className="absolute right-md"
aria-hidden="true"
>
{selected(key, facetValue) ? (
<CheckboxCheckedIcon
height={iconSize * 1.5}
Expand All @@ -307,9 +319,10 @@ export const SearchFilters: React.FC<SearchFilterProps> = ({
)}
</span>
</button>
);
},
)}
</li>
),
)}
</ul>

{value.facetValues.length > value.show && (
<Button
Expand Down Expand Up @@ -469,6 +482,9 @@ export const SearchFilters: React.FC<SearchFilterProps> = ({
size="xs"
key={index}
label={facetValue.title || facetValue.resource}
aria-label={`${t("common|clear-filters")} ${
facetValue.title || facetValue.resource
}`}
icon={CloseIcon}
iconPosition="right"
className="w-full justify-between py-md text-left font-strong md:w-auto md:py-[2px]"
Expand Down
106 changes: 60 additions & 46 deletions components/content/Search/SearchPageSelector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,68 @@ export const SearchPageSelector: React.FC<SearchTabsProps> = ({ query }) => {
const { t, lang } = useTranslation("pages");
const { pathname } = useRouter() || {};
return (
<div className="mb-lg flex gap-md overflow-x-scroll md:overflow-x-visible">
<ButtonLink
variant={"plain"}
href={`/datasets?q=${query ? query : ""}&f=`}
label={t("search$datasets")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/datasets"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
/>
<nav aria-label={t("search$search-type-navigation")}>
<div
className="mb-lg flex gap-md overflow-x-scroll md:overflow-x-visible"
role="tablist"
aria-label={t("search$search-tabs")}
>
<ButtonLink
variant={"plain"}
href={`/datasets?q=${query ? query : ""}&f=`}
label={t("search$datasets")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/datasets"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
role="tab"
aria-selected={pathname === "/datasets"}
/>

<ButtonLink
variant={"plain"}
href={`/concepts?q=${query ? query : ""}&f=`}
label={t("search$concepts")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/concepts"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
/>
<ButtonLink
variant={"plain"}
href={`/concepts?q=${query ? query : ""}&f=`}
label={t("search$concepts")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/concepts"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
role="tab"
aria-selected={pathname === "/concepts"}
/>

<ButtonLink
variant={"plain"}
href={`/specifications?q=${query ? query : ""}&f=`}
label={t("search$specifications")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/specifications"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
/>
<ButtonLink
variant={"plain"}
href={`/specifications?q=${query ? query : ""}&f=`}
label={t("search$specifications")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/specifications"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
role="tab"
aria-selected={pathname === "/specifications"}
/>

<ButtonLink
variant={"plain"}
href={`/search?q=${query ? query : ""}&f=`}
label={t("search$content")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/search"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
/>
</div>
<ButtonLink
variant={"plain"}
href={`/search?q=${query ? query : ""}&f=`}
label={t("search$content")}
locale={lang}
className={`whitespace-nowrap ${
pathname === "/search"
? "bg-pink-200 font-strong text-textPrimary"
: ""
}`}
role="tab"
aria-selected={pathname === "/search"}
/>
</div>
</nav>
);
};
19 changes: 18 additions & 1 deletion components/content/Search/SearchResults/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export const SearchResults: FC<SearchResultsProps> = ({
searchMode,
}) => {
const [isCompact, setCompact] = useState(false);
const [lastUpdate, setLastUpdate] = useState<string>("");
const { t } = useTranslation();
const hvd = "http://data.europa.eu/r5r/applicableLegislation";
const searchKey = typeof location != "undefined" ? location.search : "server";
Expand Down Expand Up @@ -195,6 +196,17 @@ export const SearchResults: FC<SearchResultsProps> = ({
}
};

// Track both result count and filter changes
useEffect(() => {
if (search.loadingHits) {
setLastUpdate(t("common|loading"));
} else if (search.result) {
const count = search.result.count || 0;
const message = `${count} ${t("pages|search$dataset-hits")}`;
setLastUpdate(message);
}
}, [search.loadingHits, search.result?.count, search.request.facetValues, t]);

function isHVD(dataset: object) {
const isHvd = Object.values(dataset).map((ds) => ds.hasOwnProperty(hvd));
return isHvd.includes(true);
Expand All @@ -204,13 +216,18 @@ export const SearchResults: FC<SearchResultsProps> = ({
<div id="search-result" className="my-lg md:my-xl">
<div className="mb-lg flex flex-col-reverse justify-between md:flex-row">
<Heading level={2} size="md" className="search-result-header">
<span aria-live="polite" role="status">
{/* Visual display of the count */}
<span aria-hidden="true">
{search.loadingHits && `${t("common|loading")}...`}
{!search.loadingHits &&
search.result &&
(search.result.count || 0) >= 0 &&
`${search.result.count} ${t("pages|search$dataset-hits")}`}
</span>
{/* Screen reader announcement */}
<div aria-live="polite" className="sr-only" role="status">
{lastUpdate}
</div>
</Heading>

{searchMode == "datasets" && (
Expand Down
4 changes: 4 additions & 0 deletions locales/en/common.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"accessibility-report": "Accessibility report",
"about": "About",
"available-filters": "Available filters",
"filter-options": "Filter options",
"beta": "BETA",
"beta-text1": "We are constantly developing Sveriges dataportal. Please send your ",
"beta-link-text": "opinions",
Expand All @@ -9,6 +11,8 @@
"change-lang": "sv",
"clear-search": "Clear search field",
"clear-filters": "Clear filters",
"close-filter": "Close filter list",
"open-filter": "Open filter list",
"close": "Close",
"close_menu": "Menu",
"close_search": "Search",
Expand Down
2 changes: 2 additions & 0 deletions locales/en/pages.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
},
"search": {
"search": "Search data",
"search-tabs": "Search tabs navigation",
"search-type-navigation": "Search type navigation",
"dataset-hits": "results ",
"concept-hits": "results",
"specification-hits": "results",
Expand Down
Loading

0 comments on commit f8448b7

Please sign in to comment.