fix(plugin-dashboard): a dataset-less provider: 'object' metric widget draws the retired-format placeholder on both surfaces (objectui#11525) - #11538
Conversation
…raws the retired-format placeholder on both surfaces (objectui#11525)
Maintainer ruling C on objectui#11525: both dashboard surfaces map a
single-value widget (metric, gauge, solid-gauge, kpi, bullet, and a
typeless widget, which resolves to metric) with no dataset and an
options.data / widget-level data of { provider: 'object', ... } to the
shared LEGACY_RETIRED_WIDGET_SCHEMA, as the pivot arms already do
(objectui#10528). The flat object-metric producer is removed from both
metric arms. The inline chart and table arms are untouched, and the
filter broadcast keeps object-metric in its filterable set, because an
author's component-envelope node still reaches the merge.
legacyRetiredWidget.ts gets a dated correction for the metric family;
the docs page, the filters guide and the README say what the stored
form now draws. New pins in inlineObjectMetricRetired-11525.test.tsx.
Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC
Co-authored-by: Claude <noreply@anthropic.com>
…ject metric, a dated note on 11514's entry, and a typed case table in the pin (objectui#11525) Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
… (objectui#11525) Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Inputs: card objectui#11525 (body and all four comments: ruling ① Derived judgments
Check-runs on the head (42). Second read, 04:27:03Z: 32 ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #11525
Clause-②: no (narrowing)
The maintainer's ruling C on objectui#11525 (record
5964914121) retires one stored widget form. The form is a dataset-less single-value widget whoseoptions.data(or widget-leveldata) is{ provider: 'object', … }. The single-value family ismetric,gauge,solid-gauge,kpiandbullet, plus a typeless widget, which resolves tometricsince objectui#11514.DashboardRendererandDashboardGridLayoutnow return the sharedLEGACY_RETIRED_WIDGET_SCHEMA. It is the same imported object the pivot arms already return for that input (objectui#10528).object-metricnode both arms used to build is removed. That node carried an ObjectQL-dialectfilterthat no node type declares.Implemented by the
domain:spec @ objectuiseat's dev, sessionsession_01XvhGmGAP79ZB8swnkapxPC, under the PM claim5965174453.Before and after, per surface
The before/after run went through the real
SchemaRendererand real registrations. The adapter'saggregateanswers 4242 andqueryDatasetanswers 510000. "Before" is base9d7419b9; "after" is this branch.DashboardRenderermetric, provideroptions.dataaggregatecallDashboardRendererkpi, same dataDashboardRenderertype, same dataDashboardRendererpivot, same data (control)DashboardRenderermetricbound to a dataset (control)queryDatasetcallDashboardGridLayoutThe placeholder text is "This widget uses a retired data format. Edit it to bind a dataset."
Chrome, measured (the dispatch's H2). The tile's chrome follows the widget's family, not the placeholder.
metric(and a typeless widget) is self-contained on both surfaces, so its tile draws the placeholder without the widget's heading. That is the same tile the retired top-levelobjectmetric shape already drew, and a pin holds the two DOMs equal.gauge,solid-gauge,kpiandbullettake the Card chrome, so their heading is drawn above the placeholder, as the pivot's is.What stays, and why: the filter broadcast's
object-metricmemberDashboardRenderer'sFilterableComponentType/FILTERABLE_COMPONENT_TYPESkeepsobject-metric. The member is not dead after the producer goes, measured:componentenvelope holding anobject-metricnode still reaches the merge.filter: { region: 'EMEA' }on that node, for both an untyped and acustomenvelope.Its docblock now says so, and a pin holds it.
DashboardGridLayouthas no filter bar, so it has no such plumbing.The pins
The pins are in
packages/plugin-dashboard/src/__tests__/inlineObjectMetricRetired-11525.test.tsx: 29 tests, both surfaces.options.datais read offMETRIC_LIKE_TYPES, not restated. Widget-leveldataand a typeless widget are cases too. Each drawsLEGACY_RETIRED_WIDGET_SCHEMA, checked by identity on the recorded node. The test also reads the placeholder text on screen, finds noobject-metricnode, and sees noaggregate,findorqueryDatasetcall. One more case holds that the retiredmetrictile's DOM equals the retired legacy-shape metric tile's.options.valuethroughplugin-dashboard:metric. A provider bar still builds anobject-chartnode namingdeal, and a provider table still buildsobject-data-tableand fetches. An envelopeobject-metricreceives{ region: 'EMEA' }from the filter bar and queries.Reverse verification. The fix was committed first (
856f56f0). The two producer files were then checked out at9d7419b9, with a trap restoring them fromHEAD.object-metricproducer lines were 2 inDashboardRenderer.tsxand 1 inDashboardGridLayout.tsx. The renderer's 2 are the producer and the kept union member. The retired-arm marker read 0 and 0.HEAD's,git diff HEADon both files is 0 bytes, and the rerun is 29 passed.Corpus re-judged (H3)
The census. I ran
git grepover the whole tracked tree for a file that pairs aprovider: 'object'literal with a metric-familytype. It found no test, fixture, story or example that authors a dataset-less inline provider metric through a dashboard surface or asserts its number. The hits are prose, CHANGELOGs, this card's own files, and two plugin-dashboard tests whose provider widget is abar.The full plugin-dashboard suite was green before this branch's pins were added. Verdicts:
DashboardGridLayout.legacyRetired.test.tsx: its header said the nested provider config is live for every family. It gets a dated note. Its provider control is abar, so the control stands as written.DashboardGridLayout.datasetPath.test.tsx,widgetDataProviderRetired-7353.test.tsx,dashboard-producer-node-types-11514.test.tsxand the threeDashboardChart.*files: these are providerbar,tableorpivotwidgets, all live or already retired. Left alone.DashboardRenderer.legacyRetired.test.tsx: it covers the top-levelobjectshape only. Left alone.content/docs/guide/dashboard-filters.mdandcontent/docs/plugins/plugin-dashboard.mdxeach get one paragraph naming the form that now draws the prompt. Inpackages/plugin-dashboard/README.md, the filters example's comment does the same, and the accent table's "inlineobject-metric" now reads "anobject-metricblock".legacyRetiredWidget.ts(the dated, append-only correction the ruling names),ObjectMetricWidget.tsx'saggregatedocblock (it said both relays compose this node), and the render-site and broadcast comments in the two surfaces.Pending changesets
.changeset/11525-inline-metric-retired.md(@object-ui/plugin-dashboard:minor) states the render change: what the tile showed before, what it shows now, and the fix, which is to bind a dataset..changeset/11514-dashboard-slot-entry-types.mdgets one: its "Every widget that names a known family draws as before" no longer holds for this form. Its frontmatter is unchanged.object-metric,ObjectMetricWidget,legacyRetiredWidget, objectui#4612, objectui#10528, objectui#11479 or the filter broadcast.11348-dashboard-widget-readsstill holds: the type guard still covers the same threeobject-*types.10528-grid-object-table-fetchand7353-retire-widget-dataprovidercover the table and pivot only.object-metricblock entries (8613,8970,9002,10221,10356,10572,10993,11254,11444,11475,7352,7752,11506) describe the widget, which stays live as an authored block. None says a dataset-less provider widget reaches it.check:changeset-claimsnamed three entries for files this branch edits:11483-metric-card-needs-value,8114-detail-tab-activity-timelineand8760-unfulfilled-chart-stubs. Their paragraphs concernmetric-card, a detail tab andline-chart, which this branch does not move.V1 census (H4)
This was a throwaway worktree detached at PR #11512's head
ff7f748e. I appliedgit merge-treeof that head and this branch, which had one conflict,zod-mirror-parity.test.ts; I took V1's side because no plugin-dashboard program reads that file. After a fresh install and a closure build, I ran plugin-dashboard's two programs. Nothing was committed or pushed from the probe, and the probe was removed.SchemaRenderercast sites, two in each surface.getComponentSchemareturns as the renderer prop:object-metriclines (3 inDashboardRenderer, 2 inDashboardGridLayout), 2plugin-dashboard:metric, 1 staticpivotand the 4 casts.object-metricat 0. Left are 2plugin-dashboard:metric, 1 staticpivotand the 4 casts, which belong to objectui#11466.Gates
Read at
29b4ab28unless stated. objectui has nodispatch-gates.mjs; the list is hand-derived frompackage.json.pnpm --filter '@object-ui/plugin-dashboard^...' buildexited 0 under the verify lock.pnpm --filter @object-ui/plugin-dashboard run type-checkexited 0. The script echoedtsc --noEmit && tsc -p tsconfig.test.json. The test program covers the new pin file: its first run failed on that file's case-table typing, which was then fixed.pnpm exec vitest run packages/plugin-dashboard/(from the worktree root): 165 files and 1620 tests passed, 6 skipped. This ran ata1c7e645; the only later change is the pin file's stub registration, whose own rerun gave 29 passed.sdui-parser's options census, the app-shellDashboardViewand preview suites, the console drill-down suites, the schema-catalog gallery render and the widget DOM-leak sweep.check:new-line-citations: 0 new.check:control-bytes,check:doc-typesandcheck-changeset-no-major.check-changeset-presence: 1 changeset for 6 published source files.check:changeset-claimsandcheck-changeset-overwrite: reports only, judged above.anywarnings, the same two the objectui#7353 listener carries. This is a targeted run, not the repo lint, which CI owns.check:doc-snippetsandcheck:doc-examples. They exited 2, PREREQUISITE NOT MET, because they need a 34-package build. They compilets/tsxfences only; this branch edits no such fence and moves no published type.check:component-surface-parityandcheck:sdui-registration-pins. No registration input moves.Acceptance notes
metrictile (and a typeless one) draws no heading, as the retired legacy-shape metric tile already does. Giving retired tiles Card chrome would move the legacy shape too. Not done; the report carries it as an open question.DashboardGridLayout.tsxline addresses. The one cross-file line address in the paragraph this branch edits was replaced by a symbol citation. Eleven others stay, in the props docblock and the render-site comment. Two of them also carry content that is stale at base: the sibling'sas anyread ofdataset, and a second fork in the sibling's self-contained branch. Their repair is a content correction outside this card. Carrier: none.packages/sdui-parser/src/dashboard-widget-options.ts. Its scope note listsobject-metricamong the legacy inline spread targets, which no longer holds for the metric family. It is a comment in a package outside this card's surface. Carrier: none.packages/plugin-dashboard/src/index.tsx.ObjectMetricBlock's docblock names "the dashboard grid path" as a props-only host; no dashboard path builds the node now. Comment only. Carrier: none.packages/data-objectstack/src/index.ts. A comment there citesisObjectProvideras how a metric'sgroupByarrives. It is a dated measurement (2026-09-08) and is left as written.Generated by Claude Code