I am trying to create a table using MUI X DataGridPro, where sorting functionality in every field is working except the email. Im going to add some gibberish here so that my question gets published. Please ignore the following string "jahgfhujagfyuawfqawguyfbvqwuhfgyuqwfvbiuwqegcvyuewqbvcuiwegvuyewbcvuyewgvfuyewvbyutgwevbuywevyuwebvuywebvuiywergvbywevbtgywebvuywebcvuiyqwfgvuyqwcbiqwueyfbvweiufvuewbfewuvbcieuwfvyuwefvbewyucvweuiyfgvqeuifhbeiuqwfgbiweufbyweiubviuwevfweifgvbweuybvcweuigfvuwifvwefbhueqwfviqugdfvuywefbweyuifvbuiwefgvwefgweyufbefgeuywhfbbfiew"
/* eslint-disable no-nested-ternary */
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import {
Box,
Grid,
IconButton,
} from '@mui/material';
import Tooltip from '@mui/material/Tooltip';
import EmailOutlinedIcon from '@mui/icons-material/EmailOutlined';
import { useTranslation } from 'react-i18next';
import { DataGridPro } from '@mui/x-data-grid-pro';
import { NavigateRoutes } from '../../../constant';
import useStyles from '../../../custom-hooks/useStyles';
import styles from '../my-class/style';
import { CustomUnsortedIcon, CustomAscendingIcon, CustomDescendingIcon } from '../../../utils/commonUiComponent';
import Constant from '../../../store/constant';
import { setLocalStorage } from '../../../utils/localStorageMethod';
export default function ListView({
studentsData,
checkboxChanged,
loading,
setError,
setOpenDialog,
// courseName,
}) {
const classes = useStyles(styles)();
const { t } = useTranslation();
const dispatch = useDispatch();
const navigate = useNavigate();
localStorage.setItem('sendSingleEmail', false);
const getMarksHeader = () => (
<div>
<span style={{ height: '5vh' }}>
{t('MARKS')}
</span>
<div>{t('Q2')}</div>
</div>
);
const getHomeworkHeader = () => (
<div>
<span style={{ height: '5vh', left: -14 }}>
{t('HOMEWORK')}
</span>
<div>{t('Q2')}</div>
</div>
);
const columns = [
{
field: 'studentName',
headerName: t('STUDENT_NAME'),
align: 'left',
sortable: true,
class: 'studentNameField',
headerClassName: 'studentNameHeader',
cellClassName: 'studentNameCell',
renderCell: (rowValues) => (
<Tooltip title={`${rowValues?.row?.studentInfo?.firstName} ${rowValues?.row?.studentInfo?.lastName}`}>
<div className={classes.wrappingCell}>{`${rowValues?.row?.studentInfo?.firstName} ${rowValues?.row?.studentInfo?.lastName}`}</div>
</Tooltip>
),
},
{
field: 'parentName',
headerName: t('PARENT_NAME'),
align: 'left',
sortable: true,
headerClassName: 'parentHeader',
cellClassName: 'parentNameCell',
renderCell: (rowValues) => (
<Tooltip title={`${rowValues?.row?.parent1Info?.firstName} ${rowValues?.row?.parent1Info?.lastName}`}>
<div className={classes.wrappingCell}>{`${rowValues?.row?.parent1Info?.firstName} ${rowValues?.row?.parent1Info?.lastName}`}</div>
</Tooltip>
),
},
{
field: 'studentEmailAddress',
headerName: t('STUDENT_EMAIL_ADDRESS'),
sortable: true,
align: 'left',
headerAlign: 'left',
headerClassName: 'studentEmailHeader',
cellClassName: 'studentEmailCell',
renderCell: (rowValues) => (
<Tooltip title={`${rowValues?.row?.studentInfo?.manabadiEmail}`}>
<div className={classes.wrappingCell}>{`${rowValues?.row?.studentInfo?.manabadiEmail}`}</div>
</Tooltip>
),
},
{
field: 'marksQ1',
sortable: false,
headerName: t('Q1'),
align: 'center',
headerClassName: 'marksHeader',
cellClassName: 'marksCell',
renderCell: (cellValues) => (
<Box
component="span"
onClick={(e) => setOpenDialog(e, cellValues, 'marks', 'Q1')}
className={cellValues?.row?.marks?.Q1?.obtainedMarks >= cellValues?.row?.marks?.Q1?.passingCriteria ? classes.marksGreen
: cellValues?.row?.marks?.Q1?.obtainedMarks < parseInt(cellValues?.row?.marks?.Q1?.passingCriteria, 10) - 10
? classes.marksRed : cellValues?.row?.marks?.Q1?.obtainedMarks >= parseInt(cellValues?.row?.marks?.Q1?.passingCriteria, 10) - 10
? classes.marksYellow : classes.marksGrey}
>
{cellValues?.row?.marks?.Q1?.passingCriteria
? Number.isInteger(cellValues?.row?.marks?.Q1?.obtainedMarks) ? cellValues?.row?.marks?.Q1?.obtainedMarks : Number(cellValues?.row?.marks?.Q1?.obtainedMarks).toFixed(2) : '-'}
{cellValues?.row?.marks?.Q1?.passingCriteria && !cellValues?.row?.marks?.Q1?.isAttended ? '(A)' : ''}
</Box>
),
},
{
field: 'marksQ2',
headerName: getMarksHeader(),
disableColumnResize: 'false',
align: 'left',
headerClassName: 'marksHeader',
cellClassName: 'marksCell',
sortable: false,
renderCell: (cellValues) => (
<Box
component="span"
onClick={(e) => setOpenDialog(e, cellValues, 'marks', 'Q2')}
className={cellValues?.row?.marks?.Q2?.obtainedMarks >= cellValues?.row?.marks?.Q2?.passingCriteria ? classes.marksGreen
: cellValues?.row?.marks?.Q2?.obtainedMarks < parseInt(cellValues?.row?.marks?.Q2?.passingCriteria, 10) - 10
? classes.marksRed : cellValues?.row?.marks?.Q2?.obtainedMarks >= parseInt(cellValues?.row?.marks?.Q2?.passingCriteria, 10) - 10
? classes.marksYellow : classes.marksGrey}
>
{cellValues?.row?.marks?.Q2?.passingCriteria
? Number.isInteger(cellValues?.row?.marks?.Q2?.obtainedMarks) ? cellValues?.row?.marks?.Q2?.obtainedMarks : Number(cellValues?.row?.marks?.Q2?.obtainedMarks).toFixed(2) : '-'}
{cellValues?.row?.marks?.Q2?.passingCriteria && !cellValues?.row?.marks?.Q2?.isAttended ? '(A)' : ''}
</Box>
),
},
{
field: 'marksQ3',
headerName: t('Q3'),
headerClassName: 'marksHeader',
align: 'left',
cellClassName: 'marksCell',
sortable: false,
renderCell: (cellValues) => (
<Box
component="span"
onClick={(e) => setOpenDialog(e, cellValues, 'marks', 'Q3')}
className={cellValues?.row?.marks?.Q3?.obtainedMarks >= cellValues?.row?.marks?.Q3?.passingCriteria
? classes.marksGreen
: cellValues?.row?.marks?.Q3?.obtainedMarks < parseInt(cellValues?.row?.marks?.Q3?.passingCriteria, 10) - 10
? classes.marksRed : cellValues?.row?.marks?.Q3?.obtainedMarks >= parseInt(cellValues?.row?.marks?.Q3?.passingCriteria, 10) - 10
? classes.marksYellow : classes.marksGrey}
>
{cellValues?.row?.marks?.Q3?.passingCriteria
? Number.isInteger(cellValues?.row?.marks?.Q3?.obtainedMarks) ? cellValues?.row?.marks?.Q3?.obtainedMarks : Number(cellValues?.row?.marks?.Q3?.obtainedMarks).toFixed(2) : '-'}
{cellValues?.row?.marks?.Q3?.passingCriteria && !cellValues?.row?.marks?.Q3?.isAttended ? '(A)' : ''}
</Box>
),
},
{
field: 'homeworkQ1',
sortable: false,
headerName: t('Q1'),
align: 'center',
headerClassName: 'marksHeader',
cellClassName: 'marksCell',
renderCell: (cellValues) => (
<Box
component="span"
onClick={(e) => setOpenDialog(e, cellValues, 'homework', 'Q1')}
className={cellValues?.row?.homeworkMarks?.Q1?.weightage
? classes.homeworkColor : classes.marksGrey}
>
{cellValues?.row?.homeworkMarks?.Q1?.weightage
? Number.isInteger(cellValues?.row?.homeworkMarks?.Q1?.obtainedMarks) ? cellValues?.row?.homeworkMarks?.Q1?.obtainedMarks : Number(cellValues?.row?.homeworkMarks?.Q1?.obtainedMarks).toFixed(2) : '-'}
</Box>
),
},
{
field: 'homeworkQ2',
headerName: getHomeworkHeader(),
disableColumnResize: 'false',
align: 'left',
headerClassName: 'homeworkHeader',
cellClassName: 'homeworkCell',
sortable: false,
renderCell: (cellValues) => (
<Box
component="span"
onClick={(e) => setOpenDialog(e, cellValues, 'homework', 'Q2')}
className={cellValues?.row?.homeworkMarks?.Q2?.weightage
? classes.homeworkColor : classes.marksGrey}
>
{cellValues?.row?.homeworkMarks?.Q2?.weightage
? Number.isInteger(cellValues?.row?.homeworkMarks?.Q2?.obtainedMarks) ? cellValues?.row?.homeworkMarks?.Q2?.obtainedMarks : Number(cellValues?.row?.homeworkMarks?.Q2?.obtainedMarks).toFixed(2) : '-'}
</Box>
),
},
{
field: 'homeworkQ3',
headerName: t('Q3'),
headerClassName: 'marksHeader',
align: 'left',
cellClassName: 'marksCell',
sortable: false,
renderCell: (cellValues) => (
<Box
component="span"
onClick={(e) => setOpenDialog(e, cellValues, 'homework', 'Q3')}
className={cellValues?.row?.homeworkMarks?.Q3?.weightage
? classes.homeworkColor : classes.marksGrey}
>
{cellValues?.row?.homeworkMarks?.Q3?.weightage
? Number.isInteger(cellValues?.row?.homeworkMarks?.Q3?.obtainedMarks) ? cellValues?.row?.homeworkMarks?.Q3?.obtainedMarks : Number(cellValues?.row?.homeworkMarks?.Q3?.obtainedMarks).toFixed(2) : '-'}
</Box>
),
},
{
field: 'bonus',
headerName: t('BONUS_MARKS'),
align: 'left',
sortable: false,
headerClassName: 'bonusHeader',
cellClassName: 'bonusCell',
renderCell: (cellValues) => (
<Box
component="span"
onClick={(e) => setOpenDialog(e, cellValues, 'bonus', null)}
className={classes.marksGreen}
>
{cellValues?.row?.bonus || 0}
</Box>
),
},
{
field: 'grade',
headerName: t('GRADE'),
align: 'left',
sortable: false,
headerClassName: 'gradeHeader',
cellClassName: 'gradeCell',
},
{
field: 'gpa',
headerName: t('GPA'),
align: 'left',
sortable: false,
headerClassName: 'gpaHeader',
cellClassName: 'gpaCell',
},
{
field: 'annualScore',
headerName: t('ANNUAL_SCORE'),
align: 'left',
sortable: true,
headerClassName: 'annualHeader',
cellClassName: 'annualCell',
},
{
field: 'actions',
headerName: t('ACTIONS'),
align: 'left',
sortable: false,
headerClassName: 'actionHeader',
cellClassName: 'actionCell',
renderCell: (row) => (
<Grid item xs={12} lg={3} display="flex">
<Tooltip title={t('SEND_EMAIL')}>
<IconButton
className={classes.emailIconColor}
onClick={() => {
const { manabadiEmail } = row.row.studentInfo;
const emailParents = [];
emailParents.push(row?.row?.parent1Info?.personalEmail?.toString());
emailParents.push(row?.row?.parent2Info?.personalEmail?.toString());
dispatch({ type: Constant.RECIPIENTS, payload: [manabadiEmail] });
dispatch({ type: Constant.MAIL_FILTER, payload: 'Student' });
dispatch({ type: Constant.MAIL_PARENTS, payload: emailParents });
setLocalStorage('showLocationFilterRecipients', false);
setLocalStorage('showLocationAnnouncementsRecipients', false);
setLocalStorage('showSelectAllinEmail', false);
localStorage.setItem('sendSingleEmail', true);
navigate(NavigateRoutes.TEACHER_VIEW_EMAIL);
}}
>
<EmailOutlinedIcon />
</IconButton>
</Tooltip>
</Grid>
),
},
];
return (
<Grid container className={classes.studentDetails}>
{/* {studentsData?.length > 0
&& ( */}
<DataGridPro
rows={studentsData}
columns={columns}
autoHeight
disableColumnFilter
disableColumnSelector
disableColumnMenu
disableColumnResize
disableSelectionOnClick
disableColumnReorder
checkboxSelection
hideFooterRowCount
hideFooter
hideFooterSelectedRowCount
hideFooterPagination
className={classes.dataGridMyClass}
components={{
ColumnUnsortedIcon: CustomUnsortedIcon,
ColumnSortedAscendingIcon: CustomAscendingIcon,
ColumnSortedDescendingIcon: CustomDescendingIcon,
}}
onSelectionModelChange={(ids) => {
setError('');
const selectedIDs = new Set(ids);
const selectedData = studentsData.filter((row) => selectedIDs.has(row.id));
checkboxChanged(selectedData);
}}
pageSize={100}
loading={loading}
/>
{/* )} */}
</Grid>
);
}
This in one of the JSON data
{
"id": 0,
"dateOfBirth": "2014-10-09T00:00:00.000Z",
"studentInfo": {
"firstName": "Chetan reddy",
"middleName": "",
"lastName": "12be548432f3",
"manabadiEmail": "Chetan.12be548432f3@manabadi.siliconandhra.org"
},
"parent1Info": {
"firstName": "Maruthi",
"middleName": "",
"lastName": "1e56d8ab18e4",
"personalEmail": "@gmail.com"
},
"parent2Info": {
"firstName": "Indhira",
"middleName": "",
"lastName": "7463913cab45",
"personalEmail": "@gmail.com"
},
"enrolled_courses": [
{
"courseId": "24b32206-b67e-4f90-9d81-3cdda3d35641",
"returningStudent": false,
"averageScore": 46.5
}
],
"newReturning": false,
"marks": {
"Q1": {
"obtainedMarks": 0,
"isAttended": null
},
"Q2": {
"obtainedMarks": 0,
"isAttended": null
},
"Q3": {
"obtainedMarks": 0,
"isAttended": null
}
},
"homeworkMarks": {
"Q1": {
"obtainedMarks": 0
},
"Q2": {
"obtainedMarks": 0
},
"Q3": {
"obtainedMarks": 0
}
},
"bonus": "",
"grade": "N/A",
"gpa": "N/A",
"annualScore": "46.50",
"key": 0,
"profilePhoto": "undefined ",
"studentName": "Chetan reddy 12be548432f3 ",
"studentId": "6dd0c081-1842-49f2-a18b-72dbb226cda6",
"parentName": "Maruthi 1e56d8ab18e4 ",
"phoneNumber": "",
"homeworkQ1": 0,
"homeworkQ2": 0,
"homeworkQ3": 0,
"marksQ1": 0,
"marksQ2": 0,
"marksQ3": 0
}
Every field is working except the email. Can anyone please give any solution?
The sorting works on the value supplied in field
, and there's no studentEmailAddress
field on the object. You could either re-map the email to be flat in line with the other fields, or use sortComparator to ensure the DataGrid's looking at row?.studentInfo?.manabadiEmail