lablup / lablup/backend.ai-webui

BAITable reverts every page-size change on controlled tables

Open Beginner friendly
#9,607 1 comment 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.