Skip to content

Commit ab46110

Browse files
baozhoutaoclaude
andauthored
fix(list): show real match total in record-count bar under server pagination (#2873)
The record-count status bar read `data.length`, which under server-side pagination (#2212) is only the current page window — so a 158-row result paginated 100/page showed "100 条记录" / "58 条记录" instead of the true total, and nothing else surfaced the count. It now shows `serverTotal` when known, falling back to `data.length` for in-memory (non-paginated / grouped / non-grid) views, which are unchanged. Browser-verified against the showcase contacts list (158 rows); grouped and flat views both behave correctly, with a regression test on the ListView → grid server-pagination contract. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0502a7c commit ab46110

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
"@object-ui/plugin-list": patch
3+
---
4+
5+
fix(list): show the real match total in the record-count status bar under server pagination
6+
7+
The Airtable-style record-count bar read `data.length`, but under server-side
8+
pagination (#2212) `data` is only the current page window — so a 158-row result
9+
paginated 100/page reported "100 条记录" on page 1 and "58 条记录" on page 2,
10+
never the true total. There was no other place to see how many records the
11+
query matched.
12+
13+
The bar now shows the server's grand total (`serverTotal`) when known, falling
14+
back to `data.length` when the whole result set is in memory (non-paginated,
15+
grouped and non-grid views are unchanged — `serverTotal` is null there, so the
16+
count is identical to before). Browser-verified against the showcase contacts
17+
list: the bar reads "158 条记录" and stays stable across pages, and switching to
18+
grouped/other views correctly resets to the loaded count.

packages/plugin-list/src/ListView.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2536,7 +2536,16 @@ export const ListView = React.forwardRef<ListViewHandle, ListViewProps>(({
25362536
data-testid="record-count-bar"
25372537
>
25382538
<span className="font-medium text-foreground/80">
2539-
{data.length === 1 ? t('list.recordCountOne', { count: data.length }) : t('list.recordCount', { count: data.length })}
2539+
{/* Under server pagination `data` is only the current page, so the
2540+
honest record count is the server's grand total (#586). When the
2541+
whole result set is in memory, serverTotal is null and data.length
2542+
already IS the total. */}
2543+
{(() => {
2544+
const totalCount = serverTotal ?? data.length;
2545+
return totalCount === 1
2546+
? t('list.recordCountOne', { count: totalCount })
2547+
: t('list.recordCount', { count: totalCount });
2548+
})()}
25402549
</span>
25412550
{dataLimitReached && (
25422551
<span className="text-amber-600" data-testid="data-limit-warning">

packages/plugin-list/src/__tests__/ListView.serverPagination.test.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ describe('ListView — server-side pagination drives the child grid (#2212)', ()
124124
expect(lastGridProps.data.length).toBe(PAGE_SIZE);
125125
});
126126

127+
it('shows the real match total in the record-count bar, not the current window length (#586)', async () => {
128+
const ds = makeDataSource();
129+
const { findByTestId } = renderList(ds);
130+
// Wait until server pagination has engaged (the window is the first batch).
131+
await waitFor(() => expect(lastGridProps?.rowCount).toBe(TOTAL));
132+
const bar = await findByTestId('record-count-bar');
133+
// The bar must report the grand total (3125), NOT the page window (50) that
134+
// `data.length` would give under server pagination.
135+
expect(bar.textContent).toContain(String(TOTAL));
136+
expect(bar.textContent).not.toContain(String(PAGE_SIZE));
137+
});
138+
127139
it('REFETCHES with $skip when the grid turns the page (reaches records past batch 1)', async () => {
128140
const ds = makeDataSource();
129141
renderList(ds);

0 commit comments

Comments
 (0)