added range
parent
7068f75008
commit
63d5232cac
|
|
@ -1,8 +1,9 @@
|
|||
/* ============================================================
|
||||
Recruitment Inbox — application tabs over GET /inbox/all-applications.
|
||||
Page size defaults to 10. skip/offset is the window start and is not
|
||||
recomputed when Per page changes: growing 10 to 30 on a window that
|
||||
started at row 11 requests skip=10, top=30 (rows 11–40). Clicking a
|
||||
Page size defaults to 10 (dropdown: 10 / 50 / 100). skip/offset is the
|
||||
window start and is not recomputed when Per page changes: growing 10 to
|
||||
50 on a window that started at row 11 requests skip=10, top=50
|
||||
(rows 11–60). Clicking a
|
||||
page number realigns skip = (page-1)*limit. Total comes from a count
|
||||
endpoint called once when the page opens.
|
||||
============================================================ */
|
||||
|
|
|
|||
|
|
@ -690,13 +690,9 @@ table.data tbody tr:last-child td { border-bottom: none; }
|
|||
.page-nums { display: flex; gap: 4px; align-items: center; min-width: 0; }
|
||||
.page-size { display: flex; align-items: center; gap: 8px; margin-right: 8px; flex-shrink: 0; }
|
||||
.page-size-label { font-size: 13px; color: var(--text-2); white-space: nowrap; }
|
||||
.page-size-select { height: 34px; padding: 0 28px 0 10px; font-size: 13px; }
|
||||
.page-size-input {
|
||||
width: 72px; height: 34px; padding: 0 8px; font-size: 13px; font-weight: 600;
|
||||
text-align: center; border-radius: 8px; border: 1px solid var(--border-strong);
|
||||
background: var(--bg-elev); color: inherit; outline: none;
|
||||
.page-size-select {
|
||||
height: 34px; min-width: 72px; padding: 0 28px 0 10px; font-size: 13px; font-weight: 600;
|
||||
}
|
||||
.page-size-input:focus { border-color: var(--primary); box-shadow: var(--ring); }
|
||||
.page-size-total { font-size: 13px; color: var(--text-2); margin-right: 8px; white-space: nowrap; }
|
||||
.page-btn { min-width: 34px; height: 34px; padding: 0 8px; border-radius: 8px; display: grid; place-items: center; font-size: 13px; font-weight: 600; color: var(--text-2); border: 1px solid transparent; }
|
||||
.page-btn:hover:not(:disabled) { background: var(--bg-sunken); }
|
||||
|
|
|
|||
|
|
@ -18,10 +18,17 @@ import { EmptyState } from './primitives'
|
|||
/** Matches the backend Query(10) default on list GET endpoints. */
|
||||
export const DEFAULT_PAGE_SIZE = 10
|
||||
|
||||
/** Fixed Per page choices — a dropdown, not a free-text box. */
|
||||
export const PAGE_SIZE_OPTIONS = [10, 50, 100]
|
||||
|
||||
export function clampPageSize(value, max = 100) {
|
||||
const allowed = PAGE_SIZE_OPTIONS.filter((n) => n <= max)
|
||||
const fallback = allowed.includes(DEFAULT_PAGE_SIZE)
|
||||
? DEFAULT_PAGE_SIZE
|
||||
: (allowed[0] ?? DEFAULT_PAGE_SIZE)
|
||||
const n = Number.parseInt(value, 10)
|
||||
if (!Number.isFinite(n) || n < 1) return DEFAULT_PAGE_SIZE
|
||||
return Math.min(n, max)
|
||||
if (!Number.isFinite(n) || !allowed.includes(n)) return fallback
|
||||
return n
|
||||
}
|
||||
|
||||
export function useDataTable({ columns, rows, pageSize = DEFAULT_PAGE_SIZE }) {
|
||||
|
|
@ -103,37 +110,25 @@ export function pageAfterSizeChange(currentPage, total, nextSize) {
|
|||
return Math.min(Math.max(1, currentPage || 1), pages)
|
||||
}
|
||||
|
||||
/** Local draft so typing "50" does not fire a GET for 5, then 50. */
|
||||
/** Per page dropdown: 10, 50, 100 (values above `max` are omitted). */
|
||||
export function PageSizeField({ value, onChange, max = 100, label = 'Per page', id }) {
|
||||
const [draft, setDraft] = useState(String(value ?? DEFAULT_PAGE_SIZE))
|
||||
useEffect(() => setDraft(String(value ?? DEFAULT_PAGE_SIZE)), [value])
|
||||
|
||||
function commit() {
|
||||
const next = clampPageSize(draft, max)
|
||||
setDraft(String(next))
|
||||
if (next !== value) onChange(next)
|
||||
}
|
||||
const options = PAGE_SIZE_OPTIONS.filter((n) => n <= max)
|
||||
const selected = clampPageSize(value, max)
|
||||
|
||||
return (
|
||||
<label className="page-size">
|
||||
<span className="page-size-label">{label}</span>
|
||||
<input
|
||||
<select
|
||||
id={id}
|
||||
className="page-size-input"
|
||||
type="number"
|
||||
min={1}
|
||||
max={max}
|
||||
value={draft}
|
||||
onChange={(e) => setDraft(e.target.value)}
|
||||
onBlur={commit}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
e.currentTarget.blur()
|
||||
}
|
||||
}}
|
||||
className="select page-size-select"
|
||||
value={selected}
|
||||
onChange={(e) => onChange(clampPageSize(e.target.value, max))}
|
||||
aria-label={label}
|
||||
/>
|
||||
>
|
||||
{options.map((n) => (
|
||||
<option key={n} value={n}>{n}</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue