docs(ui): filter the dashboards Global Filters example on the dotted path it means - #17767
Merged
claude[bot] merged 1 commit intoSep 12, 2026
Merged
Conversation
…path it means 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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU
claude
Bot
deleted the
claude/issue-16268-dashboards-filter-field-example
branch
September 12, 2026 04:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Clause-②: no
Closes #16268
The premise triage left open, settled first
Triage reserved one reading for the claiming seat: does
opportunitydeclare aregionfield? It decides whether the example is misleading or directly illegal. Measured before touching the example:opportunity's fields at all. It namesobject: 'opportunity'and stops. So the question has no literal answer on the page.opportunityobject exists anywhere in the shipped tree. The name appears only in unit-test fixtures. The CRM example shipscrm_opportunity, which declares noregionand whose dataset carries noinclude.field: 'account.region'throughinclude: ['account']. That join is only necessary ifopportunityhas no ownregion— had it one, the dimension would have been writtenfield: 'region'.Verdict: directly illegal under the page's own implied reading, undecidable under a literal one. The fix below is green under both, so nothing here hangs on the undecidable half.
Which fix, and why
Fix 2 — the dotted form — as triage preferred, and its criterion stands unchallenged: this page's reader genuinely wants to filter by the customer's region, so fix 1 (swap in
stage) would route around the confusion rather than teach the rule, and the harm on this card is precisely that the reader inferred the wrong rule.Two supporting readings taken before committing to it:
resolveFieldPathwalks them hop by hop, andpackages/lint/src/validate-widget-bindings.test.tspins the clean shape green — "is silent on the clean shape — a dotted path through a declared include".include: ['account'], so the sibling ruledashboard-filter-field-not-includedhas nothing to say.The explicit
name: 'region'is kept and now earned: left to default, the filter's variable key would beaccount.region, dots and all, in every expression and binding. The prose below the block now says so, which turns the retained name into a second lesson rather than a leftover.Acceptance 1 — measured, not assumed
Transcribed the page's own declarations into a stack and ran the real
validateWidgetBindingsfrom a freshly builtpackages/lint, under both readings of the open premise:dashboard-filter-field-unknownopportunityhas no ownregion(page-implied)field: 'region'opportunityhas no ownregion(page-implied)field: 'account.region'opportunityownsregion(counterfactual)field: 'region'opportunityownsregion(counterfactual)field: 'account.region'The error the old example raises, verbatim:
Row 2's zero across all rules is the
includeclause reporting satisfied as well. The before/after pair is a one-off proof run from the scratchpad against the builtdist; it leaves no test file behind.Acceptance 3 — the reverse-read, zeros included
On this page. Every other
regionon the page is a widgetdimensionsentry selected from the dataset by name — the correct side of the namespace boundary, untouched and still correct.One site examined and deliberately left alone: the Per-Widget Filter Bindings block comments
// Default binding: dateRange -> created_at, region -> region.That belongs to a different illustrative dashboard which declares noglobalFiltersand no dataset, and the statement stays true for any dashboard whose region filter names a field the widget's object owns. It involves no dimension and so carries none of this card's harm. Changing it toaccount.regionwould have been worse: it would smuggle an implicitincluderequirement into an example that shows no dataset. Recorded rather than edited.On pages linking here — seven pages link to this one (
capabilities/analytics,getting-started/quick-start,ui/apps,ui/index,ui/pages,ui/reports,ui/views). Zero repeat the inference; none reuses theregionfilter example.deployment/validating-metadataalready states the rule correctly.ui/translationskeys global-filter translations by the filter'sname— kept asregion, so that key is unmoved.Made-false sweep across the tree: zero. No sentence outside this page depends on the old spelling.
Changeset — skip, measured
No package's
files[]carriescontent/; the only consumer ofcontent/docsisapps/docs, which isprivate: trueand publishes nothing. Positive control on the same measurement: it readsdistin 23 packages'files[]and printspackages/spec's full list, so the zero is a real zero and not an empty probe.skip-changesetis applied as a label.Gates
All 40 families derived by
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackfrom the real change set: green.check:skill-examples— the gate that type-checks theos:checkfences this diff edits — first returned a prerequisite failure (packages/client-reactunbuilt), which is not a verdict; after building that package it reports 258 prose examples type-check across 3 surfaces. Control-byte self-scan on the edited file: zero hits;check-nul-bytesgreen.Verified at
591d48a8b0.验收备注
region -> region的绑定注释,判为独立示例、未改,理由见上;归noted, not filed。Generated by Claude Code