Skip to content

Commit 4c898f2

Browse files
authored
Merge pull request #871 from objectstack-ai/copilot/fix-empty-rows-in-list-view
2 parents 0c48758 + 8f7144e commit 4c898f2

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

ROADMAP.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,14 @@ The `FlowDesigner` is a canvas-based flow editor that bridges the gap between th
10311031

10321032
**Tests:** Added integration test in `ListViewGroupingPropagation.test.tsx` that verifies toggling a group field via the toolbar immediately updates the rendered schema. All 117 ListView tests pass.
10331033

1034+
### ListView Grouping Mode Empty Rows (February 2026)
1035+
1036+
**Root Cause:** When grouping is enabled in list view, `buildGroupTableSchema` in `ObjectGrid.tsx` sets `pagination: false` but inherits `pageSize: 10` from the parent schema. The `DataTableRenderer` filler row logic (`Array.from({ length: Math.max(0, pageSize - paginatedData.length) })`) pads each group table with empty rows up to `pageSize`, creating many blank lines.
1037+
1038+
**Fix:** Added `pagination &&` condition to filler row rendering in `data-table.tsx`. Filler rows only render when pagination is enabled, since their purpose is maintaining consistent page height during paginated views.
1039+
1040+
**Tests:** Added 2 tests in `data-table-airtable-ux.test.tsx` verifying filler rows are skipped when pagination is off and still rendered when pagination is on. All 59 related tests pass.
1041+
10341042
---
10351043

10361044
## ⚠️ Risk Management

packages/components/src/renderers/complex/__tests__/data-table-airtable-ux.test.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,55 @@ describe('Row group hover class', () => {
185185
expect(aliceRow).toHaveClass('group/row');
186186
});
187187
});
188+
189+
// =========================================================================
190+
// 5. Filler rows behavior
191+
// =========================================================================
192+
describe('Filler rows', () => {
193+
it('should not render filler rows when pagination is disabled', async () => {
194+
// pagination: false with pageSize: 10 and only 2 data rows
195+
// should NOT produce empty filler rows
196+
render(
197+
<SchemaRenderer
198+
schema={{ ...baseSchema, pagination: false, pageSize: 10 }}
199+
/>
200+
);
201+
202+
await waitFor(() => {
203+
expect(screen.getByText('Alice')).toBeInTheDocument();
204+
});
205+
206+
const table = screen.getByRole('table');
207+
const tbody = table.querySelector('tbody');
208+
const allRows = tbody!.querySelectorAll('tr');
209+
210+
// Should only have data rows (2) + add-record row if any, no filler rows
211+
// With 2 data items and no add-record, expect exactly 2 rows
212+
const fillerRows = Array.from(allRows).filter(
213+
(row) => row.querySelector('td[class*="p-0"]') && row.textContent === ''
214+
);
215+
expect(fillerRows).toHaveLength(0);
216+
});
217+
218+
it('should render filler rows when pagination is enabled and page is not full', async () => {
219+
render(
220+
<SchemaRenderer
221+
schema={{ ...baseSchema, pagination: true, pageSize: 5, searchable: false }}
222+
/>
223+
);
224+
225+
await waitFor(() => {
226+
expect(screen.getByText('Alice')).toBeInTheDocument();
227+
});
228+
229+
const table = screen.getByRole('table');
230+
const tbody = table.querySelector('tbody');
231+
const allRows = tbody!.querySelectorAll('tr');
232+
233+
// With 2 data rows and pageSize 5, expect 3 filler rows (5 - 2 = 3)
234+
const fillerRows = Array.from(allRows).filter(
235+
(row) => row.querySelector('td[class*="p-0"]') && row.textContent === ''
236+
);
237+
expect(fillerRows).toHaveLength(3);
238+
});
239+
});

packages/components/src/renderers/complex/data-table.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,8 +920,8 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
920920
</TableCell>
921921
</TableRow>
922922
)}
923-
{/* Filler rows to maintain height consistency */}
924-
{paginatedData.length > 0 && Array.from({ length: Math.max(0, pageSize - paginatedData.length) }).map((_, i) => (
923+
{/* Filler rows to maintain height consistency (only when pagination is enabled) */}
924+
{pagination && paginatedData.length > 0 && Array.from({ length: Math.max(0, pageSize - paginatedData.length) }).map((_, i) => (
925925
<TableRow key={`empty-${i}`} className="hover:bg-transparent">
926926
<TableCell colSpan={columns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0)} className="h-[52px] p-0" />
927927
</TableRow>

0 commit comments

Comments
 (0)