Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Commit 13803a1

Browse files
committed
fix: search paging without variable change
has more data tracking breaking if the same search variables are used for the new search.
1 parent 1c876b9 commit 13803a1

4 files changed

Lines changed: 36 additions & 19 deletions

File tree

apps/ui/components/search/SeasonalSearchForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ export function SeasonalSearchForm({
191191
if (cv[1] == null || cv[1] === "") return c;
192192
return { ...c, [cv[0]]: cv[1] };
193193
}, {});
194-
handleSearch(searchCriteria);
194+
handleSearch(searchCriteria, true);
195195
};
196196

197197
const translateTag = (key: string, value: string): string | undefined => {
@@ -209,7 +209,7 @@ export function SeasonalSearchForm({
209209
};
210210

211211
const multiSelectFilters = ["unit", "reservationUnitTypes", "purposes"];
212-
const hideList = ["applicationRound", "order", "sort"];
212+
const hideList = ["applicationRound", "order", "sort", "ref"];
213213

214214
return (
215215
<form noValidate onSubmit={handleSubmit(search)}>

apps/ui/components/search/SingleSearchForm.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ const multiSelectFilters = [
214214
"equipments",
215215
];
216216
// we don't want to show "showOnlyReservable" as a FilterTag, as it has its own checkbox in the form
217-
const hideTagList = ["showOnlyReservable", "order", "sort"];
217+
const hideTagList = ["showOnlyReservable", "order", "sort", "ref"];
218218

219219
// TODO rewrite this witout the form state (use query params directly, but don't refresh the page)
220220
export function SingleSearchForm({
@@ -270,13 +270,13 @@ export function SingleSearchForm({
270270
}
271271
};
272272

273-
const search: SubmitHandler<FormValues> = (criteria: FormValues) => {
273+
const onSearch: SubmitHandler<FormValues> = (criteria: FormValues) => {
274274
// Remove empty (null || "") values from the criteria
275275
const searchCriteria = Object.entries(criteria).reduce((c, cv) => {
276276
if (cv[1] == null || cv[1] === "") return c;
277277
return { ...c, [cv[0]]: cv[1] };
278278
}, {});
279-
handleSearch(searchCriteria);
279+
handleSearch(searchCriteria, true);
280280
};
281281

282282
const showOptionalFilters =
@@ -286,7 +286,7 @@ export function SingleSearchForm({
286286
formValues.textSearch != null;
287287

288288
return (
289-
<form noValidate onSubmit={handleSubmit(search)}>
289+
<form noValidate onSubmit={handleSubmit(onSearch)}>
290290
<TopContainer>
291291
<Filters>
292292
<ControlledMultiSelect
@@ -397,7 +397,7 @@ export function SingleSearchForm({
397397
placeholder={t("searchForm:searchTermPlaceholder")}
398398
onKeyDown={(e) => {
399399
if (e.key === "Enter") {
400-
handleSubmit(search)();
400+
handleSubmit(onSearch)();
401401
}
402402
}}
403403
/>

apps/ui/hooks/useSearchQuery.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
} from "@/gql/gql-types";
55
import { SEARCH_PAGING_LIMIT } from "@/modules/const";
66
import { hash } from "common/src/helpers";
7+
import { useRouter } from "next/router";
78
import { useEffect, useState } from "react";
89

910
/* Wrap the search query with a custom hook
@@ -29,20 +30,23 @@ export function useSearchQuery(
2930
const [varhash, setVarhash] = useState("");
3031
const { fetchMore } = query;
3132

33+
const router = useRouter();
34+
3235
// clear the showMore state if the variables change
3336
useEffect(() => {
34-
function check(v: typeof variables): void {
37+
async function check(v: typeof variables, version: number): Promise<void> {
3538
// use hash to make sure we don't reset unnecessarily
36-
hash(JSON.stringify(v)).then((h) => {
37-
if (h !== varhash) {
38-
setVarhash(h);
39-
setHasMoreData(true);
40-
}
41-
});
39+
const hashed = await hash(JSON.stringify({ ...v, version }));
40+
if (hashed !== varhash) {
41+
setVarhash(hashed);
42+
setHasMoreData(true);
43+
}
4244
}
4345

44-
check(variables);
45-
}, [variables, varhash]);
46+
const { ref } = router.query;
47+
const version = Number(ref) > 0 ? Number(ref) : 0;
48+
check(variables, version);
49+
}, [variables, varhash, router.query]);
4650

4751
useEffect(() => {
4852
if (query.data) {

apps/ui/hooks/useSearchValues.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,24 @@ export function useSearchModify() {
2020
const searchValues = useSearchValues();
2121

2222
// TODO type this properly (not a Record)
23-
const handleSearch = (criteria: Record<string, string>) => {
24-
const { sort, order } = router.query;
23+
const handleSearch = (criteria: Record<string, string>, force: boolean) => {
24+
const { sort, order, ref } = router.query;
2525
const newSort = sort != null && !Array.isArray(sort) ? sort : null;
2626
const newOrder = order != null && !Array.isArray(order) ? order : null;
27-
const newValues = { ...criteria, sort: newSort, order: newOrder };
27+
// form submit -> router push has no other way to communicate with the hook that updates the query
28+
// than using query params, so we need to increment the ref to trigger a re-fetch
29+
// otherwise submitting the same search without any changes breaks pagination
30+
// alternative would be to disable the form submit (or make it a no-op) if the search values are the same
31+
// which has other issues like stale data if the page is left open for a long time
32+
const v = Number(ref) > 0 ? Number(ref) : null;
33+
const nextRef = v != null ? v + 1 : 1;
34+
35+
const newValues = {
36+
...criteria,
37+
sort: newSort,
38+
order: newOrder,
39+
...(force ? { ref: nextRef } : {}),
40+
};
2841
router.replace({
2942
query: newValues,
3043
});

0 commit comments

Comments
 (0)