The header used to show '200+' once the user had loaded a partial set
of pages — opaque, useless for an operator who actually needs to know
'how many accounts are in the system right now'.
Server (app/cm_api.py):
- /acc/ and /user/ list responses now wrap the rows alongside a
COUNT(*) of the table: { rows: [...], total: N }. The single-row
/acc/<username> path is unchanged (still returns Acc[] with one row).
- Each list request issues both queries (the page SELECT and the COUNT)
on the same pooled connection. COUNT(*) on a 3k-row table is sub-ms;
even when the cache misses, total request latency stays well under
20ms on warm-cache MySQL.
Web client:
- web/lib/api.ts: Page<T> gains a field; getAccountsPage and
getUsersPage parse the new wrapped response.
- web/app/page.tsx + users/page.tsx: pass page.total down as
initialTotal.
- web/components/{accounts,users}-table.tsx: hold total in state, sync
it from every page fetch (initial, loadMore, sort change, force
refresh) so cm99 monitor inserts during the session bump it correctly.
Delete decrements it by 1 immediately so the header doesn't lie
between the optimistic delete and the next refresh.
- PageHead now shows '<total>' as the big number. When loaded < total,
a small zinc-400 line below reads 'Showing X of N — keep scrolling
to load more'. Once the user reaches the end, the line goes away.
No new round trips for the count: it piggybacks on the same /acc/?...
or /user/?... request that already fetches the page. The 30s cache
covers the count too — so tab switches still don't hit MySQL.
17 lines
480 B
TypeScript
17 lines
480 B
TypeScript
import { getAccountsPage } from "@/lib/api";
|
|
import AccountsTable from "@/components/accounts-table";
|
|
|
|
const PREFIX_PATTERN = process.env.NEXT_PUBLIC_CM_PREFIX_PATTERN ?? "13c";
|
|
|
|
export default async function AccountsPage() {
|
|
const page = await getAccountsPage({ prefix: PREFIX_PATTERN, dir: "desc" });
|
|
return (
|
|
<AccountsTable
|
|
initial={page.rows}
|
|
initialHasMore={page.hasMore}
|
|
initialTotal={page.total}
|
|
prefixPattern={PREFIX_PATTERN}
|
|
/>
|
|
);
|
|
}
|