|
1 | 1 | import { useEffect } from "react";
|
2 | 2 |
|
| 3 | +import compare from "just-compare"; |
3 | 4 | import { useRouter } from "next/router";
|
4 | 5 |
|
5 | 6 | import { PROJECT_LOCAL_STORAGE_KEY } from "../constants";
|
6 | 7 | import { getFromLocalStorage } from "../utils/localStorage";
|
7 | 8 | import type { ProjectLocalStoragePayload } from "./projectHooks";
|
8 | 9 |
|
9 |
| -const PATHS_FOR_UPDATE = ["/datasets", "/project", "/executions", "/results"]; |
10 |
| - |
| 10 | +/** |
| 11 | + * Hook to synchronise the project local storage to query params. |
| 12 | + * E.g. if the user visits example-ui.com/data-manager-ui/sub/path, the url will be *replaced* with |
| 13 | + * example-ui.com/data-manager-ui/sub/path?project=project-blah-blah-blah-blah using the project ID |
| 14 | + * loaded from local storage. |
| 15 | + * |
| 16 | + * @private |
| 17 | + * It could be better to use a local storage event listener here but I find those unreliable |
| 18 | + * If the project was stored server-side this could be done in a middleware but alas. |
| 19 | + */ |
11 | 20 | export const useBindProjectFromLSToQParams = () => {
|
12 | 21 | const router = useRouter();
|
13 | 22 |
|
14 |
| - const { isReady, pathname, query, push } = router; |
15 |
| - |
16 |
| - const shouldNavigate = PATHS_FOR_UPDATE.map((s) => pathname.startsWith(s)).some((b) => b); |
| 23 | + const { isReady, pathname, query, replace } = router; |
17 | 24 |
|
18 | 25 | useEffect(() => {
|
19 | 26 | const { projectId } = getFromLocalStorage<
|
20 | 27 | ProjectLocalStoragePayload | Record<string, undefined>
|
21 | 28 | >(PROJECT_LOCAL_STORAGE_KEY, {});
|
22 | 29 |
|
23 |
| - if (isReady && shouldNavigate && projectId) { |
24 |
| - push({ pathname, query: { project: projectId, ...query } }, undefined, { |
25 |
| - shallow: true, |
26 |
| - }); |
| 30 | + if (isReady && projectId) { |
| 31 | + const newQuery = { ...query, project: projectId }; |
| 32 | + if (!compare(query, newQuery)) { |
| 33 | + replace({ pathname, query: newQuery }, undefined, { |
| 34 | + shallow: true, |
| 35 | + }); |
| 36 | + } |
27 | 37 | }
|
28 |
| - // eslint-disable-next-line react-hooks/exhaustive-deps |
29 |
| - }, []); |
| 38 | + }, [isReady, pathname, replace, query]); |
30 | 39 | };
|
0 commit comments