skip to Main Content

Langage used : javascript with react, redux toolkit and mui

Problematic : I am trying to set all checkbox selected from different datagrid to one state

What I have tried and done : I tried to set first the checkbox from indivual datagrid (working, you can see it bellow) and tried to put the onRowsSelectionHandler function in the const with all datagrid (AdminTable)

Here is my reusable component for Datagrid

    import React from 'react';
import { DataGrid } from '@mui/x-data-grid';
import { useDispatch } from 'react-redux';
import { setSkillSelected } from '../slices/skillSlice';
import { useSearchBar } from '../hooks/useSearchBar';
export const TableReusable = ({ data, columns, bool }) => {
  const dispatch = useDispatch();

  const onRowsSelectionHandler = (ids) => {
    const selectedRowsData = ids?.map((id) =>
      data?.find((row) => row?._id === id || row?.id === id)
    );

    dispatch(setSkillSelected(selectedRowsData));
  };

  const filteredRows = useSearchBar({ row: data });

  return (
    <DataGrid
      sx={{ width: 'fit-content' }}
      rows={filteredRows}
      getRowId={(row) => row?.id || row?._id || row?.CommonId} // Spécifiez la fonction pour obtenir l'identifiant de chaque ligne
      columns={columns}
      initialState={{
        pagination: { paginationModel: { pageSize: 10 } },
      }}
      onRowSelectionModelChange={(ids) => onRowsSelectionHandler(ids)}
      componentsProps={{
        pagination: {
          labelRowsPerPage: `Nb par page`,
        },
      }}
      pageSizeOptions={[5, 10, 15, 20, 50, 100]}
      checkboxSelection={bool}
    />
  );
};

Here, the component who group mulitple datagrid component in one page/component

import React from 'react';
import { useSelector } from 'react-redux';
import { TableReusable } from '../../../reusable/TableReusable';
import { Box, Typography } from '@mui/material';

const TcgTable = () => {
  const data = useSelector((state) => state?.tcgSkill?.skills) || [];
  const columns =
    data.length > 0
      ? Object.keys(data[0])
          .filter(
            (field) =>
              field !== 'Level' &&
              field !== 'updated_at' &&
              field !== 'created_at'
          ) // Exclude 'Level' field
          .map((field) => ({
            field: field,
            headerName: field,
            width: 130,
          }))
      : [];

  return <TableReusable data={data} columns={columns} bool={true} />;
};

const AdminTable = () => {
  const data = useSelector((state) => state?.adminSkill?.skills) || [];
  const columns =
    data.length > 0
      ? Object.keys(data[0])
          .filter(
            (field) =>
              field !== 'Level' &&
              field !== 'updated_at' &&
              field !== 'created_at'
          ) // Exclude 'Level' field
          .map((field) => ({
            field: field,
            headerName: field,
            width: 130,
          }))
      : [];

  return <TableReusable data={data} columns={columns} bool={true} />;
};

const SalesTable = () => {
  const data = useSelector((state) => state?.salesSkill?.skills) || [];
  const columns =
    data.length > 0
      ? Object.keys(data[0])
          .filter(
            (field) =>
              field !== 'Level' &&
              field !== 'updated_at' &&
              field !== 'created_at'
          ) // Exclude 'Level' field
          .map((field) => ({
            field: field,
            headerName: field,
            width: 130,
          }))
      : [];
  return <TableReusable data={data} columns={columns} bool={true} />;
};

const SoftTable = () => {
  const data = useSelector((state) => state?.softSkill?.skills) || [];
  const columns =
    data.length > 0
      ? Object.keys(data[0])
          .filter(
            (field) =>
              field !== 'Level' &&
              field !== 'updated_at' &&
              field !== 'created_at'
          ) // Exclude 'Level' field
          .map((field) => ({
            field: field,
            headerName: field,
            width: 130,
          }))
      : [];
  return <TableReusable data={data} columns={columns} bool={true} />;
};

export const ListSkills = () => {
  return (
    <>
      <Box sx={{ margin: '2em 0' }}>
        <Typography
          sx={{
            color: '#006E8C !important',
            fontWeight: 'bold',
            margin: '0.5em 0',
          }}
          variant="h6"
        >
          TCG Skills
        </Typography>
        <TcgTable />
      </Box>

      <Box sx={{ margin: '2em 0' }}>
        <Typography
          sx={{
            color: '#006E8C !important',
            fontWeight: 'bold',
            margin: '0.5em 0',
          }}
          variant="h6"
        >
          ADMIN Skills
        </Typography>
        <AdminTable />
      </Box>

      <Box sx={{ margin: '2em 0' }}>
        <Typography
          sx={{
            color: '#006E8C !important',
            fontWeight: 'bold',
            margin: '0.5em 0',
          }}
          variant="h6"
        >
          SALES skills
        </Typography>
        <SalesTable />
      </Box>

      <Box sx={{ margin: '2em 0' }}>
        <Typography
          sx={{
            color: '#006E8C !important',
            fontWeight: 'bold',
            margin: '0.5em 0',
          }}
          variant="h6"
        >
          SOFT skills
        </Typography>
        <SoftTable />
      </Box>
    </>
  );
};

2

Answers


  1. Chosen as BEST ANSWER

    So, I found a solution (I don't know if it is a best practice) but it is easier to delete my data from separate collection in my db after making this.

    Instead of using a general state, I have created individual state for each datagrid

    I already had created slice (redux toolkit) for each datagrid (admin, soft, tcg)... So i have just add a setSkillSelected to each slice

    setSkillSelected: (state, action) => {
          state.selected = action.payload;
        },
    

    then, I have separate each sub component

    import { useSelector } from 'react-redux';
    import { TableReusable } from '../../../reusable/TableReusable';
    import { setSkillSelected } from '../../../slices/softSkillSlice';
    
    export const SoftTable = () => {
      const data = useSelector((state) => state?.softSkill?.skills) || [];
      const columns =
        data.length > 0
          ? Object.keys(data[0])
              .filter(
                (field) =>
                  field !== 'Level' &&
                  field !== 'updated_at' &&
                  field !== 'created_at'
              ) // Exclude 'Level' field
              .map((field) => ({
                field: field,
                headerName: field,
                width: 130,
              }))
          : [];
      return (
        <TableReusable
          data={data}
          columns={columns}
          bool={true}
          setSkillSelected={setSkillSelected}
        />
      );
    };
    

    and call them in ListSkills

     import React from 'react';
        import { Box, Typography } from '@mui/material';
        import { TcgTable } from '../list/TcgTable';
        import { AdminTable } from '../list/AdminTable';
        import { SalesTable } from '../list/SalesTable';
        import { SoftTable } from '../list/SoftTable';
        
        export const ListSkills = () => {
          return (
            <>
              <Box sx={{ margin: '2em 0' }}>
                <Typography
                  sx={{
                    color: '#006E8C !important',
                    fontWeight: 'bold',
                    margin: '0.5em 0',
                  }}
                  variant="h6"
                >
                  TCG Skills
                </Typography>
                <TcgTable />
              </Box>
        
              <Box sx={{ margin: '2em 0' }}>
                <Typography
                  sx={{
                    color: '#006E8C !important',
                    fontWeight: 'bold',
                    margin: '0.5em 0',
                  }}
                  variant="h6"
                >
                  ADMIN Skills
                </Typography>
                <AdminTable />
              </Box>
        
              <Box sx={{ margin: '2em 0' }}>
                <Typography
                  sx={{
                    color: '#006E8C !important',
                    fontWeight: 'bold',
                    margin: '0.5em 0',
                  }}
                  variant="h6"
                >
                  SALES skills
                </Typography>
                <SalesTable />
              </Box>
        
              <Box sx={{ margin: '2em 0' }}>
                <Typography
                  sx={{
                    color: '#006E8C !important',
                    fontWeight: 'bold',
                    margin: '0.5em 0',
                  }}
                  variant="h6"
                >
                  SOFT skills
                </Typography>
                <SoftTable />
              </Box>
            </>
          );
        };
    

    So in my reusable I just need to add setSkillSelected to my params and that's it

    import React from 'react';
    import { DataGrid } from '@mui/x-data-grid';
    import { useDispatch } from 'react-redux';
    import { useSearchBar } from '../hooks/useSearchBar';
    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)
        );
    
        dispatch(setSkillSelected(selectedRowsData));
      };
    
      const filteredRows = useSearchBar({ row: data });
    
      return (
        <DataGrid
          sx={{ width: 'fit-content' }}
          rows={filteredRows}
          getRowId={(row) => row?.id || row?._id || row?.CommonId} // Spécifiez la fonction pour obtenir l'identifiant de chaque ligne
          columns={columns}
          initialState={{
            pagination: { paginationModel: { pageSize: 10 } },
          }}
          onRowSelectionModelChange={(ids) => onRowsSelectionHandler(ids)}
          componentsProps={{
            pagination: {
              labelRowsPerPage: `Nb par page`,
            },
          }}
          pageSizeOptions={[5, 10, 15, 20, 50, 100]}
          checkboxSelection={bool}
        />
      );
    };
    

  2. lo que tienes que hacer es usar el operador spread para guardar el estado anterior y luego guardar un nuevo estado.
    lo que veo es que al momento de hacer el dispacht estas pisando el cambio anterior para modificar el nuevo

    {
    ...selectedRowsData,
      newData: newData
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search