Добрый день. Имеется таблица DataGrid от Material UI. Код на TypeScript с React. Нужно, чтобы при нажатии по любой строке в первой таблице во вторую таблицу выводились соответствующие данные. Например подробная информация для конкретно этой строки. Изначально во 2 таблице нет данных. Т.е. это грубо говоря развертка. Хотим узнать подробности о какой-то строке -> кликаем на нее -> во 2 таблице отображается соответствующая вложенная информация. На данный момент вторая таблица не определена, так как не знаю, нужно создать экземлпяр той же или создавать совершенно другую и как-то перебрасывать в нее данные. Как я понимаю надо как-то связать нажатие кнопки в таблице 1 с появлением данных в таблице 2. Изначально хотел, чтобы просто как дерево раскрывалась строка с вложенностью, но столкнулся с проблемой, что такая функция есть только в Pro версии DataGrid. Сделал по туториалу (
https://www.youtube.com/watch?v=9Nzvw0ycYXw ). Но там данные выводятся в ту же самую строку без раскрытия. Пробовал подгрузить Pro версию, там в DataGrid есть параметр treeData (
https://mui.com/x/react-data-grid/tree-data/), но слетел тип GridColumns, аналога которого почему-то нет в Pro версии. И слетело куча других импортов, которые попробовал заменить на прошные. Итог: в идеале нужно как описано выше вывод информации в соседнюю таблицу. Не в идеале просто такой же разворот в сворачиваемые строки как по ссылке с treeData. Казалось бы, тривиальная задача, но всю голову сломал. Спасибо, если кто откликнется
const Table = () => {
const [editRowsModel, setEditRowsModel] = useState({});
const [editRowData, setEditRowData] = useState({});
const [pageSize, setPageSize] = useState(15);
const [sortModel, setSortModel] = useState<GridSortItem[]>([{
field: 'ddate', sort: 'desc',
},]);
const {data, loading} = useTypedSelector(state => state.data);
const {role} = useTypedSelector(state => state.auth)
const {fetchData} = useActions()
const getData = useCallback(() => {
fetchData()
}, [data])
useEffect(() => {
getData()
}, [])
const addNewRecord = async () => {
await axios.post('http://адрес/api/post', {
ddate: new Date(),
scontras: "",
snumcontract: "",
stype: "",
mol: null,
kurator: "",
sdatenuminvoice: "",
ddateaccept: "",
sdatenumactosx: "",
ddatetransfer: "",
sfio: "",
sdatenumvkn: "",
sdatenumvkp: "",
ddateaccept1: "",
ddateaccept2: "",
ddateload: "",
nsum: ""
})
.catch((e) => {
console.log(e)
})
getData()
}
const handleEdit = useCallback((model: any) => {
const editedIds = Object.keys(model);
if (editedIds.length === 0 && Object.values(editRowsModel)[0] !== undefined) {
updateRecord(Object.values(editRowData), Object.keys(editRowsModel)[0])
} else {
setEditRowData(model[editedIds[0]]);
}
setEditRowsModel(model);
}, [editRowsModel, editRowData]);
const updateRecord = async (data: any, id: any) => {
if (role === 'eco') {
await axios.patch('http://адрес/api/post/eco', {
ddate: data[0].value,
scontras: data[1].value,
snumcontract: data[2].value,
stype: data[3].value,
mol: data[4].value,
kurator: data[5].value,
id: id
})
.catch((e) => console.log(e))
} else if (role === 'mol') {
await axios.patch('http://адрес/api/post/mol', {
sdatenuminvoice: data[0].value,
ddateaccept: data[1].value,
sdatenumactosx: data[2].value,
ddatetransfer: data[3].value,
id: id
})
.catch((e) => console.log(e))
} else if (role === 'ovko') {
await axios.patch('http://адрес/api/post/ovko', {
sfio: data[0].value,
sdatenumvkn: data[1].value,
sdatenumvkp: data[2].value,
id: id
})
.catch((e) => console.log(e))
} else if (role === 'kur') {
await axios.patch('http://адрес/api/post/kur', {
ddateaccept1: data[0].value, //1 столбец
ddateaccept2: data[1].value, //2 столбец
ddateload: data[2].value, //3 столбец
nsum: data[3].value, //4 столбец
id: id
})
.catch((e) => console.log(e))
}
}
const getFilteredRows = ({apiRef}: GridCsvGetRowsToExportParams) =>
gridVisibleSortedRowIdsSelector(apiRef)
return (
<GridToolbarContainer style={{order: 3}} {...props}>
<GridToolbarColumnsButton/>
<GridToolbarDensitySelector/>
<GridToolbarFilterButton/>
<Button
{...buttonBaseProps}
onClick={() => handleExport({getRowsToExport: getFilteredRows})}
>
Экспорт
</Button>
</GridToolbarContainer>)
}
const detailStyles ={
borderTop: "2px solid",
borderTopColor: "primary.main",
pt: 2
}
const [clickedIndex, setClickedIndex] = React.useState<number | undefined>(-1)
const columns: GridColumns = [
//добавил столбец с кнопками развертки сбоку. разворачивается информация в той же строке той же таблицы
{
field: 'id',
headerName: 'Развернуть строку',
width: 110,
renderCell: (cellValues: GridRenderCellParams<number>) => {
return (<IconButton
onClick={ () => {clickedIndex === cellValues.value
? setClickedIndex(-1)
: setClickedIndex(cellValues.value) }
}
> {cellValues.value === clickedIndex
? <KeyboardArrowUp/>
: <KeyboardArrowDown />}
</ IconButton>)},
},
{
field: 'ddate',
headerName: 'Дата поступления',
type: 'date',
valueGetter: ({value}) => value && new Date(value),
width: 150,
editable: role === "eco",
cellClassName: role === "eco" ? 'super-app-theme--cell' : '' },
{
field: 'scontras',
headerName: 'Агент',
width: 180,
editable: role === "eco",
cellClassName: role === "eco" ? 'super-app-theme--cell' : '',
renderCell: (params: GridRenderCellParams) => (
<Box><div>{params.value}</div><Collapse in={params.id === clickedIndex}><Box sx={detailStyles}>Expanded:
{params.value}</Box></Collapse></Box>
},
{
field: 'snumcontract',
headerName: '№ поставки',
width: 200,
editable: role === "eco",
cellClassName: role === "eco" ? 'super-app-theme--cell' : '',
renderCell: (params: GridRenderCellParams) => (
<Box><div>{params.value}</div><Collapse in={params.id === clickedIndex}><Box sx={detailStyles}>Expanded: {params.value}</Box></Collapse></Box>
) },
{
field: 'stype',
headerName: 'Тип',
width: 250,
editable: role === "eco",
cellClassName: role === "eco" ? 'super-app-theme--cell' : '',
renderCell: (params: GridRenderCellParams) => (
<Box><div>{params.value}</div><Collapse in={params.id === clickedIndex}><Box sx={detailStyles}>Expanded: {params.value}</Box></Collapse></Box>
) },
];
//ТАБЛИЦЫ
return (
<div>
<Paper className={classes.paper}>
<DataGrid
pagination
pageSize={pageSize}
className={classes.table}
onPageSizeChange={(newPageSize) => setPageSize(newPageSize)}
rowsPerPageOptions={[15, 30, 45]}
autoHeight
rows={data} //вывод строк
columns={columns} //столбцов
loading={loading}
components={{Toolbar: CustomToolbar, LoadingOverlay: LinearProgress}} //тулбар слева вверху таблицы
editRowsModel={editRowsModel}
editMode="row"
onEditRowsModelChange={handleEdit} //позволяет управлять состоянием редактирования.
sortModel={sortModel}
onSortModelChange={(model) => setSortModel(model)}
/>
</Paper>
</div>