From 591d48a8b0d7a6fcdc37d7ad24115b0e8a8941b2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 12 Sep 2026 03:41:10 +0000 Subject: [PATCH] docs(ui): filter the dashboards Global Filters example on the dotted path it means MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `## Global Filters` example filtered on `field: 'region'` while the same page's sales dataset declares `object: 'opportunity'`, `include: ['account']` and a dimension named `region` whose field is `account.region`. The shared spelling invited the inference that a filter's `field` and a dataset's `dimensions` share one namespace. They do not: a filter's `field` resolves against `dataset.object`'s own fields, so a bare `region` on an `opportunity` that reaches region only through the account join is the shape `dashboard-filter-field-unknown` (severity error) exists to refuse. Write the filter as the dotted path it actually means — `account.region`, resolved hop by hop through the `include: ['account']` the dataset already declares — and say in the block that this is a path, not a dimension name. The explicit `name: 'region'` is now earned rather than incidental, and the prose below says why: left to default, the variable key would be `account.region`, dots and all. Measured with the real validator against the page's own declarations: the old example raises one error-severity `dashboard-filter-field-unknown`; the new one raises zero, and zero of any other rule, so the `include` clause (`dashboard-filter-field-not-included`) is satisfied too. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU --- content/docs/ui/dashboards.mdx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/content/docs/ui/dashboards.mdx b/content/docs/ui/dashboards.mdx index 60c7f2b1ad..43eccaafa8 100644 --- a/content/docs/ui/dashboards.mdx +++ b/content/docs/ui/dashboards.mdx @@ -350,7 +350,11 @@ Add interactive filter controls that apply to all widgets: {/* os:check */} ```typescript globalFilters: [ - { name: 'region', field: 'region', label: 'Region', type: 'select' }, + // `account.region` is a DOTTED PATH walked from the bound widget's + // `dataset.object` (`opportunity`) through the `include: ['account']` the + // dataset declares. It is not the dataset's dimension that is also spelled + // `region` — a filter's `field` never reads dimension names. + { name: 'region', field: 'account.region', label: 'Region', type: 'select' }, { field: 'owner', label: 'Sales Rep', type: 'lookup' }, ] ``` @@ -358,7 +362,9 @@ globalFilters: [ Each filter's `name` is its stable identity: the key its value is published under as a dashboard-level variable (readable in widget expressions as `page.`) and the key widgets reference in `filterBindings`. It defaults -to `field`; the name `dateRange` is reserved for the built-in date range. +to `field`; the name `dateRange` is reserved for the built-in date range. The +filter above names itself `region` for exactly that reason — left to default it +would be keyed `account.region`, dots and all, in every expression and binding. ### Where a Filter's `field` Resolves