lablup / lablup/backend.ai-webui
BAITable reverts every page-size change on controlled tables
- Dominant language
- TypeScript
- Stars
- 133
- Forks
- 81
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 355
Description
## Summary
In `backend.ai-ui` 26.9, a controlled `BAITable` ignores every page-size change: picking 20 in the page-size selector is immediately reverted to the previous size. Verified on `26.9.0-canary-f4dbc95e6-20260911`; the same code is on `main` at `8b550d5b6`.
## Cause
Astryx's `Pagination` handles a page-size pick in one event:
```js
// @astryxdesign/core 0.5.4, Pagination.js
const handlePageSizeChange = value => {
onPageSizeChange?.(Number(value));
handlePageChange(1); // → onChange(1)
};
```
`BAITable` (`packages/backend.ai-ui/src/components/Table/BAITable.tsx`, lines 1362–1370 on `main`) forwards both callbacks to the consumer:
```tsx
onChange={(page) => {
setCurrentPage(page);
pagination?.onChange?.(page, currentPageSize); // render-time size
}}
onPageSizeChange={(pageSize) => {
setCurrentPage(1);
setCurrentPageSize(pageSize);
pagination?.onChange?.(1, pageSize);
}}
```
The second call reads `currentPageSize` from the render that is still on screen, so the consumer receives `onChange(1, 20)` and then `onChange(1, 10)`. The last call wins. Uncontrolled tables survive, because only `setCurrentPageSize` matters there. Any table that passes `pagination.pageSize` and stores the size from `onChange` reverts.
## Reproduce
```tsx
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
{ setPage(p); setPageSize(s); } }}
/>
```
Pick 20 in the page-size selector. The table stays at 10 rows.
## Suggested fix
Don't let the follow-up `onChange(1)` carry the stale size. For example, remember the newly picked size in a ref inside `onPageSizeChange` and use it in `onChange` until the next render. Or stop forwarding from `onPageSizeChange` and let `onChange` send `(1, newSize)`.
## Also observed (lower priority)
- **Pagination total at narrow widths.** At a ~768px viewport, the total text (`BAIPaginationInfoText`, e.g. `전체 1102개 중 1 - 10`) shrinks to about 20px and wraps one character per line. It's an Astryx `Text` span with `flex: 0 1 auto` in a horizontal stack; `white-space: nowrap` or `flex-shrink: 0` on it would keep it on one line.
- **English screen-reader labels under a non-English locale.** These come from Astryx's own catalog and stay English with `ko`: `Sort by createdAt, sorted descending`, `Resize column owner,email`, `Items per page`, `Select all rows`, `Go to page 2`, and the `Go to next page` tooltip. Row checkboxes default to `Select `, which is a Relay global ID for most tables, unless `rowSelection.getRowLabel` is set. The expand button keeps the label `행 펼치기` while expanded and has no `aria-expanded`.
Found while adopting the 26.9 canary in Backend.AI FastTrack, which carries a workaround for the page-size bug in its table wrapper until this is fixed.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in packages/backend.ai-ui/src/components/Table/BAITable.tsx, around lines 1362–1370, and reproduce the controlled-table example with page size 10. Trace both pagination callbacks and verify that choosing 20 leaves the table at 20 rows and does not send a later stale-size update to the consumer; the lower-priority layout and accessibility observations are separate concerns.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100