diff --git a/components/pages/searchPageLayout/SearchPageLayout.tsx b/components/pages/searchPageLayout/SearchPageLayout.tsx index 4fd22098..29936888 100644 --- a/components/pages/searchPageLayout/SearchPageLayout.tsx +++ b/components/pages/searchPageLayout/SearchPageLayout.tsx @@ -44,7 +44,7 @@ const SearchPageLayout = ({ searchQuery }: { searchQuery?: string }) => { const facetsForSearchRequest = facetDefinitions.reduce( (acc: SearchFiltersInput, facetDefinition) => { - const values = searchParams.getAll(facetDefinition) + const values = searchParams.getAll(mapFacetsToFilters[facetDefinition]) if (values.length > 0) { return { ...acc, @@ -118,6 +118,7 @@ const SearchPageLayout = ({ searchQuery }: { searchQuery?: string }) => { if (isInView) { handleLoadMore() } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isInView]) // TODO: consider finding a better way to control fetching of data without using the useEffects below @@ -132,12 +133,13 @@ const SearchPageLayout = ({ searchQuery }: { searchQuery?: string }) => { }, [q]) useEffect(() => { + // Check if the filters in URL have changed const isFilterMatching = JSON.stringify(facetFilters) === JSON.stringify(facetsForSearchRequest) if (!isFilterMatching) { setFacetFilters(facetsForSearchRequest) setCurrentPage(0) } - }, [facetsForSearchRequest]) + }, [facetsForSearchRequest, facetFilters]) const facetData = dataFacets?.search?.facets const hitcount = data?.pages?.[0]?.search.hitcount ?? 0 diff --git a/components/shared/searchFilters/SearchFiltersColumn.tsx b/components/shared/searchFilters/SearchFiltersColumn.tsx index 13a86884..c187ee21 100644 --- a/components/shared/searchFilters/SearchFiltersColumn.tsx +++ b/components/shared/searchFilters/SearchFiltersColumn.tsx @@ -1,9 +1,11 @@ -import { SearchFacetFragment } from "@/lib/graphql/generated/fbi/graphql" -import { cn } from "@/lib/helpers/helper.cn" -import React, { useEffect, useRef, useState } from "react" -import { mapFacetsToFilters, mapFilterNameToTranslation, toggleFilter } from "./helper" import { useRouter, useSearchParams } from "next/navigation" +import React, { useEffect, useRef, useState } from "react" + +import { SearchFacetFragment, SearchFiltersInput } from "@/lib/graphql/generated/fbi/graphql" +import { cn } from "@/lib/helpers/helper.cn" + import Icon from "../icon/Icon" +import { mapFilterNameToTranslation, sortByActiveFacets, toggleFilter } from "./helper" type SearchFiltersColumnProps = { facet: SearchFacetFragment @@ -19,7 +21,8 @@ const SearchFiltersColumn = ({ setIsExpanded, }: SearchFiltersColumnProps) => { const router = useRouter() - const facetName = facet.name as keyof typeof mapFacetsToFilters + const facetName = facet.name as keyof SearchFiltersInput + const searchParams = useSearchParams() const elementRef = useRef<HTMLDivElement | null>(null) const [hasOverflow, setHasOverflow] = useState(false) @@ -34,6 +37,9 @@ const SearchFiltersColumn = ({ } }, [elementRef]) + // We show the selected values first in the list + facet.values = sortByActiveFacets(facet, searchParams) + return ( <> <div diff --git a/components/shared/searchFilters/helper.ts b/components/shared/searchFilters/helper.ts index 1db4fc4e..03481dda 100644 --- a/components/shared/searchFilters/helper.ts +++ b/components/shared/searchFilters/helper.ts @@ -1,6 +1,11 @@ import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime" +import { ReadonlyURLSearchParams } from "next/navigation" -import { FacetFieldEnum, SearchFiltersInput } from "@/lib/graphql/generated/fbi/graphql" +import { + FacetFieldEnum, + SearchFacetFragment, + SearchFiltersInput, +} from "@/lib/graphql/generated/fbi/graphql" export const facetDefinitions = [ "MATERIALTYPESGENERAL", @@ -18,13 +23,13 @@ export const mapFacetsToFilters = { SUBJECTS: "subjects", } as Record<FacetFieldEnum, keyof SearchFiltersInput> -export const mapFilterNameToTranslation: Partial<Record<keyof typeof mapFacetsToFilters, string>> = +export const mapFilterNameToTranslation: Partial<Record<keyof SearchFiltersInput | "lix", string>> = { - MATERIALTYPESGENERAL: "Type", - MAINLANGUAGES: "Sprog", - AGE: "Alder", - LIX: "Lix", - SUBJECTS: "Emne", + materialTypesGeneral: "Type", + mainLanguages: "Sprog", + age: "Alder", + lix: "Lix", + subjects: "Emne", } export const toggleFilter = (filterName: string, value: string, router: AppRouterInstance) => { @@ -48,3 +53,16 @@ export const toggleFilter = (filterName: string, value: string, router: AppRoute const searchParamsString = searchParams.toString() router.push("/search" + searchParamsString ? `?${searchParamsString}` : "", { scroll: false }) } + +export const sortByActiveFacets = ( + facet: SearchFacetFragment, + searchParams: ReadonlyURLSearchParams +) => { + return [...facet.values].sort((a, b) => { + const aIncluded = searchParams.getAll(facet.name).includes(a.term) + const bIncluded = searchParams.getAll(facet.name).includes(b.term) + if (aIncluded && !bIncluded) return -1 + if (!aIncluded && bIncluded) return 1 + return 0 + }) +}