Repository navigation
Commit 5abf27e
fix(app): open a newly saved search without reloading the page (#3565)
## Summary
Saving a new search left the page through `window.location.assign`, so the whole app reloaded. On the static ClickStack export that reload is worse than slow: the export only emits `search/[savedSearchId].html` (the literal bracket filename, confirmed by running `yarn build:clickhouse`), so a document request for `/clickstack/search/<id>` has nothing to serve and the user lands on a 404 instead of their new search.
The reload was added in #2669 to work around a real race, not out of preference. nuqs 1.17 batches query-string writes and, at flush time, renders them onto `next/router`'s `asPath` — which during a client-side transition is still the *old* path. Live tail rewrites `from`/`to` through nuqs every 10s with `history: 'push'`, so a flush landing mid-transition pushed `/search?...` over the in-flight navigation to `/search/<id>` and the user bounced back to an unsaved search.
This removes the workaround and closes the race at both ends instead:
- Live tail pauses while the save modal is open, so nothing is writing the time range to the URL while the user names their search.
- The page drains the nuqs queue (`await setSearchedConfig({})`) before `router.push`, so any write already queued is applied before the transition starts rather than after it.
Navigation moves to the page component, which is where the query-state setter lives; the modal reports the new id through an `onCreate` prop. `buildSavedSearchNavigationUrl` no longer takes `basePath`, since `router.push` prepends it.
### Screenshots or video
Not a visual change — the diff is in how the page gets to `/search/<id>`. This is the new E2E test recorded in slow motion: the modal closes and the header switches to the saved search with no white flash and no sidebar re-mount.
<a href="https://cursor.com/agents/bc-21467b1b-445a-4f9b-8fd1-828647b21dc4/artifacts?path=%2Fopt%2Fcursor%2Fartifacts%2Fsaved-search-client-side-navigation.mp4"><img src="https://cursor.com/artifacts/c/art-e0dea251-cb3c-4dbd-9ba3-05dcc4fdac9e" alt="saved-search-client-side-navigation.mp4" /></a>
### How to reproduce
**Starting point:** full-stack `yarn dev` (the save flow needs the API), on `/search` with live tail on, which is the default.
**On `main`:**
1. Run any search on the Search page.
2. Click **Save**, type a name, click **Save** in the modal.
3. The whole app reloads — white flash, nav re-mounts, every query re-runs. On a ClickStack deployment served from the static export, the same click lands on a 404 page instead.
**On this branch:**
1. Same three steps.
2. The modal closes and the header switches to the saved search in place; nothing outside the page content re-renders.
### How to test on Vercel preview
N/A — the preview runs in local mode, where saved searches live in localStorage and the reload is survivable; the failure this fixes needs the static ClickStack export or a full-stack deploy.
### Tests
- New unit test (`DBSearchPage.saveSearch.test.tsx`): saving pushes `/search/<id>` through the router (basePath-free), and the queue drain is ordered before the push.
- New E2E test: a marker set on `document.documentElement` survives the save, which it cannot across a document load.
- `buildSavedSearchNavigationUrl` unit tests updated for the dropped `basePath`, plus a case for a live-tail range.
- Separately, the existing `should handle navigation via browser back button` E2E test was racing the sessions page, which writes its default time range as a *pushed* history entry shortly after mount — one Back landed on the saved search or on bare `/sessions` depending on which won. It now waits for that write before going back. This is a pre-existing flake that the faster client-side save made easier to hit; the app-side wart (a junk history entry per page load) is untouched.
`make ci-lint` and `make ci-unit` pass. The `saved-search` E2E file passes 40/40 over two repeat runs.
### References
- Linear Issue: HDX-5916
- Related PRs: #2669 (introduced the reload this replaces)
<div><a href="https://cursor.com/agents/bc-21467b1b-445a-4f9b-8fd1-828647b21dc4?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-21467b1b-445a-4f9b-8fd1-828647b21dc4&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div>
Fixes HDX-5916
Co-authored-by: Cursor Agent <199161495+cursoragent@users.noreply.github.com>1 parent 86cd38b commit 5abf27e
8 files changed
Lines changed: 403 additions & 25 deletions
File tree
- .changeset
- packages/app
- src
- __tests__
- tests/e2e
- components
- features/search
- page-objects
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
465 | 465 | | |
466 | 466 | | |
467 | 467 | | |
| 468 | + | |
468 | 469 | | |
469 | 470 | | |
470 | 471 | | |
471 | 472 | | |
472 | 473 | | |
473 | 474 | | |
| 475 | + | |
474 | 476 | | |
475 | 477 | | |
476 | 478 | | |
| |||
576 | 578 | | |
577 | 579 | | |
578 | 580 | | |
579 | | - | |
580 | | - | |
581 | | - | |
582 | | - | |
583 | | - | |
584 | | - | |
585 | | - | |
586 | | - | |
587 | | - | |
588 | | - | |
589 | | - | |
590 | | - | |
| 581 | + | |
| 582 | + | |
591 | 583 | | |
592 | 584 | | |
593 | 585 | | |
| |||
926 | 918 | | |
927 | 919 | | |
928 | 920 | | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
929 | 928 | | |
930 | | - | |
931 | 929 | | |
932 | 930 | | |
933 | 931 | | |
| |||
940 | 938 | | |
941 | 939 | | |
942 | 940 | | |
943 | | - | |
944 | | - | |
| 941 | + | |
| 942 | + | |
945 | 943 | | |
946 | 944 | | |
947 | 945 | | |
948 | 946 | | |
949 | 947 | | |
950 | 948 | | |
951 | | - | |
| 949 | + | |
952 | 950 | | |
953 | 951 | | |
954 | 952 | | |
| |||
1769 | 1767 | | |
1770 | 1768 | | |
1771 | 1769 | | |
1772 | | - | |
| 1770 | + | |
| 1771 | + | |
| 1772 | + | |
| 1773 | + | |
| 1774 | + | |
| 1775 | + | |
| 1776 | + | |
| 1777 | + | |
1773 | 1778 | | |
1774 | 1779 | | |
1775 | 1780 | | |
| |||
2246 | 2251 | | |
2247 | 2252 | | |
2248 | 2253 | | |
| 2254 | + | |
| 2255 | + | |
| 2256 | + | |
| 2257 | + | |
| 2258 | + | |
| 2259 | + | |
| 2260 | + | |
| 2261 | + | |
| 2262 | + | |
| 2263 | + | |
| 2264 | + | |
| 2265 | + | |
| 2266 | + | |
| 2267 | + | |
| 2268 | + | |
2249 | 2269 | | |
2250 | 2270 | | |
2251 | 2271 | | |
| |||
2649 | 2669 | | |
2650 | 2670 | | |
2651 | 2671 | | |
| 2672 | + | |
2652 | 2673 | | |
2653 | 2674 | | |
2654 | 2675 | | |
| |||
0 commit comments