|
- // material-ui
- import * as React from 'react';
- import {
- Button,
- } from '@mui/material';
- import {
- DataGrid,
- GridActionsCellItem,
- GridRowEditStopReasons,
- GridRowModes,
- GridToolbarContainer
- } from "@mui/x-data-grid";
- import EditIcon from '@mui/icons-material/Edit';
- import DeleteIcon from '@mui/icons-material/DeleteOutlined';
- import SaveIcon from '@mui/icons-material/Save';
- import CancelIcon from '@mui/icons-material/Close';
- import AddIcon from '@mui/icons-material/Add';
- import {useContext, useEffect} from "react";
- import axios from "axios";
- import {apiPath} from "../../auth/utils";
- import {
- CHECK_CATEGORY_DUPLICATE,
- GET_CATEGORY_LIST,
- UPDATE_CATEGORY_PATH,
- } from "../../utils/ApiPathConst";
- import {
- CustomNoRowsOverlay,
- GeneralConfirmWindow,
- notifyDeleteError,
- notifyDeleteSuccess,
- notifySaveSuccess,
- removeObjectWithId
- } from "../../utils/CommonFunction";
- import UploadContext from "../../components/UploadProvider";
- import {LIONER_BUTTON_THEME} from "../../themes/colorConst";
- import {ThemeProvider} from "@emotion/react";
-
- let customerCount = -1;
- function EditToolbar(props) {
- const {setRows, setRowModesModel} = props;
-
- const handleClick = (id) => {
- setRows((oldRows) => [
- {
- id,
- isNew:true
- }
- ,...oldRows
- ]);
- setRowModesModel((oldModel) => ({
- ...oldModel,
- [id]: {mode: GridRowModes.Edit, fieldToFocus: 'name'},
- }));
- };
-
- return (
- <GridToolbarContainer sx={{ml: 1}}>
- <Button color="primary" startIcon={<AddIcon/>}
- onClick={()=> handleClick(customerCount--)}
- >
- Add Category
- </Button>
- </GridToolbarContainer>
- );
- }
-
- // ==============================|| CATEGORY TABLE ||============================== //
-
- export default function CategoryTable({recordList}) {
- const [rows, setRows] = React.useState([]);
- const [rowModesModel, setRowModesModel] = React.useState({});
- const { setIsUploading } = useContext(UploadContext);
- // ==============================|| DELETE WINDOW RELATED ||============================== //
- const [isWindowOpen, setIsWindowOpen] = React.useState(false);
- const [selectedId, setSelectedId] = React.useState(null);
-
- const handleClose = () => {
- setIsWindowOpen(false);
- };
-
- const [paginationModel, setPaginationModel] = React.useState({
- page: 0,
- pageSize:10
- });
- useEffect(() => {
- setPaginationModel({page:0,pageSize:10});
- setRows(recordList);
- }, [recordList]);
-
- const handleDeleteClick = (id) => () => {
- setIsWindowOpen(true);
- setSelectedId(id);
- };
-
- function updateData(){
- setIsUploading(true);
- axios.delete(`${apiPath}${GET_CATEGORY_LIST}/${selectedId}`,
- )
- .then((response) => {
- if (response.status === 204) {
- notifyDeleteSuccess();
- const newList =removeObjectWithId(rows,selectedId);
- setIsWindowOpen(false);
- setRows(newList);
- }
- setIsUploading(false);
- })
- .catch(error => {
- console.log(error);
- setIsUploading(false);
- return false;
- });
- }
- // ==============================|| DELETE WINDOW RELATED ||============================== //
-
- useEffect(()=>{
- setRows(recordList);
- },[recordList]);
-
- const handleRowEditStop = (params, event) => {
- if (params.reason === GridRowEditStopReasons.rowFocusOut) {
- event.defaultMuiPrevented = true;
- }
- };
-
- const handleEditClick = (id) => () => {
- setRowModesModel({...rowModesModel, [id]: {mode: GridRowModes.Edit, fieldToFocus: 'name'}});
- };
-
- const handleSaveClick = (id) => () => {
- setRowModesModel({...rowModesModel, [id]: {mode: GridRowModes.View, fieldToFocus: 'name'}});
- };
-
- const handleCancelClick = (id) => () => {
- setRowModesModel({
- ...rowModesModel,
- [id]: {mode: GridRowModes.View, ignoreModifications: true},
- });
- const editedRow = rows.find((row) => row.id === id);
- if (editedRow.isNew) {
- setRows(rows.filter((row) => row.id !== id));
- }
- };
-
- function updateCategory(data) {
- if(data.name.trim().length === 0){
- notifyDeleteError(`Name cannot be null`);
- handleEditClick(data.id);
- }
- else{
- axios.get(`${apiPath}${CHECK_CATEGORY_DUPLICATE}`,
- {
- params: {
- "name": data.name.trim(),
- "categoryId": data.id
- },
- })
- .then((response) => {
- if (response.status === 200) {
- if(response.data.isTaken){
- notifyDeleteError(`${data.name} already exists.`)
- handleEditClick(data.id);
- }
- else if(!response.data.isTaken){
- processUpload(data);
- }
- }
- })
- .catch(error => {
- console.log(error);
- return true;
- });
- }
-
- }
-
- function processUpload(data){
- setIsUploading(true);
- axios.post(`${apiPath}${UPDATE_CATEGORY_PATH}`,
- {
- "id": data.id,
- "name": data.name.trim(),
- "description": data.description,
- },
- )
-
- .then((response) => {
- if (response.status === 200) {
- const updatedRow = { ...data };
- updatedRow.id = response.data.id;
- setIsUploading(false);
- if(data.id === -1){
- setRows(rows.map((row) => (row.id === -1 ? updatedRow : row)));
- }
- else{
- setRows(rows.map((row) => (row.id === data.id ? updatedRow : row)));
- }
- notifySaveSuccess();
- }
- })
- .catch(error => {
- console.log(error);
- setIsUploading(false);
- return false;
- });
- }
-
- const processRowUpdate = (newRow) => {
- return new Promise((resolve, reject) => {
- const updatedRow = { ...newRow, isNew: false };
- if (updatedRow.name.trim().length === 0) {
- const error = new Error('Name cannot be null');
- reject(error);
- return;
- }
- setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row)));
- updateCategory(updatedRow);
- resolve(updatedRow); // Resolve the Promise with the updated row
- });
- };
-
- const handleRowModesModelChange = (newRowModesModel) => {
- setRowModesModel(newRowModesModel);
- };
- const columns = [
- {
- field: 'actions',
- type: 'actions',
- headerName: 'Actions',
- width: 100,
- cellClassName: 'actions',
- getActions: ({id}) => {
- const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
-
- if (isInEditMode) {
- return [
- <ThemeProvider key="OutSave" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- key="InCancel"
- icon={<CancelIcon sx={{fontSize: 25}}/>}
- label="Cancel"
- className="textPrimary"
- onClick={handleCancelClick(id)}
- color="error"
- />
- </ThemeProvider>,
- <ThemeProvider key="OutSave" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- key="InSave"
- icon={<SaveIcon sx={{fontSize: 25}}/>}
- label="Save"
- // sx={{
- // color: 'primary.main',
- // }}
- color="save"
- onClick={handleSaveClick(id)}
- />
- </ThemeProvider>,
- ];
- }
-
- return [
- <ThemeProvider key="OutSave" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- key="OutDelete"
- icon={<DeleteIcon sx={{fontSize: 25}}/>}
- label="Delete"
- onClick={handleDeleteClick(id)}
- color="delete"
- />
- </ThemeProvider>
- ,
- <ThemeProvider key="OutSave" theme={LIONER_BUTTON_THEME}>
- <GridActionsCellItem
- key="OutSave"
- icon={<EditIcon sx={{fontSize: 25}}/>}
- label="Edit"
- className="textPrimary"
- onClick={handleEditClick(id)}
- color="edit"
- />
- </ThemeProvider>,
- ];
- },
- },
- {
- id: 'categoryName',
- field: 'name',
- headerName: 'Category Name',
- flex: 1,
- editable: true,
- preProcessEditCellProps: (params) => {
- if(params.props.value !== undefined){
- const hasError = params.props.value.length > 50;
- if (hasError) {
- notifyDeleteError("Input has reached the length limit (50)");
- }
- return { ...params.props, error: hasError };
- }
- },
- },
- {
- id: 'categoryDescription',
- field: 'description',
- headerName: 'Category Description',
- flex: 1,
- editable: true,
- preProcessEditCellProps: (params) => {
- if(params.props.value !== undefined){
- const hasError = params.props.value.length > 255;
- if (hasError) {
- notifyDeleteError("Input has reached the length limit (255)");
- }
- return { ...params.props, error: hasError };
- }
- },
- },
- ];
-
- return (
- <div style={{/*height: '66vh',*/ width: '100%'}}>
-
- <DataGrid
- rows={rows}
- columns={columns}
- columnHeaderHeight={45}
- editMode="row"
- rowModesModel={rowModesModel}
- onRowModesModelChange={handleRowModesModelChange}
- onRowEditStop={handleRowEditStop}
- onProcessRowUpdateError={(error) => {
- console.log(error);
- notifyDeleteError(`Name cannot be null`);
- }}
- getRowHeight={() => 'auto'}
- processRowUpdate={processRowUpdate}
- paginationModel={paginationModel}
- onPaginationModelChange={setPaginationModel}
- slots={{
- toolbar: EditToolbar,
- noRowsOverlay: () => (
- CustomNoRowsOverlay()
- )
- }}
- pageSizeOptions={[15]}
- slotProps={{
- toolbar: {setRows, setRowModesModel},
- }}
- autoHeight
- />
- <GeneralConfirmWindow
- isWindowOpen={isWindowOpen}
- title={"Attention"}
- //content={`Confirm to delete Category ${getObjectById(rows,selectedId) === null? "" : '"' + getObjectById(rows,selectedId).name + '"'} ?`}
- content={`Are you sure to delete this category?`}
- onNormalClose={handleClose}
- onConfirmClose={updateData}
- />
- </div>
- );
- }
|