feat: Persist and read variable-keyed filter state - #2964
Conversation
|
| Name | Type |
|---|---|
| @hyperdx/common-utils | Patch |
| @hyperdx/api | Patch |
| @hyperdx/app | Patch |
| @hyperdx/otel-collector | Patch |
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
a39697b to
cc522fb
Compare
Greptile SummaryThis PR migrates dashboard filter selections toward variable-name-keyed persistence while retaining expression-keyed compatibility.
Confidence Score: 4/5The PR is not yet safe to merge because linked filters with disjoint selections still cause dependent dropdowns to run without the required constraint. The attempted intersection fix represents contradictory sibling selections as an empty inclusion set, while downstream predicate generation interprets that state as no condition and returns unfiltered dependent values. Files Needing Attention: packages/app/src/hooks/useDashboardFilterValues.tsx and its linked-filter regression tests
|
| Filename | Overview |
|---|---|
| packages/app/src/hooks/useDashboardFilters.tsx | Introduces per-filter selection resolution and variable-name-keyed persistence while retaining legacy expression handling. |
| packages/app/src/hooks/useDashboardFilterValues.tsx | Adapts linked dropdown constraints to per-filter selections, but contradictory sibling selections still become an unconstrained lookup. |
| packages/app/src/DBDashboardPage.tsx | Integrates the new filter-entry state and updates ignored-variable warnings. |
| packages/app/src/utils/queryParsers.ts | Adds parsing support for the revised persisted filter-entry representation. |
| packages/app/tests/e2e/features/dashboard-filter-value-format.spec.ts | Adds end-to-end coverage for variable-keyed persistence and compatibility behavior. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[URL or saved filter entries] --> B[Resolve entries against dashboard filters]
B --> C[Selection by filter ID]
C --> D[Dashboard dropdowns]
C --> E[Tile query filters and variables]
C --> F[Persist variable-name or expression keys]
Reviews (10): Last reviewed commit: "feat: Persist and read variable-keyed fi..." | Re-trigger Greptile
E2E Test Results✅ All tests passed • 315 passed • 1 skipped • 1221s
Tests ran across 4 shards in parallel. |
cc522fb to
4f7dd76
Compare
52f11d3 to
bbefc40
Compare
4f7dd76 to
5c7ba6a
Compare
🟡 Tier 3 — StandardIntroduces new logic, modifies core functionality, or touches areas with non-trivial risk. Why this tier:
Review process: Full human review — logic, architecture, edge cases. Stats
|
Deep ReviewPart 2/2 of the variable-keyed dashboard filter state migration. The change is well-structured, carries good inline documentation, and ships substantial unit + e2e coverage. No ship-blockers found. Two correctness edge cases around filters that share a SQL expression remain, both narrow and both introduced by this diff's new ✅ No critical issues found. 🟡 P2 -- recommended
Reviewers (3): correctness, testing, previous-comments. Testing gaps:
|
bbefc40 to
a79326a
Compare
5c7ba6a to
95c5be9
Compare
a79326a to
6e8e88e
Compare
95c5be9 to
3020823
Compare
461fe8a to
dd0c178
Compare
cb98bb3 to
d1f98a8
Compare
dd0c178 to
dfd7d87
Compare
d1f98a8 to
6eb83ac
Compare
dfd7d87 to
343abba
Compare
6eb83ac to
a4cc2ed
Compare
343abba to
754b5cd
Compare
a4cc2ed to
496e647
Compare
| included: | ||
| a.included.size === 0 | ||
| ? b.included | ||
| : b.included.size === 0 | ||
| ? a.included | ||
| : new Set([...a.included].filter(v => b.included.has(v))), |
There was a problem hiding this comment.
Disjoint selections become unconstrained
When two sibling filters sharing an expression have disjoint non-empty selections, intersectSelections returns an empty inclusion set. Downstream predicate generation treats that set as no condition, causing the dependent dropdown to show unfiltered values instead of no matching values.
Knowledge Base Used: Dashboards and visualization
## Summary Part 1/2 in enabling variable-name-based dashboard filter state. This part covers the types/schema changes and the MCP + API + Import paths. ### Why Historically, dashboard filter selection state has been persisted (in the URL, dashboard documents, and exports) as keyed by the filter's expression, in the same format used by search-page filters. This has two problems: 1. Filters that share an expression (eg. ServiceName from two different sources) must necessarily share a selection state despite being two dropdowns in the UI. 2. Future "static custom values" filters will have no expression (since they're not queried) and thus would have no way to key their state ### What This change will persist dashboard filter selection state (that is, what values are selected in the filter's drop-down) based on the variableName of the filter, when it has one. - Existing expression-keyed filter state will be migrated on write. Existing URLs and saved filter states continue working. - Filters that are not variable-enabled continue being written in expression-keyed format - Variable-keyed state takes precedence over expression-keyed state, when both may apply to a single filter. ### Screenshots or video ### How to test This will be easier to test on top of [PR 2/2](#2964) - Create a dashboard and add some filters. Make some of them variable enabled and some of them not - Select values for the filters - Try saving the default filter values, importing/exporting the dashboard, sharing the link, etc - Try editing the saved values through MCP + External API ### References - Linear Issue: - Related PRs:

Summary
Part 2/2 in enabling variable-name-based dashboard filter state. This part updates the dashboard filter hooks to read and write state in the new variable-keyed format.
Why
Historically, dashboard filter selection state has been persisted (in the URL, dashboard documents, and exports) as keyed by the filter's expression, in the same format used by search-page filters. This has two problems:
What
This change will persist dashboard filter selection state (that is, what values are selected in the filter's drop-down) based on the variableName of the filter, when it has one.
Screenshots or video
Updated banner showing URL state that doesn't correspond to the declared filters
How to test
Use a URL Decoder if you want to inspect the URL
References