You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
A dashboard global filter sourced from optionsFrom commits the display LABEL as its value — every widget it drives silently returns zero rows #4465
A dashboard global filter whose options come from optionsFrom (a live server GROUP BY, rather than a static options list) commits the rendered label as the filter value. Every widget bound to that filter then queries for a value that does not exist and repaints to "No rows".
Static, metadata-declared options are not affected — Revenue Pulse's region filter shows the label EMEA on the trigger and correctly commits the value emea.
Reproduction (2× in the browser, 1× on the API)
Author a dashboard with an optionsFrom-sourced select filter and one bound widget:
Publish, open it as admin, open the Status select and pick In Review.
Expected the widget re-queries with status = 'in_review' and draws 2 tasks. Actual the widget re-queries with runtimeFilter { "status": "In Review" } and renders "No rows" (0 bars). Same with In Progress.
drillRawRows → raw values: [{status:'backlog'},…,{status:'in_review'},{status:'todo'}]
packages/plugin-dashboard/src/DashboardFilterBar.tsx reads r?.[from.valueField] off rows (the dataset branch, ~line 204 on main) and never consults drillRawRows, so the label becomes the committed value.
Sharpening contrast on the same page: the drill path consumes the same response correctly — clicking a Backlog bar issues GET /api/v1/data/showcase_task?filter=["and",…,["status","=","backlog"]] with the raw value. Two consumers of one response; one right, one wrong.
Not a stale-bundle artifact
DashboardFilterBar.tsx's optionsFrom resolution is unchanged between the vendored console pin (6314e87f2d49) and current origin/main (b4d3c2204) — same reads of from.valueField off rows, no drillRawRows consumer on either ref. Checked line by line rather than by diffing whole files.
Suggested shape (not prescriptive)
Pair each option as {value: drillRawRows[i][valueField], label: rows[i][labelField ?? valueField]} so the committed value is always the raw one, and fall back to rows only when drillRawRows is absent. Whatever the shape, the gate that keeps it fixed is a test asserting the committed filter value for an optionsFrom select equals the raw value, not the rendered label — the current tests only assert the option list renders.
Source
Found by the platform checklist retest of dashboards.global-filters-rescope (framework 279ee48a, console pin 6314e87f2d49).
Ruling (delegated authority; open veto window): fix as the card suggests — pair options index-wise as {value: drillRawRows[i][valueField], label: rows[i][labelField ?? valueField]}, falling back to rows only when drillRawRows is absent. The in-file precedent is the card's own sharpening contrast: the drill path already consumes this exact response correctly — measure how it reads drillRawRows and mirror that reading, so one response has one reading discipline (if the two reads can share a helper cheaply, do it; if that forces refactoring the drill path, don't — mirror and note).
Red-first (the gate the card names): assert the COMMITTED filter value — an optionsFrom select whose response carries both forms, pick "In Review" → pre-fix the widget re-query carries {status: 'In Review'} (the label — capture verbatim), post-fix {status: 'in_review'}. The existing tests only assert the option list renders; that gap is the defect's cover. Must-not-change (green both sides): the trigger still DISPLAYS the label; static metadata-declared options behave byte-identically (the card verifies they're unaffected); drillRawRows-absent responses fall back to today's behavior; index alignment is asserted (if rows and drillRawRows can disagree in length, decide the honest answer — likely abstain to fallback — and pin it).
Grading: patch @object-ui/plugin-dashboard (runtime-only; .d.ts-checked both ways). Never major.
Surface (mutual exclusion): packages/plugin-dashboard/src/DashboardFilterBar.tsx + its test + one changeset. ⛔ NOT: DatasetWidget.tsx (#4500 is its own pooled card), chart-series/core (#4498 armed — in-flight #4466 family), plugin-grid/ObjectGrid (#4464 in flight), plugin-calendar (#4492), the sweep file (#4434), console/**. Upstream context: #4356 (spec-side options shorthand, 候 objectstack#7917) is a DIFFERENT surface — do not touch normalizeFilterOptions.
Activity
yinlianghui commentedon Aug 12, 2026
CLAIM — session
session_017Qqyix2QcnpUC9XeYVDzx3, branchclaude/issue-4465-optionsfrom-raw-value.Ruling (delegated authority; open veto window): fix as the card suggests — pair options index-wise as
{value: drillRawRows[i][valueField], label: rows[i][labelField ?? valueField]}, falling back torowsonly whendrillRawRowsis absent. The in-file precedent is the card's own sharpening contrast: the drill path already consumes this exact response correctly — measure how it readsdrillRawRowsand mirror that reading, so one response has one reading discipline (if the two reads can share a helper cheaply, do it; if that forces refactoring the drill path, don't — mirror and note).Red-first (the gate the card names): assert the COMMITTED filter value — an
optionsFromselect whose response carries both forms, pick "In Review" → pre-fix the widget re-query carries{status: 'In Review'}(the label — capture verbatim), post-fix{status: 'in_review'}. The existing tests only assert the option list renders; that gap is the defect's cover. Must-not-change (green both sides): the trigger still DISPLAYS the label; static metadata-declaredoptionsbehave byte-identically (the card verifies they're unaffected);drillRawRows-absent responses fall back to today's behavior; index alignment is asserted (ifrowsanddrillRawRowscan disagree in length, decide the honest answer — likely abstain to fallback — and pin it).Grading: patch
@object-ui/plugin-dashboard(runtime-only;.d.ts-checked both ways). Never major.Surface (mutual exclusion):
packages/plugin-dashboard/src/DashboardFilterBar.tsx+ its test + one changeset. ⛔ NOT: DatasetWidget.tsx (#4500 is its own pooled card), chart-series/core (#4498 armed — in-flight #4466 family), plugin-grid/ObjectGrid (#4464 in flight), plugin-calendar (#4492), the sweep file (#4434), console/**. Upstream context: #4356 (spec-side options shorthand, 候 objectstack#7917) is a DIFFERENT surface — do not touch normalizeFilterOptions.Generated by Claude Code
Generated by Claude Code
fix(plugin-dashboard): optionsFrom filters commit the raw value, not …