Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 

258 Zeilen
7.8 KiB

  1. import React, { useCallback, useEffect, useMemo, useState } from 'react';
  2. import { Modal, Box, Typography, Button, TextField, FormControl, InputLabel, Select, MenuItem, Paper, SxProps } from '@mui/material';
  3. import { useForm, Controller, useFormContext } from 'react-hook-form';
  4. import { useTranslation } from 'react-i18next';
  5. import { INPUT_DATE_FORMAT, OUTPUT_DATE_FORMAT } from '@/app/utils/formatUtil';
  6. import dayjs from 'dayjs';
  7. import { DatePicker } from '@mui/x-date-pickers';
  8. import { DataGrid, GridEventListener, GridRowEditStopParams, GridRowEditStopReasons, GridRowModel, GridRowModes, GridRowModesModel, GridToolbarContainer } from '@mui/x-data-grid';
  9. import StyledDataGrid from '../StyledDataGrid';
  10. import AddIcon from '@mui/icons-material/Add';
  11. import SaveIcon from '@mui/icons-material/Save';
  12. import DeleteIcon from '@mui/icons-material/Delete';
  13. import CancelIcon from '@mui/icons-material/Cancel';
  14. import EditIcon from '@mui/icons-material/Edit';
  15. import { GridActionsCellItem } from '@mui/x-data-grid';
  16. interface SalaryEffectiveModelProps {
  17. open: boolean;
  18. onClose: () => void;
  19. modalSx?: SxProps;
  20. columns: any[]
  21. }
  22. const modalSx: SxProps = {
  23. position: "absolute",
  24. top: "50%",
  25. left: "50%",
  26. transform: "translate(-50%, -50%)",
  27. width: "90%",
  28. maxWidth: "auto",
  29. maxHeight: "auto",
  30. padding: 3,
  31. display: "flex",
  32. flexDirection: "column",
  33. gap: 2,
  34. };
  35. function EditToolbar(props: React.JSXElementConstructor<any> | null | undefined | any) {
  36. // const intl = useIntl();
  37. // const addRecordBtn = intl.formatMessage({ id: 'add' });
  38. const { count, setCount, setRows, setRowModesModel, _columns } = props;
  39. let obj: { [key: string]: string } = {};
  40. for (let i = 0; i < _columns.length - 1; i++) {
  41. obj[_columns[i].field as string] = '';
  42. }
  43. const handleClick = React.useCallback(() => {
  44. const id = Math.random();
  45. setRows((oldRows: any) => [...oldRows, { id, ...obj, isNew: true }]);
  46. setRowModesModel((oldModel: any) => ({
  47. ...oldModel,
  48. [id]: { mode: GridRowModes.Edit,
  49. // fieldToFocus: 'material'
  50. }
  51. }));
  52. setCount((prev: number) => prev+1)
  53. }, [count, setCount, setRowModesModel, setRows])
  54. return (
  55. <GridToolbarContainer>
  56. <Button disabled={count>=1} color="primary" startIcon={<AddIcon />} onClick={handleClick}>
  57. {"addRecordBtn"}
  58. </Button>
  59. {/* <Button color="primary" startIcon={<AddIcon />} onClick={handleSave}>
  60. SAVE
  61. </Button> */}
  62. </GridToolbarContainer>
  63. );
  64. }
  65. const SalaryEffectiveModel: React.FC<SalaryEffectiveModelProps> = ({ open, onClose, modalSx: mSx, columns }) => {
  66. const { t } = useTranslation();
  67. const { control, register, formState, trigger, watch, setValue, getValues } = useFormContext();
  68. const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
  69. const [count, setCount] = useState(0);
  70. const [_rows, setRows] = useState(() => {
  71. const list = getValues('salaryEffectiveInfo')
  72. console.log(list)
  73. return list && list.length > 0 ? list : []
  74. });
  75. 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.
  76. const handleClose = () => {
  77. onClose();
  78. };
  79. // const handleSave = async () => {
  80. // const isValid = await trigger();
  81. // // if (isValid) {
  82. // // onSave();
  83. // // onClose();
  84. // // }
  85. // };
  86. const handleRowEditStop: GridEventListener<"rowEditStop"> = (
  87. params,
  88. event,
  89. ) => {
  90. if (params.reason === GridRowEditStopReasons.rowFocusOut) {
  91. event.defaultMuiPrevented = true;
  92. }
  93. };
  94. const processRowUpdate =
  95. // useCallback(
  96. (newRow: GridRowModel) => {
  97. console.log(newRow)
  98. const updatedRow = { ...newRow, updated: true };
  99. console.log(_rows)
  100. if (_rows.length != 0) {
  101. setRows((prev: any[]) => prev?.map((row: any) => (row.id === newRow.id ? updatedRow : row)));
  102. }
  103. return updatedRow;
  104. }
  105. // , [_rows, setValue, setRows])
  106. useEffect(()=> {
  107. console.log(_rows)
  108. setValue('salaryEffectiveInfo', _rows)
  109. }, [_rows])
  110. const handleSaveClick = useCallback(
  111. (id: any) => () => {
  112. setRowModesModel((prevRowModesModel) => ({
  113. ...prevRowModesModel,
  114. [id]: { mode: GridRowModes.View }
  115. }));
  116. },
  117. [setRowModesModel]
  118. );
  119. const handleCancelClick = useCallback(
  120. (id: any) => () => {
  121. setRowModesModel((prevRowModesModel) => ({
  122. ...prevRowModesModel,
  123. [id]: { mode: GridRowModes.View, ignoreModifications: true }
  124. }));
  125. },
  126. [setRowModesModel]
  127. );
  128. const handleEditClick = useCallback(
  129. (id: any) => () => {
  130. setRowModesModel((prevRowModesModel) => ({
  131. ...prevRowModesModel,
  132. [id]: { mode: GridRowModes.Edit }
  133. }));
  134. },
  135. [setRowModesModel]
  136. );
  137. const handleDeleteClick = useCallback(
  138. (id: any) => () => {
  139. setRows((prevRows: any) => prevRows.filter((row: any) => row.id !== id));
  140. setCount((prev: number) => prev - 1)
  141. },
  142. [setRows, setCount]
  143. );
  144. const defaultCol = useMemo(
  145. () => (
  146. {
  147. field: 'actions',
  148. type: 'actions',
  149. headerName: 'edit',
  150. width: 100,
  151. cellClassName: 'actions',
  152. getActions: ({ id }: { id: number }) => {
  153. const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
  154. if (isInEditMode) {
  155. return [
  156. <GridActionsCellItem
  157. icon={<SaveIcon />}
  158. label="Save"
  159. key="edit"
  160. sx={{
  161. color: 'primary.main'
  162. }}
  163. onClick={handleSaveClick(id)}
  164. />,
  165. <GridActionsCellItem
  166. icon={<CancelIcon />}
  167. label="Cancel"
  168. key="edit"
  169. onClick={handleCancelClick(id)}
  170. />
  171. ];
  172. }
  173. return [
  174. <GridActionsCellItem
  175. icon={<EditIcon />}
  176. label="Edit"
  177. className="textPrimary"
  178. onClick={handleEditClick(id)}
  179. color="inherit"
  180. key="edit"
  181. />,
  182. <GridActionsCellItem
  183. icon={<DeleteIcon />}
  184. label="Delete"
  185. sx={{
  186. color: 'error.main'
  187. }}
  188. onClick={handleDeleteClick(id)} color="inherit" key="edit" />
  189. ];
  190. }
  191. }
  192. ), [rowModesModel, handleSaveClick, handleCancelClick, handleEditClick, handleDeleteClick]
  193. )
  194. let _columns: any[] = []
  195. if (columns) {
  196. _columns = [...columns, defaultCol]
  197. }
  198. useEffect(() => {
  199. console.log(formValues)
  200. }, [open])
  201. return (
  202. <Modal open={open} onClose={handleClose}>
  203. <Paper sx={{ ...modalSx, ...mSx }}>
  204. <Typography variant="h6" component="h2">
  205. {t('Salary Effective Date Change')}
  206. </Typography>
  207. <StyledDataGrid
  208. rows={_rows}
  209. columns={_columns}
  210. editMode="row"
  211. rowModesModel={rowModesModel}
  212. onRowModesModelChange={setRowModesModel}
  213. onRowEditStop={handleRowEditStop}
  214. processRowUpdate={processRowUpdate}
  215. slots={{
  216. toolbar: EditToolbar
  217. }}
  218. slotProps={{
  219. toolbar: {count, setCount, setRows, setRowModesModel, _columns}
  220. }}
  221. />
  222. <Box display="flex" justifyContent="flex-end" gap={2}>
  223. <Button variant="text" onClick={handleClose}>
  224. {t('Cancel')}
  225. </Button>
  226. <Button variant="contained" onClick={handleClose}>
  227. {t("Save")}
  228. </Button>
  229. </Box>
  230. {/* </FormControl> */}
  231. </Paper>
  232. </Modal>
  233. );
  234. };
  235. export default SalaryEffectiveModel;