|
@@ -1,3 +1,4 @@ |
|
|
|
|
|
"use client" |
|
|
import { |
|
|
import { |
|
|
Dispatch, |
|
|
Dispatch, |
|
|
SetStateAction, |
|
|
SetStateAction, |
|
@@ -12,6 +13,8 @@ import { |
|
|
GridActionsCellItem, |
|
|
GridActionsCellItem, |
|
|
GridCellParams, |
|
|
GridCellParams, |
|
|
GridColDef, |
|
|
GridColDef, |
|
|
|
|
|
GridEventListener, |
|
|
|
|
|
GridRowEditStopReasons, |
|
|
GridRowId, |
|
|
GridRowId, |
|
|
GridRowIdGetter, |
|
|
GridRowIdGetter, |
|
|
GridRowModel, |
|
|
GridRowModel, |
|
@@ -32,10 +35,10 @@ import { useTranslation } from "react-i18next"; |
|
|
interface ResultWithId { |
|
|
interface ResultWithId { |
|
|
id: string | number; |
|
|
id: string | number; |
|
|
} |
|
|
} |
|
|
export type InputGridProps = { |
|
|
|
|
|
[key: string]: any |
|
|
|
|
|
} |
|
|
|
|
|
type TableRow<T, E> = Partial< |
|
|
|
|
|
|
|
|
// export type InputGridProps = { |
|
|
|
|
|
// [key: string]: any |
|
|
|
|
|
// } |
|
|
|
|
|
export type TableRow<T, E> = Partial< |
|
|
T & { |
|
|
T & { |
|
|
_isNew: boolean; |
|
|
_isNew: boolean; |
|
|
_error: E; |
|
|
_error: E; |
|
@@ -45,7 +48,7 @@ type TableRow<T, E> = Partial< |
|
|
export type InputDataGridProps<T, E> = { |
|
|
export type InputDataGridProps<T, E> = { |
|
|
_formKey: keyof T; |
|
|
_formKey: keyof T; |
|
|
columns: GridColDef[]; |
|
|
columns: GridColDef[]; |
|
|
validation: () => E; |
|
|
|
|
|
|
|
|
validateRow: (newRow: GridRowModel<TableRow<T, E>>) => E; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
export class ProcessRowUpdateError<T, E> extends Error { |
|
|
export class ProcessRowUpdateError<T, E> extends Error { |
|
@@ -60,15 +63,11 @@ export class ProcessRowUpdateError<T, E> extends Error { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function useInputDataGrid<T, E>({ |
|
|
|
|
|
|
|
|
function InputDataGrid<T, E>({ |
|
|
_formKey, |
|
|
_formKey, |
|
|
columns, |
|
|
columns, |
|
|
validation, |
|
|
|
|
|
}: InputDataGridProps<T, E>): { |
|
|
|
|
|
DataGrid: React.FC; |
|
|
|
|
|
rowModesModel: GridRowModesModel; |
|
|
|
|
|
setRowModesModel: Dispatch<SetStateAction<GridRowModesModel>>; |
|
|
|
|
|
} { |
|
|
|
|
|
|
|
|
validateRow, |
|
|
|
|
|
}: InputDataGridProps<T, E>) { |
|
|
const { |
|
|
const { |
|
|
t, |
|
|
t, |
|
|
// i18n: { language }, |
|
|
// i18n: { language }, |
|
@@ -96,7 +95,7 @@ function useInputDataGrid<T, E>({ |
|
|
[id]: { mode: GridRowModes.View }, |
|
|
[id]: { mode: GridRowModes.View }, |
|
|
})); |
|
|
})); |
|
|
}, |
|
|
}, |
|
|
[setRowModesModel] |
|
|
|
|
|
|
|
|
[] |
|
|
); |
|
|
); |
|
|
const onProcessRowUpdateError = useCallback( |
|
|
const onProcessRowUpdateError = useCallback( |
|
|
(updateError: ProcessRowUpdateError<T, E>) => { |
|
|
(updateError: ProcessRowUpdateError<T, E>) => { |
|
@@ -108,14 +107,18 @@ function useInputDataGrid<T, E>({ |
|
|
[apiRef, rowModesModel] |
|
|
[apiRef, rowModesModel] |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
console.log("asdasdasd") |
|
|
const processRowUpdate = useCallback( |
|
|
const processRowUpdate = useCallback( |
|
|
( |
|
|
( |
|
|
newRow: GridRowModel<TableRow<T, E>>, |
|
|
|
|
|
originalRow: GridRowModel<TableRow<T, E>> |
|
|
|
|
|
|
|
|
newRow: GridValidRowModel, |
|
|
|
|
|
originalRow: GridValidRowModel, |
|
|
|
|
|
// GridRowModel<TableRow<T, E>>, |
|
|
|
|
|
// originalRow: GridRowModel<TableRow<T, E>> |
|
|
) => { |
|
|
) => { |
|
|
///////////////// |
|
|
///////////////// |
|
|
// validation here |
|
|
// validation here |
|
|
// const errors = validation(); //repace true with validation method |
|
|
|
|
|
|
|
|
// const errors = validateRow(newRow); |
|
|
|
|
|
console.log(newRow) |
|
|
// if (errors) { |
|
|
// if (errors) { |
|
|
// throw new ProcessRowUpdateError( |
|
|
// throw new ProcessRowUpdateError( |
|
|
// originalRow, |
|
|
// originalRow, |
|
@@ -128,19 +131,18 @@ function useInputDataGrid<T, E>({ |
|
|
const rowToSave = { |
|
|
const rowToSave = { |
|
|
...updatedRow, |
|
|
...updatedRow, |
|
|
} as TableRow<T, E>; /// test |
|
|
} as TableRow<T, E>; /// test |
|
|
setRows((rw) => |
|
|
|
|
|
rw.map((r) => (getRowId(r) === getRowId(originalRow) ? rowToSave : r)) |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(rowToSave) |
|
|
|
|
|
// setRows((rw) => |
|
|
|
|
|
// rw.map((r) => (getRowId(r) === getRowId(originalRow) ? rowToSave : r)) |
|
|
|
|
|
// ); |
|
|
return rowToSave; |
|
|
return rowToSave; |
|
|
}, |
|
|
}, |
|
|
[rows] |
|
|
|
|
|
|
|
|
[validateRow, getRowId] |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
const addRow = useCallback(() => { |
|
|
const addRow = useCallback(() => { |
|
|
const newEntry = { id: Date.now(), _isNew: true } as TableRow<T, E>; |
|
|
const newEntry = { id: Date.now(), _isNew: true } as TableRow<T, E>; |
|
|
setRows((prev) => [...prev, newEntry]); |
|
|
setRows((prev) => [...prev, newEntry]); |
|
|
// console.log(newEntry) |
|
|
|
|
|
setRowModesModel((model) => ({ |
|
|
setRowModesModel((model) => ({ |
|
|
...model, |
|
|
...model, |
|
|
[getRowId(newEntry)]: { |
|
|
[getRowId(newEntry)]: { |
|
@@ -173,18 +175,14 @@ function useInputDataGrid<T, E>({ |
|
|
}, |
|
|
}, |
|
|
[setRowModesModel, rows] |
|
|
[setRowModesModel, rows] |
|
|
); |
|
|
); |
|
|
useEffect(() => { |
|
|
|
|
|
console.log(rows) |
|
|
|
|
|
}, [rows]) |
|
|
|
|
|
|
|
|
|
|
|
const handleDelete = useCallback( |
|
|
const handleDelete = useCallback( |
|
|
(id: GridRowId) => () => { |
|
|
(id: GridRowId) => () => { |
|
|
setRows((prevRows) => prevRows.filter((row) => getRowId(row) !== id)); |
|
|
setRows((prevRows) => prevRows.filter((row) => getRowId(row) !== id)); |
|
|
}, |
|
|
}, |
|
|
[] |
|
|
[] |
|
|
); |
|
|
); |
|
|
if (columns) { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
const _columns = useMemo<GridColDef[]>( |
|
|
const _columns = useMemo<GridColDef[]>( |
|
|
() => [ |
|
|
() => [ |
|
|
...columns, |
|
|
...columns, |
|
@@ -230,20 +228,29 @@ function useInputDataGrid<T, E>({ |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
], |
|
|
], |
|
|
[rowModesModel, handleSave, handleCancel, handleDelete] |
|
|
|
|
|
|
|
|
[columns,rowModesModel, handleSave, handleCancel, handleDelete] |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// const processRowUpdate = (newRow: GridRowModel) => { |
|
|
|
|
|
// const updatedRow = { ...newRow, isNew: false }; |
|
|
|
|
|
// console.log("asdasdasdsda") |
|
|
|
|
|
// // setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row))); |
|
|
|
|
|
// return updatedRow; |
|
|
|
|
|
// }; |
|
|
|
|
|
|
|
|
// sync useForm |
|
|
// sync useForm |
|
|
useEffect(() => { |
|
|
useEffect(() => { |
|
|
|
|
|
console.log(formKey) |
|
|
|
|
|
console.log(rows) |
|
|
setValue(formKey, rows); |
|
|
setValue(formKey, rows); |
|
|
}, [rows]); |
|
|
|
|
|
|
|
|
}, [formKey, rows]); |
|
|
|
|
|
|
|
|
const footer = ( |
|
|
const footer = ( |
|
|
<Box display="flex" gap={2} alignItems="center"> |
|
|
<Box display="flex" gap={2} alignItems="center"> |
|
|
<Button |
|
|
<Button |
|
|
disableRipple |
|
|
disableRipple |
|
|
variant="outlined" |
|
|
variant="outlined" |
|
|
startIcon={<Add />} |
|
|
|
|
|
|
|
|
startIcon={<Add />} |
|
|
onClick={addRow} |
|
|
onClick={addRow} |
|
|
size="small" |
|
|
size="small" |
|
|
> |
|
|
> |
|
@@ -260,10 +267,16 @@ function useInputDataGrid<T, E>({ |
|
|
</Button> |
|
|
</Button> |
|
|
</Box> |
|
|
</Box> |
|
|
); |
|
|
); |
|
|
const DataGrid: React.FC<InputGridProps> = (props) => ( |
|
|
|
|
|
|
|
|
// const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => { |
|
|
|
|
|
// if (params.reason === GridRowEditStopReasons.rowFocusOut) { |
|
|
|
|
|
// event.defaultMuiPrevented = true; |
|
|
|
|
|
// } |
|
|
|
|
|
// }; |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
<StyledDataGrid |
|
|
<StyledDataGrid |
|
|
{...props} |
|
|
|
|
|
getRowId={getRowId as GridRowIdGetter<GridValidRowModel>} |
|
|
|
|
|
|
|
|
// {...props} |
|
|
|
|
|
// getRowId={getRowId as GridRowIdGetter<GridValidRowModel>} |
|
|
apiRef={apiRef} |
|
|
apiRef={apiRef} |
|
|
rows={rows} |
|
|
rows={rows} |
|
|
columns={_columns} |
|
|
columns={_columns} |
|
@@ -281,9 +294,10 @@ function useInputDataGrid<T, E>({ |
|
|
}, |
|
|
}, |
|
|
}} |
|
|
}} |
|
|
disableColumnMenu |
|
|
disableColumnMenu |
|
|
|
|
|
processRowUpdate={processRowUpdate} |
|
|
|
|
|
// onRowEditStop={handleRowEditStop} |
|
|
rowModesModel={rowModesModel} |
|
|
rowModesModel={rowModesModel} |
|
|
onRowModesModelChange={setRowModesModel} |
|
|
onRowModesModelChange={setRowModesModel} |
|
|
processRowUpdate={processRowUpdate as any} |
|
|
|
|
|
onProcessRowUpdateError={onProcessRowUpdateError} |
|
|
onProcessRowUpdateError={onProcessRowUpdateError} |
|
|
getCellClassName={(params: GridCellParams<TableRow<T, E>>) => { |
|
|
getCellClassName={(params: GridCellParams<TableRow<T, E>>) => { |
|
|
let classname = ""; |
|
|
let classname = ""; |
|
@@ -300,12 +314,7 @@ function useInputDataGrid<T, E>({ |
|
|
footer: { child: footer }, |
|
|
footer: { child: footer }, |
|
|
}} |
|
|
}} |
|
|
/> |
|
|
/> |
|
|
); |
|
|
|
|
|
return { |
|
|
|
|
|
DataGrid, |
|
|
|
|
|
rowModesModel, |
|
|
|
|
|
setRowModesModel, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
) |
|
|
} |
|
|
} |
|
|
const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => { |
|
|
const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => { |
|
|
return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>; |
|
|
return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>; |
|
@@ -323,4 +332,4 @@ const NoRowsOverlay: React.FC = () => { |
|
|
</Box> |
|
|
</Box> |
|
|
); |
|
|
); |
|
|
}; |
|
|
}; |
|
|
export default useInputDataGrid; |
|
|
|
|
|
|
|
|
export default InputDataGrid; |