Skip to content

Commit 07a43dc

Browse files
claude[bot]claude
andauthored
docs(ui): state where a dashboard global filter's field resolves (#16266)
`## Global Filters` on the dashboards page explained `name`, date defaults and `filterBindings`, but never said where a filter's `field` is looked up. The two halves of the answer were written on the validation reference page in adjacent paragraphs (`content/docs/deployment/validating-metadata.mdx:44-58`) and their asymmetry was never named: dimensions resolve against the dataset, filter fields against the dataset's object, so the same field can be filterable and not group-by-able on one dataset. Adds one section to the page authors actually read when writing `globalFilters`, stating both resolution targets side by side, the two error-severity lint rules that enforce them, the `filterBindings: { name: false }` opt-out, and a caveat scoping the statement to the authorable surface. Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8 Co-authored-by: Claude <noreply@anthropic.com>
1 parent fc3fb7c commit 07a43dc

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

content/docs/ui/dashboards.mdx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,42 @@ under as a dashboard-level variable (readable in widget expressions as
360360
`page.<name>`) and the key widgets reference in `filterBindings`. It defaults
361361
to `field`; the name `dateRange` is reserved for the built-in date range.
362362

363+
### Where a Filter's `field` Resolves
364+
365+
A global filter's `field` resolves against the **object behind each bound
366+
widget's dataset** (`dataset.object`) — never against that dataset's declared
367+
`dimensions`. Widget `dimensions` are selected from the dataset **by name**.
368+
They are two different namespaces:
369+
370+
| Key | Resolved against | Rejected by |
371+
| :--- | :--- | :--- |
372+
| `globalFilters[].field` (after any `filterBindings` re-target) | The bound widget's `dataset.object` — a bare name against that object's own fields, a dotted `relationship.field` path hop by hop with its prefix declared in the dataset's `include` | `dashboard-filter-field-unknown`, severity **error** |
373+
| `widgets[].dimensions[]` | The dataset's declared `dimensions`, by name | `widget-dimension-unknown`, severity **error** |
374+
375+
Two consequences follow, and their asymmetry is the part that surprises authors:
376+
377+
- **A filter needs no dataset dimension.** The [Complete Example](#complete-example)
378+
below filters on `project` and `assignee`, neither of which the `project_tasks`
379+
dataset declares — both are fine, because the `project_task` object has those
380+
fields.
381+
- **Declaring a dimension confers no filterability, and a filterable field is not
382+
group-by-able.** The same field can be filterable and un-group-by-able on one
383+
dataset: to filter on it the object must have it, and to group by it the dataset
384+
must declare it as a dimension. Declaring either buys the other nothing.
385+
386+
A filter naming a field the widget's own object lacks makes that widget's query
387+
address a column that does not exist. `os validate` and the runtime publish door
388+
both refuse the board rather than shipping it — see
389+
[Dangling widget bindings](/docs/deployment/validating-metadata#2-dangling-widget-bindings).
390+
Opt a single widget out with `filterBindings: { <name>: false }` (see
391+
[Per-Widget Filter Bindings](#per-widget-filter-bindings) below).
392+
393+
This describes the **authorable surface** — what a dashboard may declare, and what
394+
author-time validation accepts. It is not a claim about the analytics query API,
395+
which does accept an object's own field as an ad-hoc dimension without the dataset
396+
declaring it; `widget-dimension-unknown` is what holds the line for authored
397+
dashboards.
398+
363399
### Date Filter Defaults
364400

365401
A `type: 'date'` filter's `defaultValue` must be a value the dashboard can

0 commit comments

Comments
 (0)