Code Monkey home page Code Monkey logo

Comments (20)

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024 2

thank you so much. I gave it a quick try and it's doing what I'd like to achieve. I'll let the powers that be know about the caveat no. 3. Honestly I think it would be great to add to the recipies. I went looking outside of MUI for this behavior and I saw something sort of like this but they couldn't get it to work with as many states and so I had to open a ticket. This is beyond helpful. Thank you so much.

from mui-x.

MBilalShafi avatar MBilalShafi commented on July 3, 2024 1

I've prepared a demo implementation that saves the exported state on every state change to localStorage and reloads it on page reload.
Have a look at it: https://codesandbox.io/s/datagridpremium-basic-forked-5542fr?file=/src/App.tsx

Design details:

  1. The demo is designed keeping in mind the state has to be persisted locally, if you want to persist it for multiple people/sessions/devices you may need to replace localStorage with a database layer.
  2. Right now, it uses the onStateChange event handler which fires a lot of times based on different internal state changes, it may cause performance issues, especially if you decide to switch to API for storing the state, I'd recommend doing it in a more "controlled" way by limiting the state export to specific event handlers you are interested in, like onFilterModelChange for example.
  3. It doesn't persist and recover everything, only those which are supported by apiRef.current.exportState and accepted by initialState prop.

Let me know if the demo helps you achieve your required use case.

Thanks


I think this use case (persist and recover state locally) could be a good candidate for a recipe and could be useful for certain desktop-oriented apps. @cherniavskii Do you think it's worth it to add to the Recipes umbrella issue?

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024 1

ahh ok great. thanks for everything this was a big help

from mui-x.

cherniavskii avatar cherniavskii commented on July 3, 2024 1

Hi @lisaWriteJava
I believe there's a mistake in the initial state merging:

initialState={{
-  cachedInitialState,
+  ...cachedInitialState,
  sorting: {
    sortModel: sortModel
  }
}}

Here's a fixed demo: https://codesandbox.io/s/datagridpremium-basic-forked-w25xxc?file=/src/CommonGrid.jsx

This is a great candidate for the recipe as it's a pretty common pattern 👍🏻

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024 1

if using multiple grids in the same app, give the local storage a unique name for each. Otherwise the properties will get mingled.

from mui-x.

MBilalShafi avatar MBilalShafi commented on July 3, 2024

there isn't anything that shows this being able to be automatic once the user sorts/filters, etc

Could you elaborate more a bit the requirement? You want to save a state snapshot on every sort or filter operation? Is the rationale to revert to the current state if the user reopens/refreshes the page?

I believe you can achieve that by:

  1. Listening to the variable specific changes you are interested in (for example onFilterModelChange, onSortModelChange)
  2. Updating the state snapshot when a change event fires, which you can store in localStorage, db, etc.
  3. Revert to the saved state using initialState or apiRef.current.restoreState on page load (or whenever you want)

About supporting it out of the box:
I am not in favor of it:

  1. There could be tons of ways to manage the storage of exported state depending on user's needs
  2. This is a rarely used use-case and could easily be achieved by adding some custom code (as I mentioned above)

Let me know if the suggested method would work in your use-case.

Thanks

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

So I was trying to figure out a way that if a user sorts the columns, and/or reorders the columns, or pagination we can save that state without the need to create that view. Also, I want the state to be maintained if the user clicks goes to another page or refreshes. Essentially I'd like to persist the state of the datagrid.

how can I do this.

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

Just one question, if I have an initial state set for a grid ie sort order is it possible to have both with this scenario

from mui-x.

MBilalShafi avatar MBilalShafi commented on July 3, 2024

Just one question, if I have an initial state set for a grid ie sort order is it possible to have both with this scenario

Sure thing, feel free to update the initialState populating logic as per your requirement!

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

Just to confirm something like below is fine:

initialState={{
    ...cachedInitialState,
    sorting: {
        sortModel: sortModel
    }
}}

from mui-x.

MBilalShafi avatar MBilalShafi commented on July 3, 2024

Just to confirm something like below is fine:

Sure, you can override the sortModel if the intention is to never persist it and always use a specific initialValue for it.
But if the intention is to do this only for the first time and let the user change the sortModel afterwards, you can return this as a default value from getStateSnapshotFromLocalStorage method instead of {}

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

Hello,

While your code standbox worked for me, When I incorporated it into my code the state didn't save.
I'm workign up the sandbox

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

ok here's an example of the state not saving when implemented in my code

https://codesandbox.io/s/datagridpremium-basic-forked-pk9s6y

from mui-x.

MBilalShafi avatar MBilalShafi commented on July 3, 2024

The codesandbox link you shared appears to be broken, here's the error it's throwing

image

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

This is the updated sandbox: https://codesandbox.io/s/datagridpremium-basic-forked-pk9s6y?file=/src/CommonGrid.jsx

saving the sandbox was a challenge just in case the first link above doesn't work I also forked it to save here https://codesandbox.io/s/datagridpremium-basic-forked-6zpflz

@MBilalShafi

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

Just in case there is an issue viewing the sand box @MBilalShafi here is the code:

import { Box } from "@mui/material";
import CircularProgress from "@mui/material/CircularProgress";
import {
  DataGridPremium,
  GridToolbarContainer,
  GridToolbarColumnsButton,
  GridToolbarFilterButton,
  GridToolbarExport,
  GridToolbarDensitySelector,
  gridClasses,
  useGridApiRef,
  GRID_DETAIL_PANEL_TOGGLE_COL_DEF
} from "@mui/x-data-grid-premium";
import PropTypes from "prop-types";
import { alpha } from "@mui/material/styles";
import { styled } from "@mui/material/styles";

const ODD_OPACITY = 0.2;

//class actions
function saveStateSnapshotToLocalStorage(stateSnapshot) {
  console.info(
    "State update: Update the state snap in localStorage",
    stateSnapshot
  );
  localStorage.setItem("dataGridState", JSON.stringify(stateSnapshot));
}

function getStateSnapshotFromLocalStorage() {
  const stringifiedState = localStorage.getItem("dataGridState");
  return new Promise((resolve) => {
    if (!stringifiedState) {
      return resolve({});
    }
    const stateSnapshot = JSON.parse(stringifiedState);
    return resolve(stateSnapshot);
  });
}

function CustomToolbar() {
  return (
    <GridToolbarContainer
      sx={{
        width: "100%",
        backgroundColor: "#4d7496",
        color: "#fff !important",
        fontSize: 13,
        fontWeight: "bolder"
      }}
    >
      <GridToolbarColumnsButton
        sx={{
          backgroundColor: "#4d7496",
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        }}
      />
      <GridToolbarFilterButton
        sx={{
          backgroundColor: "#4d7496",
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        }}
      />
      <GridToolbarDensitySelector
        sx={{
          backgroundColor: "#4d7496",
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        }}
      />
      <GridToolbarExport
        sx={{
          backgroundColor: "#4d7496",
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        }}
      />
    </GridToolbarContainer>
  );
}

const StyledGridOverlay = styled("div")(({ theme }) => ({
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  justifyContent: "center",
  height: "100%",
  "& .ant-empty-img-1": {
    fill: "#262626"
  },
  "& .ant-empty-img-2": {
    fill: "#595959"
  },
  "& .ant-empty-img-3": {
    fill: "#434343"
  },
  "& .ant-empty-img-4": {
    fill: "#1c1c1c"
  },
  "& .ant-empty-img-5": {
    fillOpacity: "0.08",
    fill: "#fff"
  }
}));

function CustomNoRowsOverlay() {
  return (
    <StyledGridOverlay>
      <svg
        width="120"
        height="100"
        viewBox="0 0 184 152"
        aria-hidden
        focusable="false"
      >
        <g fill="none" fillRule="evenodd">
          <g transform="translate(24 31.67)">
            <ellipse
              className="ant-empty-img-5"
              cx="67.797"
              cy="106.89"
              rx="67.797"
              ry="12.668"
            />
            <path
              className="ant-empty-img-1"
              d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z"
            />
            <path
              className="ant-empty-img-2"
              d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z"
            />
            <path
              className="ant-empty-img-3"
              d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z"
            />
          </g>
          <path
            className="ant-empty-img-3"
            d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z"
          />
          <g className="ant-empty-img-4" transform="translate(149.65 15.383)">
            <ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815" />
            <path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z" />
          </g>
        </g>
      </svg>
      <Box sx={{ mt: 1, fontSize: 16, fontWeight: "bolder" }}>No Data</Box>
    </StyledGridOverlay>
  );
}

const mockViolationColumns = [
  {
    id: "user",
    headerName: "User",
    field: "user",
    type: "string",
    flex: 1,
    aggregable: false,
    groupable: false,
    headerAlign: "center",
    valueGetter: (params) => {
      //  console.log('in value getting for User params: ', params)

      //Asided from everything else, must set somethign in maybe name or a field to do the filter on
      return params.value.name;
    },
    renderCell: (rowInfo) => {
      // console.log('valueFormatter for User: ', rowInfo)  //you need to verify values below
      if (rowInfo.row.user.name) {
        return <div> placeHolder </div>;
      } else {
        return <span>Missing Name Info 2</span>;
      }
    }
  },
  {
    id: "violation_type",
    headerName: "Violation Type",
    field: "is_role",
    flex: 1,
    headerAlign: "center",
    aggregable: false,
    groupable: false,
    //Change to value gettter
    renderCell: (rowInfo) => {
      return rowInfo.value;
    },
    valueGetter: (params) => {
      // console.log('The violation type value getter ', params, ' \n params.row.is_role: ', params.row.is_role, ' trying value too: ', params.value)
      if (params.row.is_role) {
        return "Unqualified User (Role)";
      } else {
        return "Unassigned User (Accessor)";
      }
    }
  },
  {
    field: "accessor_or_role",
    headerName: "Accessor or Role",
    flex: 1,
    headerAlign: "center",
    aggregable: false,
    groupable: false,
    //This allows for rendering a react component
    renderCell: (rowInfo) => {
      //  console.log(' Ist accessor or role: ', rowInfo)
      if (rowInfo.row.is_role) {
        return <div> placeHolder </div>;
      }
      return <div> placeHolder </div>;
    },
    valueGetter: (params) => {
      // console.log('The violation type value getter ', params, ' \n params.row.is_role: ', params.row.is_role, ' trying value too: ', params.value)
      if (params.row.is_role) {
        return params.row.role.name;
      } else {
        return params.row.accessor.name;
      }
    }
  },
  {
    id: "detected_on",
    headerName: "Detected On",
    field: "created_date",
    flex: 1,
    type: "date",
    headerAlign: "center",
    aggregable: false,
    groupable: false,
    valueFormatter: (params) => {
      //console.log('VF The created_date on params: ', params)

      if (params.value == null) {
        return "";
      }
      return params.value;
    },
    valueGetter: (params) => {
      //  console.log('VG the created_date in params: ', params)
      if (params.row.created_date == null) {
        return "";
      }
      // console.log('created_date The last modified from row: ', params.row.created_date)
      const date = new Date(params.row.created_date);
      // console.log('to return the created_date in getter: ', date)
      return date;
    }
  },
  {
    id: "last_updated",
    headerName: "Last Updated",
    field: "last_modified",
    flex: 1,
    type: "date",
    headerAlign: "center",
    aggregable: false,
    groupable: false,
    valueFormatter: (params) => {
      //  console.log('VF The last_modified on params: ', params)

      if (params.value == null) {
        return "";
      }
      return params.value;
    },
    valueGetter: (params) => {
      // console.log('VG the last_modified in params: ', params)
      if (params.row.last_modified == null) {
        return "";
      }
      //console.log('last_modified The last modified from row: ', params.row.last_modified)
      const date = new Date(params.row.last_modified);
      //console.log('to return the last_modified in getter: ', date)
      return date;
    }
  },
  {
    headerName: "Suspension",
    type: "string",
    field: "rolesuspension",
    flex: 1,
    aggregable: false,
    groupable: false,
    headerAlign: "center",
    renderCell: (rowInfo) => {
      //  console.log('Row info rolesuspension to view: ', rowInfo)
      if (!rowInfo.row.is_role) {
        return (
          <span>
            <i>N/A</i>
          </span>
        );
      }
      const roleSus = rowInfo.row.rolesuspension;
      //console.log(rowInfo, ' = the rolesuspension  ', roleSus)
      if (!roleSus || roleSus.cleared_date) {
        return <span>None</span>;
      }
      if (roleSus.suspension_activated_date) {
        return (
          <span>
            <span
              className="fa fa-minus-circle text-danger"
              role="img"
              aria-hidden={true}
            />{" "}
            Suspended {roleSus.suspension_activated_date}
          </span>
        );
      }
      const daysRemaining = 4;
      return (
        <span>
          <span
            className="fa fa-hourglass-half"
            role="img"
            aria-hidden={true}
          />{" "}
          {daysRemaining} day{daysRemaining != 1 && "s"} until suspension
        </span>
      );
    },
    valueGetter: (rowInfo) => {
      // console.log('Row info rolesuspension: ', rowInfo)
      if (!rowInfo.row.is_role) {
        //may need to use the is_role property  This needs to be checked HS and maybe a more examples ffor this poroperty
        return "N/A";
      }
      const roleSus = rowInfo.value;
      if (!roleSus || roleSus.cleared_date) {
        return "None";
      }
      if (roleSus.suspension_activated_date) {
        return "Suspended" + roleSus.suspension_activated_date;
      }
      const daysRemaining = 4;
      let daysVerbiage = "";
      if (daysRemaining > 1) {
        daysVerbiage = daysRemaining + " days until suspension";
      } else {
        daysVerbiage = daysRemaining + " day until suspension";
      }

      return daysVerbiage;
    }
  },
  {
    ...GRID_DETAIL_PANEL_TOGGLE_COL_DEF,
    renderHeader: () => "+/-",
    headerAlign: "center",
    sortable: false,
    filterable: false,
    aggregable: false,
    groupable: false,
    valueGetter: (params) => {
      //  console.log('VG the GRID_DETAIL_PANEL_TOGGLE_COL_DEF in params: ', params)

      // console.log('return the GRID_DETAIL_PANEL_TOGGLE_COL_DEF in params: ', params.row.id + "-" + params.row.name)
      return params.row.id + "-" + params.row.url;
    },
    renderCell: (params) => {
      // console.log('renderCell the GRID_DETAIL_PANEL_TOGGLE_COL_DEF in params: ', params)
      return <div>test</div>;
    }
  }
];

const mockUserMembershipViolations = {
  data: {
    violations: [
      {
        id: 1,
        uuid: "123",
        user: {
          sid: "1234",
          name: "Apple Cider 2",
          first_name: "Apple",
          last_name: "Cider 2",
          email: "fererer",
          is_active: true,
          user_type: "user",
          duty_org: "NSA",
          org: "trrere",
          has_adm_account: true,
          url: "www.google.com",
          uuid: "fferer",
          my_permissions: {
            create: true,
            update: true,
            destroy: true,
            write: true,
            read: true
          },
          objectType: "user",
          entity_types: []
        },
        adm_account: false,
        role: {
          name: "April is A ROLE",
          description: "#f00",
          url: "www.twitter.com",
          uuid: "7890",
          parent_object: null,
          userCount: 4,
          my_permissions: [
            {
              add_users: true,
              create: true,
              read: true,
              update: true,
              delete: true,
              grant_user_suspensions: true,
              set_rules: true
            }
          ]
        },
        accessor: {
          sid: "1234",
          name: "An accessor Name",
          first_name: " bfgr",
          last_name: "fererer",
          email: "fererer",
          is_active: true,
          user_type: "user",
          duty_org: "NSA",
          org: "trrere",
          has_adm_account: true,
          url: "www.google.com",
          uuid: "fferer",
          my_permissions: {
            create: true,
            update: true,
            destroy: true,
            write: true,
            read: true
          },
          objectType: "user",
          entity_types: []
        },
        is_role: true,
        created_date: "2023-02-11T14:51:39Z",
        cleared_date: "2023-06-11T14:51:39Z",
        url: "www.fake.com",
        last_modified: "2023-03-11T14:51:39Z",
        rolesuspension: null
      },
      {
        id: 2,
        uuid: "123ab",
        user: {
          sid: "1234",
          name: "Samy Zebra",
          first_name: "Samy",
          last_name: "Zebra",
          email: "fererer",
          is_active: true,
          user_type: "user",
          duty_org: "NSA",
          org: "trrere",
          has_adm_account: true,
          url: "www.google.com",
          uuid: "fferer",
          my_permissions: {
            create: true,
            update: true,
            destroy: true,
            write: true,
            read: true
          },
          objectType: "user",
          entity_types: []
        },
        adm_account: false,
        role: {
          name: "April Role",
          description: "#f00",
          url: "www.twitter.com",
          uuid: "7890",
          parent_object: null,
          userCount: 4,
          my_permissions: [
            {
              add_users: true,
              create: true,
              read: true,
              update: true,
              delete: true,
              grant_user_suspensions: true,
              set_rules: true
            }
          ]
        },
        accessor: {
          sid: "1234",
          name: "Not a Role Accessor Name BOO",
          first_name: " bfgr",
          last_name: "fererer",
          email: "fererer",
          is_active: true,
          user_type: "user",
          duty_org: "NSA",
          org: "trrere",
          has_adm_account: true,
          url: "www.google.com",
          uuid: "fferer",
          my_permissions: {
            create: true,
            update: true,
            destroy: true,
            write: true,
            read: true
          },
          objectType: "user",
          entity_types: []
        },
        is_role: false,
        created_date: "2023-01-11T14:51:39Z",
        cleared_date: "2023-06-11T14:51:39Z",
        url: "www.fake.com",
        last_modified: "2023-05-11T14:51:39Z",
        rolesuspension: null
      }
    ],
    users: [
      {
        sid: "1234",
        name: "geger",
        first_name: " bfgr",
        last_name: "fererer",
        email: "fererer",
        is_active: true,
        user_type: "user",
        duty_org: "NSA",
        org: "trrere",
        has_adm_account: true,
        url: "www.google.com",
        uuid: "fferer",
        my_permissions: {
          create: true,
          update: true,
          destroy: true,
          write: true,
          read: true
        },
        objectType: "user",
        entity_types: []
      },
      {
        sid: "1tt234",
        name: "2geger",
        first_name: " bfgr",
        last_name: "fererer",
        email: "fererer",
        is_active: true,
        user_type: "user",
        duty_org: "NSA",
        org: "trrere",
        has_adm_account: true,
        url: "www.google.com",
        uuid: "fferer",
        my_permissions: {
          create: true,
          update: true,
          destroy: true,
          write: true,
          read: true
        },
        objectType: "user",
        entity_types: []
      }
    ],
    roles: [
      {
        name: "April",
        description: "#f00",
        url: "www.twitter.com",
        uuid: "7890",
        parent_object: null,
        userCount: 4,
        my_permissions: [
          {
            add_users: true,
            create: true,
            read: true,
            update: true,
            delete: true,
            grant_user_suspensions: true,
            set_rules: true
          }
        ]
      }
    ],
    accessors: [
      {
        sid: "1234",
        name: "geger",
        first_name: " bfgr",
        last_name: "fererer",
        email: "fererer",
        is_active: true,
        user_type: "user",
        duty_org: "NSA",
        org: "trrere",
        has_adm_account: true,
        url: "www.google.com",
        uuid: "fferer",
        my_permissions: {
          create: true,
          update: true,
          destroy: true,
          write: true,
          read: true
        },
        objectType: "accessor",
        entity_types: []
      }
    ]
  },
  isFetching: false,
  fetched: false,
  hasError: true,
  errorObj: {}
};

const CommonGrid = ({ ...other }) => {
  const apiRef = useGridApiRef();
  const [cachedInitialState, setCachedInitialState] = React.useState();

  const [sortModel, setSortModel] = React.useState([
    {
      field: "user",
      sort: "desc"
    },
    { field: "detected_on", desc: "desc" }
  ]);

  React.useEffect(() => {
    const getSnapshot = async () => {
      const snapshotFromLocalStorage = await getStateSnapshotFromLocalStorage();
      console.log(
        "Page Mount: Recovered state from localStorage",
        snapshotFromLocalStorage
      );
      setCachedInitialState(snapshotFromLocalStorage);
    };
    getSnapshot();
  }, []);

  const saveSnapshot = React.useCallback(() => {
    const stateSnapshot = apiRef.current.exportState();
    saveStateSnapshotToLocalStorage(stateSnapshot);
  }, [apiRef]);

  if (!cachedInitialState) {
    return <CircularProgress />;
  }

  return (
    <Box
      sx={{
        height: "100%",
        width: "100%",
        "& .datagridHeader": {
          backgroundColor: "#4d7496",
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        },
        "& .MuiDataGrid-footerContainer": {
          backgroundColor: "#4d7496",
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        },
        "& .MuiTablePagination-root": {
          backgroundColor: "#4d7496",
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        },
        "& .MuiTablePagination-displayedRows": {
          color: "#fff !important",
          fontSize: 13,
          fontWeight: "bolder"
        },
        "& .MuiSelect-standard": {
          fontSize: "13px !important",
          fontWeight: "bolder",
          color: "#fff !important"
        },
        "& .MuiTablePagination-actions": {
          fontSize: 13,
          fontWeight: "bolder",
          color: "#fff !important",
          "& .MuiButtonBase-root": {
            color: "#fff !important",
            fontSize: 13
          }
        },
        "& .MuiTablePagination-selectLabel": {
          fontSize: 13,
          fontWeight: "bolder",
          color: "#fff !important"
        },
        "& .MuiTablePagination-selectIcon": {
          fontSize: "13px !important",
          fontWeight: "bolder",
          color: "#fff !important"
        },
        "& .MuiTablePagination-selectRoot": {
          fontSize: "13px !important",
          fontWeight: "bolder",
          color: "#fff !important"
        },
        "& .MuiTablePagination-input": {
          fontSize: "13px !important",
          fontWeight: "bolder",
          color: "#fff !important"
        },
        "& .MuiDataGrid-columnHeader": {
          backgroundColor: "#4d7496",
          color: "#fff",
          fontSize: 13,
          fontWeight: 700
        },
        "& .MuiDataGrid-columnHeaderCheckbox": {
          backgroundColor: "#4d7496",
          color: "#fff",
          fontSize: 13,
          fontWeight: 700
        },
        "& .MuiDataGrid-cell": {
          border: "1px solid rgb(224, 224, 224)",
          fontSize: 13
        },
        "& .MuiDataGrid-root .MuiDataGrid-cell": {
          whiteSpace: "normal !important",
          wordWwrap: "break-word !important",
          textAlign: "left"
        },
        "& .MuiDataGrid-sortIcon": {
          backgroundColor: "#4d7496",
          color: "#fff",
          fontSize: 13,
          fontWeight: 700,
          opacity: "inherit !important"
        },
        "& .MuiDataGrid-filterIcon": {
          backgroundColor: "#4d7496",
          color: "#fff",
          fontSize: 13,
          fontWeight: 700,
          opacity: "inherit !important"
        },
        "& .MuiDataGrid-columnHeaderTitle": {
          fontWeight: "bolder"
        }
      }}
    >
      {"Tes"}
      <br />
      <br />
      <DataGridPremium
        apiRef={apiRef}
        onStateChange={saveSnapshot}
        rows={[
          {
            id: 1,
            uuid: "123",
            user: {
              sid: "1234",
              name: "Apple Cider 2",
              first_name: "Apple",
              last_name: "Cider 2",
              email: "fererer",
              is_active: true,
              user_type: "user",
              duty_org: "NSA",
              org: "trrere",
              has_adm_account: true,
              url: "www.google.com",
              uuid: "fferer",
              my_permissions: {
                create: true,
                update: true,
                destroy: true,
                write: true,
                read: true
              },
              objectType: "user",
              entity_types: []
            },
            adm_account: false,
            role: {
              name: "April is A ROLE",
              description: "#f00",
              url: "www.twitter.com",
              uuid: "7890",
              parent_object: null,
              userCount: 4,
              my_permissions: [
                {
                  add_users: true,
                  create: true,
                  read: true,
                  update: true,
                  delete: true,
                  grant_user_suspensions: true,
                  set_rules: true
                }
              ]
            },
            accessor: {
              sid: "1234",
              name: "An accessor Name",
              first_name: " bfgr",
              last_name: "fererer",
              email: "fererer",
              is_active: true,
              user_type: "user",
              duty_org: "NSA",
              org: "trrere",
              has_adm_account: true,
              url: "www.google.com",
              uuid: "fferer",
              my_permissions: {
                create: true,
                update: true,
                destroy: true,
                write: true,
                read: true
              },
              objectType: "user",
              entity_types: []
            },
            is_role: true,
            created_date: "2023-02-11T14:51:39Z",
            cleared_date: "2023-06-11T14:51:39Z",
            url: "www.fake.com",
            last_modified: "2023-03-11T14:51:39Z",
            rolesuspension: null
          },
          {
            id: 2,
            uuid: "123ab",
            user: {
              sid: "1234",
              name: "Samy Zebra",
              first_name: "Samy",
              last_name: "Zebra",
              email: "fererer",
              is_active: true,
              user_type: "user",
              duty_org: "NSA",
              org: "trrere",
              has_adm_account: true,
              url: "www.google.com",
              uuid: "fferer",
              my_permissions: {
                create: true,
                update: true,
                destroy: true,
                write: true,
                read: true
              },
              objectType: "user",
              entity_types: []
            },
            adm_account: false,
            role: {
              name: "April Role",
              description: "#f00",
              url: "www.twitter.com",
              uuid: "7890",
              parent_object: null,
              userCount: 4,
              my_permissions: [
                {
                  add_users: true,
                  create: true,
                  read: true,
                  update: true,
                  delete: true,
                  grant_user_suspensions: true,
                  set_rules: true
                }
              ]
            },
            accessor: {
              sid: "1234",
              name: "Not a Role Accessor Name BOO",
              first_name: " bfgr",
              last_name: "fererer",
              email: "fererer",
              is_active: true,
              user_type: "user",
              duty_org: "NSA",
              org: "trrere",
              has_adm_account: true,
              url: "www.google.com",
              uuid: "fferer",
              my_permissions: {
                create: true,
                update: true,
                destroy: true,
                write: true,
                read: true
              },
              objectType: "user",
              entity_types: []
            },
            is_role: false,
            created_date: "2023-01-11T14:51:39Z",
            cleared_date: "2023-06-11T14:51:39Z",
            url: "www.fake.com",
            last_modified: "2023-05-11T14:51:39Z",
            rolesuspension: null
          }
        ]}
        columns={mockViolationColumns}
        sx={{
          width: "100% !important",
          ".MuiDataGrid-iconButtonContainer": {
            visibility: "visible"
          },
          ".MuiDataGrid-sortIcon": {
            opacity: "inherit !important"
          },
          ".MuiTouchRipple-root": {
            opacity: "inherit !important",
            visibility: "visible !important"
          },
          ".MuiDataGrid-menuIconButton": {
            color: "#fff"
          },
          ".MuiDataGrid-columnHeaderTitleContainerContent .MuiCheckbox-root": {
            color: "#ffff !important",
            fontSize: 14,
            fontWeight: "bolder"
          },
          "& .MuiDataGrid-virtualScroller::-webkit-scrollbar": {
            width: "0.4em"
          },
          "& .MuiDataGrid-virtualScroller::-webkit-scrollbar-track": {
            color: "#4d7496"
          },
          "& .MuiDataGrid-virtualScroller::-webkit-scrollbar-thumb": {
            backgroundColor: "#4d7496",
            color: "#fff"
          },
          "& .MuiDataGrid-virtualScroller::-webkit-scrollbar-thumb:hover": {
            backgroundColor: "#4d7496",
            color: "#fff"
          },
          "& .MuiDataGrid-iconButtonContainer": {
            marginLeft: "25px",
            visibility: "visible !important",
            width: "auto !important"
          },
          "& .MuiDataGrid-cell--withRenderer": {
            fontSize: "13px !important"
          },
          "& .MuiDataGrid-menuIcon": {
            fontSize: 14,
            visibility: "visible !important",
            width: "auto !important",
            fontWeight: "bolder",
            "& .MuiSvgIcon-root": {
              fontSize: 14,
              visibility: "visible !important",
              width: "auto !important",
              fontWeight: "bolder"
            }
          }
        }}
        getDetailPanelContent={other.getDetailPanelContent}
        getDetailPanelHeight={() => "auto"}
        rowThreshold={other.rowThreshold}
        keepColumnPositionIfDraggedOutside={true}
        loading={false}
        paginationMode={"client"}
        slots={{
          noRowsOverlay: CustomNoRowsOverlay,
          toolbar: CustomToolbar
        }}
        checkboxSelection
        experimentalFeatures={{
          ariaV7: true,
          newEditingApi: true
        }}
        getRowClassName={(params) =>
          params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd"
        }
        initialState={{
          cachedInitialState,
          sorting: {
            sortModel: sortModel
          }
        }}
        sortingOrder={["desc", "asc"]}
        sortModel={sortModel}
        onSortModelChange={(model) => {
          // console.log('****************** The column sort order chagnes \n\n\n\n')
          setSortModel(model); //set the state
        }}
        pagination
      />
    </Box>
  );
};

/* CommonGrid.propTypes = {
    columns: PropTypes.array,
    rows: PropTypes.array,
    tableTitle: PropTypes.string
}; */

export default CommonGrid;

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

Hello @romgrk , please let me know what you need from me. I gave the code block above just in case the sandbox didn't load properly to show the issue.

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

Thank you. I'll give this a try
Yes I agree it's a good candidate.

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

Ok @cherniavskii I gave it a try. Your sandbox worked perfectly but when I integrated it into our code base the state still wouldn't save. I've forked the sandbox to show how a reload isn't working using my code https://codesandbox.io/s/datagridpremium-basic-forked-khqvcm?file=/src/CommonGrid.jsx

just in case the sandbox has issues like it did in the past below is the code

import React from "react";
import { Box } from '@mui/material';
import CircularProgress from "@mui/material/CircularProgress";
import {
    DataGridPremium,
    GridToolbarContainer,
    GridToolbarColumnsButton,
    GridToolbarFilterButton,
    GridToolbarExport,
    GridToolbarDensitySelector,
    gridClasses,
    useGridApiRef,
} from '@mui/x-data-grid-premium';
import PropTypes from "prop-types";
import { alpha } from "@mui/material/styles";
import { styled } from "@mui/material/styles";

const ODD_OPACITY = 0.2;

//class actions
function saveStateSnapshotToLocalStorage(stateSnapshot) {
    console.info(
        "State update: Update the state snap in localStorage",
        stateSnapshot
    );
    localStorage.setItem("dataGridState", JSON.stringify(stateSnapshot));
}


function getStateSnapshotFromLocalStorage() {
    const stringifiedState = localStorage.getItem("dataGridState");
    return new Promise((resolve) => {
        if (!stringifiedState) {
            return resolve({});
        }
        const stateSnapshot = JSON.parse(stringifiedState);
        return resolve(stateSnapshot);
    });
}

const StripedDataGrid = styled(DataGridPremium)(({ theme }) => ({
    [`& .${gridClasses.row}.even`]: {
        backgroundColor: theme.palette.grey[200],
        "&:hover, &.Mui-hovered": {
            backgroundColor: alpha(theme.palette.primary.main, ODD_OPACITY),
            "@media (hover: none)": {
                backgroundColor: "transparent"
            }
        },
        "&.Mui-selected": {
            backgroundColor: alpha(
                theme.palette.primary.main,
                ODD_OPACITY + theme.palette.action.selectedOpacity
            ),
            "&:hover, &.Mui-hovered": {
                backgroundColor: alpha(
                    theme.palette.primary.main,
                    ODD_OPACITY +
                    theme.palette.action.selectedOpacity +
                    theme.palette.action.hoverOpacity
                ),
                // Reset on touch devices, it doesn't add specificity
                "@media (hover: none)": {
                    backgroundColor: alpha(
                        theme.palette.primary.main,
                        ODD_OPACITY + theme.palette.action.selectedOpacity
                    )
                }
            }
        }
    }
}));


const StyledGridOverlay = styled('div')(({ theme }) => ({
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
    height: '100%',
    '& .ant-empty-img-1': {
        fill: theme.palette.mode === 'light' ? '#aeb8c2' : '#262626',
    },
    '& .ant-empty-img-2': {
        fill: theme.palette.mode === 'light' ? '#f5f5f7' : '#595959',
    },
    '& .ant-empty-img-3': {
        fill: theme.palette.mode === 'light' ? '#dce0e6' : '#434343',
    },
    '& .ant-empty-img-4': {
        fill: theme.palette.mode === 'light' ? '#fff' : '#1c1c1c',
    },
    '& .ant-empty-img-5': {
        fillOpacity: theme.palette.mode === 'light' ? '0.8' : '0.08',
        fill: theme.palette.mode === 'light' ? '#f5f5f5' : '#fff',
    },
}));

function CustomNoRowsOverlay() {
    return (
        <StyledGridOverlay>
            <svg
                width="120"
                height="100"
                viewBox="0 0 184 152"
                aria-hidden
                focusable="false"
            >
                <g fill="none" fillRule="evenodd">
                    <g transform="translate(24 31.67)">
                        <ellipse
                            className="ant-empty-img-5"
                            cx="67.797"
                            cy="106.89"
                            rx="67.797"
                            ry="12.668"
                        />
                        <path
                            className="ant-empty-img-1"
                            d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z"
                        />
                        <path
                            className="ant-empty-img-2"
                            d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z"
                        />
                        <path
                            className="ant-empty-img-3"
                            d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z"
                        />
                    </g>
                    <path
                        className="ant-empty-img-3"
                        d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z"
                    />
                    <g className="ant-empty-img-4" transform="translate(149.65 15.383)">
                        <ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815" />
                        <path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z" />
                    </g>
                </g>
            </svg>
            <Box sx={{ mt: 1, fontSize: 16, fontWeight: 'bolder' }}>No Data</Box>
        </StyledGridOverlay>
    );
}

const CommonGrid = ({ /*columns, rows, tableTitle,   sortingOrder, sortModel, onSortModelChange, */
    actionButton, handleSelectedItems, ...other }) => {
    const apiRef = useGridApiRef();
    const [cachedInitialState, setCachedInitialState] = React.useState();
    const [rowSelectionModel, setRowSelectionModel] = React.useState([]);
    const [checkboxSelection, setCheckboxSelection] = React.useState(true);
    const [sortModel, setSortModel] = React.useState([
        {
            field: "user",
            sort: "desc"
        },
        { field: "detected_on", desc: "desc" }
    ]);

    React.useEffect(() => {
        const getSnapshot = async () => {
            const snapshotFromLocalStorage = await getStateSnapshotFromLocalStorage();
            console.log(
                "Page Mount: Recovered state from localStorage",
                snapshotFromLocalStorage
            );
            setCachedInitialState(snapshotFromLocalStorage);
        };
        getSnapshot();
    }, []);

    const saveSnapshot = React.useCallback(() => {
        const stateSnapshot = apiRef.current.exportState();
        saveStateSnapshotToLocalStorage(stateSnapshot);
    }, [apiRef]);

    if (!cachedInitialState) {
        return <CircularProgress />;
    }

    function CustomToolbar() {
        return (
            <GridToolbarContainer sx={{
                width: "100%",
                backgroundColor: "#4d7496",
                color: "#fff !important",
                fontSize: 13,
                fontWeight: "bolder"
            }} >
                <GridToolbarColumnsButton sx={{
                    backgroundColor: "#4d7496",
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder"
                }} />
                <GridToolbarFilterButton sx={{
                    backgroundColor: "#4d7496",
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder"
                }} />
                <GridToolbarDensitySelector sx={{
                    backgroundColor: "#4d7496",
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder"
                }} />
                <GridToolbarExport sx={{
                    backgroundColor: "#4d7496",
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder"
                }} />

                {actionButton ? actionButton : null}
            </GridToolbarContainer>
        );
    }

    return (
        <Box
            sx={{
                height: "100%",
                width: "100%",
                "& .datagridHeader": {
                    backgroundColor: "#4d7496",
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder"
                },
                "& .MuiDataGrid-footerContainer": {
                    backgroundColor: "#4d7496",
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder"
                },
                "& .MuiTablePagination-root": {
                    backgroundColor: "#4d7496",
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder"
                },
                "& .MuiTablePagination-displayedRows": {
                    color: "#fff !important",
                    fontSize: 13,
                    fontWeight: "bolder",
                },
                "& .MuiSelect-standard": {
                    fontSize: "13px !important",
                    fontWeight: "bolder",
                    color: "#fff !important",
                },
                "& .MuiTablePagination-actions": {
                    fontSize: 13,
                    fontWeight: "bolder",
                    color: "#fff !important",
                    "& .MuiButtonBase-root": {
                        color: "#fff !important",
                        fontSize: 13,
                    },
                },
                "& .MuiTablePagination-selectLabel": {
                    fontSize: 13,
                    fontWeight: "bolder",
                    color: "#fff !important",
                },
                "& .MuiTablePagination-selectIcon": {
                    fontSize: "13px !important",
                    fontWeight: "bolder",
                    color: "#fff !important",
                },
                "& .MuiTablePagination-selectRoot": {
                    fontSize: "13px !important",
                    fontWeight: "bolder",
                    color: "#fff !important",
                },
                "& .MuiTablePagination-input": {
                    fontSize: "13px !important",
                    fontWeight: "bolder",
                    color: "#fff !important",
                },
                "& .MuiDataGrid-columnHeader": {
                    backgroundColor: "#4d7496",
                    color: "#fff",
                    fontSize: 13,
                    fontWeight: 700
                },
                "& .MuiDataGrid-columnHeaderCheckbox": {
                    backgroundColor: "#4d7496",
                    color: "#fff",
                    fontSize: 13,
                    fontWeight: 700
                },
                "& .MuiDataGrid-cell": {
                    border: "1px solid rgb(224, 224, 224)",
                    fontSize: 13
                },
                "& .MuiDataGrid-root .MuiDataGrid-cell": {
                    whiteSpace: "normal !important",
                    wordWwrap: "break-word !important",
                    textAlign: 'left'
                },
                "& .MuiDataGrid-sortIcon": {
                    backgroundColor: "#4d7496",
                    color: "#fff",
                    fontSize: 13,
                    fontWeight: 700,
                    opacity: "inherit !important"
                },
                "& .MuiDataGrid-filterIcon": {
                    backgroundColor: "#4d7496",
                    color: "#fff",
                    fontSize: 13,
                    fontWeight: 700,
                    opacity: "inherit !important"
                },
                "& .MuiDataGrid-columnHeaderTitle": {
                    fontWeight: 'bolder'
                }
            }} >
            {/* {tableTitle}  */}TESTING saving state
            <br />
            <br />
            <StripedDataGrid
                apiRef={apiRef}
                onStateChange={saveSnapshot}
                columns={[
                    {
                        id: "user",
                        headerName: "User",
                        field: "user",
                        type: "string",
                        flex: 1,
                        aggregable: false,
                        groupable: false,
                        headerAlign: "center",
                        valueGetter: (params) => {
                            //  console.log('in value getting for User params: ', params)

                            //Asided from everything else, must set somethign in maybe name or a field to do the filter on
                            return params.value.name;
                        },
                        renderCell: (rowInfo) => {
                            // console.log('valueFormatter for User: ', rowInfo)  //you need to verify values below
                            if (rowInfo.row.user.name) {
                                return <div> placeHolder </div>;
                            } else {
                                return <span>Missing Name Info 2</span>;
                            }
                        }
                    },
                    {
                        id: "violation_type",
                        headerName: "Violation Type",
                        field: "is_role",
                        flex: 1,
                        headerAlign: "center",
                        aggregable: false,
                        groupable: false,
                        //Change to value gettter
                        renderCell: (rowInfo) => {
                            return rowInfo.value;
                        },
                        valueGetter: (params) => {
                            // console.log('The violation type value getter ', params, ' \n params.row.is_role: ', params.row.is_role, ' trying value too: ', params.value)
                            if (params.row.is_role) {
                                return "Unqualified User (Role)";
                            } else {
                                return "Unassigned User (Accessor)";
                            }
                        }
                    },
                    {
                        field: "accessor_or_role",
                        headerName: "Accessor or Role",
                        flex: 1,
                        headerAlign: "center",
                        aggregable: false,
                        groupable: false,
                        //This allows for rendering a react component
                        renderCell: (rowInfo) => {
                            //  console.log(' Ist accessor or role: ', rowInfo)
                            if (rowInfo.row.is_role) {
                                return <div> placeHolder </div>;
                            }
                            return <div> placeHolder </div>;
                        },
                        valueGetter: (params) => {
                            // console.log('The violation type value getter ', params, ' \n params.row.is_role: ', params.row.is_role, ' trying value too: ', params.value)
                            if (params.row.is_role) {
                                return params.row.role.name;
                            } else {
                                return params.row.accessor.name;
                            }
                        }
                    },
                    {
                        id: "detected_on",
                        headerName: "Detected On",
                        field: "created_date",
                        flex: 1,
                        type: "date",
                        headerAlign: "center",
                        aggregable: false,
                        groupable: false,
                        valueFormatter: (params) => {
                            //console.log('VF The created_date on params: ', params)

                            if (params.value == null) {
                                return "";
                            }
                            return params.value;
                        },
                        valueGetter: (params) => {
                            //  console.log('VG the created_date in params: ', params)
                            if (params.row.created_date == null) {
                                return "";
                            }
                            // console.log('created_date The last modified from row: ', params.row.created_date)
                            const date = new Date(params.row.created_date);
                            // console.log('to return the created_date in getter: ', date)
                            return date;
                        }
                    },
                    {
                        id: "last_updated",
                        headerName: "Last Updated",
                        field: "last_modified",
                        flex: 1,
                        type: "date",
                        headerAlign: "center",
                        aggregable: false,
                        groupable: false,
                        valueFormatter: (params) => {
                            //  console.log('VF The last_modified on params: ', params)

                            if (params.value == null) {
                                return "";
                            }
                            return params.value;
                        },
                        valueGetter: (params) => {
                            // console.log('VG the last_modified in params: ', params)
                            if (params.row.last_modified == null) {
                                return "";
                            }
                            //console.log('last_modified The last modified from row: ', params.row.last_modified)
                            const date = new Date(params.row.last_modified);
                            //console.log('to return the last_modified in getter: ', date)
                            return date;
                        }
                    },
                    {
                        headerName: "Suspension",
                        type: "string",
                        field: "rolesuspension",
                        flex: 1,
                        aggregable: false,
                        groupable: false,
                        headerAlign: "center",
                        renderCell: (rowInfo) => {
                            //  console.log('Row info rolesuspension to view: ', rowInfo)
                            if (!rowInfo.row.is_role) {
                                return (
                                    <span>
                                        <i>N/A</i>
                                    </span>
                                );
                            }
                            const roleSus = rowInfo.row.rolesuspension;
                            //console.log(rowInfo, ' = the rolesuspension  ', roleSus)
                            if (!roleSus || roleSus.cleared_date) {
                                return <span>None</span>;
                            }
                            if (roleSus.suspension_activated_date) {
                                return (
                                    <span>
                                        <span
                                            className="fa fa-minus-circle text-danger"
                                            role="img"
                                            aria-hidden={true}
                                        />{" "}
                                        Suspended {roleSus.suspension_activated_date}
                                    </span>
                                );
                            }
                            const daysRemaining = 4;
                            return (
                                <span>
                                    <span
                                        className="fa fa-hourglass-half"
                                        role="img"
                                        aria-hidden={true}
                                    />{" "}
                                    {daysRemaining} day{daysRemaining != 1 && "s"} until suspension
                                </span>
                            );
                        },
                        valueGetter: (rowInfo) => {
                            // console.log('Row info rolesuspension: ', rowInfo)
                            if (!rowInfo.row.is_role) {
                                //may need to use the is_role property  This needs to be checked HS and maybe a more examples ffor this poroperty
                                return "N/A";
                            }
                            const roleSus = rowInfo.value;
                            if (!roleSus || roleSus.cleared_date) {
                                return "None";
                            }
                            if (roleSus.suspension_activated_date) {
                                return "Suspended" + roleSus.suspension_activated_date;
                            }
                            const daysRemaining = 4;
                            let daysVerbiage = "";
                            if (daysRemaining > 1) {
                                daysVerbiage = daysRemaining + " days until suspension";
                            } else {
                                daysVerbiage = daysRemaining + " day until suspension";
                            }

                            return daysVerbiage;
                        }
                    },
                ]}
                rows={[
                    {
                        id: 1,
                        uuid: "123",
                        user: {
                            sid: "1234",
                            name: "Apple Cider 2",
                            first_name: "Apple",
                            last_name: "Cider 2",
                            email: "fererer",
                            is_active: true,
                            user_type: "user",
                            duty_org: "NSA",
                            org: "trrere",
                            has_adm_account: true,
                            url: "www.google.com",
                            uuid: "fferer",
                            my_permissions: {
                                create: true,
                                update: true,
                                destroy: true,
                                write: true,
                                read: true
                            },
                            objectType: "user",
                            entity_types: []
                        },
                        adm_account: false,
                        role: {
                            name: "April is A ROLE",
                            description: "#f00",
                            url: "www.twitter.com",
                            uuid: "7890",
                            parent_object: null,
                            userCount: 4,
                            my_permissions: [
                                {
                                    add_users: true,
                                    create: true,
                                    read: true,
                                    update: true,
                                    delete: true,
                                    grant_user_suspensions: true,
                                    set_rules: true
                                }
                            ]
                        },
                        accessor: {
                            sid: "1234",
                            name: "An accessor Name",
                            first_name: " bfgr",
                            last_name: "fererer",
                            email: "fererer",
                            is_active: true,
                            user_type: "user",
                            duty_org: "NSA",
                            org: "trrere",
                            has_adm_account: true,
                            url: "www.google.com",
                            uuid: "fferer",
                            my_permissions: {
                                create: true,
                                update: true,
                                destroy: true,
                                write: true,
                                read: true
                            },
                            objectType: "user",
                            entity_types: []
                        },
                        is_role: true,
                        created_date: "2023-02-11T14:51:39Z",
                        cleared_date: "2023-06-11T14:51:39Z",
                        url: "www.fake.com",
                        last_modified: "2023-03-11T14:51:39Z",
                        rolesuspension: null
                    },
                    {
                        id: 2,
                        uuid: "123ab",
                        user: {
                            sid: "1234",
                            name: "Samy Zebra",
                            first_name: "Samy",
                            last_name: "Zebra",
                            email: "fererer",
                            is_active: true,
                            user_type: "user",
                            duty_org: "NSA",
                            org: "trrere",
                            has_adm_account: true,
                            url: "www.google.com",
                            uuid: "fferer",
                            my_permissions: {
                                create: true,
                                update: true,
                                destroy: true,
                                write: true,
                                read: true
                            },
                            objectType: "user",
                            entity_types: []
                        },
                        adm_account: false,
                        role: {
                            name: "April Role",
                            description: "#f00",
                            url: "www.twitter.com",
                            uuid: "7890",
                            parent_object: null,
                            userCount: 4,
                            my_permissions: [
                                {
                                    add_users: true,
                                    create: true,
                                    read: true,
                                    update: true,
                                    delete: true,
                                    grant_user_suspensions: true,
                                    set_rules: true
                                }
                            ]
                        },
                        accessor: {
                            sid: "1234",
                            name: "Not a Role Accessor Name BOO",
                            first_name: " bfgr",
                            last_name: "fererer",
                            email: "fererer",
                            is_active: true,
                            user_type: "user",
                            duty_org: "NSA",
                            org: "trrere",
                            has_adm_account: true,
                            url: "www.google.com",
                            uuid: "fferer",
                            my_permissions: {
                                create: true,
                                update: true,
                                destroy: true,
                                write: true,
                                read: true
                            },
                            objectType: "user",
                            entity_types: []
                        },
                        is_role: false,
                        created_date: "2023-01-11T14:51:39Z",
                        cleared_date: "2023-06-11T14:51:39Z",
                        url: "www.fake.com",
                        last_modified: "2023-05-11T14:51:39Z",
                        rolesuspension: null
                    }
                ]}
                sx={{
                    width: '100% !important',
                    ".MuiDataGrid-iconButtonContainer": {
                        visibility: "visible"
                    },
                    ".MuiDataGrid-sortIcon": {
                        opacity: "inherit !important"
                    },
                    ".MuiTouchRipple-root": {
                        opacity: "inherit !important",
                        visibility: "visible !important"
                    },
                    ".MuiDataGrid-menuIconButton": {
                        color: "#fff"
                    },
                    ".MuiDataGrid-columnHeaderTitleContainerContent .MuiCheckbox-root": {
                        color: '#ffff !important',
                        fontSize: 14,
                        fontWeight: 'bolder'
                    },
                    '& .MuiDataGrid-virtualScroller::-webkit-scrollbar': {
                        width: '0.4em',
                    },
                    '& .MuiDataGrid-virtualScroller::-webkit-scrollbar-track': {
                        color: '#4d7496',
                    },
                    '& .MuiDataGrid-virtualScroller::-webkit-scrollbar-thumb': {
                        backgroundColor: '#4d7496',
                        color: '#fff'
                    },
                    '& .MuiDataGrid-virtualScroller::-webkit-scrollbar-thumb:hover': {
                        backgroundColor: '#4d7496',
                        color: '#fff'
                    },
                    '& .MuiDataGrid-iconButtonContainer': {
                        marginLeft: '25px',
                        visibility: 'visible !important',
                        width: 'auto !important',
                    },
                    "& .MuiDataGrid-cell--withRenderer": {
                        fontSize: "13px !important"
                    },
                    "& .MuiDataGrid-menuIcon": {
                        fontSize: 14,
                        visibility: 'visible !important',
                        width: 'auto !important',
                        fontWeight: 'bolder',
                        "& .MuiSvgIcon-root": {
                            fontSize: 14,
                            visibility: 'visible !important',
                            width: 'auto !important',
                            fontWeight: 'bolder',
                        }
                    },
                }}
                getDetailPanelContent={other.getDetailPanelContent}
                getDetailPanelHeight={() => 'auto'}
                rowThreshold={other.rowThreshold}
                keepColumnPositionIfDraggedOutside={true}
                loading={false}
                paginationMode={"client"}
                slots={{
                    noRowsOverlay: CustomNoRowsOverlay,
                    toolbar: CustomToolbar,
                }}
                checkboxSelection
                experimentalFeatures={{
                    ariaV7: true,
                    newEditingApi: true
                }}
                getRowClassName={(params) =>
                    params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd"
                }
                initialState={{
                    ...cachedInitialState,
                    sorting: {
                        sortModel: sortModel
                    }
                }}
                sortingOrder={["desc", "asc"]}
                sortModel={sortModel}
                onSortModelChange={(model) => {
                    // console.log('****************** The column sort order chagnes \n\n\n\n')
                    setSortModel(model); //set the state
                }}
                pagination
            />
        </Box>
    );
};

/* CommonGrid.propTypes = {
    columns: PropTypes.array,
    rows: PropTypes.array,
    tableTitle: PropTypes.string
}; */

export default CommonGrid;

from mui-x.

lisaWriteJava avatar lisaWriteJava commented on July 3, 2024

So after fooling with this a bit more I got it working. Not sure why the example didn't work but after playing in the my code the state was saved and retrieved as expected.

from mui-x.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.