feat: persist instrumentation filter state in URL search params#428
feat: persist instrumentation filter state in URL search params#428Rama542 wants to merge 1 commit into
Conversation
✅ Deploy Preview for otel-ecosystem-explorer ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR updates the Java Agent Instrumentation list page so the active filter state (search text, telemetry toggles, and type toggles) is persisted in the URL query string, enabling bookmarking and link sharing of filtered views.
Changes:
- Replaced local React state for filters with
useSearchParams-derived filter state. - Added a handler that writes the active filters back into URL search params.
- Added new test cases intended to cover URL-based filter initialization and persistence.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| ecosystem-explorer/src/features/java-agent/java-instrumentation-list-page.tsx | Derives filters from useSearchParams and updates query params when filters change. |
| ecosystem-explorer/src/features/java-agent/java-instrumentation-list-page.test.tsx | Adds tests around initializing filters from URL params and (intended) URL updates on interaction. |
vitorvasc
left a comment
There was a problem hiding this comment.
Hey @Rama542, thanks for the contribution!
I spotted a minor UX regression while testing this. Here's how to reproduce it:
- Type something in the search box, the list filters as expected.
- Press CMD + A / CTRL + A to select the input contents.
- Immediately start typing a new query.
Expected behavior: the selected text should be replaced immediately by the new keystrokes.
The actual behavior is a bit flaky, but I can reproduce it a few times out of ten. Sometimes the first keystroke is dropped, the old value flickers back, or the entire new query disappears.
AFAICS, this is likely due to the input now being controlled by the URL state. Since value is being read from filters.search (which derives from useSearchParams), there's probably a slight lag between the local input change and the URL state syncing back.
You can give it a try on the preview to confirm it on your end: https://deploy-preview-428--otel-ecosystem-explorer.netlify.app/java-agent/instrumentation/2.27.0
|
Hey @vitorvasc, thanks for catching that and for the clear reproduction steps! You were right the root cause was that the search was fully controlled by filters.search, which derived from useSearchParams. Every keystroke had to complete a full URL round-trip before the input re-rendered with the new value. Under normal typing that lag is invisible, but with CTRL+A + immediate typing the selection state and the delayed re render collide, causing the flicker or dropped keystroke. What I changed: Added a local useState (localSearch) initialized from the URL on mount. The input now reads its value from that local state, so every keystroke updates it synchronously with zero lag. The URL params are still updated on every change (so sharing links and browser back/forward still work), but the input no longer depends on the URL re render cycle for its displayed value. A small useEffect watches for external URL changes (back/forward navigation) and syncs local state back from the URL in those cases only. |
|
Hi @Rama542, could you please take a look at the conflicts and update this branch? |
e02d33a to
966417f
Compare
|
Sorry for the delay in getting this resolved. I've rebased the branch onto the latest main and resolved all conflicts. The filter state URL persistence logic is now fully compatible with the semantic and features fields added in the upstream changes, and the loading/error UI with AlertCircle and Loader2 is preserved. Should be good for another review. |
|
Hi @Rama542, I'm sorry for the delay here. There's another conflict, could you please rebase it once again? |
e460f31 to
5543885
Compare
|
Hey, I've gone through and brought the branch fully up to date with main. The URL persistence now covers all filter fields including the new semantic conventions and features params, so shared links will carry those filters too. I also pulled in the updated filter bar, the SearchableMultiSelect component, the ResizeObserver stub needed for the cmdk tests, and fixed the FilterState type across all the affected test files so everything compiles cleanly. All 806 tests are passing. Please take a look and kindly consider merging this when you get a chance. Let me know if you have any feedback. |
|
These files still have conflicts, PTAL:
|
…params Filters (search, telemetry, type, semantic conventions, features) are now stored as URL query params so users can share and bookmark filtered views. The no-version-to-latest redirect preserves existing query params. Local search state is kept in sync with URL via derived-state-during-render so the search input never lags on keystrokes. Co-Authored-By: Rama Sasank Gudipati <ramasasankgudipati@gmail.com>
508a5c4 to
1efdc9c
Compare
Fixes #426
Currently when a user applies filters on the Java Agent Instrumentation page like typing in the search box or clicking Spans, Metrics, Java Agent, or Standalone, those filters are stored only in React component state. If the user refreshes the page or copies the URL and shares it with someone, all the filters are lost and the page resets to showing all instrumentations.
Here is what the problem looks like before this fix:
Screenshot 1

Screenshot 2

As you can see in the address bar in Screenshot 2, the URL is just the plain page URL with no filter params. There is no way to share this filtered view or bookmark it.
This change replaces the useState hook with useSearchParams from react-router-dom so that the active filters are written into the URL as query parameters. Now a filtered view looks like:
/java-agent/instrumentation/2.26.1?search=akka&telemetry=spans&type=javaagent
This means users can bookmark a specific filtered view and come back to it later, share a link with a teammate so they see the exact same results, and use the browser back button to return to a previous filter state.
The filter params used in the URL are:
New tests were added covering reading filters from the URL on initial render, updating the URL when a filter is toggled, clearing the URL param when a filter is toggled off, and combining multiple filters from the URL at once.
All existing filter tests continue to pass without any changes.