The bar reports ListView's own paged query — the row count, the "Showing
first N records" warning tied to `$top: pageSize`, and the rows-per-page
selector that re-issues it. Every other view type draws the `data` ListView
hands down, so there the bar is accurate. The registered `object-gantt`
renderer forwards no prop but `schema`, so the chart queries for itself with
no `$top`: measured at 18 rows / pageSize 6, the chart drew 18 while the bar
read "6 records - Showing first 6 records. More data may be available."
Scoped to gantt; grid and kanban controls pin that the shared chrome is
untouched elsewhere. The gantt's own query is left exactly as it is.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012wwHa4aaFybxXrfmfHioDM
Part of #7210 — half 1 only. Halves 2 and 3 stay open on that card, deliberately; see "Half 3" below.
What changed
ListViewrenders one record-count bar for everyviewType: the row count, the "Showing first N records. More data may be available." warning tied to its own$top: pageSizequery, and a rows-per-page selector that re-issues that query. It is now suppressed onganttalone, behind a named constant (surfaceDrawsFetchedRows) whose doc comment carries the measurement and the reason.One line of behaviour, one guard, two controls, plus a pin in
plugin-ganttfor the fact the guard rests on.Why suppression rather than "make it describe the chart"
The ruling allowed either.
ListViewcannot report the chart's row count without a new upward channel fromObjectGantt— more published surface, and a channel whose meaning changes if a ceiling is ever added. Suppression is invariant to that decision, which is the property the split was made for. None of the bar's three parts describes the chart: not the count, not the warning, and not the page-size selector, which re-issues a query the chart ignores.Measured, not inherited
Everything below was measured in this branch. Nothing was copied from the report.
Request count — the order said "count them yourself", and the answer is not two. Harness: one
list-viewofviewType: 'gantt', 18 rows in the store,pagination.pageSize: 6, instrumented adapter recording everyfind.Calls 2 and 3 are one defect the reporter's browser capture read as one request: the second/third split is the "two queries, the first unexpanded" regime already recorded for
ObjectGantton #6482, which is no longer open; re-confirmed here. Only call 1 has a$topat all.The chart consumes the unbounded fetch. The DOM reading reproduced in the harness's own terms: the paged query answered 6 rows, and the chart rendered 18
gantt-task-row-*rows while the bar under it read6 records - Showing first 6 records. More data may be available.That is the defect in miniature, one screen, both halves visible.The chrome is shared, so the change is scoped. Same harness, same store, only
viewTypediffering:gantt6 records - Showing first 6 records...while the chart drew 18grid18 records(server total, no warning)kanban6 records - Showing first 6 records..., and the board drew 6kanbanis the load-bearing control: a non-grid, page-scoped surface whose warning is correct and had to survive.The mechanism.
plugin-gantt/src/index.tsx'sObjectGanttRendererdestructures{ schema }and hands its child onlyschemaanddataSource. Every sibling wrapper — grid, kanban, calendar, map, tree — spreads{...props}. So thedataListViewpasses never reaches the chart,ObjectGantt.reload'srest.datashort-circuit is unreachable from the registry path, and the component queries for itself with no$top. Pinned inpackages/plugin-gantt/src/ObjectGantt.hostDataProp-7210.test.tsx.Half 3 — condition FAILED, so both requests stay
The order was explicit: measure whether the paged request has any consumer other than the footer; if it does, stop and report rather than pick a dialect. It does. Reads of
ListView'sdataon the gantt surface:ListView.tsx:2801dataListView.tsx:2938UserFilters data={data}— option counts (showCount)ListView.tsx:3573ListView.tsx:3583ListView.tsx:3630ListView.tsx:3841The last two are behavioural, not cosmetic, and one of them was measured directly: with the paged response delayed 600ms and the unbounded one immediate, at t=250ms the skeleton was up and the chart had 0 rows on screen although its own data had already arrived. The paged query decides whether the chart mounts at all. Removing it is not a no-op, so no dialect was picked and nothing was deduped.
Falsified ZONE 2 assumptions
ObjectView's non-grid list-view path" — the paged request in the report isListView's (plugin-list), identified by its$selectprojection and$top, whichObjectView's non-grid fetch does not emit.ObjectView(plugin-view) delegates toListViewthroughrenderListViewand skips its own fetch when it does. The unbounded one isObjectGantt.reload.ListView, rendered for every view type, correct on all of them butgantt.@objectstack/restapplies no cap whenlimitis absent" — NOT MEASURED here. Out of reach from this repo; nothing in this change depends on it. What is measured is one layer up: the request carries no$top, so no page size authored on the view can bound it.Not touched, deliberately
$topon the gantt's query. Half 2 is a maintainer decision (escalated on [pm:seat] domain:ui @ objectui — 🟢 session_01EMrWaQw3XS5DxTHxp4yRyC · R1 · landed #7349 #7182 #7004 #6810 #7212, closed #7221 · ⚠️ 2 OPEN DECISIONS #7399 #7402 block #7391 + #7400 #5560) and adding one would turn a complete schedule into a quietly truncated one that still looks like a schedule.mergeFilterNodes#7221.ObjectGanttRendererdropping every host prop, the inertdataclause it makes ofListView'sganttOwnsData, and a live comment that states the opposite — finding(plugin-gantt):ObjectGanttRendererforwards no host prop butschema— the one view wrapper that does not, soListView'sdata/onRowClicknever arrive and a live comment says the opposite #7222. ⛔ That card explicitly does not propose spreading{...props}: forwardingdatawould cap the chart at one page, which is half 2's decision arriving through the back door.plugin-view's own non-grid path double-fetches for a gantt in the same way (its$top: 100query plus the chart's unbounded one). No paging chrome renders there, so half 1 has nothing to correct on it; it belongs to A gantt lens fetches its rows twice — once paged (which feeds the footer) and once unbounded (which feeds the chart), so the footer misdescribes the chart and the real fetch has no ceiling #7210's still-open half 3.ObjectGantt's two unbounded queries per load — already recorded asplugin-ganttin the table on finding(ui): the schema-settled$expandgate is now four hand copies, and four more views resolve the schema without gating on it #6482, which is no longer open. Re-confirmed here rather than re-filed; worth reopening that card rather than duplicating it.Reverse verification
Direction and counts predicted before running: drop
surfaceDrawsFetchedRowsfrom the bar's render condition and exactly the two gantt cases go red while both controls stay green — 2 failed / 2 passed. Observed exactly that, then 4 passed after restore.Mutation proved on disk: removed-token count 2 to 1, mutated-line count 0 to 1, blob hash
4a1ce3c1to7f55c73b. Restore proved by state:git diff HEAD,git diff --cachedandgit status --shortall empty, and the blob hash back to4a1ce3c1, the HEAD blob.Verification (all at
f3d7b3cd3)pnpm exec vitest run packages/plugin-list/ packages/plugin-gantt/— 113 files passed, 1183 tests passed.pnpm --filter @object-ui/plugin-list run type-checkand the same for@object-ui/plugin-gantt— both exit 0, over a freshly built dependency closure. Both new test files proved present in thetsconfig.test.jsonprogram viatsc --listFiles(1 hit each), so "typecheck is clean" actually covers them.check:control-bytes,check:phantom-deps,check:self-import,check:vi-mock-specifiers,check:vi-mock-inherit,check:i18n-keys,check:i18n-dead-keys,check:element-data-source-declaration,check:side-effects-array,lint:coverage(46/46 packages, 0 errors), and all four changeset guards — every one exit 0.check:sdui-registration-pinsreturned exit 2, PRECONDITION NOT MET (noapps/consolebuild to weigh) — recorded as NOT MEASURED, not as a pass; this diff adds no registration and moves no entry array. Left to CI.--format json, file count read from that output, not guessed). The narrowing is a measurement rather than a skip becauseeslint.config.jsenables no type-aware linting (noproject/projectServicein itslanguageOptions), so no untouched file's verdict can move because of this diff, and the diff adds no config and no inline directive.Generated by Claude Code
Generated by Claude Code