|
|
|
@@ -1,17 +1,25 @@ |
|
|
|
|
|
|
|
import React, { useEffect } from 'react'; |
|
|
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'; |
|
|
|
import { Modal, Box, Typography, Button, TextField, FormControl, InputLabel, Select, MenuItem, Paper, SxProps } from '@mui/material'; |
|
|
|
import { useForm, Controller } from 'react-hook-form'; |
|
|
|
import { useForm, Controller, useFormContext } from 'react-hook-form'; |
|
|
|
import { useTranslation } from 'react-i18next'; |
|
|
|
import { INPUT_DATE_FORMAT, OUTPUT_DATE_FORMAT } from '@/app/utils/formatUtil'; |
|
|
|
import dayjs from 'dayjs'; |
|
|
|
import { DatePicker } from '@mui/x-date-pickers'; |
|
|
|
import { DataGrid, GridEventListener, GridRowEditStopParams, GridRowEditStopReasons, GridRowModel, GridRowModes, GridRowModesModel, GridToolbarContainer } from '@mui/x-data-grid'; |
|
|
|
import StyledDataGrid from '../StyledDataGrid'; |
|
|
|
import AddIcon from '@mui/icons-material/Add'; |
|
|
|
import SaveIcon from '@mui/icons-material/Save'; |
|
|
|
import DeleteIcon from '@mui/icons-material/Delete'; |
|
|
|
import CancelIcon from '@mui/icons-material/Cancel'; |
|
|
|
import EditIcon from '@mui/icons-material/Edit'; |
|
|
|
import { GridActionsCellItem } from '@mui/x-data-grid'; |
|
|
|
|
|
|
|
interface SalaryEffectiveModelProps { |
|
|
|
open: boolean; |
|
|
|
onClose: () => void; |
|
|
|
modalSx?: SxProps; |
|
|
|
onSave: () => void; |
|
|
|
columns: any[] |
|
|
|
} |
|
|
|
|
|
|
|
const modalSx: SxProps = { |
|
|
|
@@ -20,17 +28,57 @@ const modalSx: SxProps = { |
|
|
|
left: "50%", |
|
|
|
transform: "translate(-50%, -50%)", |
|
|
|
width: "90%", |
|
|
|
maxWidth: "sm", |
|
|
|
maxHeight: "90%", |
|
|
|
maxWidth: "auto", |
|
|
|
maxHeight: "auto", |
|
|
|
padding: 3, |
|
|
|
display: "flex", |
|
|
|
flexDirection: "column", |
|
|
|
gap: 2, |
|
|
|
}; |
|
|
|
|
|
|
|
const SalaryEffectiveModel: React.FC<SalaryEffectiveModelProps> = ({ open, onClose, modalSx: mSx, onSave }) => { |
|
|
|
function EditToolbar(props: React.JSXElementConstructor<any> | null | undefined | any) { |
|
|
|
// const intl = useIntl(); |
|
|
|
// const addRecordBtn = intl.formatMessage({ id: 'add' }); |
|
|
|
const { count, setCount, setRows, setRowModesModel, _columns } = props; |
|
|
|
let obj: { [key: string]: string } = {}; |
|
|
|
for (let i = 0; i < _columns.length - 1; i++) { |
|
|
|
obj[_columns[i].field as string] = ''; |
|
|
|
} |
|
|
|
|
|
|
|
const handleClick = React.useCallback(() => { |
|
|
|
const id = Math.random(); |
|
|
|
setRows((oldRows: any) => [...oldRows, { id, ...obj, isNew: true }]); |
|
|
|
setRowModesModel((oldModel: any) => ({ |
|
|
|
...oldModel, |
|
|
|
[id]: { mode: GridRowModes.Edit, |
|
|
|
// fieldToFocus: 'material' |
|
|
|
} |
|
|
|
})); |
|
|
|
setCount((prev: number) => prev+1) |
|
|
|
}, [count, setCount, setRowModesModel, setRows]) |
|
|
|
|
|
|
|
return ( |
|
|
|
<GridToolbarContainer> |
|
|
|
<Button disabled={count>=1} color="primary" startIcon={<AddIcon />} onClick={handleClick}> |
|
|
|
{"addRecordBtn"} |
|
|
|
</Button> |
|
|
|
{/* <Button color="primary" startIcon={<AddIcon />} onClick={handleSave}> |
|
|
|
SAVE |
|
|
|
</Button> */} |
|
|
|
</GridToolbarContainer> |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
const SalaryEffectiveModel: React.FC<SalaryEffectiveModelProps> = ({ open, onClose, modalSx: mSx, onSave, columns }) => { |
|
|
|
const { t } = useTranslation(); |
|
|
|
const { control, register, formState, trigger, watch, setValue } = useForm({}); |
|
|
|
const { control, register, formState, trigger, watch, setValue, getValues } = useFormContext(); |
|
|
|
const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({}); |
|
|
|
const [count, setCount] = useState(0); |
|
|
|
const [_rows, setRows] = useState(() => { |
|
|
|
const list = getValues('salaryEffectiveInfo') |
|
|
|
console.log(list) |
|
|
|
return list && list.length > 0 ? list : [] |
|
|
|
}); |
|
|
|
|
|
|
|
const formValues = watch(); // This line of code is using the watch function from react-hook-form to get the current values of the form fields. |
|
|
|
|
|
|
|
@@ -38,14 +86,133 @@ const SalaryEffectiveModel: React.FC<SalaryEffectiveModelProps> = ({ open, onClo |
|
|
|
onClose(); |
|
|
|
}; |
|
|
|
|
|
|
|
const handleSave = async () => { |
|
|
|
const isValid = await trigger(); |
|
|
|
if (isValid) { |
|
|
|
onSave(); |
|
|
|
onClose(); |
|
|
|
// const handleSave = async () => { |
|
|
|
// const isValid = await trigger(); |
|
|
|
// // if (isValid) { |
|
|
|
// // onSave(); |
|
|
|
// // onClose(); |
|
|
|
// // } |
|
|
|
// }; |
|
|
|
|
|
|
|
const handleRowEditStop: GridEventListener<"rowEditStop"> = ( |
|
|
|
params, |
|
|
|
event, |
|
|
|
) => { |
|
|
|
if (params.reason === GridRowEditStopReasons.rowFocusOut) { |
|
|
|
event.defaultMuiPrevented = true; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const processRowUpdate = useCallback((newRow: GridRowModel) => { |
|
|
|
console.log(newRow) |
|
|
|
const updatedRow = { ...newRow, updated: true }; |
|
|
|
console.log(_rows) |
|
|
|
if (_rows.length != 0) { |
|
|
|
setRows(_rows?.map((row: any) => (row.id === newRow.id ? updatedRow : row))); |
|
|
|
} |
|
|
|
return updatedRow; |
|
|
|
}, [_rows, setValue, setRows]) |
|
|
|
|
|
|
|
useEffect(()=> { |
|
|
|
setValue('salaryEffectiveInfo', _rows) |
|
|
|
}, [_rows]) |
|
|
|
|
|
|
|
const handleSaveClick = useCallback( |
|
|
|
(id: any) => () => { |
|
|
|
setRowModesModel((prevRowModesModel) => ({ |
|
|
|
...prevRowModesModel, |
|
|
|
[id]: { mode: GridRowModes.View } |
|
|
|
})); |
|
|
|
}, |
|
|
|
[setRowModesModel] |
|
|
|
); |
|
|
|
|
|
|
|
const handleCancelClick = useCallback( |
|
|
|
(id: any) => () => { |
|
|
|
setRowModesModel((prevRowModesModel) => ({ |
|
|
|
...prevRowModesModel, |
|
|
|
[id]: { mode: GridRowModes.View, ignoreModifications: true } |
|
|
|
})); |
|
|
|
}, |
|
|
|
[setRowModesModel] |
|
|
|
); |
|
|
|
|
|
|
|
const handleEditClick = useCallback( |
|
|
|
(id: any) => () => { |
|
|
|
setRowModesModel((prevRowModesModel) => ({ |
|
|
|
...prevRowModesModel, |
|
|
|
[id]: { mode: GridRowModes.Edit } |
|
|
|
})); |
|
|
|
|
|
|
|
}, |
|
|
|
[setRowModesModel] |
|
|
|
); |
|
|
|
|
|
|
|
const handleDeleteClick = useCallback( |
|
|
|
(id: any) => () => { |
|
|
|
setRows((prevRows: any) => prevRows.filter((row: any) => row.id !== id)); |
|
|
|
setCount((prev: number) => prev - 1) |
|
|
|
}, |
|
|
|
[setRows, setCount] |
|
|
|
); |
|
|
|
|
|
|
|
const defaultCol = useMemo( |
|
|
|
() => ( |
|
|
|
{ |
|
|
|
field: 'actions', |
|
|
|
type: 'actions', |
|
|
|
headerName: 'edit', |
|
|
|
width: 100, |
|
|
|
cellClassName: 'actions', |
|
|
|
getActions: ({ id }: { id: number }) => { |
|
|
|
const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; |
|
|
|
if (isInEditMode) { |
|
|
|
return [ |
|
|
|
<GridActionsCellItem |
|
|
|
icon={<SaveIcon />} |
|
|
|
label="Save" |
|
|
|
key="edit" |
|
|
|
sx={{ |
|
|
|
color: 'primary.main' |
|
|
|
}} |
|
|
|
onClick={handleSaveClick(id)} |
|
|
|
/>, |
|
|
|
<GridActionsCellItem |
|
|
|
icon={<CancelIcon />} |
|
|
|
label="Cancel" |
|
|
|
key="edit" |
|
|
|
onClick={handleCancelClick(id)} |
|
|
|
/> |
|
|
|
]; |
|
|
|
} |
|
|
|
return [ |
|
|
|
<GridActionsCellItem |
|
|
|
icon={<EditIcon />} |
|
|
|
label="Edit" |
|
|
|
className="textPrimary" |
|
|
|
onClick={handleEditClick(id)} |
|
|
|
color="inherit" |
|
|
|
key="edit" |
|
|
|
/>, |
|
|
|
<GridActionsCellItem |
|
|
|
icon={<DeleteIcon />} |
|
|
|
label="Delete" |
|
|
|
sx={{ |
|
|
|
color: 'error.main' |
|
|
|
}} |
|
|
|
onClick={handleDeleteClick(id)} color="inherit" key="edit" /> |
|
|
|
]; |
|
|
|
} |
|
|
|
} |
|
|
|
), [rowModesModel, handleSaveClick, handleCancelClick, handleEditClick, handleDeleteClick] |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
let _columns: any[] = [] |
|
|
|
if (columns) { |
|
|
|
_columns = [...columns, defaultCol] |
|
|
|
} |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
console.log(formValues) |
|
|
|
}, [open]) |
|
|
|
@@ -56,30 +223,33 @@ const SalaryEffectiveModel: React.FC<SalaryEffectiveModelProps> = ({ open, onClo |
|
|
|
<Typography variant="h6" component="h2"> |
|
|
|
{t('Salary Effective Date Change')} |
|
|
|
</Typography> |
|
|
|
<FormControl> |
|
|
|
<TextField |
|
|
|
label={t('Salary')} |
|
|
|
type="number" |
|
|
|
fullWidth |
|
|
|
{...register('salary', { |
|
|
|
valueAsNumber: true, |
|
|
|
required: t('Salary is required'), |
|
|
|
})} |
|
|
|
error={Boolean(formState.errors.salary)} |
|
|
|
// helperText={formState.errors.salary?.message} |
|
|
|
/> |
|
|
|
<StyledDataGrid |
|
|
|
rows={_rows} |
|
|
|
columns={_columns} |
|
|
|
editMode="row" |
|
|
|
rowModesModel={rowModesModel} |
|
|
|
onRowModesModelChange={setRowModesModel} |
|
|
|
onRowEditStop={handleRowEditStop} |
|
|
|
processRowUpdate={processRowUpdate} |
|
|
|
slots={{ |
|
|
|
toolbar: EditToolbar |
|
|
|
}} |
|
|
|
slotProps={{ |
|
|
|
toolbar: {count, setCount, setRows, setRowModesModel, _columns} |
|
|
|
}} |
|
|
|
/> |
|
|
|
<Box display="flex" justifyContent="flex-end" gap={2}> |
|
|
|
<Button variant="text" onClick={handleClose}> |
|
|
|
{t('Cancel')} |
|
|
|
</Button> |
|
|
|
<Button variant="contained" onClick={handleSave}> |
|
|
|
<Button variant="contained" onClick={handleClose}> |
|
|
|
{t("Save")} |
|
|
|
</Button> |
|
|
|
</Box> |
|
|
|
</FormControl> |
|
|
|
{/* </FormControl> */} |
|
|
|
</Paper> |
|
|
|
</Modal> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
export default SalaryEffectiveModel; |
|
|
|
export default SalaryEffectiveModel; |