daisycrego / jbg-admin

Admin app for Jill Biggs Group follow-up boss event management
1 stars 0 forks source link

Source filter - click handler taking too long #18

Closed daisycrego closed 3 years ago

daisycrego commented 3 years ago

Problem

The source filter allows us to display a subset of the events based on source type (Zillow Flex) by default. Clicking Ylopo, which return ~800 events, leads to a long click handler (3000ms).

Specifics

daisycrego commented 3 years ago

Issue

export default function EventsTable({ rows }) {
  const [order, setOrder] = React.useState("desc");
  const [orderBy, setOrderBy] = React.useState("created");
  const [page, setPage] = React.useState(0);
  const [rowsPerPage, setRowsPerPage] = React.useState(10);
  const [activeRows, setActiveRows] = React.useState([]);
  const [sources, setSources] = React.useState([]);
  const [showSourceSelect, setShowSourceSelect] = React.useState(false);
  const [activeSources, setActiveSources] = React.useState(["Zillow Flex"]);

  React.useEffect(() => {
    console.log(`EventsTable: useEffect`);
    // Extract property.street from property object (for sorting)
    const rowsWithPropertyStreet = rows.map((event) => {
      if (event.property && event.property.street) {
        event.propertyStreet = event.property.street;
      } else {
        event.propertyStreet = "";
      }
      return event;
    });
    const rowsWithActiveSource = rowsWithPropertyStreet.filter((row) =>
      activeSources.includes(row.source)
    );
    const activeRows = stableSort(
      rowsWithActiveSource,
      getComparator(order, orderBy)
    ).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
    const allSources = rows.map((row) => row.source).filter((x) => x);
    const uniqueSources = _.uniq(allSources);
    setSources(uniqueSources);
    console.log(`activeRows:`);
    console.log(activeRows);
    setActiveRows(activeRows);
  }, [rows, order]);

  const handleCheckboxClick = (source) => {
    console.log(`handleCheckboxClick: ${source}`);
    let newActiveSources;
    if (activeSources.includes(source)) {
      newActiveSources = activeSources.filter(
        (activeSource) => activeSource != source
      );
    } else {
      newActiveSources = [...activeSources, source];
    }
    setActiveSources(newActiveSources);
    const rowsWithActiveSource = rows.filter((row) =>
      newActiveSources.includes(row.source)
    );
    console.log(`stableSort(
      rowsWithActiveSource,
      getComparator(order, orderBy)
    )`);
    console.log(
      stableSort(rowsWithActiveSource, getComparator(order, orderBy))
    );
    console.log(`slicing:`);
    console.log(`page: ${page}, rowsPerPage: ${rowsPerPage}`);
    console.log(
      `from: ${page * rowsPerPage}, to: ${page * rowsPerPage + rowsPerPage}`
    );
    console.log(`
    const newActiveRows = stableSort(
      rowsWithActiveSource,
      getComparator(order, orderBy)
    ).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
    `);
    console.log(
      stableSort(rowsWithActiveSource, getComparator(order, orderBy)).slice(
        page * rowsPerPage,
        page * rowsPerPage + rowsPerPage
      )
    );
    const newActiveRows = stableSort(
      rowsWithActiveSource,
      getComparator(order, orderBy)
    ).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
    /*console.log(`const newActiveRows = stableSort(
      rowsWithActiveSource,
      getComparator(order, orderBy)`);
    console.log(
      stableSort(rowsWithActiveSource, getComparator(order, orderBy))
    );
    console.log(`handleCheckboxClick: activeRows:`);
    console.log(newActiveRows);
    */
    setActiveRows(newActiveRows);
  };

  return (
    <div className={classes.root}>
      // ... 
            <TableBody>
              {activeRows.map((row, index) => {
                const labelId = `enhanced-table-checkbox-${index}`;

                return (
                  <TableRow hover tabIndex={-1} key={row._id}>
                    <TableCell
                      component="th"
                      id={labelId}
                      scope="row"
                      align={"default"}
                      padding={"left"}
                    >
                      {row.property ? row.property.street : ""}
                    </TableCell>
                    <TableCell align={"default"} padding={"left"}>
                      {`${new Date(row.created).toDateString()} ${new Date(
                        row.created
                      ).toLocaleTimeString()}`}
                    </TableCell>
                    <TableCell align={"default"} padding={"left"}>
                      {row.source}
                    </TableCell>
                    <TableCell align={"default"} padding={"left"}>
                      {data(row)}
                    </TableCell>
                    <TableCell align={"default"} padding={"left"}>
                      <Link to={"/event/" + row._id} key={row._id}>
                        <IconButton>
                          <ArrowForward />
                        </IconButton>
                      </Link>
                    </TableCell>
                  </TableRow>
                );
              })}
              {emptyRows > 0 && (
                <TableRow style={{ height: (dense ? 33 : 53) * emptyRows }}>
                  <TableCell colSpan={6} />
                </TableRow>
              )}
            </TableBody>
          </Table>
        </TableContainer>
        <TablePagination
          rowsPerPageOptions={[5, 10, 25, 50, 100]}
          component="div"
          count={activeRows.length}
          rowsPerPage={rowsPerPage}
          page={page}
          onChangePage={handleChangePage}
          onChangeRowsPerPage={handleChangeRowsPerPage}
        />
      </Paper>
    </div>
  );
}
daisycrego commented 3 years ago

Changed the code, getting a little bit closer. Using some new state to determine what should be displayed on the current page ("currentEvents") vs. all of the "activeEvents" for this query. These names might be a poor choice, something to consider.

The first page of data loads fine, and advancing to the next page no longer crashes, but it doesn't load the next page of data, it keeps the previous page.