Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/29382-filter-binding-daterange-prose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@objectstack/lint': patch
---

docs(lint): the `dashboard-filter-binding-unknown` explanation no longer says a `dateRange` binding is always reported on a dashboard without `dateRange`

Clause-②: no
Metadata-protocol: none

`os explain dashboard-filter-binding-unknown` said a widget's `filterBindings.dateRange` key "on a dashboard that declares no `dateRange` is reported the same way". The rule never did that when the dashboard declares a `globalFilters` entry named `dateRange`: every `globalFilters` entry's name is a declared filter, so the key binds it and the rule accepts it, as the explanation's first paragraph already says. The sentence now reads that a `dateRange` key is reported only when the dashboard declares neither `dateRange` nor a `globalFilters` entry named `dateRange`. The rule's behaviour is unchanged; a new test pins the accepted case.
5 changes: 3 additions & 2 deletions packages/lint/src/rule-explanations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,9 @@ const DASHBOARD_FILTER_BINDING_UNKNOWN_EXPLANATION: RuleExplanation = {
'way the widget counts different rows than the author wrote, with nothing on the page to say so, ' +
'which is why the rule is an error and is not suppressible.',
'To fix it, rename the key to a declared filter name (the finding names the nearest one), declare ' +
'the filter on the dashboard, or delete the entry. A `dateRange` key on a dashboard that declares ' +
'no `dateRange` is reported the same way: there is no date range for it to bind.',
'the filter on the dashboard, or delete the entry. A `dateRange` key is reported the same way ' +
'only when the dashboard declares neither `dateRange` nor a `globalFilters` entry named `dateRange`: ' +
'either one is a declared filter under that name, and with neither there is nothing for it to bind.',
],
};

Expand Down
8 changes: 8 additions & 0 deletions packages/lint/src/validate-widget-bindings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,14 @@ describe('dashboard-filter-binding-unknown (#27445)', () => {
expect(findings[0].hint).toBe('Declare `dateRange` on the dashboard, or delete the `dateRange` entry.');
});

it('a `globalFilters` entry named `dateRange` declares the name on a dashboard without `dateRange`', () => {
const findings = only(validateWidgetBindings(stack(
{ dateRange: undefined, globalFilters: [{ name: 'dateRange', field: 'signed_at', type: 'date' }] },
{ filterBindings: { dateRange: false } },
)));
expect(findings).toEqual([]);
});

it('a dashboard with no filters at all refuses every key and says so', () => {
const findings = only(validateWidgetBindings(stack(
{ dateRange: undefined, globalFilters: undefined },
Expand Down
12 changes: 8 additions & 4 deletions packages/lint/src/validate-widget-bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,12 @@ import {
* counts, which is why this is an error and not the warning tier
* `chart-field-unknown` took for its ignored keys (#15463): those re-dress
* the same numbers, this one changes them. The declared names are the ones
* {@link dashboardFilterDefs} builds, so the reserved `dateRange` key is
* valid only on a dashboard that declares `dateRange` — the runtime, this
* file and `@objectstack/verify`'s window proof all build that def only then.
* {@link dashboardFilterDefs} builds: every `globalFilters` entry's name,
* and the reserved `dateRange` when the dashboard declares `dateRange` (the
* runtime, this file and `@objectstack/verify`'s window proof all build that
* built-in def only then). A `globalFilters` entry named `dateRange` is a
* declared filter by that name too, so a `dateRange` key binds it on a
* dashboard that declares no `dateRange`.
*
* Advisory rules — severity `warning`, build stays green:
*
Expand Down Expand Up @@ -450,7 +453,8 @@ export const DASHBOARD_FILTER_FIELD_UNPROVISIONED = 'dashboard-filter-field-unpr
export const DASHBOARD_FILTER_FIELD_NOT_INCLUDED = 'dashboard-filter-field-not-included';
/**
* [#27445] A widget `filterBindings` key that names no filter the dashboard
* declares (`dateRange` counts only when the dashboard declares one).
* declares (`dateRange` counts when the dashboard declares `dateRange` or a
* `globalFilters` entry named `dateRange`).
*/
export const DASHBOARD_FILTER_BINDING_UNKNOWN = 'dashboard-filter-binding-unknown';
/** [#14148] A key of the widget's OWN `filter` that resolves to no column. */
Expand Down
Loading