Repository navigation
fix(plugin-report,plugin-dashboard): report, chart and table drills list the records a filtered measure counted - #30651
Merged
Conversation
…Scopes (#30615) Claude-Session: https://claude.ai/code/session_01L6bhgUBrAU6n2ZJWk6VmTV Co-authored-by: Claude <noreply@anthropic.com>
…ix drills (#30615) Claude-Session: https://claude.ai/code/session_01L6bhgUBrAU6n2ZJWk6VmTV Co-authored-by: Claude <noreply@anthropic.com>
…opes (#30615) Claude-Session: https://claude.ai/code/session_01L6bhgUBrAU6n2ZJWk6VmTV Co-authored-by: Claude <noreply@anthropic.com>
…and chart drills (#30615) Claude-Session: https://claude.ai/code/session_01L6bhgUBrAU6n2ZJWk6VmTV Co-authored-by: Claude <noreply@anthropic.com>
…copes (#30615) Claude-Session: https://claude.ai/code/session_01L6bhgUBrAU6n2ZJWk6VmTV Co-authored-by: Claude <noreply@anthropic.com>
…ureDrillScope type (#30615) The one-authority-per-exported-name gate refuses a type name declared in two packages; plugin-report keeps the name, the dashboard helper spells the record type inline. Claude-Session: https://claude.ai/code/session_01L6bhgUBrAU6n2ZJWk6VmTV Co-authored-by: Claude <noreply@anthropic.com>
2 tasks
Contributor
Author
|
domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL 维护者速读
席位核对 — ACCEPT · head f954312
|
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 free
to 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.
Requested by Sales · project thread
Fixes #30615
Clause-②: no
Metadata-protocol: none
维护者速读
What changes
drillScopesentry for the measure the click stands for (PR feat(spec,service-analytics): a dataset answer says which records each measure counted, so a drill lists what the number counted #30596's sidecar). A{}entry hands the widget or report filter back untouched, so a drill on an unfiltered measure is byte-identical to the drill it was before.MEASURE__compareseries: nothing, it has no entry). A cross-tab or matrix cell: its column's measure. A table row, a report line or a subtotal line: every measure it holds.dataset-drill-row). Otherwise the row is not a drill target, and each measure cell with an entry is (dataset-drill-cell), drilling that measure's records. This is the case ontable_rate_by_status:invoice_count({}) besidepaid_count(status = paid).objectbut nodrillScopes; a chart none of whose drawn measures has an entry gets no click handler.ui/packages/plugin-dashboard/src/measureDrill.ts(new, internal):sharedMeasureDrillScopeandscopeDrillFilter, reading entries with the mergedreadMeasureDrillScopefrommetricDrill.ts(unchanged).ui/packages/plugin-report/src/measureDrillScope.ts(new, internal): the same two plusmeasureDrillScope, since plugin-report does not depend on plugin-dashboard. Neither is exported from a package entry;@object-ui/coreis untouched.@object-ui/plugin-reportand@object-ui/plugin-dashboard, patch.Why
A dataset number is computed under the dataset's
filter, the measure'sfilterand the widget filter. The drills composed only the last one with the bucket, so a filtered measure drilled to a superset. The server now states the missing two per measure (PR #30596); the KPI tile reads them since PR #30634. This PR makes the report, chart, table and cross-tab drills read them too.What the drill does when the answer has no
drillScopes(the reading the claim asked for)queryDatasetsetsdrillScopeson every dataset answer that has rows (analytics-service.ts, the block after the drill ranges). It is absent on (1) an answer with no rows, where there is nothing to click; (2) a draft-preview answer, which returns beforedimensionFields,drillRawRowsanddrillRangesare set, so the widget'scanDrillis already false there, and the Studio report preview passes noonDrill; (3) a cube query answer, which these consumers never request (they callqueryDatasetonly).drillScopes" never meets a clickable bucket. The consumers treat a missing map like a missing entry: no drill (the tile's rule in PR feat(plugin-dashboard): a dataset KPI tile opens the records behind its number #30634).object(a server older than ADR-0021 D2) still handsReportViewits group-key fallback drill, unchanged, asdrill: omits objectFilter when the server returns no drill metadata (older server)pins.Tests
On
f9543126(the head):pnpm --dir ui exec vitest run --maxWorkers=2 packages/plugin-report/: Test Files 33 passed (33), Tests 313 passed, 7 skipped. VERDICT command-exit 0.pnpm --dir ui exec vitest run --maxWorkers=2 packages/plugin-dashboard/: Test Files 203 passed (203), Tests 1957 passed, 6 skipped. VERDICT command-exit 0.pnpm --filter @object-ui/plugin-report --filter @object-ui/plugin-dashboard run type-check(tsc --noEmitandtsc -p tsconfig.test.jsoneach): VERDICT command-exit 0.describein a shared harness:plugin-report/src/__tests__/DatasetReportRenderer.test.tsx, "measure drill scopes (Report, chart and table drills list more records than the number for a filtered measure: they do not read the answer's per-measure drillScopes #30615)": a filtered measure cell carries its scope; a{}cell carries bucket and report scope only; a derived measure offers no drill; an answer with an object and nodrillScopesoffers no drill; a line of one filtered measure drills as a line with its scope; a matrix cell carries its measure's scope and a no-entry measure's cell is not clickable.plugin-dashboard/src/__tests__/DatasetWidget.test.tsx, "table drill — measure drill scopes (Report, chart and table drills list more records than the number for a filtered measure: they do not read the answer's per-measure drillScopes #30615)": the same five table cases plus the cross-tab cell, asserting the$filterthe drawer's list sends.plugin-dashboard/src/__tests__/DatasetWidget.chartBucketIdentity.test.tsx, "chart drill — measure drill scopes (Report, chart and table drills list more records than the number for a filtered measure: they do not read the answer's per-measure drillScopes #30615)": a filtered series bar, a{}series bar, a no-entry series (opens nothing) and an answer with nodrillScopes(no click handler).drillScopesentry of{}for their measures (17 test files), which is what a current server answers for a plain measure; their assertions are unchanged.Ablations (two, one per package, on the scope leg)
Both through
node scripts/ablation-replace.mjsunder the verify lock, replacingreturn composeDrillFilter(runtimeFilter, scope);withreturn runtimeFilter;(anchor 1 to 0 each), restored to the HEAD blob withgit diff HEADempty. ui vitest resolves@object-ui/*to source, so there is no dist leg.plugin-dashboard/src/measureDrill.ts(blob db75569cbe8d to 902425afed01, re-run onf9543126): Tests 4 failed, 74 passed overDatasetWidget.test.tsxandDatasetWidget.chartBucketIdentity.test.tsx: the filtered bar, the filtered table cell, the one-scope row, the cross-tab cell.plugin-report/src/measureDrillScope.ts(blob 3ada35c7e701 to e47abefae51b): Tests 3 failed, 48 passed overDatasetReportRenderer.test.tsx: the filtered cell, the one-scope line, the matrix cell.Acceptance notes
showcase_invoice/data?filter[issued_on][gte]=2026-08-07&filter[issued_on][lte]=2026-11-05&filter[status]=sent, which lists the 4 sent invoices.serializeDrillFilterParams(ui/packages/app-shell/src/views/drillUrlFilters.ts) writes one URL param per field withparams.set, so the scope'sstatus = paidis overwritten by the bucket'sstatus = sent, and a list comparand ($in,$nin) is skipped. Reported to the seat for a card.ReportView's group-key fallback is now reached only for a report answer with noobject; it is unchanged.@object-ui/core, which this claim keeps read only.drillRawTotalsis not passed through@object-ui/data-objectstack: no totals row or total cell drills on any of these surfaces, so nothing reads it.Verification
Live: app-showcase Revenue Pulse (filtered), table "Paid Rate by Status", en-US, 1440 wide
objectstack dev --fresh --seed-adminapp-showcase plus the Console vite dev server. The answer'sdrillScopes:{ invoice_count: {}, paid_count: { status: 'paid' } }, nopaid_rateentry. Rows: Paid (Invoices 3, Paid Invoices 3, Paid Rate 100.0%), Sent (4, 0, 0.0%). The seed has noopenstatus; the Sent row is the card's case.Before (
14c67d44, main with PR #30634): both rows carrydataset-drill-row. Every cell of the Sent row opens the same list,issued_onwindow ANDstatus = sent: 4 records, allsent, including under Paid Invoices (number 0) and Paid Rate.After (
ca694112; the one later commitf9543126only drops a duplicate type alias): no row carriesdataset-drill-row; Invoices and Paid Invoices cells carrydataset-drill-cell, Paid Rate cells none.status = paidANDstatus = sent: 0 records.status = sent: 4 records, allsent.paid. Paid / Invoices (3): 3 records.Gates on f954312
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 35 families onf9543126(the same list as onca694112). Each ran with its exit code captured before any pipe; all 35 exit 0.--ranreconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN. Alsopnpm --dir ui run check:spec-symbols: exit 0.The first pass, on
ca694112, was red on one family:pnpm --dir ui exec vitest run scripts/failedone-authority-per-exported-name-6273.test.ts, because both new helpers declared a type namedMeasureDrillScope.f9543126removes the dashboard's alias (plugin-report keeps the name); the family re-ran green there (Test Files 170 passed, 2 skipped; Tests 4970 passed), and the 34 other families re-ran onf9543126too.Families CI runs are read from this PR's check-runs.
Branch:
claude/project-thread-8u6mg4is the card thread's platform-assigned branch (claim 6667494492, amendment 6667568430), not theclaude/issue-30615-*convention.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01L6bhgUBrAU6n2ZJWk6VmTV