fix(lint): chart-config-missing no longer fires on a widget whose binding the renderer derives (#14436) - #15461
Conversation
…ding the renderer derives `chart-config-missing` warned on every chart-family widget with no `chartConfig`, claiming the renderer "cannot determine which measure to plot, so the series renders empty". Read at the `@object-ui` revision this repo pins (`.objectui-sha`), that is false: `DatasetWidget` derives the x-axis key and one series per measure from the widget's own `dimensions`/`values` (`buildChartSeries`) and refuses an authored `ChartAxis.field` / `ChartSeries.name`. `chartConfig` carries presentation only. The false finding landed on this platform's own shipped `system_overview` tiles. One true arm survives, under the same rule id: a `combo` widget with no `chartConfig` takes no per-series mark, so every measure draws with the same default and the chart is not a combination at all. Its message now names that consequence. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…art-config-missing-overreach
📓 Docs Drift CheckThis PR changes 1 package(s): ⛔ 2 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 5 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6530cff5acfb304640e116a241203c716301ff28 && git checkout 6530cff5acfb304640e116a241203c716301ff28
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 0db29473cbc43d2c678b434fa5e4bcc0422f9fd3 e9a4a58770730bad70123897f4cc366c40270676 && git checkout -B drift-repro 0db29473cbc43d2c678b434fa5e4bcc0422f9fd3 && git merge --no-ff e9a4a58770730bad70123897f4cc366c40270676
node scripts/docs-audit/affected-docs.mjs --json 0db29473cbc43d2c678b434fa5e4bcc0422f9fd3
|
|
ACCEPT — PM seat Reviewed against the three-dot diff
Out-of-scope findings #15462 and #15463 are graded separately on the cards. Flipping ready and arming auto-merge now; Generated by Claude Code |
Fixes #14436
What the rule claimed, and why it was false
chart-config-missingwarned on every chart-family widget that declared nochartConfig:That consequence is false. It is also this platform's own shipped metadata that was tripping it: the
system_overviewdashboard's two Row 3 tiles (a pie and a bar, one dimension and one measure each), on the Setup board every customer opens first.Closing the gap triage left: the reading is against the PINNED renderer
Triage read objectui's
origin/mainand said so. This repo does not consume objectui from npm — the Console is built from the git revision in.objectui-sha, today00d3f09c500c4a45b5f27aca8af80349412faaf1. Every quotation below was read at that revision, and the derivation is identical to the one triage described:packages/plugin-dashboard/src/DatasetWidget.tsx:1397callsbuildChartSeries(chartRows, dimensions, values, state.fields, …)and destructures{ data: chartData, xAxisKey, series }.chartConfigis not an argument.packages/core/src/utils/chart-series.ts:674— the default branch isxAxisKey: dims[0],series: vals.map((v) => ({ dataKey: v, label: labelOf(v) })).chartConfigreaches the chart only throughmergeAuthoredPresentation(per-series/axis PRESENTATION merged ONTO those derived bindings,DatasetWidget.tsx:1405) andchartConfigPresentation(chrome,:1473).packages/plugin-dashboard/src/__tests__/DatasetWidget.chartConfig.test.tsxat that same revision — same names, same line numbers triage quoted::179"ignores an authored axisfieldand keeps the derived axis binding",:192"ignores an authored series and keeps one derived series per measure",:204"ignoreschartConfig.type— the widget type owns the chart family",:159"emits none of the presentation keys when no chartConfig is declared".So the pinned behaviour is the behaviour triage described, and the exemption is written against it.
Adding a
chartConfigcould not have repaired a widget with an empty selection either:chart-field-unknown(this same rule file) errors on ayAxis[].fieldnaming anything the widget did not select, sochartConfigcan never supply a measure thevaluesarray is missing.The one arm that survives, measured rather than assumed
Triage asked whether a genuinely un-derivable shape exists. One does, and
combois it. A combination chart's identity is a per-series MARK, authored aschartConfig.series[].type— presentation, so it merges forward.mergeAuthoredSeriesstates the fallback: "a derived series with no authored entry keeps the family default", andDatasetWidget.comboPresentation.test.tsxrecords the cost: "Without it the line measure drew as the second bar." Acombowith nochartConfigdraws every measure with one mark, so it is not a combination at all. Warning-tier, because the numbers and the axis are right — the shape is not.Two shapes are deliberately NOT folded in under this id, because neither is caused by nor repairable with
chartConfig, and folding them in would leave the id misnaming its own condition: a chart widget selecting no measures (the pin renders an explicit "Pick measures (values)" placeholder) and one selecting no dimensions (the pin'sisMetriccoversdimensions.length === 0, so it renders as a KPI number). Both are filed separately.The change
MEASURE_EXEMPT_CHART_TYPES+CHART_TYPES(the taxonomy minus a hand-written exemption list) is replaced byMARK_MIXING_CHART_TYPES = new Set(['combo']). objectui#2945's lesson survives as a test that every member is a declaredChartTypeSchemaoption — membership is a fact about the RENDERER, which a taxonomy cannot derive.suppressWarnings: ['chart-config-missing']stays valid. Changeset:patchfor@objectstack/lint.packages/platform-objects/**— ADR-0072 D1: the rule is repaired, not the metadata.Fixture pass: the card's repro, before and after
validateWidgetBindingsover a stack of@objectstack/platform-objects' exported objects (53) +SystemOverviewDatasets(5) +SystemOverviewDashboard. Run as a reverse verification from the committed state — the pre-fix rule source restored from the merge basef01adfa5c, then restored fromHEAD, each leg proved on disk by blob hash:The two widgets are also pinned inline as a fixture in
validate-widget-bindings.test.tsthat must report nothing.Verification (all at
e9a4a5877; exit codes captured before any pipe)pnpm --filter @objectstack/lint test—Test Files 94 passed (94) · Tests 2908 passed (2908), EXIT=0pnpm --filter @objectstack/lint typecheck— EXIT=0;check:test-typecheck: OK — @objectstack/lint's test layer compiles under packages/lint/tsconfig.test.jsonnode scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack→ 44 commands, all run: 42 EXIT=0, 2 EXIT=3 (NOT MEASURED, not a red):check:dual-build-cjs-loadsandcheck:type-check-debtboth printPREREQUISITE NOT MET/ "nothing was measured" because they read built output and this worktree has no whole-repodist. CI builds first and measures them there.pnpm check:declared-population-live—✓ … 203 of 254 famil(ies) … every one of them reaches this tree's 7494 tracked file(s), EXIT=0pnpm check:nul-bytes— EXIT=0pnpm -s check:pm-dispatch-gates—✓ dispatch-gates self-test: 1402 cases pass., EXIT=0pnpm lint(eslint . --no-inline-config) — EXIT=0, no narrowinggrep -rn chart-config-missingoutsidenode_moduleshits only the two packageCHANGELOG.mdfiles (historical release prose, not a contract) and the rule source itself. Nodocs/qa/platform-checklistitem and nocontent/docspage states the rule's old consequence, so nothing to correct there.🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code