feat: Add filter variable configuration - #2836
Conversation
🦋 Changeset detectedLatest commit: 94ec6a5 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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThe PR adds dashboard filter broadcast/variable configuration, shared validation, persistence support, feature gating, and UI/E2E coverage. The HTTP APIs now reject unusable variable names, but the dashboard provisioning path still bypasses that validation.
Confidence Score: 4/5The PR is not yet safe to merge because provisioned dashboards can still persist enabled variables without usable tokens. The internal, external, and MCP dashboard write paths now enforce the variable-name contract, but ProvisionDashboardsTask still parses the unrefined shared schema and directly persists filters, leaving the previously reported provisioning failure reachable. Files Needing Attention: packages/common-utils/src/types.ts and packages/api/src/tasks/provisionDashboards/index.ts
|
| Filename | Overview |
|---|---|
| packages/common-utils/src/types.ts | Adds optional filter mode and variable-name fields, but the bare shared dashboard schema still permits tokenless enabled variables on provisioning paths. |
| packages/common-utils/src/dashboardValidation.ts | Adds centralized checks for resolvable unique variable names and at least one enabled filter mode. |
| packages/api/src/routers/api/dashboards.ts | Applies the new shared filter refinements to internal dashboard creation and updates. |
| packages/api/src/routers/external-api/v2/utils/dashboards.ts | Applies equivalent filter validation to external API and MCP dashboard body schemas. |
| packages/app/src/DashboardFiltersModal.tsx | Adds feature-gated broadcast and variable configuration, generated names, and client-side validation. |
| packages/app/src/hooks/useDashboardFilters.tsx | Excludes broadcast-disabled filter definitions from tile query predicates. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
Input[Dashboard filter configuration]
Internal[Internal dashboard API]
External[External API and MCP]
Provisioner[Provisioned dashboard JSON]
Refine[Variable-name and mode validation]
BareSchema[Bare DashboardWithoutIdSchema]
Mongo[(Dashboard in MongoDB)]
Input --> Internal --> Refine --> Mongo
Input --> External --> Refine
Provisioner --> BareSchema --> Mongo
Reviews (4): Last reviewed commit: "Merge branch 'main' into drew/filter-var..." | Re-trigger Greptile
E2E Test Results✅ All tests passed • 278 passed • 1 skipped • 1070s
Tests ran across 4 shards in parallel. |
6c65b8c to
03f5bee
Compare
🔴 Tier 4 — CriticalTouches authentication, tenancy data models, the public API or shipped database config — or substantially changes background tasks, the OTel pipeline, image build, or release CI. Why this tier:
Review process: Deep review from a domain expert. Synchronous walkthrough may be required. Stats
|
Deep Review✅ No critical issues found. No P0/P1 defects: the security pass found nothing exploitable (the variable-name regex is fully anchored and linear, all display goes through JSX auto-escaping, and query substitution is explicitly not implemented in this diff), and no data-loss, auth-bypass, or happy-path crash was introduced. The backwards-compat defaulting ( 🟡 P2 -- recommended
🔵 P3 nitpicks (7)
Reviewers (11): correctness, security, adversarial, testing, maintainability, project-standards, api-contract, kieran-typescript, julik-frontend-races, agent-native, learnings-researcher. Testing gaps:
|
03f5bee to
33e693f
Compare
| * Whether a filter definition broadcasts its selected value onto a tile | ||
| * whose source is `sourceId`. | ||
| */ | ||
| const definitionAppliesToSource = ( |
There was a problem hiding this comment.
Changes in this file prevent filters with broadcast mode disabled from being applied to any dashboard tiles.
| onRemoveFilter={handleRemoveFilter} | ||
| source={source} | ||
| isLoading={isFetchingFilters || isFiltersMutationPending} | ||
| showVariableOptions={false} |
There was a problem hiding this comment.
The user doesn't define tiles on this dashboard, so there is no reason for variable-type filters. The UI will not show the option to enable variable mode or disable broadcast mode.
| * field broadcasts, and that must not change. Read it through | ||
| * `isFilterBroadcastEnabled` rather than defaulting at each call site. | ||
| */ | ||
| isBroadcastEnabled: z.boolean().optional(), |
There was a problem hiding this comment.
do we want to make these changes on the model side as well?
There was a problem hiding this comment.
Probably not, at least not outside of a separate refactor. Dashboard filters are currently stored in two tables:
- Dashboards - here
filtersis registered as a schema-less Array, like most other fields on the dashboard model. A nice refactor could be to improve the schemas across each of the fields. I can file an issue for that if you think it would be a worthwhile improvement. - PresetDashboardFilters - these are filters specfically for preset dashboards (eg. Services Dashboard), and while these have a schema, these filters will not support variable mode, so we are intentionally not adding these new properties.
There was a problem hiding this comment.
Got it. I just want to make sure that, since the schema isn't persistent on the model side, those fields might be overridden. But if you're sure those corner cases are covered, I think we should be good.
| * Undefined / missing means DISABLED. Ignored while the dashboard-variables | ||
| * feature is off. | ||
| */ | ||
| isVariableEnabled: z.boolean().optional(), |
There was a problem hiding this comment.
Provisioned variables can lack tokens
When provisioned dashboard JSON enables variable mode without variableName and its display name contains no token-safe characters, the provisioning task parses the unrefined DashboardWithoutIdSchema and persists the filter, causing an enabled variable with no usable $variableName reference.
Knowledge Base Used:
Summary
This PR updates the dashboard filter configuration modal to support enabling "variable" mode for a filter, which will allow users to refer to the filter value as a variable in queries.
This feature is behind the
NEXT_PUBLIC_ENABLE_DASHBOARD_VARIABLESfeature toggle, since the actual variable replacement is not yet implemented.Variable mode is off by default for existing filters and on by default for new filters, when the toggle is on. The user may specify a custom name for the variable. A default variable name is generated from the filter's name. Variable names must be unique in the dashboard, while filter names may not be.
Variable mode and broadcast mode (the current behavior) may both be enabled or disabled independently. When the feature is disabled, broadcast mode cannot be disabled and variable mode cannot be enabled - the checkboxes do not appear.
**Note: Variable substitution functionality is not implemented by this PR. ** Only configuration of variable type filters is implemented.
Screenshots or video
With the toggle enabled
Screen.Recording.2026-08-07.at.2.26.31.PM.mov
Updated tooltips and broadcast-disabled functionality
Screen.Recording.2026-08-10.at.12.33.45.PM.mov
Variable mode is not available on Preset Dashboards, and broadcast mode cannot be disabled
This works on temporary/local dashboards as well
Screen.Recording.2026-08-07.at.2.32.12.PM.mov
Import/Export preserves variable mode
Screen.Recording.2026-08-07.at.2.33.56.PM.mov
With the toggle disabled
Screen.Recording.2026-08-07.at.2.40.45.PM.mov
How to test locally
NEXT_PUBLIC_ENABLE_DASHBOARD_VARIABLESis enabledReferences