Uh oh!
There was an error while loading. Please reload this page.
fix(dashboard): resolve a dotted dimension's labels on table and pivot dataset widgets - #4273
Merged
Merged
Conversation
…t widgets (#4263) The dataset widget's client-side dimension-label net returned early for table / pivot / metric (`if (isMetric || isTable) { …; return; }`), and the relabeling it feeds was applied only on the chart branch. So a DOTTED dimension (`crm_account.industry`) on a table or pivot rendered the raw stored enum (`education`) — the same symptom objectui#4053 fixed for charts, on the widget types that fix deliberately did not reach. Open the net for DOTTED dimensions only. The early return was not arbitrary: on a table the SERVER resolves a local dimension's display label (ADR-0021), which is exactly why #4053's `table` widget rendered `Education` while its chart rendered `education`. Running the client net for local dimensions there would be a second resolution of an already-resolved value, so it stays off for them and opens only where the server is silent too. #4261's `resolveDimensionFieldOptions` is reused unchanged, multi-hop paths included. Unchanged means unchanged: a table with no dotted dimension resolves nothing and never issues the metadata read at all, so `relabelDimensions` returns the same array identity and the rendered bytes are the ones it produced before. Per- category colours and the declared category order stay chart-only. Two consumers had to follow the display rows or they would have gone quietly inconsistent: a pivot's marginal totals, whose bucket ids are re-derived from the same dimension values its headers are built from (relabeling one side alone made every total cell fall back to `—`), and the CSV export, which is the table's own data. Drill-through is untouched — the relabel preserves row order and count, so `openDrill(i)` and `pivot.cellIndex` still index the raw `drillRawRows` and a drill filters by the stored value. Metric widgets are unaffected by measurement, not by omission: that branch renders one measure value plus its header label and puts no dimension value on screen in any spelling, so there is nothing there to resolve. Pinned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 11, 2026 10:29
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 11, 2026
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 freeto 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.
Fixes#4263
Implements the dotted-only gap-fill ruling on the card. Built on top of #4261, which is on
main.Premise: confirmed, red-first
The pins were written and run BEFORE the source was touched. Four went red on exactly the reported symptom, two were green from the start (the controls):
Where the labels actually enter each render path (measured)
This was the card's open question — the label map does NOT enter the table paths the way it enters the chart path, and one consumer had to follow it or it would have gone quietly wrong.
relabelDimensions(state.rows, dimensionLabels)aschartRowsstate.rowsrendered verbatim throughformatDimensionValue(row[c])displayRowsbuildPivot(state.rows, …), which derives header labels AND bucket ids from the same row valuesbuildPivot(displayRows, …)state.totalsrows, whose bucket ids are RE-DERIVED here to meet the pivot's headersstate.rowsdisplayRowsNo new rendering plumbing was needed: every table/pivot consumer reads rows, so feeding it the already-relabeled rows is sufficient. That is why this is not a
needs_decision.The pivot totals were the real trap.
buildPivotbuilds a row's bucket id fromString(row[d])and its header label from the same value, while the totals lookup re-derives ids from the rawstate.totalsrows. Relabeling the rows alone would have left the headers readingEducationwhile the total lookup still asked foreducation, so every total cell would have silently fallen back to—. Both sides now speak the same vocabulary. The pivot pin carries server totals specifically to hold this.Metric verdict: nothing to resolve, by measurement
The
METRIC_TYPESbranch (metric/kpi/gauge/solid-gauge/bullet) rendersformatMeasure(value, …)plusheaderLabel(values[0]). A dimension's value never reaches its output in any spelling, so a dotted dimension on a metric has no raw value on screen to resolve — the gap the issue describes for table/pivot is empty there, and turning the resolution on would be a metadata read whose result nothing consumes. The effect therefore still returns early for metric, and a pin asserts the branch renders the measure while containing neithereducationnorEducation.The boundary: local dimensions stay the server's job
The early return was not arbitrary. On a table the server resolves a local dimension's label (ADR-0021) — that is exactly why #4053's
tablewidget renderedEducationwhile its chart renderededucation. Running the client net for local dimensions there would be a SECOND resolution of an already-resolved value, so it stays off for them and opens only for dotted paths.Two proofs that local-on-table is byte-identical:
Education; the local cell still renderseducationin the same render. Any difference between them is the bug and nothing else — and an implementation that just switched the early return off fails this, which a dotted-only fixture could not detect.dimensionLabelsstays null andrelabelDimensionsreturnsstate.rowsITSELF (same array identity, not a copy). The control pin asserts the server-provided label passes through untouched AND that the list of requested objects is empty.Per-category colours and the declared category order stay chart-only — a table renders neither.
Drill-through is untouched: the relabel preserves row order and count, so
openDrill(i)andpivot.cellIndexstill index the rawdrillRawRows, and a drill filters by the stored value rather than the label.Reverse verification
Predicted RED on the four new pins with the raw values returning, and both controls staying GREEN. Reverted
DatasetWidget.tsxalone viagit checkout origin/main -- ...(no stash), keeping the tests:Exactly as predicted, then restored to 6 passed.
Verification
vitest run packages/plugin-dashboard/ packages/plugin-charts/ packages/core/src/utils/__tests__/chart-series.test.ts— 58 files, 491 tests passed, including fix(analytics): resolve a dotted dimension's select options against the relationship target #4261's dotted-chart pins (unchanged) and the existing pivot / compareTo / CSV suites.pnpm --filter @object-ui/plugin-dashboard type-check— clean.pnpm --filter @object-ui/plugin-dashboard lint— 0 errors (252 pre-existinganywarnings).pnpm check:control-bytes— OK, 3987 files; plus a self-scan of both touched files for raw control bytes: clean.--filter '@object-ui/plugin-dashboard^...' build).@object-ui/plugin-dashboardpatch.Region note
Stayed out of
buildPivot's bucket-id encoding, which #4056 is editing. The only line ofbuildPivot's call site that changed is the argument passed to it.Generated by Claude Code