support server side table for admin users table

This commit is contained in:
miloschwartz
2026-04-20 22:05:29 -07:00
parent 6f06f98cc1
commit 85f7c1e87b
5 changed files with 464 additions and 461 deletions

View File

@@ -1,33 +1,70 @@
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
import { AxiosResponse } from "axios";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { AdminListUsersResponse } from "@server/routers/user/adminListUsers";
import type { AdminListUsersResponse } from "@server/routers/user/adminListUsers";
import type { ListIdpsResponse } from "@server/routers/idp/listIdps";
import UsersTable, { GlobalUserRow } from "@app/components/AdminUsersTable";
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { InfoIcon } from "lucide-react";
import { getTranslations } from "next-intl/server";
type PageProps = {
params: Promise<{ orgId: string }>;
/** API JSON body shape for `response<T>()` handlers (see `server/lib/response.ts`). */
type ApiPayload<T> = {
data: T;
success: boolean;
error: boolean;
message: string;
status: number;
};
type AdminUsersPageProps = {
searchParams: Promise<Record<string, string>>;
};
export const dynamic = "force-dynamic";
export default async function UsersPage(props: PageProps) {
export default async function UsersPage(props: AdminUsersPageProps) {
const searchParams = new URLSearchParams(await props.searchParams);
const cookieHeader = await authCookieHeader();
let rows: AdminListUsersResponse["users"] = [];
try {
const res = await internal.get<AxiosResponse<AdminListUsersResponse>>(
`/users`,
await authCookieHeader()
);
rows = res.data.data.users;
} catch (e) {
console.error(e);
let pagination: AdminListUsersResponse["pagination"] = {
total: 0,
page: 1,
pageSize: 20
};
const [usersRes, idpsRes] = await Promise.all([
internal
.get<
ApiPayload<AdminListUsersResponse>
>(`/users?${searchParams.toString()}`, cookieHeader)
.catch(() => {}),
internal
.get<
ApiPayload<ListIdpsResponse>
>(`/idp?limit=500&offset=0`, cookieHeader)
.catch(() => {})
]);
if (usersRes && usersRes.status === 200) {
const list = usersRes.data.data;
rows = list.users;
pagination = list.pagination;
}
const t = await getTranslations();
const globalIdps =
idpsRes && idpsRes.status === 200 ? (idpsRes.data.data.idps ?? []) : [];
const idpFilterOptions = [
{ value: "internal", label: t("idpNameInternal") },
...globalIdps.map((i: ListIdpsResponse["idps"][number]) => ({
value: String(i.idpId),
label: i.name
}))
];
const userRows: GlobalUserRow[] = rows.map((row) => {
return {
id: row.id,
@@ -59,7 +96,15 @@ export default async function UsersPage(props: PageProps) {
{t("userAbountDescription")}
</AlertDescription>
</Alert>
<UsersTable users={userRows} />
<UsersTable
users={userRows}
rowCount={pagination.total}
pagination={{
pageIndex: pagination.page - 1,
pageSize: pagination.pageSize
}}
idpFilterOptions={idpFilterOptions}
/>
</>
);
}