|
- // material-ui
- import * as React from 'react';
- import {
- DataGrid,
- GridActionsCellItem,
- GridRowModes,
- GridRowEditStopReasons,
- } from "@mui/x-data-grid";
- import EditIcon from '@mui/icons-material/Edit';
- import DeleteIcon from '@mui/icons-material/Delete';
- import SaveIcon from '@mui/icons-material/Save';
- import CancelIcon from '@mui/icons-material/Cancel';
- import {useContext, useEffect} from "react";
- import {CustomNoRowsOverlay, dateComparator, getDateString} from "../../../utils/CommonFunction";
- import AbilityContext from "../../../components/AbilityProvider";
- import {LIONER_BUTTON_THEME} from "../../../themes/colorConst";
- import {ThemeProvider} from "@emotion/react";
- import axios from "axios"; // Add this
- import {apiPath} from "../../../auth/utils"; // Add this (same as in index.js)
-
- // ==============================|| Consultant TABLE ||============================== //
-
- export default function ConsultantTable({recordList, applySearch}) {
- const [rows, setRows] = React.useState([]);
- const [rowModesModel, setRowModesModel] = React.useState({});
-
- const ability = useContext(AbilityContext);
-
- const [paginationModel, setPaginationModel] = React.useState({
- page: 0,
- pageSize: 10
- });
-
- useEffect(() => {
- setPaginationModel({page: 0, pageSize: 10});
- // Ensure each row has a unique 'id' field (required by DataGrid)
- setRows(recordList.map(row => ({ ...row, id: row.id || row.someUniqueKey })));
- }, [recordList]);
-
- const handleRowEditStop = (params, event) => {
- if (params.reason === GridRowEditStopReasons.rowFocusOut) {
- event.defaultMuiPrevented = true;
- }
- };
-
- const handleEditClick = (id) => () => {
- setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } });
- };
-
- const handleSaveClick = (id) => () => {
- setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
- };
-
- const handleCancelClick = (id) => () => {
- setRowModesModel({
- ...rowModesModel,
- [id]: { mode: GridRowModes.View, ignoreModifications: true },
- });
- };
-
- const handleDeleteClick = (id) => async () => {
- if (window.confirm("Are you sure you want to delete this consultant? This action cannot be undone.")) {
- try {
- const response = await axios.post(`${apiPath}/consultant/delete`, { id });
-
- if (response.status === 200 || response.status === 204) {
- applySearch(); // Refresh the table
- }
- } catch (err) {
- console.error("Delete error:", err);
- alert("Failed to delete consultant. Please try again.");
- }
- }
- };
-
- const processRowUpdate = async (newRow) => {
- // Optimistically update UI
- const updatedRow = { ...newRow };
-
- try {
- const response = await axios.post(`${apiPath}/consultant/save`, newRow);
- if (response.status === 200) {
- // If backend returns updated data, use it
- return response.data || updatedRow;
- }
- } catch (err) {
- console.error("Save error:", err);
- alert("Failed to save changes. Please try again.");
- // On failure, you could revert, but here we keep the edited value
- }
-
- return updatedRow;
- };
-
- const columns = [
- {
- field: 'actions',
- type: 'actions',
- headerName: 'Actions',
- width: 150,
- getActions: ({ id }) => {
- const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
-
- if (isInEditMode) {
- return [
- <ThemeProvider key="save" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- icon={<SaveIcon />}
- label="Save"
- onClick={handleSaveClick(id)}
- color="save"
- />
- </ThemeProvider>,
- <ThemeProvider key="cancel" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- icon={<CancelIcon />}
- label="Cancel"
- onClick={handleCancelClick(id)}
- color="cancel"
- />
- </ThemeProvider>,
- ];
- }
-
- return [
- <ThemeProvider key="edit" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- icon={<EditIcon sx={{fontSize: 25}}/>}
- label="Edit"
- onClick={handleEditClick(id)}
- color="edit"
- />
- </ThemeProvider>,
- <ThemeProvider key="delete" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- icon={<DeleteIcon />}
- label="Delete"
- onClick={handleDeleteClick(id)}
- color="error" // Use "error" if no 'delete' color defined
- />
- </ThemeProvider>,
- ];
- },
- },
- {
- field: 'name',
- headerName: 'Name',
- flex: 2,
- editable: true, // Enables inline editing
- renderCell: (params) => (
- <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', whiteSpace: 'normal', wordBreak: 'break-word'}}>
- {params.value}
- </div>
- ),
- },
- {
- field: 'createDate',
- headerName: 'Create Datetime',
- flex: 1,
- sortComparator: dateComparator,
- renderCell: (params) => (
- <div>
- {getDateString(params.row.created, 'dd/MM/yyyy HH:mm:ss')}
- </div>
- ),
- },
- ];
-
- return (
- <div style={{ width: '100%' }}>
- <DataGrid
- rows={rows}
- columns={columns}
- editMode="row"
- rowModesModel={rowModesModel}
- onRowModesModelChange={setRowModesModel}
- onRowEditStop={handleRowEditStop}
- processRowUpdate={processRowUpdate}
- onProcessRowUpdateError={(error) => console.error(error)}
- getRowHeight={() => 'auto'}
- paginationModel={paginationModel}
- onPaginationModelChange={setPaginationModel}
- slots={{ noRowsOverlay: CustomNoRowsOverlay }}
- pageSizeOptions={[10]}
- autoHeight
- />
- </div>
- );
- }
|