feat: replace page buttons with a Rows selector on record views
Instead of Previous/Next paging, a Rows selector (5-100) sets how many records the server returns, and the pager shows "Showing X of Y records". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
bd141e3585
commit
086c397f78
@ -2,7 +2,6 @@ import { useEffect, useState } from 'react'
|
||||
import {
|
||||
AssetStateBadge,
|
||||
Avatar,
|
||||
Button,
|
||||
EmployeeStatusBadge,
|
||||
EmptyState,
|
||||
HistoryActionBadge,
|
||||
@ -17,11 +16,16 @@ import { FileLinks, imageSources } from './FieldValue'
|
||||
/**
|
||||
* Renders a record view straight from the backend response: the columns are
|
||||
* whatever `config.fields` returns, in that order, with the backend's own
|
||||
* labels. Paging, sorting and search are handled by the server.
|
||||
* labels. Sorting and search are handled by the server; instead of page
|
||||
* buttons, a "Rows" selector sets how many records the server returns
|
||||
* (search_query.limit), so picking 5 shows 5 rows and picking 100 shows 100.
|
||||
* `toolbar` adds controls (e.g. a filter) next to the search box. A field with
|
||||
* `sortable: false` can't be sorted. A rich column (see api/richColumns.js)
|
||||
* shows several fields in one cell and sorts by its `sort_key`.
|
||||
*/
|
||||
/** How many rows the "Rows" selector can ask the server for. */
|
||||
const ROW_OPTIONS = [5, 10, 25, 50, 100]
|
||||
|
||||
export default function RecordView({
|
||||
fields,
|
||||
rows,
|
||||
@ -29,7 +33,7 @@ export default function RecordView({
|
||||
loading,
|
||||
error,
|
||||
query,
|
||||
setPage,
|
||||
setLimit,
|
||||
setSearch,
|
||||
setSort,
|
||||
rowKey = 'instance_id',
|
||||
@ -61,8 +65,6 @@ export default function RecordView({
|
||||
setSort(sortKey(field), dir)
|
||||
}
|
||||
|
||||
const page = pagination?.page ?? 1
|
||||
const totalPages = pagination?.total_pages ?? 1
|
||||
const total = pagination?.total_count ?? rows.length
|
||||
|
||||
return (
|
||||
@ -143,26 +145,26 @@ export default function RecordView({
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{totalPages > 1 && (
|
||||
{total > 0 && (
|
||||
<div className="pager">
|
||||
<Button
|
||||
size="sm"
|
||||
icon="chevronLeft"
|
||||
disabled={page <= 1 || loading}
|
||||
onClick={() => setPage(page - 1)}
|
||||
<label className="pager__label">
|
||||
Rows{' '}
|
||||
<select
|
||||
className="pager__select"
|
||||
value={query.limit}
|
||||
disabled={loading}
|
||||
onChange={(e) => setLimit(Number(e.target.value))}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
{ROW_OPTIONS.map((n) => (
|
||||
<option key={n} value={n}>
|
||||
{n}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<span className="pager__label">
|
||||
Page {page} of {totalPages}
|
||||
Showing {Math.min(rows.length, total)} of {total} records
|
||||
</span>
|
||||
<Button
|
||||
size="sm"
|
||||
disabled={page >= totalPages || loading}
|
||||
onClick={() => setPage(page + 1)}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
@ -71,6 +71,7 @@ export default function useRecordView(
|
||||
error,
|
||||
query,
|
||||
setPage: (page) => setQuery((q) => ({ ...q, page })),
|
||||
setLimit: (limit) => setQuery((q) => ({ ...q, limit, page: 1 })),
|
||||
setSearch: (search) => setQuery((q) => ({ ...q, search, page: 1 })),
|
||||
setSort: (sortBy, sortDir) => setQuery((q) => ({ ...q, sortBy, sortDir, page: 1 })),
|
||||
setFilter: (filter) => setQuery((q) => ({ ...q, filter, page: 1 })),
|
||||
|
||||
@ -1197,6 +1197,17 @@ button {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.pager__select {
|
||||
margin-left: 4px;
|
||||
padding: 4px 8px;
|
||||
font-size: 12.5px;
|
||||
color: var(--text);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cell-clamp {
|
||||
max-width: 220px;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user