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 {
|
import {
|
||||||
AssetStateBadge,
|
AssetStateBadge,
|
||||||
Avatar,
|
Avatar,
|
||||||
Button,
|
|
||||||
EmployeeStatusBadge,
|
EmployeeStatusBadge,
|
||||||
EmptyState,
|
EmptyState,
|
||||||
HistoryActionBadge,
|
HistoryActionBadge,
|
||||||
@ -17,11 +16,16 @@ import { FileLinks, imageSources } from './FieldValue'
|
|||||||
/**
|
/**
|
||||||
* Renders a record view straight from the backend response: the columns are
|
* Renders a record view straight from the backend response: the columns are
|
||||||
* whatever `config.fields` returns, in that order, with the backend's own
|
* 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
|
* `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)
|
* `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`.
|
* 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({
|
export default function RecordView({
|
||||||
fields,
|
fields,
|
||||||
rows,
|
rows,
|
||||||
@ -29,7 +33,7 @@ export default function RecordView({
|
|||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
query,
|
query,
|
||||||
setPage,
|
setLimit,
|
||||||
setSearch,
|
setSearch,
|
||||||
setSort,
|
setSort,
|
||||||
rowKey = 'instance_id',
|
rowKey = 'instance_id',
|
||||||
@ -61,8 +65,6 @@ export default function RecordView({
|
|||||||
setSort(sortKey(field), dir)
|
setSort(sortKey(field), dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = pagination?.page ?? 1
|
|
||||||
const totalPages = pagination?.total_pages ?? 1
|
|
||||||
const total = pagination?.total_count ?? rows.length
|
const total = pagination?.total_count ?? rows.length
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -143,26 +145,26 @@ export default function RecordView({
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{totalPages > 1 && (
|
{total > 0 && (
|
||||||
<div className="pager">
|
<div className="pager">
|
||||||
<Button
|
<label className="pager__label">
|
||||||
size="sm"
|
Rows{' '}
|
||||||
icon="chevronLeft"
|
<select
|
||||||
disabled={page <= 1 || loading}
|
className="pager__select"
|
||||||
onClick={() => setPage(page - 1)}
|
value={query.limit}
|
||||||
|
disabled={loading}
|
||||||
|
onChange={(e) => setLimit(Number(e.target.value))}
|
||||||
>
|
>
|
||||||
Previous
|
{ROW_OPTIONS.map((n) => (
|
||||||
</Button>
|
<option key={n} value={n}>
|
||||||
|
{n}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
<span className="pager__label">
|
<span className="pager__label">
|
||||||
Page {page} of {totalPages}
|
Showing {Math.min(rows.length, total)} of {total} records
|
||||||
</span>
|
</span>
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
disabled={page >= totalPages || loading}
|
|
||||||
onClick={() => setPage(page + 1)}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -71,6 +71,7 @@ export default function useRecordView(
|
|||||||
error,
|
error,
|
||||||
query,
|
query,
|
||||||
setPage: (page) => setQuery((q) => ({ ...q, page })),
|
setPage: (page) => setQuery((q) => ({ ...q, page })),
|
||||||
|
setLimit: (limit) => setQuery((q) => ({ ...q, limit, page: 1 })),
|
||||||
setSearch: (search) => setQuery((q) => ({ ...q, search, page: 1 })),
|
setSearch: (search) => setQuery((q) => ({ ...q, search, page: 1 })),
|
||||||
setSort: (sortBy, sortDir) => setQuery((q) => ({ ...q, sortBy, sortDir, page: 1 })),
|
setSort: (sortBy, sortDir) => setQuery((q) => ({ ...q, sortBy, sortDir, page: 1 })),
|
||||||
setFilter: (filter) => setQuery((q) => ({ ...q, filter, page: 1 })),
|
setFilter: (filter) => setQuery((q) => ({ ...q, filter, page: 1 })),
|
||||||
|
|||||||
@ -1197,6 +1197,17 @@ button {
|
|||||||
color: var(--text-muted);
|
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 {
|
.cell-clamp {
|
||||||
max-width: 220px;
|
max-width: 220px;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user