135 lines
4.2 KiB
TypeScript
135 lines
4.2 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState, useCallback, useMemo } from "react";
|
|
import { DataGrid, GridPaginationModel } from "@mui/x-data-grid";
|
|
import { Box, Paper, Alert } from "@mui/material";
|
|
import DataTableHeader from "./DataTableHeader";
|
|
import StatusChangeDialog from "./StatusChangeDialog";
|
|
import Spinner from "@/app/components/Spinner/Spinner";
|
|
import {
|
|
selectStatus,
|
|
selectError,
|
|
selectPagination,
|
|
selectPaginationModel,
|
|
} from "@/app/redux/advanedSearch/selectors";
|
|
import { makeSelectEnhancedColumns } from "./re-selectors";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { DataRowBase } from "./types";
|
|
import { setPagination } from "@/app/redux/advanedSearch/advancedSearchSlice";
|
|
import { AppDispatch } from "@/app/redux/store";
|
|
|
|
interface DataTableProps<TRow extends DataRowBase> {
|
|
rows: TRow[];
|
|
extraColumns?: string[];
|
|
enableStatusActions?: boolean;
|
|
totalRows?: number;
|
|
}
|
|
|
|
const DataTable = <TRow extends DataRowBase>({
|
|
rows: localRows,
|
|
extraColumns,
|
|
enableStatusActions = false,
|
|
totalRows: totalRows,
|
|
}: DataTableProps<TRow>) => {
|
|
const dispatch = useDispatch<AppDispatch>();
|
|
const [showExtraColumns, setShowExtraColumns] = useState(false);
|
|
const [statusDialogData, setStatusDialogData] = useState<{
|
|
rowId: number;
|
|
newStatus: string;
|
|
} | null>(null);
|
|
|
|
const status = useSelector(selectStatus);
|
|
const errorMessage = useSelector(selectError);
|
|
const pagination = useSelector(selectPagination);
|
|
const paginationModel = useSelector(selectPaginationModel);
|
|
|
|
const handlePaginationModelChange = useCallback(
|
|
(model: GridPaginationModel) => {
|
|
const nextPage = model.page + 1;
|
|
const nextLimit = model.pageSize;
|
|
|
|
if (nextPage !== pagination.page || nextLimit !== pagination.limit) {
|
|
dispatch(setPagination({ page: nextPage, limit: nextLimit }));
|
|
}
|
|
},
|
|
[dispatch, pagination.page, pagination.limit]
|
|
);
|
|
|
|
const handleStatusChange = useCallback((rowId: number, newStatus: string) => {
|
|
setStatusDialogData({ rowId, newStatus });
|
|
}, []);
|
|
|
|
const handleDialogClose = useCallback(() => {
|
|
setStatusDialogData(null);
|
|
}, []);
|
|
|
|
const selectEnhancedColumns = useMemo(makeSelectEnhancedColumns, []);
|
|
|
|
const enhancedColumns = useSelector(state =>
|
|
selectEnhancedColumns(state, {
|
|
enableStatusActions,
|
|
extraColumns,
|
|
showExtraColumns,
|
|
localRows,
|
|
handleStatusChange,
|
|
})
|
|
);
|
|
return (
|
|
<>
|
|
{status === "loading" && <Spinner size="small" color="#fff" />}
|
|
{status === "failed" && (
|
|
<Alert severity="error">
|
|
{errorMessage || "Failed to load transactions."}
|
|
</Alert>
|
|
)}
|
|
<Paper sx={{ width: "100%", overflowX: "hidden" }}>
|
|
<DataTableHeader
|
|
extraColumns={extraColumns}
|
|
showExtraColumns={showExtraColumns}
|
|
onToggleExtraColumns={() => setShowExtraColumns(prev => !prev)}
|
|
onOpenExport={() => {}}
|
|
/>
|
|
|
|
<Box sx={{ width: "85vw" }}>
|
|
<Box sx={{ minWidth: 1200 }}>
|
|
<DataGrid
|
|
rows={localRows}
|
|
columns={enhancedColumns}
|
|
paginationModel={paginationModel}
|
|
onPaginationModelChange={handlePaginationModelChange}
|
|
paginationMode={totalRows ? "server" : "client"}
|
|
rowCount={totalRows}
|
|
pageSizeOptions={[10, 25, 50, 100]}
|
|
sx={{
|
|
border: 0,
|
|
cursor: "pointer",
|
|
"& .MuiDataGrid-cell": {
|
|
py: 1,
|
|
textAlign: "center",
|
|
justifyContent: "center",
|
|
display: "flex",
|
|
alignItems: "center",
|
|
},
|
|
"& .MuiDataGrid-columnHeader": {
|
|
textAlign: "center",
|
|
justifyContent: "center",
|
|
},
|
|
}}
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
|
|
<StatusChangeDialog
|
|
open={Boolean(statusDialogData)}
|
|
transactionId={statusDialogData?.rowId}
|
|
newStatus={statusDialogData?.newStatus ?? ""}
|
|
onClose={handleDialogClose}
|
|
/>
|
|
</Paper>
|
|
</>
|
|
);
|
|
};
|
|
|
|
// Memoize to avoid unnecessary re-renders
|
|
export default React.memo(DataTable);
|