pagination

This commit is contained in:
2026-04-03 19:58:56 +05:30
parent 9b87fb31a7
commit f8cea025a3
6 changed files with 62 additions and 9 deletions

View File

@@ -23,6 +23,7 @@ import {
GridColDef, GridColDef,
GridActionsCellItem, GridActionsCellItem,
GridRenderCellParams, GridRenderCellParams,
GridPaginationModel,
} from '@mui/x-data-grid'; } from '@mui/x-data-grid';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete'; import DeleteIcon from '@mui/icons-material/Delete';
@@ -34,6 +35,10 @@ import { ResourceConfig } from '../types/config';
interface EnhancedTableProps { interface EnhancedTableProps {
config: ResourceConfig; config: ResourceConfig;
data: any[]; data: any[];
total?: number;
paginationModel?: GridPaginationModel;
onPaginationModelChange?: (model: GridPaginationModel) => void;
loading?: boolean;
onEdit: (item: any) => void; onEdit: (item: any) => void;
onDelete: (id: string) => void; onDelete: (id: string) => void;
onCreate: () => void; onCreate: () => void;
@@ -43,6 +48,10 @@ interface EnhancedTableProps {
export default function EnhancedTable({ export default function EnhancedTable({
config, config,
data, data,
total,
paginationModel,
onPaginationModelChange,
loading = false,
onEdit, onEdit,
onDelete, onDelete,
onCreate, onCreate,
@@ -152,6 +161,23 @@ export default function EnhancedTable({
rows={data || []} rows={data || []}
columns={columns} columns={columns}
autoHeight autoHeight
paginationMode={config.pagination ? 'server' : 'client'}
rowCount={(() => {
if (!config.pagination) return data.length;
if (total !== undefined) return total;
// Graceful fallback for missing total count
const page = paginationModel?.page || 0;
const pageSize = paginationModel?.pageSize || 10;
if (data.length < pageSize) {
return page * pageSize + data.length;
}
// Enable 'Next' button by pretending there's at least one more page
return (page + 2) * pageSize;
})()}
loading={loading}
paginationModel={paginationModel || { page: 0, pageSize: 10 }}
onPaginationModelChange={onPaginationModelChange}
getRowId={(row) => { getRowId={(row) => {
const pk = config.primaryKey; const pk = config.primaryKey;
if (row[pk] !== undefined && row[pk] !== null) return row[pk]; if (row[pk] !== undefined && row[pk] !== null) return row[pk];
@@ -162,11 +188,6 @@ export default function EnhancedTable({
return `temp-id-${data.indexOf(row)}`; return `temp-id-${data.indexOf(row)}`;
}} }}
disableRowSelectionOnClick disableRowSelectionOnClick
initialState={{
pagination: {
paginationModel: { page: 0, pageSize: 10 },
},
}}
pageSizeOptions={[10, 25, 50]} pageSizeOptions={[10, 25, 50]}
sx={{ sx={{
border: 'none', border: 'none',

View File

@@ -11,6 +11,8 @@ interface ResourceViewProps {
onNavigateToResource?: (resourceName: string, id: string) => void; onNavigateToResource?: (resourceName: string, id: string) => void;
} }
import { GridPaginationModel } from '@mui/x-data-grid';
export default function ResourceView({ config, onNavigateToResource }: ResourceViewProps) { export default function ResourceView({ config, onNavigateToResource }: ResourceViewProps) {
const { id } = useParams(); const { id } = useParams();
const location = useLocation(); const location = useLocation();
@@ -21,11 +23,26 @@ export default function ResourceView({ config, onNavigateToResource }: ResourceV
const isView = !!id && !isEdit; const isView = !!id && !isEdit;
const isList = !id && !isCreate; const isList = !id && !isCreate;
const [paginationModel, setPaginationModel] = React.useState<GridPaginationModel>({
page: 0,
pageSize: 10,
});
const { useList, useRead, useCreate, useUpdate, useDelete } = useResource(config); const { useList, useRead, useCreate, useUpdate, useDelete } = useResource(config);
const listQuery = useList(); // Determine query parameters based on pagination config
const queryParams = React.useMemo(() => {
if (!config.pagination) return {};
return {
skip: paginationModel.page * paginationModel.pageSize,
limit: paginationModel.pageSize,
};
}, [config.pagination, paginationModel]);
const listQuery = useList(queryParams);
const itemQuery = useRead(id || ""); const itemQuery = useRead(id || "");
const paginatedData = listQuery.data || { data: [], total: undefined };
const createMutation = useCreate(); const createMutation = useCreate();
const updateMutation = useUpdate(); const updateMutation = useUpdate();
const deleteMutation = useDelete(); const deleteMutation = useDelete();
@@ -65,7 +82,11 @@ export default function ResourceView({ config, onNavigateToResource }: ResourceV
{isList ? ( {isList ? (
<EnhancedTable <EnhancedTable
config={config} config={config}
data={listQuery.data || []} data={paginatedData.data || []}
total={paginatedData.total}
paginationModel={paginationModel}
onPaginationModelChange={setPaginationModel}
loading={listQuery.isFetching}
onEdit={handleEdit} onEdit={handleEdit}
onDelete={handleDelete} onDelete={handleDelete}
onCreate={handleCreate} onCreate={handleCreate}

View File

@@ -38,6 +38,7 @@ export const configuration: Record<string, ResourceOverride> = {
display: false display: false
} }
}, },
pagination: true,
}, },
}; };

View File

@@ -13,7 +13,11 @@ export function useResource<T = any>(config: ResourceConfig) {
queryFn: async () => { queryFn: async () => {
// @ts-ignore // @ts-ignore
const res = await api.get<T[]>(endpoint, { params }); const res = await api.get<T[]>(endpoint, { params });
return res.data; const total = res.headers ? parseInt(res.headers['x-total-count'] || res.headers['X-Total-Count']) : undefined;
return {
data: res.data,
total: isNaN(total as any) ? undefined : total
};
} }
}); });
@@ -77,7 +81,11 @@ export function useResource<T = any>(config: ResourceConfig) {
queryFn: async () => { queryFn: async () => {
// @ts-ignore // @ts-ignore
const res = await api.get<T[]>(endpoint, { params }); const res = await api.get<T[]>(endpoint, { params });
return res.data; const total = res.headers ? parseInt(res.headers['x-total-count'] || res.headers['X-Total-Count']) : undefined;
return {
data: res.data,
total: isNaN(total as any) ? undefined : total
};
}, },
}); });

View File

@@ -29,6 +29,7 @@ export interface ResourceConfig {
endpoint: string; endpoint: string;
primaryKey: string; primaryKey: string;
fields: Record<string, ResourceField>; fields: Record<string, ResourceField>;
pagination?: boolean;
} }
export interface AppConfig { export interface AppConfig {

View File

@@ -11,4 +11,5 @@ export interface FieldOverride {
export interface ResourceOverride { export interface ResourceOverride {
fields?: Record<string, FieldOverride>; fields?: Record<string, FieldOverride>;
pagination?: boolean;
} }