From 67f130fd40ade2dbbe70f607d8a9c112782f5651 Mon Sep 17 00:00:00 2001 From: pamfilos Date: Wed, 3 Apr 2024 15:49:36 +0200 Subject: [PATCH] ui: fixes search issues Signed-off-by: pamfilos --- ui/src/components/search/CheckboxFacet.tsx | 4 +-- ui/src/components/search/SearchPagination.tsx | 12 ++++++-- ui/src/components/search/YearFacet.tsx | 24 ++++++++-------- ui/src/components/shared/SearchBar.tsx | 2 +- ui/src/pages/index.tsx | 3 +- ui/src/pages/search.tsx | 28 ++++++++++++++++--- ui/src/utils/utils.tsx | 14 +++------- 7 files changed, 54 insertions(+), 33 deletions(-) diff --git a/ui/src/components/search/CheckboxFacet.tsx b/ui/src/components/search/CheckboxFacet.tsx index 03d3db41d..67d24c339 100644 --- a/ui/src/components/search/CheckboxFacet.tsx +++ b/ui/src/components/search/CheckboxFacet.tsx @@ -3,8 +3,7 @@ import React, { useState, useEffect, useCallback } from "react"; import { useRouter, useSearchParams, usePathname } from "next/navigation"; import { Card } from "antd"; -import { getSearchUrl } from "@/utils/utils"; -import { Country, Journal, Params } from "@/types"; +import { Country, Journal } from "@/types"; interface CheckboxFacetProps { type: "country" | "journal"; @@ -29,6 +28,7 @@ const CheckboxFacet: React.FC = ({ const params = new URLSearchParams(searchParams) params.delete(name); + params.delete("page"); if (!Array.isArray(value)) value = [value]; value.forEach((val: string) => { diff --git a/ui/src/components/search/SearchPagination.tsx b/ui/src/components/search/SearchPagination.tsx index 0d73703bd..cf63ee898 100644 --- a/ui/src/components/search/SearchPagination.tsx +++ b/ui/src/components/search/SearchPagination.tsx @@ -1,6 +1,6 @@ import React from "react"; import { Pagination } from "antd"; -import { useRouter } from "next/navigation"; +import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { getSearchUrl } from "@/utils/utils"; import { Params } from "@/types"; @@ -12,9 +12,15 @@ interface SearchPagination { const SearchPagination: React.FC = ({ count, params }) => { const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + const currentPage = searchParams.get("page") || 1 const onPageChange = (page: number) => { - router.push(getSearchUrl({ ...params, page })); + const params = new URLSearchParams(searchParams) + params.set("page", `${page}`); + + router.replace(pathname + (params.toString() ? `?${params.toString()}` : '')); }; return ( @@ -24,7 +30,7 @@ const SearchPagination: React.FC = ({ count, params }) => { total={count} onChange={(page) => onPageChange(page)} showSizeChanger={false} - current={Number(params?.page) || 1} + current={Number(currentPage) || 1} hideOnSinglePage className="md:mb-0 mb-3" /> diff --git a/ui/src/components/search/YearFacet.tsx b/ui/src/components/search/YearFacet.tsx index e442a62ee..3033297c3 100644 --- a/ui/src/components/search/YearFacet.tsx +++ b/ui/src/components/search/YearFacet.tsx @@ -4,12 +4,8 @@ import { Button, Card, Slider } from "antd"; import { useRouter, usePathname, useSearchParams } from "next/navigation"; import "react-vis/dist/style.css"; -import { PublicationYear, YearFacetData, Params } from "@/types"; +import { PublicationYear, YearFacetData } from "@/types"; -interface YearFacetProps { - data: PublicationYear[]; - params: Params; -} const mapInitialDataToYears = ( initial: PublicationYear[] @@ -20,7 +16,7 @@ const mapInitialDataToYears = ( })); }; -const YearFacet: React.FC = ({ data, params }) => { +const YearFacet = ({ data }: any) => { const [hoveredBar, setHoveredBar] = useState(null); const [filters, setFilters] = useState([]); const [initialEndpoints, setInitialEndpoints] = useState([]); @@ -49,6 +45,7 @@ const YearFacet: React.FC = ({ data, params }) => { const params = new URLSearchParams(searchParams) params.delete(name); + params.delete("page"); params.set(name, resolveYearQuery([value[0].x, value[1].x])); return params.toString() @@ -65,13 +62,15 @@ const YearFacet: React.FC = ({ data, params }) => { setSliderEndpoints(data) }; - const onSliderChange2 = (data: number[]) => { + const onSliderAfterChange = (data: number[]) => { setSliderEndpoints(data) - router.replace(pathname + '?' + createQueryString('publication_year__range', [{x:data[0]}, {x:data[1]}])) + const params = createQueryString('publication_year__range', [{x:data[0]}, {x:data[1]}]); + router.replace(pathname + (params ? `?${params.toString()}` : "")) }; const onBarClick = (value: YearFacetData) => { - router.replace(pathname + '?' + createQueryString('publication_year__range', [value, value])) + const params = createQueryString('publication_year__range', [value, value]); + router.replace(pathname + (params ? `?${params.toString()}` : "")) }; const onBarMouseHover = (bar: YearFacetData) => { @@ -83,10 +82,11 @@ const YearFacet: React.FC = ({ data, params }) => { const resetFilters = () => { const params = new URLSearchParams(searchParams); params.delete('publication_year__range'); - router.replace(pathname + params.toString()) + params.delete('page'); + router.replace(pathname + (params.toString() ? `?${params.toString()}` : "")) }; - let marks:any = {} + let marks: any = {} filters.map( (i, idx) => { marks[`${i.x}`] = { @@ -133,7 +133,7 @@ const YearFacet: React.FC = ({ data, params }) => { step={null} className="year-facet-slider" onChange={onSliderChange} - onAfterChange={onSliderChange2} + onAfterChange={onSliderAfterChange} value={sliderEndpoints} defaultValue={initialEndpoints} min={initialEndpoints[0]} diff --git a/ui/src/components/shared/SearchBar.tsx b/ui/src/components/shared/SearchBar.tsx index a50d10a71..9a463c19e 100644 --- a/ui/src/components/shared/SearchBar.tsx +++ b/ui/src/components/shared/SearchBar.tsx @@ -25,7 +25,7 @@ const SearchBar: React.FC = ({ <> {!hide && ( router.push(getSearchUrl({ search: val }, true))} + onSearch={() => router.push(getSearchUrl({...(val ? {search: val} : {})} , true))} placeholder={placeholder} enterButton className={className} diff --git a/ui/src/pages/index.tsx b/ui/src/pages/index.tsx index 71facccc1..0de269ec7 100644 --- a/ui/src/pages/index.tsx +++ b/ui/src/pages/index.tsx @@ -69,7 +69,8 @@ const HomePage: React.FC = ({ count, facets }) => { export const getServerSideProps: GetServerSideProps = async () => { const query = { search: "" }; - const res = await fetch(`${getApiUrl() + getSearchUrl(query)}`, authToken); + const url = `${getApiUrl() + getSearchUrl(query)}`; + const res = await fetch(url, authToken); const { count, facets } = (await res?.json()) as Response; const countValue = { count: count || 0 }; const facetsValue = { facets: facets || null }; diff --git a/ui/src/pages/search.tsx b/ui/src/pages/search.tsx index 9ab14f2a7..cdd8b09b4 100644 --- a/ui/src/pages/search.tsx +++ b/ui/src/pages/search.tsx @@ -7,6 +7,7 @@ import SearchResults from "@/components/search/SearchResults"; import YearFacet from "@/components/search/YearFacet"; import { authToken, getApiUrl, getSearchUrl } from "@/utils/utils"; import CheckboxFacet from "@/components/search/CheckboxFacet"; +import { encode } from 'querystring' interface SearchPageProps { results: Result[]; @@ -66,11 +67,30 @@ const SearchPage: React.FC = ({ export const getServerSideProps: GetServerSideProps = async (context) => { const query = context?.query as unknown as Params; - const url = getApiUrl() + getSearchUrl(query); - const res = await fetch(url, authToken); - const { results, count, facets } = (await res.json()) as Response; + const searchParams = new URLSearchParams(encode(query)) + const params = searchParams ? `?${searchParams}` : ""; + const url = getApiUrl() + params + let results = [], count = 0 , facets =[]; - return { props: { results, count, query, facets } }; + try { + const res = await fetch(url, authToken); + + const contentType = res.headers.get("content-type"); + if (contentType && contentType.indexOf("application/json") !== -1) { + const data = await res.json(); + results = data.results; + count = data.count; + facets = data.facets; + } + } catch (err) { + console.error("Error fetching or parsing data:", err); + } + + + + return { + props: { results, count, query, facets }, + }; }; export default SearchPage; diff --git a/ui/src/utils/utils.tsx b/ui/src/utils/utils.tsx index ab061c932..f87a1c3cd 100644 --- a/ui/src/utils/utils.tsx +++ b/ui/src/utils/utils.tsx @@ -1,6 +1,6 @@ import ReactHtmlParser from "react-html-parser"; -import { ArticleIdentifier, Params, QueryType, queryTypes } from "@/types"; +import { ArticleIdentifier, Params } from "@/types"; import { PARTNER_COUNTRIES } from "./data"; import { Token } from "../../token"; @@ -16,14 +16,6 @@ export const authToken = Token } : {}; -const defaultQueryValues = { - page: 1, - page_size: 20, -}; - -const isValue = (value: any): boolean => - value !== undefined && value !== null && value !== ""; - const buildSearchParams = (q: Params): string => { const searchParams = new URLSearchParams(); @@ -40,7 +32,9 @@ const buildSearchParams = (q: Params): string => { const getSearchUrl = (query: Params, local?: boolean) => { const searchParams = buildSearchParams(query); - const url = local ? `/search?${searchParams}` : `?${searchParams}`; + const path = local ? "/search" : ""; + const params = searchParams ? `?${searchParams}` : ""; + const url = `${path}${params}`; return url; };