I use material ui to render my data in table form.
I have to use renderCell for two properties (level by user and level by referent)
problem: material ui shows me 'level by referent' twice because it replaces 'level by user' with 'level by referent'.
import React from 'react';
import { useSelector } from 'react-redux';
import { TableReusable } from '../../reusable/TableReusable';
import { Box, CircularProgress, Typography } from '@mui/material';
import useLevelToLetterConversion from '../../reusable/UseLevelConverter';
const TcgTable = () => {
const oneUserSkill = useSelector((state) => state.user?.oneUserSkill);
const rows = oneUserSkill?.skills?.tcg;
const convertedRows = useLevelToLetterConversion(rows);
let columns =
convertedRows?.length > 0
? [ {
headerName: 'Level by user',
headerAlign: 'center',
align: 'center',
renderCell: (convertedRows) => {
const userLevel = convertedRows?.row?.Level?.find(
(level) => level?.Role === 'User'
);
return (
<Typography
sx={{
textAlign: 'center',
fontSize: '0.875rem',
width: 150,
height: 40,
...(userLevel?.Level === 'Expert' && {
color: 'green',
fontWeight: 'bold',
}),
...(userLevel?.Level === 'Confirmed' && {
color: 'green',
}),
...(userLevel?.Level === 'Intermediate' && {
color: 'orange',
}),
...(userLevel?.Level === 'Beginner' && {
color: 'lightsalmon',
}),
...(userLevel?.Level === 'Unknow' && { color: 'grey' }),
}}
>
{userLevel?.Level}
</Typography>
);
},
},
{
headerName: 'Level by referent',
headerAlign: 'center',
align: 'center',
renderCell: (convertedRows) => {
const referentLevel = convertedRows?.row?.Level?.find(
(level) => level?.Role === 'Referent'
);
console.log('2', referentLevel);
return (
<Typography
sx={{
textAlign: 'center',
fontSize: '0.875rem',
width: 150,
height: 40,
...(referentLevel?.Level === 'Expert' && {
color: 'green',
fontWeight: 'bold',
}),
...(referentLevel?.Level === 'Confirmed' && {
color: 'green',
}),
...(referentLevel?.Level === 'Intermediate' && {
color: 'orange',
}),
...(referentLevel?.Level === 'Beginner' && {
color: 'lightsalmon',
}),
...(referentLevel?.Level === 'Unknow' && { color: 'grey' }),
}}
>
{referentLevel?.Level}
</Typography>
);
},
},
].concat(
Object.keys(convertedRows[0])
.filter(
(field) =>
field !== 'updated_at' &&
field !== 'created_at' &&
field !== 'id' &&
field !== 'Level'
)
.map((field) => {
return {
field: field,
headerName: field,
flex: 1,
};
})
)
: [];
return <TableReusable data={convertedRows} columns={columns} bool={false} />;
};
My 'table reusable'
import React from 'react';
import {
DataGrid,
GridToolbar,
GridToolbarQuickFilter,
} from '@mui/x-data-grid';
import { useDispatch } from 'react-redux';
import { Box, Stack } from '@mui/material';
export const TableReusable = ({ data, columns, bool, setSkillSelected }) => {
const dispatch = useDispatch();
const onRowsSelectionHandler = (ids) => {
const selectedRowsData = ids?.map((id) =>
data?.find((row) => row?._id === id || row?.id === id)
);
if (setSkillSelected) {
dispatch(setSkillSelected(selectedRowsData));
}
};
function NoRowsOverlay() {
return (
<Stack height="100%" alignItems="center" justifyContent="center">
No skills for the moment
</Stack>
);
}
function NoResultsOverlay() {
return (
<Stack height="100%" alignItems="center" justifyContent="center">
No results
</Stack>
);
}
function QuickSearchToolbar() {
return (
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
p: 0.5,
pb: 0,
}}
>
<GridToolbar />
<GridToolbarQuickFilter
quickFilterParser={(searchInput) =>
searchInput
.split(',')
.map((value) => value.trim())
.filter((value) => value !== '')
}
/>
</Box>
);
}
return (
<>
<DataGrid
density="comfortable"
sx={{
height: data?.length > 0 ? '100%' : 250,
width: '100%',
background: 'white',
'.MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold !important',
overflow: 'visible !important',
},
}}
rows={data}
getRowId={(row) => row?.id || row?._id || row?.CommonId}
columns={columns}
initialState={{
pagination: { paginationModel: { pageSize: 10 } },
...data.initialState,
}}
onRowSelectionModelChange={(ids) => onRowsSelectionHandler(ids)}
components={{ NoRowsOverlay, NoResultsOverlay }}
pageSizeOptions={[5, 10, 15, 20, 50, 100]}
checkboxSelection={bool}
slots={{ toolbar: QuickSearchToolbar }}
componentsProps={{
pagination: {
labelRowsPerPage: 'Nb by page',
},
}}
/>
</>
);
};
What I have already tried:
If I switch the position in columns of 'level by user' and 'level by referent' then it is now 'level by user' which will be displayed twice
I also tried putting 'level by user' first and then adding 'level by referent' in the concat. But the same problem happens (I get the columns 'level by referent' twice)
I found an answer. Each column in the DataGrid should have a unique field property that identifies the column. In my code, the field property is not explicitly set for the 'Level by user' and 'Level by referent' columns, which might be causing the issue.
I have now add 'field: 'levelByReferent' and the same for user and it's now working!
{
headerName: 'Level by user',
headerAlign: 'center',
align: 'center',
field: 'levelByUser',
renderCell: (convertedRows) => {
const userLevel = convertedRows?.row?.Level?.find(
(level) => level?.Role === 'User'
);
return (
<Typography
sx={{
textAlign: 'center',
fontSize: '0.875rem',
width: 150,
height: 40,
...(userLevel?.Level === 'Expert' && {
color: 'green',
fontWeight: 'bold',
}),
...(userLevel?.Level === 'Confirmed' && {
color: 'green',
}),
...(userLevel?.Level === 'Intermediate' && {
color: 'orange',
}),
...(userLevel?.Level === 'Beginner' && {
color: 'lightsalmon',
}),
...(userLevel?.Level === 'Unknow' && { color: 'grey' }),
}}
>
{userLevel?.Level}
</Typography>
);
},
},
{
headerName: 'Level by referent',
headerAlign: 'center',
align: 'center',
field: 'levelByReferent',
renderCell: (convertedRows) => {
const referentLevel = convertedRows?.row?.Level?.find(
(level) => level?.Role === 'Referent'
);
console.log('2', referentLevel);
return (
<Typography
sx={{
textAlign: 'center',
fontSize: '0.875rem',
width: 150,
height: 40,
...(referentLevel?.Level === 'Expert' && {
color: 'green',
fontWeight: 'bold',
}),
...(referentLevel?.Level === 'Confirmed' && {
color: 'green',
}),
...(referentLevel?.Level === 'Intermediate' && {
color: 'orange',
}),
...(referentLevel?.Level === 'Beginner' && {
color: 'lightsalmon',
}),
...(referentLevel?.Level === 'Unknow' && { color: 'grey' }),
}}
>
{referentLevel?.Level}
</Typography>
);
},
},