Rows Duplicates MUI DataGrid - reactjs

I have a Data Grid component of the MUI and I am fetching data using axios, of course the objective is to show the data fetched in the Data Grid component, when I looked in the console it returns me correct, but in the page it returns me only one result o duplicating.
I believe there is a problem with the front-end but I am not able to identify it.
JSON
//Code
export default function ListGrid() {
const [load, setLoad] = useState(false);
const [users, setUsers] = useState<IDados[]>([]);
interface IDados {
empresa: number,
nome: string,
matricula: number,
ano: number,
}
useEffect(() => {
setLoad(true);
if (load === true) {
axios
.get("http://localhost:8080/questionarios/all", {
headers: {
...getTokenAuth()
},
})
.then((res) => {
setUsers(res.data);
// console.log(res.data);
})
}
}, [load]);
const columns: GridColDef[] = [
{
field: 'empresa',
headerName: 'Empresa',
width: 120,
headerAlign: 'center',
align: 'center',
},
{
field: 'nome',
headerName: 'Nome',
width: 250,
headerAlign: 'center',
align: 'center',
valueGetter: (params) => {
return params.getValue(params.id, "colaborador").nome;
}
},
{
field: 'matricula',
headerName: 'Matrícula',
width: 150,
headerAlign: 'center',
align: 'center',
},
{
field: 'ano',
headerName: 'Ano',
width: 150,
headerAlign: 'center',
align: 'center',
},
];
return (
<Box sx={{ height: 400, width: '100%' }}>
<DataGrid
rows={users}
columns={columns}
checkboxSelection
disableSelectionOnClick
experimentalFeatures={{ newEditingApi: true }}
localeText={ptBR.components.MuiDataGrid.defaultProps.localeText}
pageSize={pageSize}
onPageSizeChange={(newPageSize) => setPageSize(newPageSize)}
rowsPerPageOptions={[5, 10, 20]}
pagination
initialState={{
filter: {
filterModel: {
items: [],
quickFilterLogicOperator: GridLinkOperator.Or,
},
},
}}
components={{ Toolbar: barraPesquisa }}
getRowId={(row: any) => row.name + row.matricula}
/>
</Box>
);
}

Your warning message seems to indicate some keys are NaN. Maybe you have a problem with
getRowId={(row: any) => row.name + row.matricula}
which return NaN for some rows

Related

Using MUI DataGrid, how to update a cell state onChange?

What I need: I'm using MUI DataGrid > 5. I need that the data that is filled in a cell change automatically the state (onChange). At this moment, I have an useEffect that is listening to these changes to “enable/disable” the “Save” and “Cancel” buttons.
What I tried: Using onCellEditCommit property, it saves the cell content only when I click outside the DataGrid component (or when I press tab or enter). I would like to save the content on cell change.
...
import {
DataGrid,
GridColDef,
GridPreProcessEditCellProps,
GridRowId,
} from "#mui/x-data-grid";
...
const [devices, setDevices] = useState<Device[]>(formValues.devices);
const columns: GridColDef[] = [
{
field: "id",
headerName: "ID",
flex: 10,
},
{
field: "uniqueIdentification",
headerName: "Unique ID",
editable: true,
flex: 30,
},
{
field: "description",
headerName: "Description",
editable: true,
flex: 50,
},
{
field: "isActive",
headerName: "Active",
type: "boolean",
editable: true,
flex: 10,
},
{
field: "actions",
type: "actions",
headerName: "Actions",
width: 100,
cellClassName: "actions",
renderCell: (params) => (
<Box id={`${params.id}`} component="div">
<IconButton
title="Remove"
onClick={() => deleteRow(params.id)}
size="small"
>
<DeleteIcon />
</IconButton>
</Box>
),
},
];
function saveDeviceCell(params) {
const oldDevices = [...devices];
const rowDeviceIndex = oldDevices.findIndex((dev) => dev.id === params.id);
oldDevices[rowDeviceIndex] = {
...oldDevices[rowDeviceIndex],
[params.field]: params.value,
};
setDevices(oldDevices);
}
...
return (
<DataGrid
rows={devices}
columns={columns}
hideFooterPagination
hideFooter
disableSelectionOnClick
autoHeight
onCellEditCommit={saveDeviceCell}
editMode="cell"
/>
...
);

Material-UI Datagrid - Replace column headers with a custom toolbar

I am using Material UI DataGrid in my project and I need to replace all the column headers (except the checkbox column) to a toolbar. currently what I have columns like this:
I need to replace those columns headers with a toolbar like this, but leave the checkbox
header cell
As you can see, the columns header replaced with this toolbar except the checkbox.
my columns definitions looks like this:
export const columns: GridColDef[] = [
{
field: "summary",
flex: 1,
minWidth: 110,
renderCell: (params: GridRenderCellParams) => <SummaryCell />,
},
{
field: "accounts",
flex: 1,
renderCell: (params: GridRenderCellParams) => (
<PossibleAccountsCell/>
),
},
{
field: "found",
headerName: "Found",
flex: 1,
renderCell: (params: GridRenderCellParams) => (
<FoundSubjectsCell/>
),
},
{
field: "inputType",
headerName: "Progress",
flex: 1,
renderCell: (params: GridRenderCellParams) => (
<ProgressCell/>
),
},
{
field: "view",
width: 245,
renderCell: (params: GridRenderCellParams) => (
<ViewReportCell />
),
},
];
My DataGrid:
<DataGrid
sx={{
"& .MuiDataGrid-cell": {
padding: 0,
},
"& .MuiCheckbox-root": {
padding: 0,
},
"& .MuiDataGrid-columnHeader:focus-within, & .MuiDataGrid-cell:focus-within":
{
outline: "none",
},
"& .MuiDataGrid-columnHeader:focus, & .MuiDataGrid-cell:focus": {
outline: "none",
},
}}
autoHeight
rows={collectionData.collections}
columns={columns}
paginationMode="server"
pageSize={collectionData.collectionsPerPage}
checkboxSelection
disableSelectionOnClick
rowHeight={80}
/>
I know I can set all the column headers to "display: none" and replace them with custom toolbar, but then I will loose the checkbox column header that I need.
Is there a way to replace them?

react-redux prevent rerendering of list items when the state changes

I have a list item callled Row. The Row has three sections, I have stored the width of each sections in a state
rowWidth: [
{
id: 'name',
width: 200,
},
{
id: 'size',
width: 70,
},
{
id: 'status',
width: 150,
},
{
id: 'progress',
width: 200,
},
{
id: 'lasttry',
width: 200,
},
{
id: 'eta',
width: 50,
},
]
I change width of a single column by an external handle which updates the store.
switch (actions.type) {
case consts.CHANGE_HEADER_WIDTH : return {
...state,
headerWidth: state.headerWidth.map((item) =>
item.id === actions.payload.id ? { ...item, width: actions.payload.neWidth } : item
),
}
break;
default : return state;
}
This is the row
const headerWidth = useSelector((state) => state.ui.headerWidth)
const getWidth = useCallback((id) => {
const l = _.find(headerWidth, function (item) {
return item.id === id
})
return l.width
})
return(
<Row>
<Section1 style={{ width: getRow('name') }}/>
<Section2 style={{ width: getRow('size') }}/>
<Section3 style={{ width: getRow('status') }}/>
</Row>
)
My question is - how do I change the width of these divs without rerendering row
Thank you all for the help. I understand that there has to be a rerender in order to view the state change.

React material-ui datagrid editing Issue

I have created a Material UI DataGrid table and trying to make its fields editable. I am facing an issue while editing the fields using my custom logic. My custom editing logic works when I press enter however when I edit the value and then click outside of the column (somewhere else on the page) the internal value gets updated according to the logic however the displayed cell value doesn't match the updated value, it shows the user-edited value.
import React, { useEffect } from "react";
import { makeStyles, LinearProgress } from "#material-ui/core";
import {
DataGrid,
GridColDef,
GridOverlay,
GridCellEditCommitParams,
GridValueFormatterParams,
} from "#material-ui/data-grid";
const useStyles = makeStyles({
root: {
"& .super-app-theme--header": {
backgroundColor: "#f2f2f2",
},
},
muiGridRoot: {
maxHeight: "77px !important",
"& .MuiDataGrid-columnHeaderTitle": {
fontWeight: "600 !important" as any,
},
},
});
interface props {
coilId: string;
}
export default function TargetMechnicalPropsTable({
coilId,
}: props) {
const classes = useStyles();
const [rows, setRows] = React.useState<any>([
{
id: 1,
UpperLimitValue: 124.232,
lowerLimitValue: 24.232,
targetValue: 67.33,
element: "Yield Strength",
},
]);
const columns: GridColDef[] = [
{
field: "id",
hide: true,
headerClassName: "super-app-theme--header",
sortable: false,
flex: 1,
align: "center",
headerAlign: "center",
},
{
field: "element",
headerName: "Element",
headerClassName: "super-app-theme--header",
editable: false,
sortable: false,
flex: 1,
align: "center",
headerAlign: "center",
},
{
field: "targetValue",
headerName: "Target value",
headerClassName: "super-app-theme--header",
valueFormatter: (params: GridValueFormatterParams) => {
const valueFormatted = Number(params.value as number).toFixed(4);
return `${valueFormatted}`;
},
editable: true,
//type: "number",
sortable: false,
flex: 1,
align: "center",
headerAlign: "center",
},
{
field: "lowerLimitValue",
headerName: "Lower Limit",
headerClassName: "super-app-theme--header",
valueFormatter: (params: GridValueFormatterParams) => {
const valueFormatted = Number(params.value as number).toFixed(4);
return `${valueFormatted}`;
},
editable: true,
sortable: false,
flex: 1,
align: "center",
headerAlign: "center",
},
{
field: "UpperLimitValue",
headerName: "Upper Limit",
headerClassName: "super-app-theme--header",
sortable: false,
valueFormatter: (params: GridValueFormatterParams) => {
const valueFormatted = Number(params.value as number).toFixed(4);
return `${valueFormatted}`;
},
editable: true,
flex: 1,
align: "center",
headerAlign: "center",
},
];
const handleCellEditCommit = React.useCallback(
({ id, field, value }: GridCellEditCommitParams) => {
const updatedRows = rows.map((row: any) => {
if (row.id === id) {
switch (field) {
case "lowerLimitValue":
if (
Number(value) < Number(row.targetValue) &&
Number(value) < Number(row.UpperLimitValue)
) {
return { ...row, lowerLimitValue: Number(value) };
} else {
return {
...row,
lowerLimitValue: Number(row.lowerLimitValue),
};
}
case "UpperLimitValue":
if (
Number(value) > Number(row.targetValue) &&
Number(value) > Number(row.lowerLimitValue)
) {
return { ...row, UpperLimitValue: Number(value) };
} else {
return {
...row,
UpperLimitValue: Number(row.UpperLimitValue),
};
}
case "targetValue":
if (
Number(value) > Number(row.lowerLimitValue) &&
Number(value) < Number(row.UpperLimitValue)
) {
return { ...row, targetValue: Number(value) };
} else {
return {
...row,
targetValue: Number(row.targetValue),
};
}
}
}
return row;
});
setRows(updatedRows);
},
[rows]
);
return (
<div style={{ width: "100%" }} className={classes.root}>
<DataGrid
classes={{
root: classes.muiGridRoot,
}}
rows={rows}
columns={columns}
hideFooterPagination
hideFooter
disableColumnMenu
disableColumnFilter
disableColumnSelector
autoHeight
disableExtendRowFullWidth
density="compact"
onCellEditCommit={handleCellEditCommit}
/>
</div>
);
}
Please let me know what needs to be done for my custom logic to work when the user clicks outside of the column while editing it so that the user displayed value matches with the internal logic value.
Thank you!

How to add a dropdown or checkbox to the filter in Material-UI dataGrid/XGrid

I am trying to add a checkbox or dropdown to one of the column filter. I have tried using type="boolean" to the columns, it is creating the dropdown but not it not creating the list as I expect. I am expecting the dropdown with two option like "Reachable" and "Unreachable" but it is creating "true" or "false".
Is their any prop name to create the names for the Filter types? I am expecting like this
or
But I am getting like this
My code looks like this
let rows = list.map((obj, index) => {
return (rows = {
id: index,
"Device ID": obj.device_ID,
Status: obj.device_status,
"Last Reading": obj.device_time
});
});
const columns = [
{
field: "Device ID",
flex: 1,
renderHeader: () => <FormattedMessage id={"device.param.deviceMrid"} />
},
{
field: "Status",
flex: 1,
type: "boolean",
renderHeader: () => <FormattedMessage id={"history.param.deviceStatus"} />
},
{
field: "Last Reading",
flex: 1,
type: "dateTime",
renderHeader: () => (
<FormattedMessage id={"history.param.deviceStatusDate"} />
)
}
];
<div style={{ height: "90%", width: "100%" }}>
<XGrid
pageSize={50}
rowsPerPageOptions={[25, 50, 100]}
rows={rows}
columns={columns}
pagination={true}
/>
</div>;
Thank you!!
You need to add these 2 rows in your column const:
type: "singleSelect",
valueOptions: ["select1","select2",.....]
from {
field: 'brand',
headerName: 'Brand',
width: 150,
editable: false,
},
to
{
field: 'brand',
headerName: 'Brand',
width: 150,
editable: false,
type: "singleSelect",
valueOptions: ["select1","select2",.....]
},

Resources