user23600793
user23600793

Reputation: 1

MUI-X DataGrid not updating

I wanted to make my own custom component that will render with the slots prop of MUI-X DataGrid.

But I have a problem, when filtering the rowdata, rowData state it is not rerendering or updating the DataGrid.

This is the component holding state and the DataGrid

import { useEffect, useState } from "react";
import { Box, IconButton, Stack, Typography } from "@mui/material";
import QuestionAnswerIcon from "@mui/icons-material/QuestionAnswer";
import Drawer from "../reusable/Drawer";
import { styles } from "../styling/Styles";
import { DataGrid, GridToolbar } from "@mui/x-data-grid";
import useSWR from "swr";
import { getAll } from "../../api";
import { formatDate } from "../../utils/formatDate";
import GroupedGridRow from "../reusable/GroupedGridRow";
import { useGridApiRef } from "@mui/x-data-grid";

const ADMIN_ITEMS = ["Customers", "Suppliers", "Review change requests"];
const DATAGRID_COLUMNS = [
  {
    field: "createdAt",
    headerName: "Request date",
    width: 150,
    valueFormatter: (params) => formatDate(params.value),
  },
  {
    field: "name",
    headerName: "Name",
    width: 150,
  },
  {
    field: "username",
    headerName: "Username",
    width: 150,
  },
  {
    field: "emailaddress",
    headerName: "Emailaddress",
    width: 150,
  },
  {
    field: "phoneNumber",
    headerName: "Phone Number",
    width: 150,
  },
  {
    field: "vatNumber",
    headerName: "VAT Number",
    width: 150,
  },
  {
    field: "sector",
    headerName: "Sector",
    width: 150,
  },
  {
    field: "billingAddressLine",
    headerName: "Billing Address",
    width: 150,
  },
  {
    field: "billingPostalCode",
    headerName: "Billing Postal Code",
    width: 150,
  },
  {
    field: "billingCity",
    headerName: "Billing City",
    width: 150,
  },
  {
    field: "billingCountry",
    headerName: "Billing Country",
    width: 150,
  },
  {
    field: "shippingAddressLine",
    headerName: "Shipping Address",
    width: 150,
  },
  {
    field: "shippingPostalCode",
    headerName: "Shipping Postal Code",
    width: 150,
  },
  {
    field: "shippingCity",
    headerName: "Shipping City",
    width: 150,
  },
  {
    field: "shippingCountry",
    headerName: "Shipping Country",
    width: 150,
  },
];

const INITIAL_DATA = [
  {
    id: 1,
    oldData: {
      name: "Roger's Poppie Shop",
      username: "PoppiePoppin",
      billingAddressLine: "PoppieStreet 21",
      vatNumber: "BE56143",
      phoneNumber: "+2 578941312",
    },
    newData: {
      name: "Roger's Coffee Shop",
      username: "CoffeePoppin",
      billingAddressLine: "CoffeStreet 21",
      vatNumber: "FR56143",
    },
  },
  {
    id: 2,
    oldData: {
      name: "Billie's Poppie Shop",
      username: "BilliePoppie",
      billingAddressLine: "Billystreet 21",
      vatNumber: "BE56143",
    },
    newData: {
      name: "Billy's Coffee Shop",
      username: "Billy coffee",
      billingAddressLine: "BillingCoffee 21",
      vatNumber: "FR56143",
    },
  },
  {
    id: 3,
    oldData: {
      name: "Chinese Shop",
      username: "ChineseeShop",
      billingAddressLine: "ChinaStreet 21",
      vatNumber: "ES56143",
      phoneNumber: "+2 578941312",
    },
    newData: {
      name: "Japan shop",
      username: "JapanShop",
      billingAddressLine: "JapanStreet 21",
      vatNumber: "JA56143",
    },
  },
];

export default function Admin() {
  const [selectedTabIdx, setSelectedTabIdx] = useState(0);
  const [selectedRows, setSelectedRows] = useState([]);
  const apiRef = useGridApiRef();
  const [rowData, setRowData] = useState(INITIAL_DATA);

  const handleListItemBtnClick = (tabIdx) => {
    setSelectedTabIdx(tabIdx);
  };



  const handleFilterModelChange = (model, details) => {
    const filteredData = filterData(INITIAL_DATA, model);
    setRowData(filteredData);
  };

  const filterData = (data, model) => {
    // model.items = model.items.filter((item) => item.value != undefined);
    // if (model.items.length < 1) {
    //   return INITIAL_DATA;
    // }
    console.log(model);
    const operators = {
      contains: (v, value) => v && v.includes(value),
      equals: (v, value) => v === value,
      startsWith: (v, value) => v && v.startsWith(value),
      endsWith: (v, value) => v && v.endsWith(value),
      isEmpty: (v) => v === "",
      isNotEmpty: (v) => v !== "",
      isAnyOf: (v, value) => v && value.includes(v),
    };

    return data.filter((row) => {
      console.log("in here");
      return model.items.every((filterItem) => {
        const { field, operator, value } = filterItem;
        const cellValueOld = row.oldData[field];
        const cellValueNew = row.newData[field];
        const operatorFunction = operators[operator];
        console.log(`Field:${field}, Operator:${operator}, Value:${value}`);

        if (operatorFunction) {
          if (cellValueOld && operatorFunction(String(cellValueOld), value)) {
            return true;
          }
          if (cellValueNew && operatorFunction(String(cellValueNew), value)) {
            return true;
          }
          return false;
        }

        return false;
      });
    });
  };

  const handleSelectionModelChange = (id) => {
    if (selectedRows.indexOf(id) !== -1) {
      const update = selectedRows.filter((e) => e !== id);
      setSelectedRows(update);
      return;
    } else if (id instanceof Array) {
      setSelectedRows(id);
      return;
    } else {
      setSelectedRows((oldValue) => [...oldValue, id]);
    }
  };

  const handleSortModelChange = (model, details) => {
    console.log("sorting changed");
    setRowData(sortData(rowData, model));
  };

  function sortData(data, sortModel) {
    const sortedData = [...data];

    sortedData.sort((a, b) => {
      for (let i = 0; i < sortModel.length; i++) {
        const { field, sort } = sortModel[i];
        const aValueOld = a.oldData[field];
        const bValueOld = b.oldData[field];
        const aValueNew = a.newData[field];
        const bValueNew = b.newData[field];
        if (aValueOld < bValueOld || aValueNew < bValueNew) {
          return sort === "asc" ? -1 : 1;
        }
        if (aValueOld > bValueOld || aValueNew > bValueNew) {
          return sort === "asc" ? 1 : -1;
        }
      }
      return 0;
    });

    return sortedData;
  }

  const handleColumnModelChange = (model, details) => {
    console.log(model);
    //setRowData(rowData);
  };

  useEffect(() => {
    console.log(rowData);
    // if (apiRef.current.forceUpdate) {
    //   apiRef.current.forceUpdate();
    //   console.log("forrcing updatee");
    // }
  }, [rowData]);

  return (
    <>
      <Stack direction="row" display="flex">
        <Box sx={{ display: "flex" }}>
          <Drawer
            type="admin"
            handleListItemBtnClick={handleListItemBtnClick}
            listItems={ADMIN_ITEMS}
          />
        </Box>
        <Stack sx={{ width: "100%" }} spacing={1}>
          <Box
            sx={{
              width: "100%",
              textAlign: "center",
              bgcolor: "box.main",
              color: "white.main",
            }}
          >
            <Typography variant="h5">{`Welcome to the ${
              ADMIN_ITEMS[selectedTabIdx].charAt(0).toLowerCase() +
              ADMIN_ITEMS[selectedTabIdx].slice(1)
            } section`}</Typography>
          </Box>

          {selectedTabIdx === 2 && (
            <Box sx={{ width: "100%" }}>
              <DataGrid
                apiRef={apiRef}
                columns={DATAGRID_COLUMNS}
                rows={rowData}
                checkboxSelection
                slots={{
                  toolbar: GridToolbar,
                  row: (props) => (
                    <GroupedGridRow
                      {...props}
                      columns={DATAGRID_COLUMNS}
                      handleSelectionModelChange={handleSelectionModelChange}
                    />
                  ),
                }}
                onRowSelectionModelChange={handleSelectionModelChange}
                rowSelectionModel={selectedRows}
                onSortModelChange={handleSortModelChange}
                onFilterModelChange={handleFilterModelChange}
                onColumnVisibilityModelChange={handleColumnModelChange}
                density="standard"
              />
            </Box>
          )}
        </Stack>
        <Box
          m={4}
          p={2}
          height={"50px"}
          width={"50px"}
          sx={{ ...styles.redBox, ...styles.chatBot }}
        >
          <IconButton>
            <QuestionAnswerIcon />
          </IconButton>
        </Box>
      </Stack>
    </>
  );
}

This is the custom row component

import { gridClasses } from "@mui/x-data-grid";

export default function GroupedGridRow({
  row,
  selected,
  columns,
  handleSelectionModelChange,
  ...other
}) {

  
  const handleCheckboxChange = (e) => {
    handleSelectionModelChange(row.id);
  };

  return (
    <div {...other} className={gridClasses.row}>
      <input
        type="checkbox"
        checked={selected}
        onChange={handleCheckboxChange}
      />
      <div
        style={{ display: "flex", flexDirection: "column", marginLeft: "8px" }}
      >
        <div className={gridClasses.row}>
          {columns.map((column) => (
            <div
              key={column.field}
              className={gridClasses.cell}
              style={{ width: column.width }}
            >
              {row.oldData[column.field]}
            </div>
          ))}
        </div>
        <div className={gridClasses.row}>
          {columns.map((column) => (
            <div
              key={column.field}
              className={gridClasses.cell}
              style={{ width: column.width }}
            >
              {row.newData[column.field]}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

I have tried forceUpdating with the apiRef, console.logging if the state changes (it does), checking if my filter function works correctly (it does)

Do you guys know how I can fix this?

Codesandbox I made:https://rb.gy/u4i7wl

Upvotes: 0

Views: 171

Answers (0)

Related Questions