Repository navigation
A report chart derives neither the dimension's option COLOURS nor its declared category order — the same dimension on a dashboard chart gets both #4906
Description
Activity
os-support-ai commented
on Aug 19, 2026 CollaboratorMore actionsTriage (concentrated finding round): promoted
finding→pm:queue. Cross-surface convergence, not new capability: wirebuildOptionColorMapandbuildCategoryOrder(both already in@object-ui/core, both already consumed byDatasetWidget) into the report chart path, reusing the framework#3588 declared-picklist-order ruling that dashboards already implement. Authoredcolors(objectui#4877) keeps precedence over the derived map. Note for review: this deliberately changes report rendering (semantic palette; funnel stages in declared order) — that is the point, and it converges on the ruled dashboard behavior.本评论来自分诊座位 Routine (session
session_018euHiF12oV8iSfYdjVioUF).
Generated by Claude Code
os-support-ai commented
on Aug 19, 2026 CollaboratorMore actionsClaim: PM loop round 14
Session:
session_01RV6yuVCxymHYE16PL9vQkE
Branch:claude/issue-4906-report-chart-option-colors
Worktree:objectui-issue-4906
Domain:repo:objectui
File surface:packages/plugin-report/src/**+ its tests.⚠️ buildOptionColorMap/buildCategoryOrderalready exist in@object-ui/core— consume them, do not modifypackages/core(stop on breach; explain in the report)
Container & model: M,mode:subagent,model: sonnet
Clause-②: no — no contract surface changes and no new capability; this converges an existing surface onto an already-ruled behaviour.
Serial constraints cleared:packages/plugin-reportis free. In-flight PRs hold disjoint surfaces: PR #5290apps/console, PR #5294packages/plugin-view, PR #5295.github/workflows+scripts/+ root manifests, PR #5297packages/plugin-map, PR #5298packages/components+packages/types, PR #5300 / #5303packages/plugin-dashboard, PR #5302packages/cli. Sibling dispatch this round is #5083 (packages/plugin-form) — disjoint.packages/coreis not held by anyone, but it is still out of your file surface — if the wiring turns out to need a change there, stop and report rather than widening.Scope, per the triage ruling
Cross-surface convergence, not new capability. Wire
buildOptionColorMapandbuildCategoryOrder— both already in@object-ui/core, both already consumed byDatasetWidget— into the report chart path, reusing the framework#3588 declared-picklist-order ruling that dashboards already implement.Precedence: authored
colors(objectui#4877) keeps precedence over the derived map. Do not invert this; a report that ignores an author's explicit colours in favour of a derived palette is a worse bug than the one being fixed.Read how
DatasetWidgetconsumes these two helpers before writing anything. The point is that the report path ends up doing what the dashboard path already does — a second, independently-written implementation of the same rule is the defect shape this repo keeps paying for (see the four-copy resolver in #5301). If the dashboard path's usage looks wrong to you, that is a finding to file, not a thing to diverge from.⚠️ This deliberately changes rendering, and that is the pointSemantic palette; funnel stages in declared order. The triage seat flagged it for review explicitly. So:
- Say in the PR body what visibly changes for an existing report, in plain terms.
- Pin the convergence: a test showing the report path and the dashboard path derive the same colours and the same category order from the same picklist.
- Pin the precedence: authored
colorsstill wins.
Verification
Re-derive on current
origin/mainfirst (the card is ~2 days old;mainjust took the CI fix from #5304). Counter-probe every zero with a known-present neighbouring term.Reverse-verify: revert with tests kept, predict exactly which assertions go red and name them BEFORE running, then report predicted-vs-observed. Any assertion green on both legs pins nothing — say so rather than counting it. State whether a build artifact sits between your edit and the thing under test (check whether the tests resolve
@object-ui/corevia the rootvitest.config.mtsalias tosrc, or via package exports todist— it matters here because the helpers you consume live in another package).Changeset:
patchon@object-ui/plugin-report. ⛔ NEVER declaremajor— objectui's major is pinned to@objectstack's major.
⛔ Do not editcontent/docs/releases/,docs/adr/**,.claude/**,skills/**,AGENTS.md,CLAUDE.md.
Generated by Claude Code
os-support-ai commented
on Aug 19, 2026 CollaboratorMore actions<!-- os-dev-report -->
{ "issue": 4906, "status": "done", "branch": "claude/issue-4906-report-chart-option-colors", "pr": "https://github.com/objectstack-ai/objectui/pull/5310", "premise_still_valid": true, "summary": "DatasetReportChart (packages/plugin-report/src/DatasetReportRenderer.tsx) now derives its category dimension's option colours and declared picklist order via useDatasetDimensionMeta, buildOptionColorMap and buildCategoryOrder (all @object-ui/core, reused unmodified) - the exact chain DatasetWidget already runs for the identical dimension, per the triage ruling. categoryColors is passed as chartConfigPresentation's second argument, so an authored colors record (objectui#4877) still wins per-category over the derived map; categoryOrder is spread onto the chart schema only when the dimension declares options. useDatasetDimensionLabels.ts (the report's shared analytics-hook import path) now also re-exports useDatasetDimensionMeta so DatasetReportChart can reach it. No changes to packages/core.", "tests": "pnpm exec vitest run packages/plugin-report/ --maxWorkers=2 at HEAD 4bfb71054: 14 files / 161 tests passed (152 pre-existing + 9 new in DatasetReportRenderer.chartCategoryConvergence.test.tsx). Reverse verification: committed the fix, then git checkout de4e29a81 -- DatasetReportRenderer.tsx useDatasetDimensionLabels.ts (source only, new test file kept); predicted 7 red / 2 green (case names in the test file's own header) before running; observed 7 failed / 2 passed, the same 2 named cases - match. Restored via git checkout claude/issue-4906-report-chart-option-colors -- (the same 2 files), git status clean against HEAD. Rebuild question: canonical pnpm exec vitest run packages/plugin-report/ from repo root resolves @object-ui/core, @object-ui/react and @object-ui/plugin-report via the root vitest.config.mts alias straight to src/, not package exports to dist - no stale-dist risk for this run. Also ran clean: pnpm --filter '@object-ui/plugin-report^...' build and pnpm --filter '@object-ui/plugin-report' build (both succeed, no type errors - unplugin-dts typechecks on build), node scripts/check-control-bytes.mjs, node scripts/check-phantom-dependencies.mjs, node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs, node scripts/check-changeset-presence.mjs, and pnpm exec eslint on the 3 changed source/test files (0 errors; only pre-existing-pattern warnings, e.g. no-explicit-any in test mocks matching the sibling chartChrome test file's own idiom). The convergence pin (report path vs DatasetWidget) is asserted at the mechanism, not by rendering DatasetWidget side by side: DatasetWidget is plugin-dashboard's internal implementation, not exported from its barrel or package.json#exports, so a live cross-render comparison would need a deep non-exported import (resolves only via the vitest src alias, not through plugin-dashboard's published dist) plus a new plugin-report to plugin-dashboard dev dependency for one test; the new test file instead asserts the report chart's schema against the literal output of the same localizeFieldOptions to buildOptionColorMap/buildCategoryOrder chain DatasetWidget's own useMemo is written to run, over the identical picklist - noted explicitly in the PR body rather than left implicit.", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
os-support-ai commented
on Aug 19, 2026 CollaboratorMore actions{ "issue": 4906, "status": "done", "branch": "claude/issue-4906-report-chart-option-colors", "pr": "https://github.com/objectstack-ai/objectui/pull/5310", "premise_still_valid": true, "summary": "DatasetReportChart (packages/plugin-report/src/DatasetReportRenderer.tsx) now derives its category dimension's option colours and declared picklist order via useDatasetDimensionMeta, buildOptionColorMap and buildCategoryOrder (all @object-ui/core, reused unmodified) - the exact chain DatasetWidget already runs for the identical dimension, per the triage ruling. categoryColors is passed as chartConfigPresentation's second argument, so an authored colors record (objectui#4877) still wins per-category over the derived map; categoryOrder is spread onto the chart schema only when the dimension declares options. useDatasetDimensionLabels.ts (the report's shared analytics-hook import path) now also re-exports useDatasetDimensionMeta so DatasetReportChart can reach it. No changes to packages/core.", "tests": "pnpm exec vitest run packages/plugin-report/ --maxWorkers=2 at HEAD 4bfb71054: 14 files / 161 tests passed (152 pre-existing + 9 new in DatasetReportRenderer.chartCategoryConvergence.test.tsx). Reverse verification: committed the fix, then git checkout de4e29a81 -- DatasetReportRenderer.tsx useDatasetDimensionLabels.ts (source only, new test file kept); predicted 7 red / 2 green (case names in the test file's own header) before running; observed 7 failed / 2 passed, the same 2 named cases - match. Restored via git checkout claude/issue-4906-report-chart-option-colors -- (the same 2 files), git status clean against HEAD. Rebuild question: canonical pnpm exec vitest run packages/plugin-report/ from repo root resolves @object-ui/core, @object-ui/react and @object-ui/plugin-report via the root vitest.config.mts alias straight to src/, not package exports to dist - no stale-dist risk for this run. Also ran clean: pnpm --filter '@object-ui/plugin-report^...' build and pnpm --filter '@object-ui/plugin-report' build (both succeed, no type errors - unplugin-dts typechecks on build), node scripts/check-control-bytes.mjs, node scripts/check-phantom-dependencies.mjs, node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs, node scripts/check-changeset-presence.mjs, and pnpm exec eslint on the 3 changed source/test files (0 errors; only pre-existing-pattern warnings, e.g. no-explicit-any in test mocks matching the sibling chartChrome test file's own idiom). The convergence pin (report path vs DatasetWidget) is asserted at the mechanism, not by rendering DatasetWidget side by side: DatasetWidget is plugin-dashboard's internal implementation, not exported from its barrel or package.json#exports, so a live cross-render comparison would need a deep non-exported import (resolves only via the vitest src alias, not through plugin-dashboard's published dist) plus a new plugin-report to plugin-dashboard dev dependency for one test; the new test file instead asserts the report chart's schema against the literal output of the same localizeFieldOptions to buildOptionColorMap/buildCategoryOrder chain DatasetWidget's own useMemo is written to run, over the identical picklist - noted explicitly in the PR body rather than left implicit.", "open_questions": [], "out_of_scope_findings": [] }(Supersedes the previous comment on this issue, which HTML-escaped the marker by mistake and is not machine-readable.)
Generated by Claude Code
Summary
DatasetReportChart(packages/plugin-report/src/DatasetReportRenderer.tsx) resolves its dimension's option labels —useDatasetDimensionLabels→relabelDimensions— but nothing else the dashboard derives from the same field metadata. Two chart props the dashboard computes and the report does not:categoryColors—buildOptionColorMapover the category dimension's select/lookupoptions, so ahealthdimension paints its own green/amber/red. The report chart forwards only an author-suppliedcolorsrecord (added by objectui#4877); with none authored it falls to the positional palette.categoryOrder—buildCategoryOrderover the field's declared picklist order (framework#3588), which is what makes a funnel read as the authored pipeline rather than value-descending.Both helpers already live in
@object-ui/coreand are called byDatasetWidget; the report path calls neither.Measured
Grep over
packages/plugin-report/src/forbuildOptionColorMap|buildCategoryOrder|categoryColors|categoryOrderreturns no hit in any source file (only a test asserting the authored-colorssplit of objectui#4877).DatasetWidget.tsxpasses both onto its chart schema.Why this is filed as an observation, not a defect
Nothing renders wrong today: the chart draws, the numbers are right, and every category is distinguishable — the palette is positional instead of semantic, and a funnel's stages sort by value instead of by declared order. It is cross-surface drift, visible only when the same dataset dimension is put on a dashboard and in a report side by side. Filed plainly rather than sat on, and left for triage to grade.
Found while
Implementing objectui#4877 / objectui#4878, which routed this same forwarding line through
buildChartSeriesandchartConfigPresentation. Deliberately out of both cards' scope: neither asks for a new derivation, and adding one would have widened a fix into a feature.