[HDX-2300] introduce Shared Filters for team-wide filter visibility and discoverability#2047
[HDX-2300] introduce Shared Filters for team-wide filter visibility and discoverability#2047brandon-pereira wants to merge 24 commits intomainfrom
Conversation
- Add PinnedFilter Mongoose model with team+source+user compound index - Add GET/PUT /pinned-filters API routes with Zod validation - Replace localStorage-based pinned filters with MongoDB-backed TanStack Query hooks - Add SharedFilters UI section showing team-pinned fields at top of filter sidebar - Add FilterSettingsPanel popover with show/hide toggle and reset button - Add optimistic local state to prevent stale reads during rapid toggles - Add one-time localStorage → MongoDB migration for existing users - Add local-mode fallback for development without API - Remove pinned fields from main filters list when shown in SharedFilters - Persist 'Show Shared Filters' preference in localStorage - Add integration tests for pinned filters API (14 tests) - Add unit tests for merge logic and migration (12 tests) - Add E2E tests for shared filters UI flow (8 tests)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 8ab5199 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
E2E Test Results✅ All tests passed • 141 passed • 3 skipped • 1060s
Tests ran across 4 shards in parallel. |
…perdxio/hyperdx into brandon/global-pinned-filters
PR ReviewGood overall implementation — source ownership verification, Zod validation, and optimistic UI with proper sourceId keying all look correct. A few things worth addressing:
|
- Fix integration test team scoping by inserting PinnedFilter directly in MongoDB instead of trying to register a second user (409 Conflict) - Fix E2E shared-filters test isolation by resetting pinned filters via API in beforeEach so state doesn't leak between tests - Add title attribute to field pin ActionIcons so E2E pinField selector can find them - Use dispatchEvent in scrollAndClick to avoid flaky CSS hover state - Replace waitForTimeout with expect.poll and Playwright assertions for proper wait mechanisms
| return PinnedFilterModel.findOne({ | ||
| team: new mongoose.Types.ObjectId(teamId), | ||
| source: new mongoose.Types.ObjectId(sourceId), | ||
| user: null, |
There was a problem hiding this comment.
I see that the code includes the capability to store user-level pinned filters, but I don't see that implemented anywhere.
IMO, we shouldn't remove user-specific pinned filters, since different users are likely to care about different filter keys and values. Having no special UI for "pin for team" vs "pin for me" is likely to result in various teammates modifying the filters for the entire team without realizing they're doing so.
It's also odd that the migration from local --> team/db filters is automatic, and applies to the entire team. The first user to login after deploying this will have their filters set for the entire team, possibly unexpectedly.
I would suggest we implement both user-level and team-level filters, and have the migration create user-level pinned filters.
There was a problem hiding this comment.
@pulpdrew you're right, I was trying to keep the scope small and minimize UX changes, but it didn't make sense.
I have changed the UX of this so that clicking the pin icons opens a menu where you can select between pin and share. I have updated the PR description with a video.
Previously localStorage was still used for local mode, but now localStorage is used for pinning and mongo is used for sharing with team.
I have also removed the migration since it's not needed.
There was a problem hiding this comment.
Makes sense, though with user-specific pinned filters always using local storage, should we remove the user field from this model now?
packages/app/src/components/DBSearchPageFilters/SharedFilters.tsx
Outdated
Show resolved
Hide resolved
packages/app/src/components/DBSearchPageFilters/SharedFilters.tsx
Outdated
Show resolved
Hide resolved
🔴 Tier 4 — CriticalTouches auth, data models, config, tasks, OTel pipeline, ClickHouse, or CI/CD. Why this tier:
Additional context: touches API routes or data models Review process: Deep review from a domain expert. Synchronous walkthrough may be required. Stats
|
|
The behavior is odd for shared filters that don't load in the initial round of filters. Clicking Load More doesn't work, until clicking More filters in the non-shared section. See ScopeName here Screen.Recording.2026-04-10.at.9.13.50.AM.mov |
pulpdrew
left a comment
There was a problem hiding this comment.
I like this approach much better - just a couple more comments

Summary
Introduces a "Shared Filters" feature (in addition to locally pinned items in HyperDX.
Especially helpful for teams with lots of filters and team members, allows users to highlight the top filters easily for all members.
This has been one of the most requested features we have received from enterprise customers. \
Screenshots or video
export-1775685397652.mp4
How to test locally or on Vercel
yarn dev)References
brandon/shared-filters-ui(superseded by this implementation)