@material-ui/core#TablePagination JavaScript Examples

The following examples show how to use @material-ui/core#TablePagination. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ApplicationListPage.jsx    From frontend with MIT License 5 votes vote down vote up
ApplicationPage = () => {
  const classes = useStyles();
  const [handlePageChange,
    handleChangeRowsPerPage,
    pagination, paginateData] = usePaginateHandlers(applications);
  return (
    <>
      <Box mb={2}>
        <Typography variant="h4">Applications</Typography>
      </Box>
      <Box>
        <Paper elevation={2}>
          <Table>
            <TableHead>
              <TableRow>
                {columns.map((c) => <TableCell key={c.label}>{c.label}</TableCell>)}
              </TableRow>
            </TableHead>
            <TableBody>
              {paginateData.map((x) => (
                <TableRow key={x.id}>
                  <TableCell>
                    {x.requestId}
                  </TableCell>
                  <TableCell>{x.firstName}</TableCell>
                  <TableCell>{x.lastName}</TableCell>
                  <TableCell>{x.phone}</TableCell>
                  <TableCell>{x.help}</TableCell>
                  <TableCell>
                    {x.status
                      ? (
                        <Select
                          value={x.status}
                          classes={{ root: classes[x.status], select: classes[x.status] }}
                        >
                          <MenuItem value="on_hold">On hold</MenuItem>
                          <MenuItem value="in_progress">In progress</MenuItem>
                          <MenuItem value="receieved">Received</MenuItem>
                          <MenuItem value="closed">Closed</MenuItem>
                        </Select>
                      ) : 'Pending'}
                  </TableCell>
                  <TableCell align="right">
                    {!x.approved && (
                    <>
                      <IconButton color="primary">
                        <Icon>check</Icon>
                      </IconButton>
                      <IconButton color="secondary">
                        <Icon>clear</Icon>
                      </IconButton>
                    </>
                    )}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
            <TableFooter>
              <TableRow>
                <TablePagination
                  count={applications.length}
                  onChangePage={handlePageChange}
                  page={pagination.page}
                  rowsPerPage={pagination.limit}
                  onChangeRowsPerPage={handleChangeRowsPerPage}
                />
              </TableRow>
            </TableFooter>
          </Table>
        </Paper>
      </Box>
    </>
  );
}
Example #2
Source File: Storage.js    From acsys with MIT License 4 votes vote down vote up
Storage = (props) => {
  const [locked, setLocked] = useState(true);
  const [isDialog, setIsDialog] = useState(false);
  const [mode, setMode] = useState('');
  const [imgUrl, setImgUrl] = useState(undefined);
  const [con, setCon] = useState(true);
  const [fileName, setFileName] = useState('');
  const [currentDir, setCurrentDir] = useState('');
  const [newFolderName, setNewFolderName] = useState('');
  const [files, setFiles] = useState([]);
  const [uploadFile, setUploadFile] = useState('');
  const [page, setPage] = useState(0);
  const [rowsPerPage] = useState(15);
  const [openMessage, setOpenMessage] = useState(false);
  const [loading, setLoading] = useState(false);
  const [syncing, setSyncing] = useState(false);
  const [newFolder, setNewFolder] = useState(false);
  const [isOpenImage, setIsOpenImage] = useState(false);
  const [messageTitle, setMessageTitle] = useState('');
  const [message, setMessage] = useState('');
  const [setError] = useState('');
  const [deleteLoading, setDeleteLoading] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [previousDir, setPreviousDir] = useState('');

  const set = (name, ref) => {
    try {
      props.setFile(name, ref);
    } catch (error) {}
  };

  const closeMessage = () => {
    setOpenMessage(false);
  };

  const openDir = async (dir) => {
    setLoading(true);
    const parentDir = files[0].parent;
    const filesTemp = await Acsys.getData('acsys_storage_items', [
      ['parent', '=', dir],
    ]);
    for (var i = 0; i < filesTemp.length; i++) {
      await Acsys.getStorageURL(filesTemp[i].acsys_id)
        .then((result) => {
          filesTemp[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    filesTemp.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    setLoading(false);
    setPreviousDir(parentDir);
    setCurrentDir('/' + dir);
    setFiles(filesTemp);
  };

  const openDirPage = async (dir) => {
    props.history.push('/Storage?' + dir);
    setLocked(false);
  };

  const previousDirFunc = async () => {
    setLoading(true);
    let parentFile = '/';
    let currentDir;
    let files;
    if (previousDir !== '/') {
      const parent = await Acsys.getData(
        'acsys_storage_items',
        [['acsys_id', '=', previousDir]],
        1
      );
      parentFile = parent[0].parent;
      currentDir = '/' + previousDir;
      files = await Acsys.getData('acsys_storage_items', [
        ['parent', '=', previousDir],
      ]);
    } else {
      currentDir = previousDir;
      files = await Acsys.getData('acsys_storage_items', [
        ['parent', '=', '/'],
      ]);
    }
    for (var i = 0; i < files.length; i++) {
      await Acsys.getStorageURL(files[i].acsys_id)
        .then((result) => {
          files[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));

    setLoading(false);
    setPreviousDir(parentFile);
    setCurrentDir(currentDir);
    setFiles(files);
  };

  const setRef = (ref) => {
    setUploadFile(ref);
  };

  const uploadFileFunc = async () => {
    try {
      setLoading(true);
      await Acsys.uploadFile(uploadFile.files[0], currentDir).then(async () => {
        await loadFiles();
      });
      setLoading(false);
    } catch (error) {}
  };

  const syncFiles = async () => {
    handleSyncClose();
    setLoading(true);
    await Acsys.syncFiles();
    let files = await Acsys.getData('acsys_storage_items', [
      ['parent', '=', '/'],
    ]);
    for (var i = 0; i < files.length; i++) {
      await Acsys.getStorageURL(files[i].acsys_id)
        .then((result) => {
          files[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    setLoading(false);
    setFiles(files);
  };

  const handleSyncOpen = () => {
    setSyncing(true);
  };

  const handleSyncClose = () => {
    setSyncing(false);
  };

  const openImg = (url) => {
    setIsOpenImage(true);
    setImgUrl(url);
  };

  const handleImgClose = () => {
    setIsOpenImage(false);
  };

  const handleChange = (event) => {
    setNewFolderName(event);
  };

  const newFolderOpen = () => {
    setNewFolder(true);
  };

  const newFolderClose = () => {
    setNewFolder(false);
  };

  const createNewFolder = async () => {
    if (newFolderName.indexOf(' ') >= 0) {
      setNewFolder(false);
      setOpenMessage(true);
      setMessageTitle('Error');
      setMessage('Folder name cannot contain spaces.');
    } else {
      setLoading(true);
      setNewFolder(false);
      await Acsys.createNewFolder(newFolderName, currentDir);
      await loadFiles();
      setLoading(false);
    }
  };

  const makeFilePublic = async (fileName) => {
    setLoading(true);
    await Acsys.makeFilePublic(fileName)
      .then(async () => {
        await loadFiles();
      })
      .catch((error) => setError(error));
    setLoading(false);
  };

  const makeFilePrivate = async (fileName) => {
    setLoading(true);
    await Acsys.makeFilePrivate(fileName)
      .then(async () => {
        await loadFiles();
      })
      .catch((error) => setError(error));
    setLoading(false);
  };

  const deleteFile = async () => {
    setDeleteLoading(true);
    await Acsys.deleteFile(fileName)
      .then(async () => {
        await loadFiles();
      })
      .catch((error) => setError(error));
    handleDeleteClose();
  };

  const handleDeleteOpen = async (fileName) => {
    setDeleting(true);
    setFileName(fileName);
  };

  const handleDeleteClose = () => {
    setDeleting(false);
    setDeleteLoading(false);
  };

  const loadFiles = async () => {
    setTimeout(() => {}, 1000);
    let dir = currentDir;
    if (dir !== '/') {
      dir = dir.substring(1, dir.length);
    }
    const files = await Acsys.getData('acsys_storage_items', [
      ['parent', '=', dir],
    ]);
    for (var i = 0; i < files.length; i++) {
      await Acsys.getStorageURL(files[i].acsys_id)
        .then((result) => {
          files[i]['url'] = result;
        })
        .catch((error) => console.log(error));
    }
    files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    setFiles(files);
  };

  const handleChangePage = (event, page) => {
    setPage(page);
  };

  useEffect(async () => {
    try {
      if (
        props.location.search.substring(1) !== currentDir.substring(1) &&
        !locked
      ) {
        let newDir = props.location.search.substring(1);
        if (newDir.length < 1) {
          newDir = '/';
        }
        setLocked(true);
        setLoading(true);
        setIsOpenImage(false);
        const files = await Acsys.getData('acsys_storage_items', [
          ['parent', '=', newDir],
        ]).catch();
        for (var i = 0; i < files.length; i++) {
          await Acsys.getStorageURL(files[i].acsys_id)
            .then((result) => {
              files[i]['url'] = result;
            })
            .catch((error) => console.log(error));
        }
        files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
        let currentDir = '/';
        if (newDir !== '/') {
          currentDir += newDir;
        }
        setLocked(false);
        setLoading(false);
        setCurrentDir(currentDir);
        setFiles(files);
      }
    } catch (error) {}
  }, [locked, currentDir, props.location]);

  useEffect(async () => {
    setLoading(true);
    let parent = '/';
    let mode = 'standard';

    try {
      if (props.mode.length > 0) {
        mode = props.mode;
      }
    } catch (error) {
      props.setHeader('Storage');
    }
    let con;
    let files;
    try {
      con = await Acsys.isStorageConnected();
      if (!con) {
        setLoading(false);
        setCon(con);
      }
      files = await Acsys.getData('acsys_storage_items', [
        ['parent', '=', parent],
      ]);
      for (var i = 0; i < files.length; i++) {
        await Acsys.getStorageURL(files[i].acsys_id)
          .then((result) => {
            files[i]['url'] = result;
          })
          .catch((error) => console.log(error));
      }
      files.sort((a, b) => (a.file_order > b.file_order ? 1 : -1));
    } catch (error) {}
    setLoading(false);
    setIsDialog(isDialog);
    setMode(mode);
    setCon(con);
    setFiles(files);
  }, []);

  const getPrevButton = () => {
    return mode !== 'standard' ? (
      <Grid item>
        <Tooltip title="Back">
          <IconButton onClick={() => previousDirFunc()}>
            <KeyboardArrowLeft color="inherit" />
          </IconButton>
        </Tooltip>
      </Grid>
    ) : (
      <div></div>
    );
  };
  const renderIcon = (content_type, url) => {
    if (content_type === 'Folder') {
      return (
        <TableCell style={{ width: 40, paddingRight: 0 }}>
          <FolderOpen />
        </TableCell>
      );
    } else if (content_type.includes('image')) {
      return (
        <TableCell style={{ width: 40, paddingRight: 0 }}>
          <img
            src={url}
            style={{ cursor: 'pointer', height: 40, width: 40, margin: 0 }}
            onClick={() => openImg(url)}
          />
        </TableCell>
      );
    } else {
      return (
        <TableCell style={{ width: 40, paddingRight: 0 }}>
          <Description
            style={{ cursor: 'pointer', height: 40, width: 40, margin: 0 }}
            onClick={() => window.open(url, '_blank')}
          />
        </TableCell>
      );
    }
  };
  const renderName = (id, content_type, name) => {
    if (content_type === 'Folder') {
      if (mode === 'standard') {
        return (
          <TableCell>
            <a onClick={() => openDirPage(id)} style={{ cursor: 'pointer' }}>
              {name}
            </a>
          </TableCell>
        );
      } else {
        return (
          <TableCell>
            <a onClick={() => openDir(id)} style={{ cursor: 'pointer' }}>
              {name}
            </a>
          </TableCell>
        );
      }
    } else {
      if (mode === 'standard') {
        return (
          <TableCell>
            <a>{name}</a>
          </TableCell>
        );
      } else {
        return (
          <TableCell>
            <a onClick={() => set(name, id)} style={{ cursor: 'pointer' }}>
              {name}
            </a>
          </TableCell>
        );
      }
    }
  };
  const renderTableData = () => {
    return files
      .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
      .map((file, index) => {
        const { acsys_id, name, content_type, updated, is_public, url } = file;
        if (name.length > 0) {
          return (
            <TableRow key={index}>
              {renderIcon(content_type, url, name)}
              {renderName(acsys_id, content_type, name)}
              <TableCell>{content_type}</TableCell>
              <TableCell>{updated}</TableCell>
              {Acsys.getMode() !== 'Viewer' ? (
                <TableCell style={{ minWidth: 100 }} align="right">
                  {is_public ? (
                    <Tooltip title="Public To Internet">
                      <IconButton
                        edge="start"
                        color="inherit"
                        aria-label="make private"
                        onClick={() => makeFilePrivate(acsys_id)}
                        style={{ marginRight: 10 }}
                      >
                        <LockOpen />
                      </IconButton>
                    </Tooltip>
                  ) : (
                    <Tooltip title="Not Public">
                      <IconButton
                        edge="start"
                        color="inherit"
                        aria-label="make public"
                        onClick={() => makeFilePublic(acsys_id)}
                        style={{ marginRight: 10 }}
                      >
                        <Lock />
                      </IconButton>
                    </Tooltip>
                  )}
                  <Tooltip title="Delete File">
                    <IconButton
                      edge="start"
                      color="inherit"
                      aria-label="delete"
                      onClick={() => handleDeleteOpen(acsys_id)}
                    >
                      <Delete />
                    </IconButton>
                  </Tooltip>
                </TableCell>
              ) : (
                <div />
              )}
            </TableRow>
          );
        } else {
          return <div />;
        }
      });
  };

  if (con) {
    try {
      return (
        <div>
          <Paper style={{ margin: 'auto', overflow: 'hidden', clear: 'both' }}>
            <AppBar
              position="static"
              elevation={0}
              style={{
                backgroundColor: '#fafafa',
                borderBottom: '1px solid #dcdcdc',
              }}
            >
              <Toolbar style={{ margin: 4, paddingLeft: 12, paddingRight: 12 }}>
                {Acsys.getMode() !== 'Viewer' ? (
                  <Grid container spacing={1}>
                    <Grid item xs style={{ overflow: 'hidden' }}>
                      <Typography
                        align="left"
                        variant="subtitle2"
                        noWrap
                        style={{ marginTop: 10, color: '#000000' }}
                      >
                        {currentDir}
                      </Typography>
                    </Grid>
                    {getPrevButton()}
                    <Grid item style={{ minWidth: 20 }}>
                      <Tooltip title="Scan For File Updates">
                        <Button
                          variant="contained"
                          color="primary"
                          onClick={handleSyncOpen}
                        >
                          Scan
                        </Button>
                      </Tooltip>
                    </Grid>
                    <Grid item style={{ minWidth: 20 }}>
                      <input
                        id="contained-button-file"
                        type="file"
                        style={{ display: 'none' }}
                        ref={setRef}
                        onChange={uploadFileFunc}
                      />
                      <label htmlFor="contained-button-file">
                        <Tooltip title="Upload File">
                          <Button
                            variant="contained"
                            color="primary"
                            component="span"
                          >
                            Upload
                          </Button>
                        </Tooltip>
                      </label>
                    </Grid>
                    <Grid item style={{ minWidth: 20 }}>
                      <Tooltip title="New Folder">
                        <Button
                          variant="contained"
                          color="primary"
                          onClick={newFolderOpen}
                        >
                          New Folder
                        </Button>
                      </Tooltip>
                    </Grid>
                  </Grid>
                ) : (
                  <Grid container spacing={1}>
                    <Grid item xs style={{ overflow: 'hidden' }}>
                      <Typography
                        align="left"
                        variant="subtitle2"
                        noWrap
                        style={{ marginTop: 10, color: '#000000' }}
                      >
                        {currentDir}
                      </Typography>
                    </Grid>
                    {getPrevButton()}
                  </Grid>
                )}
              </Toolbar>
            </AppBar>
            <div style={{ margin: 'auto', overflow: 'auto' }}>
              <Table>
                <TableHead style={{ backgroundColor: '#fafafa' }}>
                  <TableRow>
                    <TableCell
                      colSpan={2}
                      style={{
                        paddingLeft: 16,
                        paddingRight: 16,
                        paddingTop: 5,
                        paddingBottom: 5,
                      }}
                    >
                      NAME
                    </TableCell>
                    <TableCell
                      style={{
                        paddingLeft: 16,
                        paddingRight: 16,
                        paddingTop: 5,
                        paddingBottom: 5,
                        width: 100,
                      }}
                    >
                      TYPE
                    </TableCell>
                    <TableCell
                      style={{
                        paddingLeft: 16,
                        paddingRight: 16,
                        paddingTop: 5,
                        paddingBottom: 5,
                        width: 110,
                      }}
                    >
                      LAST MODIFIED
                    </TableCell>
                    {Acsys.getMode() !== 'Viewer' ? (
                      <TableCell
                        style={{
                          paddingLeft: 16,
                          paddingRight: 16,
                          paddingTop: 5,
                          paddingBottom: 5,
                          width: 100,
                        }}
                        align="right"
                      >
                        ACTIONS
                      </TableCell>
                    ) : (
                      <div />
                    )}
                  </TableRow>
                </TableHead>
                <TableBody>{renderTableData()}</TableBody>
              </Table>
            </div>
            <TablePagination
              rowsPerPageOptions={[25]}
              component="div"
              count={files.length}
              rowsPerPage={rowsPerPage}
              page={page}
              backIconButtonProps={{
                'aria-label': 'previous page',
              }}
              nextIconButtonProps={{
                'aria-label': 'next page',
              }}
              onChangePage={handleChangePage}
              // onChangeRowsPerPage={handleChangeRowsPerPage}
            />
            <LoadingDialog loading={loading} message={'Loading'} />
            <MessageDialog
              open={openMessage}
              closeDialog={closeMessage}
              title={messageTitle}
              message={message}
            />
            <YesNoDialog
              open={syncing}
              closeDialog={handleSyncClose}
              title={'Sync files?'}
              message={
                'Are you sure you want to resync files? This operation can require multiple writes.'
              }
              action={syncFiles}
            />
            <ImageDialog
              open={isOpenImage}
              closeDialog={handleImgClose}
              imgUrl={imgUrl}
            />
            <NewFolderDialog
              open={newFolder}
              closeDialog={newFolderClose}
              handleChange={handleChange}
              createNewFolder={createNewFolder}
            />
            <YesNoDialog
              open={deleting}
              closeDialog={handleDeleteClose}
              title={'Delete file?'}
              message={'Are you sure you want to delete this file?'}
              action={deleteFile}
              actionProcess={deleteLoading}
            />
          </Paper>
        </div>
      );
    } catch (error) {
      console.log('error', error);
      return (
        <div style={{ maxWidth: 1236, margin: 'auto' }}>
          <Paper style={{ height: 40 }}>
            <div style={{ padding: 10, margin: 'auto' }}>
              Please make sure database has been created.
            </div>
          </Paper>
        </div>
      );
    }
  } else {
    return (
      <div style={{ maxWidth: 1236, margin: 'auto' }}>
        <Paper style={{ height: 40 }}>
          <div style={{ padding: 10, margin: 'auto' }}>
            Please configure storage.
          </div>
        </Paper>
      </div>
    );
  }
}
Example #3
Source File: ListUrls.js    From fireshort with MIT License 4 votes vote down vote up
export default function ListUrls(props) {
    const classes = useStyles();

    const [page, setPage] = React.useState(0);
    const [rowsPerPage, setRowsPerPage] = React.useState(10);

    const handleChangePage = (event, newPage) => {
        setPage(newPage);
    };

    const handleChangeRowsPerPage = (event) => {
        setRowsPerPage(+event.target.value);
        setPage(0);
    };

    return (
        <Container className={classes.cardGrid} maxWidth="md">
            <Paper className={classes.root}>
                <TableContainer className={classes.container}>
                    <Table stickyHeader aria-label="sticky table">
                        <TableHead>
                            <TableRow>
                                <TableCell key="curl" align="left" style={{ minWidth: "100px" }}>
                                    Short URL
                                </TableCell>
                                <TableCell key="lurl" align="left" style={{ minWidth: "100px" }}>
                                    Long URL
                                </TableCell>
                                <TableCell key="action" align="right" style={{ minWidth: "100px" }}>
                                    Action
                                </TableCell>
                            </TableRow>
                        </TableHead>
                        <TableBody>
                            {props.shortUrls.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((card) => {
                                return (
                                    <TableRow hover role="checkbox" tabIndex={-1} key={card.id}>
                                        <TableCell key="curl" align="left" style={{ minWidth: "100px" }}>
                                            <Button
                                                startIcon={
                                                    <FileCopyOutlinedIcon />
                                                }
                                                onClick={() => { navigator.clipboard.writeText(window.location.hostname + "/" + card.data.curl) }}
                                                classes={{
                                                    label: classes.label
                                                }}
                                                >{card.data.curl}</Button>
                                        </TableCell>
                                        <TableCell key="lurl" align="left" style={{ minWidth: "100px" }}>
                                            <Box bgcolor="text.primary" color="background.paper" p={2} style={{ overflowX: 'auto', overflowY: 'hidden', whiteSpace: "nowrap" }}>
                                                {card.data.lurl}
                                            </Box>
                                        </TableCell>
                                        <TableCell key="action" align="right" style={{ minWidth: "100px" }}>
                                            <ButtonGroup variant="outlined" color="default">
                                                <Button size="small" color="primary" href={card.data.lurl} target="_blank">
                                                    <VisibilityIcon />
                                                </Button>
                                                <Button size="small" onClick={() => props.handleEditShortUrl(card.data.curl)}>
                                                    <EditIcon />
                                                </Button>
                                                <Button size="small" color="secondary" onClick={() => props.handleDeleteShortUrl(card.data.curl)}>
                                                    <DeleteForeverIcon />
                                                </Button>
                                            </ButtonGroup>
                                        </TableCell>
                                    </TableRow>
                                );
                            })}
                        </TableBody>
                    </Table>
                </TableContainer>
                <TablePagination
                    rowsPerPageOptions={[10, 25, 100]}
                    component="div"
                    count={props.shortUrls.length}
                    rowsPerPage={rowsPerPage}
                    page={page}
                    onChangePage={handleChangePage}
                    onChangeRowsPerPage={handleChangeRowsPerPage}
                />
            </Paper>
        </Container>
    );
}
Example #4
Source File: ListUrls.js    From FireShort with MIT License 4 votes vote down vote up
export default function ListUrls(props) {
  const classes = useStyles();
  const history = useHistory();

  const [page, setPage] = React.useState(0);
  const [rowsPerPage, setRowsPerPage] = React.useState(10);

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (event) => {
    setRowsPerPage(+event.target.value);
    setPage(0);
  };

  return (
    <Container className={classes.cardGrid} maxWidth="lg">
      <Paper className={classes.root}>
        <TableContainer className={classes.container}>
          <Table stickyHeader aria-label="sticky table">
            <TableHead>
              <TableRow>
                <TableCell
                  key="curl"
                  align="left"
                  style={{
                    minWidth: "100px",
                  }}
                >
                  Short URL
                </TableCell>
                <TableCell
                  key="action"
                  align="center"
                  style={{
                    minWidth: "100px",
                  }}
                >
                  Action
                </TableCell>
                <TableCell
                  key="lurl"
                  align="left"
                  style={{ minWidth: "100px" }}
                >
                  Long URL
                </TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {props.shortUrls
                .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                .map((card) => {
                  return (
                    <TableRow hover role="checkbox" tabIndex={-1} key={card.id}>
                      <TableCell
                        key="curl"
                        align="left"
                        style={{ minWidth: "100px" }}
                      >
                        <Tooltip title="Copy to clipboard">
                          <Button
                            startIcon={<FileCopyOutlinedIcon />}
                            onClick={() => {
                              navigator.clipboard.writeText(
                                window.location.origin + "/" + card.data.curl
                              );
                            }}
                            classes={{ label: classes.label }}
                          >
                            {card.data.curl}
                          </Button>
                        </Tooltip>
                        <Tooltip title={card.data.hits + " Hits"}>
                          <IconButton onClick={() => { props.openHits(card.data.curl) }} style={{ cursor: "pointer" }}>
                            <Badge
                              badgeContent={card.data.hits}
                              color="secondary"
                              max={Infinity}
                              showZero
                            >
                              <OpenInBrowser />
                            </Badge>
                          </IconButton>
                        </Tooltip>
                      </TableCell>
                      <TableCell
                        key="action"
                        align="right"
                        style={{ minWidth: "100px" }}
                      >
                        <ButtonGroup variant="outlined" color="default">
                          <Tooltip title="Preview link">
                            <Button
                              size="small"
                              color="primary"
                              href={card.data.lurl}
                              target="_blank"
                            >
                              <VisibilityIcon />
                            </Button>
                          </Tooltip>
                          <Tooltip title="Analytics">
                            <Button
                              size='small'
                              disabled={!card.data.track}
                              onClick={() => history.push(`/analytics/${card.data.curl}`)}
                            >
                              <AnalyticsIcon />
                            </Button>
                          </Tooltip>
                          <Tooltip title="Edit link">
                            <Button
                              size="small"
                              onClick={() =>
                                props.handleEditShortUrl(card.data.curl)
                              }
                            >
                              <EditIcon />
                            </Button>
                          </Tooltip>
                          <Tooltip title="Delete link">
                            <Button
                              size="small"
                              color="secondary"
                              onClick={() =>
                                props.handleDeleteShortUrl(card.data.curl)
                              }
                            >
                              <DeleteForeverIcon />
                            </Button>
                          </Tooltip>
                          <Tooltip title="Toggle link protection">
                            <Button
                              size="small"
                              color="default"
                              onClick={() => props.toggleSecurity(card.data.curl)}
                            >
                              {card.data.locked ? <LockIcon /> : <LockOpenIcon />}
                            </Button>
                          </Tooltip>
                        </ButtonGroup>
                      </TableCell>
                      <TableCell
                        key="lurl"
                        align="left"
                        style={{ minWidth: "100px" }}
                      >
                        <Box
                          bgcolor="text.primary"
                          color="background.paper"
                          p={2}
                          style={{
                            overflowX: "auto",
                            overflowY: "hidden",
                            whiteSpace: "nowrap",
                          }}
                        >
                          {card.data.lurl}
                        </Box>
                      </TableCell>

                    </TableRow>
                  );
                })}
            </TableBody>
          </Table>
        </TableContainer>
        <TablePagination
          rowsPerPageOptions={[10, 25, 100]}
          component="div"
          count={props.shortUrls.length}
          rowsPerPage={rowsPerPage}
          page={page}
          onChangePage={handleChangePage}
          onChangeRowsPerPage={handleChangeRowsPerPage}
        />
      </Paper>
    </Container>
  );
}
Example #5
Source File: table-pagination-container.js    From horondi_admin with MIT License 4 votes vote down vote up
TablePaginator = () => {
  const styles = useStyles();
  const dispatch = useDispatch();
  const { itemsCount, rowsPerPage, rowsPerPageOptions, currentPage } =
    useSelector(selectTablePaginationCurrentRowsOptions);

  const formSchema = Yup.object().shape({
    pageInput: Yup.number()
      .min(1)
      .max(Math.ceil(itemsCount / rowsPerPage), PAGE_NOT_FOUND)
      .typeError(MUST_BE_NUMBER)
      .positive(MUST_BE_POSITIVE)
  });

  const { values, handleChange, handleSubmit, errors } = useFormik({
    validationSchema: formSchema,
    validateOnBlur: true,
    initialValues: {
      pageInput: ''
    },
    onSubmit: (data) => {
      dispatch(setCurrentPage(data.pageInput - 1));
    }
  });

  const handleChangePage = (event, newPage) => {
    dispatch(setCurrentPage(newPage));
  };

  const handlePressEnter = (event) => {
    if (event.key === 'Enter' && values.pageInput && !errors.pageInput) {
      handleSubmit(values);
    }
  };

  const handleChangeRowsPerPage = (event) => {
    const rowsPerPageValue = parseInt(event.target.value);
    dispatch(setCurrentPage(0));
    dispatch(setRowsPerPage(rowsPerPageValue));
  };

  const getDisplayedRowsLabel = (from, to, count) => `${from}-${to} ะท ${count}`;
  return (
    <div className={styles.pagination}>
      <TablePagination
        component='div'
        rowsPerPageOptions={rowsPerPageOptions}
        count={itemsCount}
        rowsPerPage={rowsPerPage}
        page={currentPage}
        SelectProps={{ native: true }}
        labelRowsPerPage={ROWS_PER_PAGE}
        labelDisplayedRows={({ from, to, count }) =>
          getDisplayedRowsLabel(from, to, count)
        }
        onChangePage={handleChangePage}
        onChangeRowsPerPage={handleChangeRowsPerPage}
        ActionsComponent={PaginationController}
      />
      <div className={styles.goToPage}>
        <Typography variant='body2'>{goToPage}</Typography>
        <TextField
          id='pageInput'
          className={styles.root}
          variant='outlined'
          value={values.pageInput}
          onChange={handleChange}
          onKeyPress={handlePressEnter}
          error={!!errors.pageInput}
        />
        <Button
          disabled={!values.pageInput || !!errors.pageInput}
          onClick={handleSubmit}
          variant='outlined'
          color='default'
        >
          {GO}
        </Button>
        {errors.pageInput && (
          <div className={styles.error}>{errors.pageInput}</div>
        )}
      </div>
    </div>
  );
}
Example #6
Source File: UsersTable.js    From git-insights with MIT License 4 votes vote down vote up
UsersTable = props => {
  const { className, users, ...rest } = props;

  const classes = useStyles();

  const [selectedUsers, setSelectedUsers] = useState([]);
  const [rowsPerPage, setRowsPerPage] = useState(10);
  const [page, setPage] = useState(0);

  const handleSelectAll = event => {
    const { users } = props;

    let selectedUsers;

    if (event.target.checked) {
      selectedUsers = users.map(user => user.id);
    } else {
      selectedUsers = [];
    }

    setSelectedUsers(selectedUsers);
  };

  const handleSelectOne = (event, id) => {
    const selectedIndex = selectedUsers.indexOf(id);
    let newSelectedUsers = [];

    if (selectedIndex === -1) {
      newSelectedUsers = newSelectedUsers.concat(selectedUsers, id);
    } else if (selectedIndex === 0) {
      newSelectedUsers = newSelectedUsers.concat(selectedUsers.slice(1));
    } else if (selectedIndex === selectedUsers.length - 1) {
      newSelectedUsers = newSelectedUsers.concat(selectedUsers.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelectedUsers = newSelectedUsers.concat(
        selectedUsers.slice(0, selectedIndex),
        selectedUsers.slice(selectedIndex + 1)
      );
    }

    setSelectedUsers(newSelectedUsers);
  };

  const handlePageChange = (event, page) => {
    setPage(page);
  };

  const handleRowsPerPageChange = event => {
    setRowsPerPage(event.target.value);
  };

  return (
    <Card
      {...rest}
      className={clsx(classes.root, className)}
    >
      <CardContent className={classes.content}>
        <PerfectScrollbar>
          <div className={classes.inner}>
            <Table>
              <TableHead>
                <TableRow>
                  <TableCell padding="checkbox">
                    <Checkbox
                      checked={selectedUsers.length === users.length}
                      color="primary"
                      indeterminate={
                        selectedUsers.length > 0 &&
                        selectedUsers.length < users.length
                      }
                      onChange={handleSelectAll}
                    />
                  </TableCell>
                  <TableCell>Name</TableCell>
                  <TableCell>Email</TableCell>
                  <TableCell>Location</TableCell>
                  <TableCell>Phone</TableCell>
                  <TableCell>Registration date</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {users.slice(0, rowsPerPage).map(user => (
                  <TableRow
                    className={classes.tableRow}
                    hover
                    key={user.id}
                    selected={selectedUsers.indexOf(user.id) !== -1}
                  >
                    <TableCell padding="checkbox">
                      <Checkbox
                        checked={selectedUsers.indexOf(user.id) !== -1}
                        color="primary"
                        onChange={event => handleSelectOne(event, user.id)}
                        value="true"
                      />
                    </TableCell>
                    <TableCell>
                      <div className={classes.nameContainer}>
                        <Avatar
                          className={classes.avatar}
                          src={user.avatarUrl}
                        >
                          {getInitials(user.name)}
                        </Avatar>
                        <Typography variant="body1">{user.name}</Typography>
                      </div>
                    </TableCell>
                    <TableCell>{user.email}</TableCell>
                    <TableCell>
                      {user.address.city}, {user.address.state},{' '}
                      {user.address.country}
                    </TableCell>
                    <TableCell>{user.phone}</TableCell>
                    <TableCell>
                      {moment(user.createdAt).format('DD/MM/YYYY')}
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </PerfectScrollbar>
      </CardContent>
      <CardActions className={classes.actions}>
        <TablePagination
          component="div"
          count={users.length}
          onChangePage={handlePageChange}
          onChangeRowsPerPage={handleRowsPerPageChange}
          page={page}
          rowsPerPage={rowsPerPage}
          rowsPerPageOptions={[5, 10, 25]}
        />
      </CardActions>
    </Card>
  );
}
Example #7
Source File: ContributorsTable.js    From git-insights with MIT License 4 votes vote down vote up
ContributorsTable = props => {
  const { className, repoid, ...rest } = props;
  const [data, dataLoading] = useFetch(
    `api/repo/${repoid}/contributors`
  );

  const classes = useStyles();

  const [page, setPage] = React.useState(0);
  const rowsPerPage = 5;
  let emptyRows = 0;

  if (data) {
    emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage);
  }

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  return (
    <div {...rest} className={clsx(classes.root, className)}>
      <Paper className={classes.paper}>
        {dataLoading ? (
          <Grid
            container
            spacing={0}
            alignItems="center"
            justify="center"
            style={{ minHeight: "100%" }}
          >
            <Grid item xs={6}  align="center">
              <CircularProgress/>
              <Typography>
                Loading Chart..
              </Typography>
            </Grid>
          </Grid>
        ) : (
          <div>
            <TableContainer>
              <Table className={classes.table} aria-label="custom pagination table">
                <TableHead>
                  <TableRow>
                    <TableCell>Contributor Name</TableCell>
                    <TableCell align="right">Total Contributions</TableCell>
                    <TableCell align="right">Code Contributions</TableCell>
                    <TableCell align="right">Issue Contributions</TableCell>
                    <TableCell align="right">Code Reviews</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {(rowsPerPage > 0
                    ? data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                    : data
                  ).map(row => (
                    <TableRow key={row.name}>
                      <TableCell component="th" scope="row">
                        {row.name}
                      </TableCell>
                      <TableCell align="right">{row.total}</TableCell>
                      <TableCell align="right">{row.code}</TableCell>
                      <TableCell align="right">{row.issues}</TableCell>
                      <TableCell align="right">{row.reviews}</TableCell>
                    </TableRow>
                  ))}

                  {emptyRows > 0 && (
                    <TableRow style={{ height: 53 * emptyRows }}>
                      <TableCell colSpan={6} />
                    </TableRow>
                  )}
                </TableBody>
                <TableFooter>
                  <TableRow>

                  </TableRow>
                </TableFooter>
              </Table>
            </TableContainer>
            <TablePagination
              colSpan={3}
              count={data.length}
              rowsPerPage={5}
              page={page}
              onChangePage={handleChangePage}
              rowsPerPageOptions={-1}
              ActionsComponent={TablePaginationActions}
            />
          </div>
        )}
      </Paper>
    </div>
  );
}
Example #8
Source File: InventoryTable.js    From inventory-management-web with MIT License 4 votes vote down vote up
export default function InventoryTable() {
  // list of inventory got from API
  const [inventoryList, setInventoryList] = useState([]);
  // contains the index of the row, if delete is used
  const [deletedRow, setDeletedRow] = useState([]);
  // true when waiting for an response from API
  const [isLoading, setIsLoading] = useState(false);
  // dialog box
  const [open, setOpen] = useState(false);
  // row to be selected on clicking the delete icon
  const [selectedRow, setSelectedRow] = useState({});
  // list of search results got from API
  const [searchList, setSearchList] = useState([]);
  // search results input field
  const [search, setSearch] = useState('');
  // pagination
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(10);
  const [count, setCount] = useState(0);
  // search pagination
  const [searchPage, setSearchPage] = useState(0);
  const [searchRowsPerPage, setSearchRowsPerPage] = useState(10);
  const [searchCount, setSearchCount] = useState(0);

  const handleClose = () => {
    setOpen(false);
  };
  const history = useHistory();

  const { setSnack } = useContext(SnackContext);

  const handleSearchChangePage = async (event, newPage) => {
    try {
      setIsLoading(true);
      setSearchPage(newPage);
      const response = await getEndPoint(
        `/api/productlist/?limit=${searchRowsPerPage}&offset=${newPage *
          searchRowsPerPage}&search=${search}`,
        null,
        history
      );
      // Use utility function

      // console.log("error",response) check error code here for reference

      const { data } = response;
      setSearchCount(data.count);
      const list = data.results.map(val => ({
        name: val.name,
        quantity: val.quantity,
        sellingPrice: val.latest_selling_price,
        loose: val.loose,
        id: val.id,
        upperLimit: val.upper_limit === null ? '' : val.upper_limit,
        lowerLimit: val.lower_limit === null ? '' : val.lower_limit,
      }));
      setInventoryList(list);
      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  const handleSearchChangeRowsPerPage = async event => {
    try {
      setIsLoading(true);
      setSearchPage(0);
      setSearchRowsPerPage(+event.target.value);
      const response = await getEndPoint(
        `/api/productlist/?limit=${+event.target
          .value}&offset=0&search=${search}`,
        null,
        history
      );
      // Use utility function

      // console.log("error",response) check error code here for reference

      const { data } = response;
      setSearchCount(data.count);
      const list = data.results.map(val => ({
        name: val.name,
        quantity: val.quantity,
        sellingPrice: val.latest_selling_price,
        loose: val.loose,
        id: val.id,
        upperLimit: val.upper_limit === null ? '' : val.upper_limit,
        lowerLimit: val.lower_limit === null ? '' : val.lower_limit,
      }));
      setInventoryList(list);

      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  const handleChangePage = async (event, newPage) => {
    try {
      setIsLoading(true);
      setPage(newPage);
      const response = await getEndPoint(
        `/api/productlist/?limit=${rowsPerPage}&offset=${newPage *
          rowsPerPage}`,
        null,
        history
      );
      // Use utility function

      // console.log("error",response) check error code here for reference

      const { data } = response;
      setCount(data.count);
      const list = data.results.map(val => ({
        name: val.name,
        quantity: val.quantity,
        sellingPrice: val.latest_selling_price,
        loose: val.loose,
        id: val.id,
        upperLimit: val.upper_limit === null ? '' : val.upper_limit,
        lowerLimit: val.lower_limit === null ? '' : val.lower_limit,
      }));
      setSearchList(list);
      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  const handleChangeRowsPerPage = async event => {
    try {
      setIsLoading(true);
      setPage(0);
      setRowsPerPage(+event.target.value);
      const response = await getEndPoint(
        `/api/productlist/?limit=${+event.target.value}&offset=0`,
        null,
        history
      );
      // Use utility function

      // console.log("error",response) check error code here for reference

      const { data } = response;
      setCount(data.count);
      const list = data.results.map(val => ({
        name: val.name,
        quantity: val.quantity,
        sellingPrice: val.latest_selling_price,
        loose: val.loose,
        id: val.id,
        upperLimit: val.upper_limit === null ? '' : val.upper_limit,
        lowerLimit: val.lower_limit === null ? '' : val.lower_limit,
      }));
      setSearchList(list);

      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  const handleClickOpen = () => {
    setOpen(true);
  };

  const handleSearch = async data => {
    setSearch(data); // set data

    // console.log("data",data) //reference
    setSearchPage(0);
    const response = await getEndPoint(
      `/api/productlist/?limit=${searchRowsPerPage}&offset=0&search=${data}`,
      null,
      history
    );

    // console.log("res2",response.data.results) // reference
    setSearchCount(response.data.count);
    const list = response.data.results.map(val => ({
      name: val.name,
      quantity: val.quantity,
      sellingPrice: val.latest_selling_price,
      loose: val.loose,
      id: val.id,
      upperLimit: val.upper_limit === null ? '' : val.upper_limit,
      lowerLimit: val.lower_limit === null ? '' : val.lower_limit,
    }));
    console.log(list);
    setInventoryList(list); // set state
  };

  const apiFetch = async () => {
    try {
      setIsLoading(true);

      const response = await getEndPoint(
        '/api/productlist/?limit=10&offset=0',
        null,
        history
      );
      // Use utility function

      // console.log("error",response) check error code here for reference
      console.log(response.data.results);

      const { data } = response;
      setCount(data.count);
      const list = data.results.map(val => ({
        name: val.name,
        quantity: val.quantity,
        sellingPrice: val.latest_selling_price,
        loose: val.loose,
        id: val.id,
        upperLimit: val.upper_limit === null ? '' : val.upper_limit,
        lowerLimit: val.lower_limit === null ? '' : val.lower_limit,
      }));
      setSearchList(list);
      setInventoryList(list);
      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  // call API on component load
  useEffect(() => {
    apiFetch();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const classes = useStyles();

  // handle product delete
  const handleDelete = async row => {
    setIsLoading(true);
    const { id } = row;
    setDeletedRow(prevState => [...prevState, inventoryList.indexOf(row)]);
    try {
      await axios.delete(`/api/productlist/${id}/`);

      // add success snackbar on successful request
      const { name } = inventoryList.find(val => val.id === id);
      setIsLoading(false);
      setSnack({
        open: true,
        message: `Succesfully deleted ${name}`,
        action: '',
        actionParams: '',
        type: 'success',
      });
    } catch (e) {
      console.log(e);
    }
  };

  // handle product edit
  const handleEdit = row => {
    history.push('/updateproduct', {
      name: row.name,
      sellingPrice: row.sellingPrice,
      loose: row.loose,
      id: row.id,
      upperLimit: row.upperLimit,
      lowerLimit: row.lowerLimit,
    });
  };

  return (
    <>
      {isLoading ? <Spinner /> : null}

      <div className={classes.search}>
        <TextField
          onChange={e => handleSearch(e.target.value)}
          style={{ width: '350px' }}
          id='standard-basic'
          label='Search'
          variant='filled'
          InputProps={{
            startAdornment: (
              <InputAdornment position='start'>
                <SearchIcon />
              </InputAdornment>
            ),
          }}
        />
      </div>

      {search === '' ? (
        <>
          {' '}
          <Paper className={classes.paper}>
            <TableContainer>
              <Table className={classes.table} aria-label='simple table'>
                <TableHead>
                  <TableRow>
                    <TableCell />
                    <TableCell>Product</TableCell>
                    <TableCell align='right'>Items</TableCell>
                    <TableCell align='right'>Price (Rs)</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {searchList.map((row, index) => (
                    <TableRow
                      key={row.name}
                      hover
                      className={deletedRow.includes(index) ? 'delete' : ''}
                    >
                      <TableCell className={classes.firstColumn}>
                        <Hidden xsDown>
                          <IconButton
                            onClick={() => {
                              handleEdit(row);
                            }}
                          >
                            <EditIcon />
                          </IconButton>
                          <IconButton
                            onClick={() => {
                              setSelectedRow(row);
                              handleClickOpen();
                            }}
                          >
                            <DeleteIcon />
                          </IconButton>
                        </Hidden>
                        <Hidden smUp>
                          <MobileEditMenu
                            handleDelete={() => {
                              setSelectedRow(row);
                              handleClickOpen();
                            }}
                            handleEdit={handleEdit}
                            row={row}
                          />
                        </Hidden>
                      </TableCell>
                      <TableCell>{row.name}</TableCell>
                      <TableCell align='right'>{row.quantity}</TableCell>
                      <TableCell align='right'>
                        {row.sellingPrice || 'Not Set'}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </TableContainer>
            <TablePagination
              rowsPerPageOptions={[5, 10]}
              component='div'
              count={count}
              page={page}
              rowsPerPage={rowsPerPage}
              onChangePage={handleChangePage}
              onChangeRowsPerPage={handleChangeRowsPerPage}
            />
          </Paper>
          <DialogBox
            open={open}
            handleClose={handleClose}
            selectedRow={selectedRow}
            handleDelete={handleDelete}
            number='1'
          />
        </>
      ) : (
        <>
          <Paper className={classes.paper}>
            <TableContainer>
              <Table className={classes.table} aria-label='simple table'>
                <TableHead>
                  <TableRow>
                    <TableCell />
                    <TableCell>Product</TableCell>
                    <TableCell align='right'>Items</TableCell>
                    <TableCell align='right'>Price (Rs)</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {inventoryList.map((row, index) => (
                    <TableRow
                      key={row.name}
                      hover
                      className={deletedRow.includes(index) ? 'delete' : ''}
                    >
                      <TableCell className={classes.firstColumn}>
                        <Hidden xsDown>
                          <IconButton
                            onClick={() => {
                              handleEdit(row);
                            }}
                          >
                            <EditIcon />
                          </IconButton>
                          <IconButton
                            onClick={() => {
                              setSelectedRow(row);
                              handleClickOpen();
                            }}
                          >
                            <DeleteIcon />
                          </IconButton>
                        </Hidden>
                        <Hidden smUp>
                          <MobileEditMenu
                            handleDelete={() => {
                              setSelectedRow(row);
                              handleClickOpen();
                            }}
                            handleEdit={handleEdit}
                            row={row}
                          />
                        </Hidden>
                      </TableCell>
                      <TableCell>{row.name}</TableCell>
                      <TableCell align='right'>{row.quantity}</TableCell>
                      <TableCell align='right'>
                        {row.sellingPrice || 'Not Set'}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </TableContainer>
            <TablePagination
              rowsPerPageOptions={[5, 10]}
              component='div'
              count={searchCount}
              page={searchPage}
              rowsPerPage={searchRowsPerPage}
              onChangePage={handleSearchChangePage}
              onChangeRowsPerPage={handleSearchChangeRowsPerPage}
            />
          </Paper>
          <DialogBox
            open={open}
            handleClose={handleClose}
            selectedRow={selectedRow}
            handleDelete={handleDelete}
            number='1'
          />
        </>
      )}
    </>
  );
}
Example #9
Source File: ExpiryTable.js    From inventory-management-web with MIT License 4 votes vote down vote up
export default function ExpiryTable() {
  // list of near expiry products got from API
  const [expiryList, setExpiryList] = useState([]);
  // true when waiting for an response from API
  const [isLoading, setIsLoading] = useState(false);
  // pagination
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(10);
  const [count, setCount] = useState(0);

  const history = useHistory();

  const handleChangePage = async (event, newPage) => {
    try {
      setIsLoading(true);
      setPage(newPage);
      const response = await getEndPoint(
        `/api/explist/?limit=${rowsPerPage}&offset=${newPage * rowsPerPage}`,
        null,
        history
      );
      const { data } = response;
      setCount(data.count);
      console.log(data);
      const list = data.results.map(val => ({
        name: val.Product,
        quantity: val['No. of items'],
        daysLeft: val['Days left'],
      }));
      setExpiryList(list);
      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  const handleChangeRowsPerPage = async event => {
    try {
      setIsLoading(true);
      setPage(0);
      setRowsPerPage(+event.target.value);
      const response = await getEndPoint(
        `/api/explist/?limit=${+event.target.value}&offset=0`,
        null,
        history
      );
      const { data } = response;
      setCount(data.count);
      console.log(data);
      const list = data.results.map(val => ({
        name: val.Product,
        quantity: val['No. of items'],
        daysLeft: val['Days left'],
      }));
      setExpiryList(list);
      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  const apiFetch = async () => {
    try {
      setIsLoading(true);
      const response = await getEndPoint(
        '/api/explist/?limit=10&offset=0',
        null,
        history
      );
      const { data } = response;
      setCount(data.count);
      console.log(data);
      const list = data.results.map(val => ({
        name: val.Product,
        quantity: val['No. of items'],
        daysLeft: val['Days left'],
      }));
      setExpiryList(list);
      setIsLoading(false);
    } catch (e) {
      console.log(e);
    }
  };

  // call API on component load
  useEffect(() => {
    apiFetch();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const classes = useStyles();

  return (
    <>
      {isLoading ? <Spinner /> : null}
      <Paper className={classes.paper}>
        <TableContainer className={classes.tableContainer}>
          <Table className={classes.table} aria-label='simple table'>
            <TableHead>
              <TableRow>
                <TableCell>Product</TableCell>
                <TableCell align='right'>Items</TableCell>
                <TableCell align='right'>Days Left</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {expiryList.map(row => (
                <TableRow key={row.name} hover>
                  <TableCell>{row.name}</TableCell>
                  <TableCell align='right'>{row.quantity}</TableCell>
                  <TableCell align='right'>{row.daysLeft}</TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
        <TablePagination
          rowsPerPageOptions={[5, 10]}
          component='div'
          count={count}
          page={page}
          rowsPerPage={rowsPerPage}
          onChangePage={handleChangePage}
          onChangeRowsPerPage={handleChangeRowsPerPage}
        />
      </Paper>
    </>
  );
}
Example #10
Source File: Users.js    From acsys with MIT License 4 votes vote down vote up
Users = (props) => {
  const [userId, setUserId] = useState(0);
  const [message, setMessage] = useState('');
  const [users, setUsers] = useState([]);
  const [username, setUsername] = useState('');
  const [role, setRole] = useState('Administrator');
  const [email, setEmail] = useState('');
  const [passwordOne, setPasswordOne] = useState('');
  const [passwordTwo, setPasswordTwo] = useState('');
  const [page, setPage] = useState(0);
  const [rowsPerPage] = useState(15);
  const [setOpen, setSetOpen] = useState(false);
  const [addLoading, setAddLoading] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [deleteLoading, setDeleteLoading] = useState(false);
  const [setError] = useState('');
  const [projectName, setProjectName] = useState('');

  const deleteUser = async () => {
    await Acsys.deleteData('acsys_users', [['acsys_id', '=', userId]])
      .then(() => {
        inDidMount();
      })
      .catch((error) => setError(error));
    setDeleting(false);
    setDeleteLoading(false);
  };

  const handleChangePage = (event, page) => {
    setPage(page);
  };

  const handleClickOpen = () => {
    setSetOpen(true);
  };

  const handleClose = () => {
    setSetOpen(false);
  };

  const handleDeleteOpen = async (userId) => {
    setDeleting(true);
    setUserId(userId);
  };

  const handleDeleteClose = () => {
    setDeleting(false);
    setDeleteLoading(false);
  };

  const inDidMount = async () => {
    props.setHeader('Users');
    let projectName = await Acsys.getProjectName();
    let users = [];
    try {
      users = await Acsys.getUsers(Acsys.getUser());
    } catch (error) {}
    setProjectName(projectName);
    setUsers(users);
  };
  const addUser = async () => {
    setAddLoading(true);
    if (
      username.length < 1 ||
      email.length < 1 ||
      passwordOne.length < 1 ||
      passwordTwo.length < 1
    ) {
      setMessage('Please fill all fields.');
    } else if (passwordOne !== passwordTwo) {
      setMessage('Passwords do not match.');
    } else {
      const user = {
        acsys_id: uniqid(),
        role: role,
        mode: role,
        username: username,
        email: email,
        password: passwordOne,
      };
      await Acsys.createUser(user)
        .then((result) => {
          if (result === true) {
            setSetOpen(false);
            inDidMount();
          } else {
            setMessage(result);
          }
        })
        .catch((error) => {
          setError(error);
        });
      setUsername('');
      setEmail('');
      setPasswordOne('');
      setPasswordTwo('');
      setMessage('');
    }
    setAddLoading(false);
  };

  useEffect(() => {
    inDidMount();
  }, []);

  const renderTableData = () => {
    return users
      .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
      .map((users) => {
        const { acsys_id, username, email, role } = users;
        return (
          <TableRow key={acsys_id}>
            <TableCell>{username}</TableCell>
            <TableCell>{role}</TableCell>
            <TableCell>{email}</TableCell>
            <TableCell align="right">
              <Tooltip title="Remove User">
                <IconButton
                  edge="start"
                  color="inherit"
                  aria-label="delete"
                  onClick={() => handleDeleteOpen(acsys_id)}
                >
                  <DeleteIcon />
                </IconButton>
              </Tooltip>
            </TableCell>
          </TableRow>
        );
      });
  };
  try {
    return (
      <div>
        <Paper
          style={{
            margin: 'auto',
            overflow: 'hidden',
            clear: 'both',
            marginBottom: 20,
          }}
        >
          <AppBar
            position="static"
            elevation={0}
            style={{
              backgroundColor: '#fafafa',
              borderBottom: '1px solid #dcdcdc',
            }}
          >
            <Toolbar style={{ margin: 4, paddingLeft: 12, paddingRight: 12 }}>
              <Grid container spacing={1}>
                <Grid item xs style={{ overflow: 'hidden' }}>
                  <Typography
                    align="left"
                    variant="subtitle2"
                    noWrap
                    style={{ marginTop: 10, color: '#000000' }}
                  >
                    Project: {projectName}
                  </Typography>
                </Grid>
                <Grid item>
                  <Tooltip title="Add New User">
                    <Button
                      variant="contained"
                      color="primary"
                      onClick={handleClickOpen}
                    >
                      Add User
                    </Button>
                  </Tooltip>
                </Grid>
              </Grid>
            </Toolbar>
          </AppBar>
          <div style={{ margin: 'auto', overflow: 'auto' }}>
            <Table>
              <TableHead style={{ backgroundColor: '#fafafa' }}>
                <TableRow>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                    }}
                  >
                    USERNAME
                  </TableCell>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                    }}
                  >
                    ROLE
                  </TableCell>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                    }}
                  >
                    EMAIL
                  </TableCell>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                    }}
                    align="right"
                  >
                    ACTIONS
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>{renderTableData()}</TableBody>
            </Table>
          </div>
          <TablePagination
            rowsPerPageOptions={[25]}
            component="div"
            count={users.length}
            rowsPerPage={rowsPerPage}
            page={page}
            backIconButtonProps={{
              'aria-label': 'previous page',
            }}
            nextIconButtonProps={{
              'aria-label': 'next page',
            }}
            onChangePage={handleChangePage}
            // onChangeRowsPerPage={handleChangeRowsPerPage}
          />
          <NewUserDialog
            open={setOpen}
            closeDialog={handleClose}
            message={message}
            setRole={(value) => setRole(value)}
            email={email}
            setEmail={(value) => setEmail(value)}
            username={username}
            setUsername={(value) => {
              setUsername(value);
            }}
            passwordOne={passwordOne}
            setPasswordOne={(value) => {
              setPasswordOne(value);
            }}
            passwordTwo={passwordTwo}
            setPasswordTwo={(value) => setPasswordTwo(value)}
            action={addUser}
            actionProcess={addLoading}
          />
          <YesNoDialog
            open={deleting}
            closeDialog={handleDeleteClose}
            title={'Delete data?'}
            message={'Are you sure you want to delete this user?'}
            action={deleteUser}
            actionProcess={deleteLoading}
          />
        </Paper>
      </div>
    );
  } catch (error) {
    console.log(error, 'error');
    return (
      <div style={{ maxWidth: 1236, margin: 'auto' }}>
        <Paper style={{ height: 40 }}>
          <div style={{ padding: 10, margin: 'auto' }}>
            Please make sure database has been created.
          </div>
        </Paper>
      </div>
    );
  }
}
Example #11
Source File: AdminEventList.js    From AdaptivApps-fe with MIT License 4 votes vote down vote up
AdminEventList = props => {
  // Declare Create, Update, and Delete mutation functions
  const [CreateEvent] = useMutation(CREATE_EVENT);
  const [UpdateEvent] = useMutation(UPDATE_EVENT);
  const [DeleteEvent] = useMutation(DELETE_EVENT);

  // Grab the events data from props
  const events = props.events;
  //commented out to remove console warning, eventType defined but never used
  //const eventType = props.events.type;

  const useStyles = makeStyles({
    grid: {
      maxWidth: "120rem",
      marginLeft: "3rem",
      "& .MuiButton-label": {
        fontSize: "1.6rem",
        fontWeight: "500",
      },
    },
    tableHead: {
      "& th": {
        fontSize: "1.6rem",
      },
    },
    addBtn: {
      color: "#2763FF",
      textTransform: "none",
    },
    img: { width: "15rem", objectFit: "contain" },
    label: {
      marginTop: ".8rem",
      color: "red",
      fontSize: "1rem",
    },
  });
  const classes = useStyles();
  // This code is returning a material table object
  // For more info on material table, please visit their docs at
  // https://material-table.com/
  return (
    <Grid className={classes.grid}>
      <MaterialTable
        components={{
          Pagination: props => (
            <TablePagination
              {...props}
              SelectProps={{
                style: {
                  fontSize: "1.4rem",
                },
              }}
            />
          ),
        }}
        title=""
        columns={[
          {
            title: "Title",
            field: "title",
            render: rowData => (
              <div
                style={{
                  fontSize: "1.6rem",
                  width: "20rem",
                }}
              >
                {rowData.title}
              </div>
            ),
            editComponent: props => (
              <>
                <Input
                  type="text"
                  value={props.value}
                  onChange={e => props.onChange(e.target.value)}
                />
                <InputLabel className={classes.label}>*Required</InputLabel>
              </>
            ),
          },
          {
            title: "Type",
            field: "type",
            render: rowData => (
              <div
                style={{
                  fontSize: "1.6rem",
                  width: "10rem",
                }}
              >
                {rowData.type}
              </div>
            ),
            editComponent: props => (
              <>
                <Select
                  value={props.value}
                  onChange={e => props.onChange(e.target.value)}
                >
                  <MenuItem value="In Person">In Person</MenuItem>
                  <MenuItem value="Webinar">Webinar</MenuItem>
                </Select>
                <InputLabel className={classes.label}>*Required</InputLabel>
              </>
            ),
          },
          {
            title: "Host",
            field: "host",
            render: rowData => (
              <div
                style={{
                  fontSize: "1.6rem",
                  width: "16rem",
                }}
              >
                {rowData.host}
              </div>
            ),
            editComponent: props => (
              <Input
                type="text"
                value={props.value}
                onChange={e => props.onChange(e.target.value)}
              />
            ),
          },
          {
            title: "Speakers",
            field: "speakers",
            render: rowData => (
              <div
                style={{
                  overflow: "scroll",
                  maxHeight: "10rem",
                  fontSize: "1.6rem",
                  width: "20rem",
                }}
              >
                {rowData.speakers}
              </div>
            ),
            editComponent: props => (
              <Input
                type="text"
                value={props.value}
                onChange={e => props.onChange(e.target.value)}
              />
            ),
          },

          {
            title: "Start Time",
            field: "startTime",
            editComponent: props => (
              <Input
                type="time"
                value={props.value}
                onChange={e => props.onChange(e.target.value)}
              />
            ),
          },
          {
            title: "Start Date",
            field: "startDate",
            render: rowData => (
              <div
                style={{
                  fontSize: "1.6rem",
                  width: "9rem",
                }}
              >
                {rowData.startDate}
              </div>
            ),
            editComponent: props => (
              <>
                <Input
                  type="date"
                  value={props.value}
                  onChange={e => props.onChange(e.target.value)}
                />
                <InputLabel className={classes.label}>*Required</InputLabel>
              </>
            ),
          },
          {
            title: "End Date",
            field: "endDate",
            render: rowData => (
              <div
                style={{
                  fontSize: "1.6rem",
                  width: "9rem",
                }}
              >
                {rowData.endDate}
              </div>
            ),
            editComponent: props => (
              <>
                <Input
                  type="date"
                  value={props.value}
                  onChange={e => props.onChange(e.target.value)}
                />
                <InputLabel className={classes.label}>*Required</InputLabel>
              </>
            ),
          },
          {
            title: "Location",
            field: "location",
            render: rowData => (
              <div
                style={{
                  fontSize: "1.6rem",
                  width: "14rem",
                }}
              >
                {rowData.location}
              </div>
            ),
            editComponent: props => (
              <>
                <Input
                  type="text"
                  value={props.value}
                  onChange={e => props.onChange(e.target.value)}
                />
                <InputLabel className={classes.label}>*Required</InputLabel>
              </>
            ),
          },
          {
            title: "Link",
            field: "link",
            render: rowData => (
              <div
                style={{
                  overflow: "scroll",
                  fontSize: "1.6rem",
                  width: "22rem",
                }}
              >
                {rowData.link}
              </div>
            ),
            editComponent: props => (
              <Input
                type="url"
                value={props.value}
                onChange={e => props.onChange(e.target.value)}
              />
            ),
          },
          {
            title: "Image Url",
            field: "imgUrl",
            render: rowData => (
              <img
                style={{
                  maxHeight: "12rem",
                }}
                src={rowData.imgUrl}
                alt="Event"
                className={classes.img}
              />
            ),
            editComponent: props => (
              <Input
                type="text"
                value={props.value}
                onChange={e => props.onChange(e.target.value)}
              />
            ),
          },
          {
            title: "Sponsors",
            field: "sponsors",
            render: rowData => (
              <div
                style={{
                  overflow: "scroll",
                  fontSize: "1.6rem",
                  width: "20rem",
                }}
              >
                {rowData.sponsors}
              </div>
            ),
            editComponent: props => (
              <Input
                type="text"
                value={props.value}
                onChange={e => props.onChange(e.target.value)}
              />
            ),
          },
          {
            title: "Details",
            field: "details",
            render: rowData => (
              <div
                style={{
                  fontSize: "1.6rem",
                  width: "30rem",
                  maxHeight: "14rem",
                  overflow: "scroll",
                }}
              >
                {rowData.details}
              </div>
            ),
            editComponent: props => (
              <textarea
                style={{
                  fontSize: "1.6rem",
                }}
                rows="8"
                cols="60"
                type="text"
                value={props.value}
                onChange={e => props.onChange(e.target.value)}
              />
            ),
          },
        ]}
        data={events}
        editable={{
          onRowAdd: async newData => {
            await CreateEvent({
              variables: {
                title: newData.title,
                type: newData.type,
                host: newData.host,
                speakers: newData.speakers,
                startTime: newData.startTime,
                startDate: newData.startDate,
                endDate: newData.endDate,
                location: newData.location,
                imgUrl: newData.imgUrl,
                sponsors: newData.sponsors,
                details: newData.details,
                link: newData.link,
              },
            });
            props.eventsRefetch();
          },
          onRowUpdate: async (newData, oldData) => {
            await UpdateEvent({
              variables: {
                id: newData.id,
                title: newData.title,
                type: newData.type,
                host: newData.host,
                speakers: newData.speakers,
                startTime: newData.startTime,
                startDate: newData.startDate,
                endDate: newData.endDate,
                location: newData.location,
                imgUrl: newData.imgUrl,
                sponsors: newData.sponsors,
                details: newData.details,
                link: newData.link,
              },
            });
            props.eventsRefetch();
          },
          onRowDelete: async oldData => {
            await DeleteEvent({
              variables: {
                id: oldData.id,
              },
            });
            props.eventsRefetch();
          },
        }}
        icons={{
          Add: () => (
            <>
              <AddCircleOutlineIcon
                style={{ color: "#2962FF" }}
                fontSize="large"
              />
              <Button className={classes.addBtn}>Add Event</Button>
            </>
          ),
          Edit: () => (
            <EditIcon style={{ color: "#2962FF" }} fontSize="large" />
          ),
          Delete: () => (
            <DeleteIcon style={{ color: "#2962FF" }} fontSize="large" />
          ),
        }}
        detailPanel={[
          {
            tooltip: "Show Activities",
            isFreeAction: true,
            render: rowData => {
              // When clicking on a row, display a list of activities associated
              // With the event
              const event_id = rowData.id;
              return <AdminActivityList event_id={event_id} />;
            },
          },
        ]}
        options={{
          cellStyle: {
            fontSize: "1.6rem",
          },
          headerStyle: {
            fontSize: "4rem",
            backgroundColor: "#2962FF",
            color: "#FFF",
          },
          rowStyle: {
            backgroundColor: "#FFF",
          },
          emptyRowsWhenPaging: false,
          toolbarButtonAlignment: "left",
          searchFieldStyle: {
            width: "20rem",
            fontSize: "1.6rem",
          },
          doubleHorizontalScrolldoubleHorizontalScroll: false,
          columnsButton: true,
        }}
      />
    </Grid>
  );
}
Example #12
Source File: LogicalContent.js    From acsys with MIT License 4 votes vote down vote up
LogicalContent = (props) => {
  const [viewId, setViewId] = useState('');
  const [name, setName] = useState('');
  const [collectionArr, setCollectionArr] = useState([]);
  const [collection, setCollection] = useState('');
  const [description, setDescription] = useState('');
  const [views, setViews] = useState([]);
  const [page, setPage] = useState(0);
  const [rowsPerPage] = useState(15);
  const [loading, setLoading] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [open, setOpen] = useState(false);
  const [editOpen, setEditOpen] = useState(false);
  const [addLoading, setAddLoading] = useState(false);
  const [saveLoading, setSaveLoading] = useState(false);
  const [deleteLoading, setDeleteLoading] = useState(false);
  const context = useContext(AcsysContext);
  const [projectName, setProjectName] = useState('');

  const setPosition = (pos) => {
    position = pos;
  };

  const setTempName = (value) => {
    tempView['name'] = value;
  };

  const setTempDescription = (value) => {
    tempView['description'] = value;
  };

  const deleteView = async () => {
    setDeleteLoading(true);
    if (viewId.length > 0) {
      await Acsys.deleteView(viewId);
    }
    handleDeleteClose();
    mount();
  };

  const handleChangePage = (event, page) => {
    setPage(page);
  };

  const handleClickOpen = async () => {
    let collections = [];
    await Acsys.getTables().then((json) => {
      collections = json;
      setCollectionArr(collections);
      setOpen(true);
    });
  };

  const handleClose = () => {
    setOpen(false);
    setAddLoading(false);
  };

  const handleEditOpen = (view) => {
    tempView = view;
    position = tempView.position;
    setEditOpen(true);
  };

  const handleEditClose = () => {
    setEditOpen(false);
  };

  const editView = async () => {
    if (position === tempView.position) {
      await Acsys.updateData('acsys_logical_content', tempView, [
        ['acsys_id', '=', tempView.acsys_id],
      ]);
    } else {
      const oldPosition = tempView['position'];
      tempView['position'] = position;
      await Acsys.repositionViews(tempView, oldPosition, position);
      await sleep(1000);
    }
    const currentView = await Acsys.getData('acsys_logical_content', [], '', [
      'position',
    ]);
    setSaveLoading(false);
    setEditOpen(false);
    setViews(currentView);
  };

  const handleDeleteOpen = async (viewId) => {
    setDeleting(true);
    setViewId(viewId);
  };

  const handleDeleteClose = () => {
    setDeleting(false);
    setDeleteLoading(false);
  };

  const sleep = (time) => {
    return new Promise((resolve) => setTimeout(resolve, time));
  };

  useEffect(() => {
    mount();
  }, []);

  const mount = async () => {
    props.setHeader('Content');
    context.setHeld(false);
    tempView = [];
    setLoading(true);
    let projectName = '';

    await Acsys.getProjectName().then((result) => {
      projectName = result;
    });

    let currentView = [];

    currentView = await Acsys.getData('acsys_logical_content', [], '', [
      'position',
    ]);

    setLoading(false);
    setProjectName(projectName);
    setViews(currentView);
    setLoading(false);
  };

  const addView = async () => {
    setAddLoading(true);
    const uId = uniqid();
    let newView = {
      acsys_id: uId,
      is_table_mode: true,
      is_removable: true,
      link_view_id: '',
      link_table: '',
      order_by: '',
      view_order: '',
      row_num: 10,
    };
    await Acsys.insertData('acsys_views', { ...newView }).then(async () => {
      let newEntry = {
        acsys_id: uniqid(),
        name: name,
        description: description,
        viewId: uId,
        source_collection: collection,
        position: views.length + 1,
        table_keys: [],
      };
      await Acsys.insertData('acsys_logical_content', { ...newEntry });
    });

    setAddLoading(false);
    handleClose();
    mount();
  };

  const renderTableData = () => {
    return views
      .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
      .map((views, key) => {
        const {
          acsys_id,
          name,
          description,
          viewId,
          source_collection,
          table_keys,
        } = views;
        return (
          <TableRow key={key}>
            {table_keys.length < 1 ? (
              <TableCell
                to={{
                  pathname:
                    '/CollectionView/' + source_collection + '/' + viewId,
                  state: {
                    table_keys: [],
                    view: name,
                  },
                }}
                component={Link}
                style={{ minWidth: 150 }}
              >
                {name}
              </TableCell>
            ) : (
              <TableCell
                to={{
                  pathname: '/DocumentView',
                  state: {
                    mode: 'update',
                    table_keys: views.table_keys,
                    routed: true,
                    viewId: views.viewId,
                  },
                }}
                component={Link}
                style={{ minWidth: 150 }}
              >
                {name}
              </TableCell>
            )}
            {table_keys.length < 1 ? (
              <TableCell
                to={{
                  pathname:
                    '/CollectionView/' + source_collection + '/' + viewId,
                  state: {
                    table_keys: [],
                    view: name,
                  },
                }}
                component={Link}
                style={{ width: '100%' }}
              >
                {description}
              </TableCell>
            ) : (
              <TableCell
                to={{
                  pathname: '/DocumentView',
                  state: {
                    mode: 'update',
                    table_keys: views.table_keys,
                    routed: true,
                    viewId: views.viewId,
                  },
                }}
                component={Link}
              >
                {description}
              </TableCell>
            )}
            {Acsys.getMode() === 'Administrator' ? (
              <TableCell style={{ minWidth: 70 }} align="right">
                <Tooltip title="Edit View">
                  <IconButton
                    edge="start"
                    color="inherit"
                    aria-label="edit"
                    onClick={() => handleEditOpen(views)}
                    style={{ marginRight: 10 }}
                  >
                    <CreateIcon />
                  </IconButton>
                </Tooltip>
                <Tooltip title="Delete View">
                  <IconButton
                    edge="start"
                    color="inherit"
                    aria-label="delete"
                    onClick={() => handleDeleteOpen(viewId)}
                  >
                    <DeleteIcon />
                  </IconButton>
                </Tooltip>
              </TableCell>
            ) : (
              <div />
            )}
          </TableRow>
        );
      });
  };
  try {
    return (
      <div>
        <Paper
          style={{
            margin: 'auto',
            overflow: 'hidden',
            clear: 'both',
            marginBottom: 20,
          }}
        >
          <AppBar
            position="static"
            elevation={0}
            style={{
              backgroundColor: '#fafafa',
              borderBottom: '1px solid #dcdcdc',
            }}
          >
            <Toolbar style={{ margin: 4, paddingLeft: 12, paddingRight: 12 }}>
              {Acsys.getMode() === 'Administrator' ? (
                <Grid container spacing={1}>
                  <Grid item xs style={{ overflow: 'hidden' }}>
                    <Typography
                      align="left"
                      variant="subtitle2"
                      noWrap
                      style={{ marginTop: 10, color: '#000000' }}
                    >
                      Project: {projectName}
                    </Typography>
                  </Grid>
                  <Grid item>
                    <Tooltip title="Add New View For Table">
                      <Button
                        variant="contained"
                        color="primary"
                        onClick={handleClickOpen}
                      >
                        Add View
                      </Button>
                    </Tooltip>
                  </Grid>
                </Grid>
              ) : (
                <Grid container spacing={1}>
                  <Grid item xs style={{ overflow: 'hidden' }}>
                    <Typography
                      align="left"
                      variant="subtitle2"
                      noWrap
                      style={{ marginTop: 5, color: '#000000' }}
                    >
                      Project: {projectName}
                    </Typography>
                  </Grid>
                </Grid>
              )}
            </Toolbar>
          </AppBar>
          <div style={{ margin: 'auto', overflow: 'auto' }}>
            <Table>
              <TableHead style={{ backgroundColor: '#fafafa' }}>
                <TableRow>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                      width: 150,
                    }}
                  >
                    NAME
                  </TableCell>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                    }}
                  >
                    DESCRIPTION
                  </TableCell>
                  {Acsys.getMode() === 'Administrator' ? (
                    <TableCell
                      style={{
                        paddingLeft: 16,
                        paddingRight: 16,
                        paddingTop: 5,
                        paddingBottom: 5,
                      }}
                      align="right"
                    >
                      ACTIONS
                    </TableCell>
                  ) : (
                    <div />
                  )}
                </TableRow>
              </TableHead>
              <TableBody>{renderTableData()}</TableBody>
            </Table>
          </div>
          <TablePagination
            rowsPerPageOptions={[25]}
            component="div"
            count={views.length}
            rowsPerPage={rowsPerPage}
            page={page}
            backIconButtonProps={{
              'aria-label': 'previous page',
            }}
            nextIconButtonProps={{
              'aria-label': 'next page',
            }}
            onChangePage={handleChangePage}
            // onChangeRowsPerPage={this.handleChangeRowsPerPage}
          />
          <LoadingDialog loading={loading} message={'Loading'} />
          <AddViewDialog
            open={open}
            closeDialog={handleClose}
            title={'Add Logical View'}
            collection={collection}
            setCollection={(value) => setCollection(value)}
            collectionArr={collectionArr}
            setName={(value) => setName(value)}
            setDescription={(value) => setDescription(value)}
            action={addView}
            actionProcess={addLoading}
          />
          <EditViewDialog
            open={editOpen}
            closeDialog={handleEditClose}
            title={'Edit Logical View'}
            position={tempView.position}
            setPosition={setPosition}
            views={views}
            name={tempView.name}
            setName={setTempName}
            description={tempView.description}
            setDescription={setTempDescription}
            action={editView}
            actionProcess={saveLoading}
          />
          <YesNoDialog
            open={deleting}
            closeDialog={handleDeleteClose}
            title={'Delete data?'}
            message={'Are you sure you want to delete this data?'}
            action={deleteView}
            actionProcess={deleteLoading}
          />
        </Paper>
      </div>
    );
  } catch (error) {
    return (
      <div style={{ maxWidth: 1236, margin: 'auto' }}>
        <Paper style={{ height: 40 }}>
          <div style={{ padding: 10, margin: 'auto' }}>
            Please make sure database has been created.
          </div>
        </Paper>
      </div>
    );
  }
}
Example #13
Source File: Database.js    From acsys with MIT License 4 votes vote down vote up
Database = (props) => {
  const context = useContext(AcsysContext);
  const [viewId, setviewId] = useState('');
  const [views, setviews] = useState([]);
  const [page, setpage] = useState(0);
  const [rowsPerPage] = useState(15);
  const [message, setmessage] = useState('');
  const [loading, setloading] = useState(false);
  const [deleting, setdeleting] = useState(false);
  const [open, setOpen] = useState(false);
  const [addLoading, setAddLoading] = useState(false);
  const [deleteLoading, setdeleteLoading] = useState(false);
  const [openMessage, setopenMessage] = useState(false);
  const [projectName] = useState('');

  const deleteTable = async () => {
    setdeleteLoading(true);
    if (viewId.length > 0) {
      await Acsys.dropTable(viewId);
    }
    handleDeleteClose();
    inDidMount();
  };

  const handleChangePage = (event, page) => {
    setpage(page);
  };

  const handleClickOpen = async () => {
    entry = [];
    entry.push({ dataType: 'string', fieldName: '', value: '' });
    setOpen(true);
  };

  const handleClose = () => {
    tableName = '';
    setOpen(false);
    setAddLoading(false);
  };

  const handleMessageClose = () => {
    setopenMessage(false);
  };

  const editView = async () => {
    await Acsys.updateData('acsys_logical_content', tempView, [
      ['acsys_id', '=', tempView.acsys_id],
    ]);
    const currentView = await Acsys.getData('acsys_logical_content');
    setviews(currentView);
  };

  const handleDeleteOpen = async (viewId) => {
    setdeleting(true);
    setviewId(viewId);
  };

  const handleDeleteClose = () => {
    setdeleting(false);
    setdeleteLoading(false);
  };

  const inDidMount = async () => {
    props.setHeader('Database');
    context.setHeld(false);
    tempView = [];
    setloading(true);
    let projectName = await Acsys.getProjectName();
    let currentView = [];
    currentView = await Acsys.getTableData();
    projectName: projectName, setloading(false);
    setAddLoading(false);
    setviews(currentView);
  };

  useEffect(() => {
    inDidMount();
  }, []);

  const setName = (name) => {
    tableName = name;
  };

  const addTable = async () => {
    setAddLoading(true);
    let error = false;
    let newEntry = {};
    entry.forEach((obj) => {
      const field = obj['fieldName'];
      const value = obj['value'];
      if (value.length < 1 || field.length < 1) {
        error = true;
      }
      if (obj['dataType'] === 'string') {
        newEntry[field] = value;
      } else if (obj['dataType'] === 'number') {
        newEntry[field] = parseInt(value);
      } else if (obj['dataType'] === 'boolean') {
        newEntry[field] = 'true' == value;
      }
    });

    if (error || tableName.length < 1) {
      setAddLoading(false);
      setopenMessage(true);
      setmessage('Allfields must be filled before submitting.');
    } else {
      await Acsys.createTable(tableName, newEntry);
      handleClose();
      inDidMount();
    }
  };

  const renderTableData = () => {
    return views
      .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
      .map((views) => {
        const { acsys_id, table, rows } = views;
        return (
          <TableRow key={acsys_id}>
            <TableCell>{table}</TableCell>
            <TableCell style={{ width: 50 }}>{rows}</TableCell>
            <TableCell style={{ width: 100 }} align="right">
              <Tooltip title="Delete Table">
                <IconButton
                  edge="start"
                  color="inherit"
                  aria-label="delete"
                  onClick={() => handleDeleteOpen(table)}
                >
                  <DeleteIcon />
                </IconButton>
              </Tooltip>
            </TableCell>
          </TableRow>
        );
      });
  };
  try {
    return (
      <div>
        <Paper
          style={{
            margin: 'auto',
            overflow: 'hidden',
            clear: 'both',
            marginBottom: 20,
          }}
        >
          <AppBar
            position="static"
            elevation={0}
            style={{
              backgroundColor: '#fafafa',
              borderBottom: '1px solid #dcdcdc',
            }}
          >
            <Toolbar style={{ margin: 4, paddingLeft: 12, paddingRight: 12 }}>
              <Grid container spacing={1}>
                <Grid item xs style={{ overflow: 'hidden' }}>
                  <Typography
                    align="left"
                    variant="subtitle2"
                    noWrap
                    style={{ marginTop: 10, color: '#000000' }}
                  >
                    Project: {projectName}
                  </Typography>
                </Grid>
                <Grid item>
                  <Tooltip title="Create New Table">
                    <Button
                      variant="contained"
                      color="primary"
                      onClick={handleClickOpen}
                    >
                      Add Table
                    </Button>
                  </Tooltip>
                </Grid>
              </Grid>
            </Toolbar>
          </AppBar>
          <div style={{ margin: 'auto', overflow: 'auto' }}>
            <Table>
              <TableHead style={{ backgroundColor: '#fafafa' }}>
                <TableRow>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                    }}
                  >
                    TABLE NAME
                  </TableCell>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                      width: 50,
                    }}
                  >
                    ROWS
                  </TableCell>
                  <TableCell
                    style={{
                      paddingLeft: 16,
                      paddingRight: 16,
                      paddingTop: 5,
                      paddingBottom: 5,
                      width: 100,
                    }}
                    align="right"
                  >
                    ACTIONS
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>{renderTableData()}</TableBody>
            </Table>
          </div>
          <TablePagination
            rowsPerPageOptions={[25]}
            component="div"
            count={views.length}
            rowsPerPage={rowsPerPage}
            page={page}
            backIconButtonProps={{
              'aria-label': 'previous page',
            }}
            nextIconButtonProps={{
              'aria-label': 'next page',
            }}
            onChangePage={handleChangePage}
            // onChangeRowsPerPage={handleChangeRowsPerPage}
          />
          <LoadingDialog loading={loading} message={'Loading'} />
          <FieldControlDialog
            open={open}
            closeDialog={handleClose}
            title={'Add Table'}
            backend={HTML5Backend}
            component={<TableControl setName={setName} entry={entry} />}
            action={addTable}
            actionProcess={addLoading}
          />
          <YesNoDialog
            open={deleting}
            closeDialog={handleDeleteClose}
            title={'Delete data?'}
            message={'Are you sure you want to delete this data?'}
            action={deleteTable}
            actionProcess={deleteLoading}
          />
          <MessageDialog
            open={openMessage}
            closeDialog={handleMessageClose}
            title={'Error'}
            message={message}
          />
        </Paper>
      </div>
    );
  } catch (error) {
    alert(error);
    return (
      <div style={{ maxWidth: 1236, margin: 'auto' }}>
        <Paper style={{ height: 40 }}>
          <div style={{ padding: 10, margin: 'auto' }}>
            Please make sure database has been created.
          </div>
        </Paper>
      </div>
    );
  }
}
Example #14
Source File: List.js    From course-manager with MIT License 4 votes vote down vote up
export default function List() {
  const [page, setPage] = useState(0);
  const [order, setOrder] = useState('asc');
  const [selected, setSelected] = useState([]);
  const [orderBy, setOrderBy] = useState('fullName');
  const [filterName, setFilterName] = useState('');
  const [rowsPerPage, setRowsPerPage] = useState(5);
  const [users, setUsers] = useState([]);
  const [total, setTotal] = useState(0);

  useEffect(() => {
    const fetchData = async () => {
      console.log(order.toUpperCase());
      const queryString = RequestQueryBuilder.create({
        page,
        limit: rowsPerPage,
        join: [
          {
            field: 'account',
            select: ['username']
          },
          {
            field: 'roles',
            select: ['name']
          }
        ],
        sort: [{ field: orderBy, order: order.toUpperCase() }]
      });
      const response = await apis.user.find(queryString.query());
      const { data: fetchedUsers, total: fetchedTotal } = response;
      if (fetchedUsers && fetchedUsers.length > 0) {
        setUsers(
          fetchedUsers.map(({ id, email, fullName, account: { username }, roles }) => ({
            id,
            email,
            fullName,
            username,
            roles: roles.map(({ name }) => name).join(',')
          }))
        );
      }
      setTotal(fetchedTotal);
    };
    fetchData();
  }, [page, orderBy, order, rowsPerPage]);

  const handleRequestSort = (event, property) => {
    const isAsc = orderBy === property && order === 'asc';
    setOrder(isAsc ? 'desc' : 'asc');
    setOrderBy(property);
  };

  const handleSelectAllClick = (event) => {
    if (event.target.checked) {
      const newSelecteds = users.map((n) => n.name);
      setSelected(newSelecteds);
      return;
    }
    setSelected([]);
  };

  const handleClick = (event, name) => {
    const selectedIndex = selected.indexOf(name);
    let newSelected = [];
    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, name);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1)
      );
    }
    setSelected(newSelected);
  };

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (event) => {
    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(0);
  };

  const handleFilterByName = (event) => {
    setFilterName(event.target.value);
  };

  const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - users.length) : 0;

  const filteredUsers = applySortFilter(users, getComparator(order, orderBy), filterName);

  const isUserNotFound = filteredUsers.length === 0;

  return (
    <Page title="Users">
      <Container>
        <Stack direction="row" alignItems="center" justifyContent="space-between" mb={5}>
          <Typography variant="h4" gutterBottom>
            Users
          </Typography>
          <Button
            variant="contained"
            component={RouterLink}
            to="/dashboard/user/create"
            startIcon={<Icon icon={plusFill} />}
          >
            New User
          </Button>
        </Stack>

        <Card>
          <UserListToolbar
            numSelected={selected.length}
            filterName={filterName}
            onFilterName={handleFilterByName}
          />

          <Scrollbar>
            <TableContainer sx={{ minWidth: 800 }}>
              <Table>
                <UserListHead
                  order={order}
                  orderBy={orderBy}
                  headLabel={TABLE_HEAD}
                  rowCount={total}
                  numSelected={selected.length}
                  onRequestSort={handleRequestSort}
                  onSelectAllClick={handleSelectAllClick}
                />
                <TableBody>
                  {filteredUsers
                    .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                    .map((row) => {
                      const { id, fullName, roles, email, username } = row;
                      const isItemSelected = selected.indexOf(fullName) !== -1;

                      return (
                        <TableRow
                          hover
                          key={id}
                          tabIndex={-1}
                          role="checkbox"
                          selected={isItemSelected}
                          aria-checked={isItemSelected}
                        >
                          <TableCell padding="checkbox">
                            <Checkbox
                              checked={isItemSelected}
                              onChange={(event) => handleClick(event, fullName)}
                            />
                          </TableCell>
                          <TableCell component="th" scope="row" padding="none">
                            <Stack direction="row" alignItems="center" spacing={2}>
                              {/* <Avatar alt={fullName} src={avatarUrl} /> */}
                              <Typography variant="subtitle2" noWrap>
                                {fullName}
                              </Typography>
                            </Stack>
                          </TableCell>
                          <TableCell align="left">{username}</TableCell>
                          <TableCell align="left">{email}</TableCell>
                          <TableCell align="left">{roles}</TableCell>
                          <TableCell align="right">
                            <UserMoreMenu id={id} />
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  {emptyRows > 0 && (
                    <TableRow style={{ height: 53 * emptyRows }}>
                      <TableCell colSpan={6} />
                    </TableRow>
                  )}
                </TableBody>
                {isUserNotFound && (
                  <TableBody>
                    <TableRow>
                      <TableCell align="center" colSpan={6} sx={{ py: 3 }}>
                        <SearchNotFound searchQuery={filterName} />
                      </TableCell>
                    </TableRow>
                  </TableBody>
                )}
              </Table>
            </TableContainer>
          </Scrollbar>

          <TablePagination
            rowsPerPageOptions={[5, 10, 25]}
            component="div"
            count={total}
            rowsPerPage={rowsPerPage}
            page={page}
            onPageChange={handleChangePage}
            onRowsPerPageChange={handleChangeRowsPerPage}
          />
        </Card>
      </Container>
    </Page>
  );
}
Example #15
Source File: KailonaTable.js    From ehr with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
        const columnsLength = this.props.columns.length;
        const noDataColSpan = this.props.contextMenu ? columnsLength + 1 : columnsLength;
        const rowHeight = 50;
        const isWayPointAvailable = !this.state.loading && this.state.previousDataLength !== this.props.data.length;
        const tableHeight = (this.props.rowsPerPage + 1) * rowHeight;

        return (
            <Paper style={{ height: `${tableHeight}px`, width: '100%', position: 'relative', overflowY: 'auto' }}>
                <TableContainer>
                    <Table>
                        <TableHead>
                            <TableRow>
                                {this.props.columns.map(col => (
                                    <HeadCell>{col.label}</HeadCell>
                                ))}
                                {this.props.contextMenu && <HeadCell></HeadCell>}
                            </TableRow>
                        </TableHead>
                        <TableBody>
                            {this.props.data.map(record => (
                                <TableRow>
                                    {this.props.columns.map((col, index) => {
                                        let displayText = record[col.key];

                                        if (col.display && typeof col.display === 'function') {
                                            displayText = col.display(record, record[col.key]);
                                        }

                                        return (
                                            <TableCell>
                                                <div>{displayText}</div>
                                                {index === 0 && (
                                                    <div>
                                                        <Link color="primary">{record.source}</Link>
                                                    </div>
                                                )}
                                            </TableCell>
                                        );
                                    })}
                                    {this.props.contextMenu && (
                                        <TableCell>
                                            <IconButton onClick={e => this.toggleContextMenu(e, record)}>
                                                <MoreHoriz />
                                            </IconButton>
                                        </TableCell>
                                    )}
                                </TableRow>
                            ))}
                        </TableBody>
                        <TableFooter>
                            {this.props.loading && (
                                <TableRow>
                                    <TableCell colSpan={this.props.columns.length} align="center">
                                        <Loader />
                                    </TableCell>
                                </TableRow>
                            )}
                            {!this.props.loading && (!this.props.data || !this.props.data.length) && (
                                <TableRow>
                                    <TableCell colSpan={noDataColSpan} align="center">
                                        <Typography variant="h5">{t('ehr', 'No data available')}</Typography>
                                    </TableCell>
                                </TableRow>
                            )}
                        </TableFooter>
                    </Table>
                </TableContainer>
                {isWayPointAvailable && (
                    <div style={{ marginTop: `10px`, height: '20px' }}>
                        <Waypoint onEnter={this.handleScroll}></Waypoint>
                    </div>
                )}

                {this.props.pagination && (
                    <TablePagination
                        rowsPerPageOptions={[1, 5, 10, 25]}
                        component="div"
                        count={this.props.data.length}
                        rowsPerPage={this.props.rowsPerPage}
                        page={this.state.page}
                        onChangePage={(e, page) => this.props.onChangePage(e, page)}
                        onChangeRowsPerPage={e => this.props.onChangeRowsPerPage(e)}
                    />
                )}

                <Menu
                    id="table-context-menu"
                    anchorEl={this.state.anchorEl}
                    keepMounted
                    open={Boolean(this.state.anchorEl)}
                    onClose={this.handleContextMenuClose}
                >
                    {this.props.contextMenu &&
                        this.props.contextMenu.map(menuItem => {
                            return (
                                <MenuItem onClick={() => this.handleMenuItemClick(menuItem.onClick)}>
                                    <ListItemIcon size="small" style={{ minWidth: '32px' }}>
                                        {menuItem.icon}
                                    </ListItemIcon>
                                    <ListItemText primary={menuItem.label} />
                                </MenuItem>
                            );
                        })}
                </Menu>
            </Paper>
        );
    }
Example #16
Source File: CustomTable.js    From treetracker-admin-client with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * @function
 * @name CustomTable
 * @description displays table containing  rows with data
 *
 * @param {Object} props - properties passed to component
 * @param {Object} props.sortBy - current sort by field and sort order
 * @param {Object} props.selectedRow - selected row
 * @param {Object[]} props.tableMetaData - meta data of the table (carries infomation about table columns etc..)
 * @param {function} props.handleGetData - handler function that triggers get data to be displayed in table
 * @param {function} props.openDateFilter - opens date filter
 * @param {function} props.openMainFilter - opens main filter
 * @param {function} props.setPage - sets current page number
 * @param {function} props.setRowsPerPage - sets number of rows per page number
 * @param {function} props.setSortBy - sets sort by field and sort order
 * @param {function} props.onSelectFile - callback function to be called when file is selected
 * @param {function} props.setSelectedRow - sets selected/clicked row
 * @param {string} props.headerTitle - title of the table header
 * @param {string} props.actionButtonType - determines which action button to render(value can either be 'export' or 'upload')
 * @param {string} props.activeDateRage - string representing the active date range (i.e. 'Oct 1 - Oct 5') in the date filter button
 * @param {boolean} props.isLoading - shows loading spinner when true
 * @param {number} props.page - current page number
 * @param {number} props.rowsPerPage - current number of rows per page
 * @param {number} props.totalCount - total number of rows to be displayed
 * @param {number} props.activeFiltersCount - number of active filters
 * @param {Array} props.rows - rows to be displayed in table
 * @param {React.Component}  props.rowDetails - row  component to display details of a selected row
 * @param {React.Component} props.mainFilterComponent - renders main filter component
 * @param {React.Component} props.dateFilterComponent - renders date filter component
 *
 * @returns {React.Component} custom table
 */
function CustomTable({
  tableMetaData,
  mainFilterComponent,
  dateFilterComponent,
  headerTitle,
  actionButtonType,
  exportDataFetch,
  setSelectedRow,
  selectedRow,
  sortBy,
  rows,
  totalCount,
  rowDetails,
  openDateFilter,
  openMainFilter,
  setPage,
  setRowsPerPage,
  rowsPerPage,
  setSortBy,
  isLoading,
  activeDateRange,
  onSelectFile,
  page,
  activeFiltersCount,
}) {
  // managing custom table  state
  const classes = useStyles();
  const [sortableColumnsObject, setSortableColumnsObject] = useState({});
  const [growerDetail, setGrowerDetail] = useState({
    isOpen: false,
    grower: {},
  });

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (event) => {
    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(0);
  };

  const handleOpenRowDetails = (row) => {
    setSelectedRow(row);
  };

  const handleSortableColumns = (column) => {
    const sortableColumns = {
      ...sortableColumnsObject,
      [column.name]: sortableColumnsObject[column.name]
        ? sortableColumnsObject[column.name] === 'asc'
          ? 'desc'
          : 'asc'
        : 'asc',
    };
    setSortableColumnsObject(sortableColumns);
    setSortBy({ field: column.name, order: sortableColumns[column.name] });
  };

  const handleShowGrowerDetail = (e, grower) => {
    e.preventDefault();
    e.stopPropagation();
    setGrowerDetail({
      isOpen: true,
      growerId: grower.worker_id,
    });
  };

  function handleCloseGrowerDetail() {
    setGrowerDetail({
      isOpen: false,
      growerId: null,
    });
  }

  const isRowSelected = (id) => id === selectedRow?.id;

  const tablePagination = () => {
    return (
      <TablePagination
        rowsPerPageOptions={[20, 50, 100]}
        component="div"
        count={totalCount || 0}
        page={page}
        rowsPerPage={rowsPerPage}
        onChangePage={handleChangePage}
        onChangeRowsPerPage={handleChangeRowsPerPage}
        aria-label="rows per page"
      />
    );
  };

  return (
    <Paper className={classes.customTable}>
      <CustomTableHeader
        openDateFilter={openDateFilter}
        openMainFilter={openMainFilter}
        data={rows}
        headerTitle={headerTitle}
        activeDateRange={activeDateRange}
        actionButtonType={actionButtonType}
        onSelectFile={onSelectFile}
        activeFiltersCount={activeFiltersCount}
        exportDataFetch={exportDataFetch}
      />
      {tablePagination()}
      <TableContainer className={classes.tableHeight}>
        <Table stickyHeader aria-label="sticky table">
          <TableHead>
            <TableRow className={classes.customTableHeader}>
              {tableMetaData.map((column, i) => (
                <TableCell
                  key={`${i}-${column.description}`}
                  sortDirection={
                    sortableColumnsObject[column.name] || column.sortDirection
                  }
                  style={{
                    textAlign: column.align === 'right' ? 'right' : 'inherit',
                  }}
                >
                  {column?.sortable ? (
                    <TableSortLabel
                      active={sortBy?.field === column.name}
                      onClick={() => handleSortableColumns(column)}
                      direction={sortableColumnsObject[column.name]}
                      classes={{ icon: classes.customTableHeadSortIcon }}
                      IconComponent={ArrowDropDownIcon}
                    >
                      <Typography
                        variant="h6"
                        align={column.align === 'right' ? 'right' : 'inherit'}
                      >
                        {column.description}
                        {column?.showInfoIcon && (
                          <Tooltip title={column.showInfoIcon}>
                            <InfoOutlinedIcon className={classes.infoIcon} />
                          </Tooltip>
                        )}
                      </Typography>
                    </TableSortLabel>
                  ) : (
                    <Typography
                      variant="h6"
                      align={column.align === 'right' ? 'right' : 'inherit'}
                    >
                      {column.description}
                      {column?.showInfoIcon && (
                        <Tooltip title={column.showInfoIcon}>
                          <InfoOutlinedIcon className={classes.infoIcon} />
                        </Tooltip>
                      )}
                    </Typography>
                  )}
                </TableCell>
              ))}
            </TableRow>
          </TableHead>

          <TableBody>
            {isLoading ? (
              <TableRow>
                <TableCell>
                  <Grid item container className={classes.progressContainer}>
                    <CircularProgress />
                  </Grid>
                </TableCell>
              </TableRow>
            ) : rows.length > 0 ? (
              <>
                {rows.map((row, i) => (
                  <TableRow
                    key={`${i}-${row.id}`}
                    onClick={() => handleOpenRowDetails(row)}
                    className={
                      isRowSelected(row.id) ? classes.selectedRow : null
                    }
                  >
                    {tableMetaData.map((column, j) => (
                      <TableCell key={`${i}-${j}-${column.name}`}>
                        {column.name === 'grower' ? (
                          <Grid item>
                            <Typography
                              variant="body1"
                              style={{ textTransform: 'capitalize' }}
                            >
                              {row[column.name]}

                              <IconButton
                                onClick={(e) => {
                                  handleShowGrowerDetail(e, row);
                                }}
                                aria-label={`View/Edit Grower details`}
                                title={`View/Edit Grower details`}
                                style={{ padding: '0 2px 2px 0' }}
                                disabled
                              >
                                <Person color="disabled" />
                              </IconButton>
                            </Typography>
                          </Grid>
                        ) : (
                          <Typography
                            variant="body1"
                            style={{
                              textTransform: 'capitalize',
                              textAlign:
                                column.align === 'right' ? 'right' : 'inherit',
                            }}
                          >
                            {row[column.name]}
                          </Typography>
                        )}
                      </TableCell>
                    ))}
                  </TableRow>
                ))}
              </>
            ) : (
              <TableRow>
                <TableCell>
                  <Typography
                    variant="body1"
                    className={classes.noDataToDisplay}
                  >
                    No data to display
                  </Typography>
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </TableContainer>
      {tablePagination()}

      <GrowerProvider>
        <GrowerDetail
          open={growerDetail.isOpen}
          growerId={growerDetail.growerId}
          onClose={() => handleCloseGrowerDetail()}
        />
      </GrowerProvider>

      {/* start table main filter */}
      {mainFilterComponent}
      {/* end table main filter */}

      {/* start table date filter */}
      {dateFilterComponent}
      {/* end table date filter */}

      {/* start table row details */}
      {rowDetails}
      {/* end table row details */}
    </Paper>
  );
}
Example #17
Source File: SpeciesTable.js    From treetracker-admin-client with GNU Affero General Public License v3.0 4 votes vote down vote up
SpeciesTable = (props) => {
  const { classes } = props;
  const sortOptions = { byId: 'id', byName: 'name' };
  const speciesContext = useContext(SpeciesContext);
  const { isLoading } = useContext(SpeciesContext);
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(25);
  const [isEdit, setIsEdit] = useState(false);
  const [isAdding, setIsAdding] = useState(false);
  const [speciesEdit, setSpeciesEdit] = useState(undefined);
  const [openDelete, setOpenDelete] = useState(false);
  const [sortedSpeciesList, setSortedSpeciesList] = useState([]);
  const [option, setOption] = useState(sortOptions.byName);
  const [selected, setSelected] = useState([]);
  const [showCombine, setShowCombine] = useState(false);

  const tableRef = useRef(null);

  useEffect(() => {
    const sortBy = (option) => {
      let sortedSpecies;
      if (option === sortOptions.byId) {
        sortedSpecies = [...speciesContext.speciesList].sort(
          (a, b) => a[option] - b[option]
        );
      }
      if (option === sortOptions.byName) {
        sortedSpecies = [...speciesContext.speciesList].sort((a, b) =>
          a[option].localeCompare(b[option])
        );
      }
      setSortedSpeciesList(sortedSpecies);
    };
    sortBy(option);
  }, [
    option,
    sortOptions.byId,
    sortOptions.byName,
    speciesContext.speciesList,
  ]);

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (event) => {
    tableRef.current && tableRef.current.scrollIntoView();

    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(0);
  };

  const handleEdit = (species) => {
    setSpeciesEdit(species);
    setIsEdit(true);
  };

  const openDeleteDialog = (species) => {
    setSpeciesEdit(species);
    setOpenDelete(true);
  };

  const openCombineModal = () => {
    if (selected.length > 1) setShowCombine(true);
    else alert('Please select two or more species to be combined!');
  };

  const handleSelect = (checked, id) => {
    if (checked) setSelected([...selected, id]);
    else setSelected(selected.filter((item) => item !== id));
  };

  const renderSpecies = () => {
    return (rowsPerPage > 0
      ? sortedSpeciesList.slice(
          page * rowsPerPage,
          page * rowsPerPage + rowsPerPage
        )
      : sortedSpeciesList
    ).map((species) => (
      <TableRow key={species.id} role="listitem">
        <TableCell>
          <Checkbox
            onChange={(e) => handleSelect(e.target.checked, species.id)}
            checked={selected.includes(species.id)}
          />
        </TableCell>
        <TableCell component="th" scope="row">
          {species.id}
        </TableCell>
        <TableCell component="th" scope="row" data-testid="species">
          {species.name}
        </TableCell>
        <TableCell>{species.desc}</TableCell>
        <TableCell>{species.captureCount}</TableCell>
        <TableCell>
          <IconButton title="edit" onClick={() => handleEdit(species)}>
            <Edit />
          </IconButton>
          <IconButton title="delete" onClick={() => openDeleteDialog(species)}>
            <Delete />
          </IconButton>
        </TableCell>
      </TableRow>
    ));
  };

  const tablePagination = () => (
    <TablePagination
      count={speciesContext.speciesList.length}
      rowsPerPageOptions={[25, 50, 100, { label: 'All', value: -1 }]}
      colSpan={3}
      page={page}
      rowsPerPage={rowsPerPage}
      onChangePage={handleChangePage}
      onChangeRowsPerPage={handleChangeRowsPerPage}
      SelectProps={{
        inputProps: { 'aria-label': 'rows per page' },
        native: true,
      }}
    />
  );

  return (
    <Grid className={classes.speciesTableContainer}>
      <Paper elevation={3} className={classes.menu}>
        <Menu variant="plain" />
      </Paper>

      <Grid item container className={classes.rightBox}>
        <Grid item xs={12}>
          <Grid container justify="space-between" className={classes.titleBox}>
            <Grid item>
              <Grid container>
                <Grid item>
                  <Typography variant="h2">Species</Typography>
                </Grid>
              </Grid>
            </Grid>
            <Grid item className={classes.addUserBox}>
              <Button
                onClick={openCombineModal}
                variant="outlined"
                color="primary"
              >
                COMBINE SPECIES
              </Button>
              <Button
                onClick={() => setIsAdding(true)}
                variant="contained"
                className={classes.addUser}
                color="primary"
              >
                ADD NEW SPECIES
              </Button>
            </Grid>
          </Grid>
          <Grid container direction="column" className={classes.bodyBox}>
            <TableContainer component={Paper} ref={tableRef}>
              <Table className={classes.table} aria-label="simple table">
                <TableHead>
                  <TableRow>
                    <TableCell></TableCell>
                    <TableCell>
                      ID
                      <IconButton
                        title="sortbyId"
                        onClick={() => setOption(sortOptions.byId)}
                      >
                        <SortIcon />
                      </IconButton>
                    </TableCell>
                    <TableCell>
                      name
                      <IconButton
                        title="sortbyName"
                        onClick={() => setOption(sortOptions.byName)}
                      >
                        <SortIcon />
                      </IconButton>
                    </TableCell>
                    <TableCell>Description</TableCell>
                    <TableCell>Tagged Captures</TableCell>
                    <TableCell>Operations</TableCell>
                  </TableRow>
                </TableHead>
                {isLoading ? (
                  <Grid item container className={classes.loadingIndicator}>
                    <CircularProgress />
                  </Grid>
                ) : (
                  <TableBody>{renderSpecies()}</TableBody>
                )}

                <TableFooter>
                  <TableRow>{tablePagination()}</TableRow>
                </TableFooter>
              </Table>
            </TableContainer>
          </Grid>
        </Grid>
      </Grid>

      <EditModal
        isEdit={isAdding || isEdit}
        setIsEdit={isAdding ? setIsAdding : setIsEdit}
        speciesEdit={speciesEdit}
        setSpeciesEdit={setSpeciesEdit}
        styles={{ ...classes }}
        editSpecies={
          isAdding ? speciesContext.createSpecies : speciesContext.editSpecies
        }
        loadSpeciesList={speciesContext.loadSpeciesList}
        data={sortedSpeciesList}
      />
      <DeleteDialog
        speciesEdit={speciesEdit}
        setSpeciesEdit={setSpeciesEdit}
        openDelete={openDelete}
        setOpenDelete={setOpenDelete}
        deleteSpecies={speciesContext.deleteSpecies}
        loadSpeciesList={speciesContext.loadSpeciesList}
      />
      <CombineModal
        show={showCombine}
        setShow={setShowCombine}
        data={sortedSpeciesList}
        combineSpecies={speciesContext.combineSpecies}
        loadSpeciesList={speciesContext.loadSpeciesList}
        selected={selected}
        styles={{ ...classes }}
      />
    </Grid>
  );
}
Example #18
Source File: Regions.js    From treetracker-admin-client with GNU Affero General Public License v3.0 4 votes vote down vote up
RegionTable = (props) => {
  const { classes } = props;
  // const sortOptions = { byName: 'name' };
  const {
    regions,
    collections,
    currentPage,
    pageSize,
    showCollections,
    changeCurrentPage,
    changePageSize,
    // changeSort,
    setShowCollections,
    regionCount,
    collectionCount,
    upload,
    updateRegion,
    updateCollection,
    deleteRegion,
    deleteCollection,
  } = useContext(RegionContext);
  const { orgList, userHasOrg } = useContext(AppContext);
  const [openEdit, setOpenEdit] = useState(false);
  const [isUpload, setIsUpload] = useState(false);
  const [selectedItem, setSelectedItem] = useState(undefined);
  const [openDelete, setOpenDelete] = useState(false);
  const [snackbarOpen, setSnackbarOpen] = useState(false);
  const [snackbarMessage, setSnackbarMesssage] = useState('');

  useEffect(() => {
    if (!openDelete && !openEdit) {
      // Wait for the dialog to disappear before clearing the selected item.
      setTimeout(() => {
        setSelectedItem(undefined);
        setIsUpload(false);
      }, 300);
    }
  }, [openDelete, openEdit]);

  const tableRef = useRef(null);

  const handleChangeCurrentPage = (event, value) => {
    tableRef.current && tableRef.current.scrollIntoView();
    changeCurrentPage(value);
  };

  const handleChangeRowsPerPage = (event) => {
    changePageSize(Number(event.target.value));
    changeCurrentPage(0);
  };

  const handleEdit = (item, isCollection) => {
    setSelectedItem({
      ...item,
      isCollection,
    });
    setOpenEdit(true);
  };

  const handleDelete = (item, isCollection) => {
    setSelectedItem({
      ...item,
      isCollection,
    });
    setOpenDelete(true);
  };

  const handleChangeShowCollections = (event, val) => {
    if (val !== null) {
      setShowCollections(val);
    }
  };

  const handleUploadClick = () => {
    setIsUpload(true);
    setOpenEdit(true);
  };

  const handleSnackbarClose = (event, reason) => {
    if (reason === 'clickaway') {
      return;
    }
    setSnackbarOpen(false);
    setSnackbarMesssage('');
  };

  const showSnackbar = (message) => {
    setSnackbarMesssage(message);
    setSnackbarOpen(true);
  };

  const RegionProperties = ({ region, max = 0 }) => {
    return Object.keys(region.properties || {}).map((key, idx) => {
      if (max === 0 || idx < max)
        return (
          <Grid key={`prop_${region.id}_${key}_${max}`}>
            <span>
              <b>{key}:</b>
            </span>
            &nbsp;
            <span>{JSON.stringify(region.properties[key])}</span>
            {max > 0 && idx === max - 1 && <span>&nbsp;&hellip;</span>}
          </Grid>
        );
    });
  };

  const RegionTableRows = () => {
    return (showCollections ? collections : regions).map((item) => (
      <TableRow key={item.id} role="listitem">
        {/* <TableCell>
          <Checkbox
            onChange={(e) => handleSelect(e.target.checked, region.id)}
            checked={selected.includes(region.id)}
          />
        </TableCell> */}
        <TableCell component="th" scope="row" data-testid="region">
          {item.name}
        </TableCell>
        {!userHasOrg && (
          <TableCell>
            {orgList.find((org) => org.stakeholder_uuid === item.owner_id)
              ?.name || '---'}
          </TableCell>
        )}
        {!showCollections && (
          <>
            <TableCell>{item.collection_name || '---'}</TableCell>
            <Tooltip title={<RegionProperties region={item} />}>
              <TableCell>
                <RegionProperties region={item} max={3} />
              </TableCell>
            </Tooltip>
            <TableCell align="center">
              {item.show_on_org_map ? 'Yes' : 'No'}
            </TableCell>
            <TableCell align="center">
              {item.calculate_statistics ? 'Yes' : 'No'}
            </TableCell>
          </>
        )}
        <TableCell align="right" className={classes.operations}>
          <IconButton
            title="edit"
            onClick={() => handleEdit(item, showCollections)}
          >
            <Edit />
          </IconButton>
          <IconButton
            title="delete"
            onClick={() => handleDelete(item, showCollections)}
          >
            <Delete />
          </IconButton>
        </TableCell>
      </TableRow>
    ));
  };

  const RegionTablePagination = () => (
    <TablePagination
      count={Number(showCollections ? collectionCount : regionCount)}
      rowsPerPageOptions={[25, 50, 100, { label: 'All', value: -1 }]}
      page={currentPage}
      rowsPerPage={pageSize}
      onChangePage={handleChangeCurrentPage}
      onChangeRowsPerPage={handleChangeRowsPerPage}
      SelectProps={{
        inputProps: { 'aria-label': 'rows per page' },
        native: true,
      }}
    />
  );

  return (
    <>
      <Grid container className={classes.regionsTableContainer}>
        <Paper elevation={3} className={classes.menu}>
          <Menu variant="plain" />
        </Paper>

        <Grid item container className={classes.rightBox}>
          <Grid item xs={12}>
            <Grid
              container
              justify="space-between"
              className={classes.titleBox}
            >
              <Grid item>
                <Grid container>
                  <Grid item>
                    <Typography variant="h2">Regions</Typography>
                  </Grid>
                </Grid>
              </Grid>
              <Grid item className={classes.headerButtonBox}>
                <ToggleButtonGroup
                  color="primary"
                  value={showCollections}
                  exclusive
                  onChange={handleChangeShowCollections}
                >
                  <ToggleButton value={false}>Regions</ToggleButton>
                  <ToggleButton value={true}>Collections</ToggleButton>
                </ToggleButtonGroup>
              </Grid>
              <Grid item className={classes.headerButtonBox}>
                <Button
                  onClick={handleUploadClick}
                  variant="contained"
                  className={classes.upload}
                  color="primary"
                >
                  UPLOAD
                </Button>
              </Grid>
            </Grid>
            <Grid container direction="column" className={classes.bodyBox}>
              <TableContainer component={Paper} ref={tableRef}>
                <Table className={classes.table} aria-label="simple table">
                  <TableHead>
                    <TableRow>
                      <TableCell>
                        Name
                        {/* <IconButton
                          title="sortbyName"
                          onClick={() => changeSort(sortOptions.byName)}
                        >
                          <SortIcon />
                        </IconButton> */}
                      </TableCell>
                      {!userHasOrg && <TableCell>Owner</TableCell>}
                      {!showCollections && (
                        <>
                          <TableCell>Collection</TableCell>
                          <TableCell>Properties</TableCell>
                          <TableCell align="center">Shown on Org Map</TableCell>
                          <TableCell align="center">
                            Statistics Calculated
                          </TableCell>
                        </>
                      )}
                      <TableCell></TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    <RegionTableRows />
                  </TableBody>
                  <TableFooter>
                    <TableRow>
                      <RegionTablePagination />
                    </TableRow>
                  </TableFooter>
                </Table>
              </TableContainer>
            </Grid>
          </Grid>
        </Grid>
      </Grid>
      <EditModal
        openEdit={openEdit}
        setOpenEdit={setOpenEdit}
        isUpload={isUpload}
        selectedItem={selectedItem}
        styles={{ ...classes }}
        upload={upload}
        updateRegion={updateRegion}
        updateCollection={updateCollection}
        showSnackbar={showSnackbar}
      />
      <DeleteDialog
        selectedItem={selectedItem}
        openDelete={openDelete}
        setOpenDelete={setOpenDelete}
        deleteRegion={deleteRegion}
        deleteCollection={deleteCollection}
        showSnackbar={showSnackbar}
      />
      <Snackbar
        open={snackbarOpen}
        autoHideDuration={3000}
        onClose={handleSnackbarClose}
        message={snackbarMessage}
        action={
          <>
            <IconButton
              size="small"
              aria-label="close"
              color="inherit"
              onClick={handleSnackbarClose}
            >
              <Close fontSize="small" />
            </IconButton>
          </>
        }
      />
    </>
  );
}
Example #19
Source File: CaptureTable.js    From treetracker-admin-client with GNU Affero General Public License v3.0 4 votes vote down vote up
CaptureTable = () => {
  const {
    filter,
    rowsPerPage,
    page,
    order,
    orderBy,
    captures,
    capture,
    captureCount,
    isLoading,
    setPage,
    setRowsPerPage,
    setOrder,
    setOrderBy,
    setCapture,
    getCaptureAsync,
  } = useContext(CapturesContext);
  const speciesContext = useContext(SpeciesContext);
  const tagsContext = useContext(TagsContext);
  const [isDetailsPaneOpen, setIsDetailsPaneOpen] = useState(false);
  const [speciesLookup, setSpeciesLookup] = useState({});
  const [tagLookup, setTagLookup] = useState({});
  const [captureTagLookup, setCaptureTagLookup] = useState({});
  const [isOpenExport, setOpenExport] = useState(false);
  const [disableHoverListener, setDisableHoverListener] = useState(false);
  const classes = useStyle();

  useEffect(() => {
    populateSpeciesLookup();
  }, [speciesContext.speciesList]);

  useEffect(() => {
    populateTagLookup();
  }, [tagsContext.tagList]);

  const getCaptureTags = async () => {
    // Don't do anything if there are no captures
    if (!captures?.length) {
      return;
    }
    // Get the capture tags for all of the displayed captures
    const captureTags = await api.getCaptureTags({
      captureIds: captures.map((c) => c.id),
    });

    // Populate a lookup for quick access when rendering the table
    let lookup = {};
    captureTags.forEach((captureTag) => {
      if (!lookup[captureTag.treeId]) {
        lookup[captureTag.treeId] = [];
      }
      lookup[captureTag.treeId].push(tagLookup[captureTag.tagId]);
    });
    setCaptureTagLookup(lookup);
  };

  useEffect(() => {
    getCaptureTags();
  }, [captures, tagLookup]);

  const populateSpeciesLookup = async () => {
    let species = {};
    speciesContext.speciesList.forEach((s) => {
      species[s.id] = s.name;
    });
    setSpeciesLookup(species);
  };

  const populateTagLookup = async () => {
    let tags = {};
    tagsContext.tagList.forEach((t) => {
      tags[t.id] = t.tagName;
    });
    setTagLookup(tags);
  };

  const toggleDrawer = (id) => {
    getCaptureAsync(id);
    setIsDetailsPaneOpen(!isDetailsPaneOpen);
  };

  const createToggleDrawerHandler = (id) => {
    return () => {
      toggleDrawer(id);
    };
  };

  const closeDrawer = () => {
    setIsDetailsPaneOpen(false);
    setDisableHoverListener(false);
    setCapture({});
  };

  const handleOpenExport = () => {
    setOpenExport(true);
  };

  const handlePageChange = (e, page) => {
    setPage(page);
  };

  const handleRowsPerPageChange = (e) => {
    setRowsPerPage(parseInt(e.target.value));
  };

  const createSortHandler = (attr) => {
    return () => {
      const newOrder = orderBy === attr && order === 'asc' ? 'desc' : 'asc';
      const newOrderBy = attr;
      setOrder(newOrder);
      setOrderBy(newOrderBy);
    };
  };

  const tablePagination = () => {
    return (
      <TablePagination
        rowsPerPageOptions={[25, 50, 100, 250, 500]}
        component="div"
        count={captureCount || 0}
        page={page}
        rowsPerPage={rowsPerPage}
        onChangePage={handlePageChange}
        onChangeRowsPerPage={handleRowsPerPageChange}
      />
    );
  };

  const enableTooltips = process.env.REACT_APP_ENABLE_TOOLTIPS === 'true';

  return (
    <Grid style={{ height: '100%', overflow: 'auto', textAlign: 'center' }}>
      <Grid
        container
        direction="row"
        justify="space-between"
        alignItems="center"
      >
        <Typography variant="h5" className={classes.title}>
          Captures
        </Typography>
        <Grid className={classes.cornerTable}>
          <Button
            variant="outlined"
            color="primary"
            startIcon={<GetApp />}
            className={classes.buttonCsv}
            onClick={handleOpenExport}
          >
            Export Captures
          </Button>
          <ExportCaptures
            isOpen={isOpenExport}
            handleClose={() => setOpenExport(false)}
            columns={columns}
            filter={filter}
            speciesLookup={speciesLookup}
            captureTagLookup={captureTagLookup}
          />
          {tablePagination()}
        </Grid>
      </Grid>
      <Table data-testid="captures-table">
        <TableHead>
          <TableRow>
            {columns.map(({ attr, label, noSort }) => (
              <TableCell
                key={attr}
                sortDirection={orderBy === attr ? order : false}
              >
                <TableSortLabel
                  active={orderBy === attr}
                  direction={orderBy === attr ? order : 'asc'}
                  onClick={createSortHandler(attr)}
                  disabled={noSort}
                >
                  {label}
                </TableSortLabel>
              </TableCell>
            ))}
          </TableRow>
        </TableHead>
        <TableBody data-testid="captures-table-body">
          {isLoading && !captures?.length ? (
            <TableRow className={classes.loadingIndicator}>
              <TableCell className={classes.loadingIndicator}>
                <CircularProgress />
              </TableCell>
            </TableRow>
          ) : (
            <>
              {captures &&
                captures.map((capture) => (
                  <Tooltip
                    key={capture.id}
                    placement="top"
                    arrow={true}
                    interactive={!disableHoverListener}
                    enterDelay={500}
                    enterNextDelay={500}
                    disableFocusListener={true}
                    disableHoverListener={disableHoverListener}
                    classes={{
                      tooltipPlacementTop: classes.tooltipTop,
                      arrow: classes.arrow,
                    }}
                    title={
                      enableTooltips ? (
                        <CaptureTooltip
                          capture={capture}
                          toggleDrawer={createToggleDrawerHandler}
                        />
                      ) : (
                        ''
                      )
                    }
                  >
                    <TableRow
                      key={capture.id}
                      onClick={createToggleDrawerHandler(capture.id)}
                      className={classes.tableRow}
                    >
                      {columns.map(({ attr, renderer }, i) => (
                        <TableCell key={`${attr}_${i}`}>
                          {formatCell(
                            capture,
                            speciesLookup,
                            captureTagLookup[capture.id] || [],
                            attr,
                            renderer
                          )}
                        </TableCell>
                      ))}
                    </TableRow>
                  </Tooltip>
                ))}
            </>
          )}
        </TableBody>
      </Table>
      {tablePagination()}
      <CaptureDetailProvider>
        <CaptureDetailDialog
          open={isDetailsPaneOpen}
          capture={capture}
          onClose={closeDrawer}
        />
      </CaptureDetailProvider>
    </Grid>
  );
}
Example #20
Source File: Observations.jsx    From Corona-tracker with MIT License 4 votes vote down vote up
Observations = props => {
  const classes = useStyles();

  const { detailData, observations, tempUnit } = props;

  const [page, setPage] = React.useState(0);
  const [rowsPerPage, setRowsPerPage] = React.useState(4);

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = event => {
    setRowsPerPage(+event.target.value);
    setPage(0);
  };

  return (
    <div className={classes.root}>
      {(detailData.length ? detailData : observations)
        .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
        .map(observation => (
          <ExpansionPanel
            className={classes.expansionPanel}
            defaultExpanded={detailData.length === 1}
            key={observation.date}
          >
            <ExpansionPanelSummary
              expandIcon={<ExpandMoreIcon />}
              aria-controls="observation"
              id="observation"
              className={classes.summary}
            >
              <Grid container alignItems="center" justify="center" spacing={1}>
                <Grid item justify="center">
                  <RedFont>
                    <span>Date:</span> {new Date(observation.date).toLocaleDateString()}
                  </RedFont>
                </Grid>
                <Grid item>
                  <RedFont>
                    <span>Overall Feeling:</span> {`${observation.physical.dailyfeeling} /5`}
                  </RedFont>
                </Grid>
                <Grid item>
                  <RedFont>
                    {tempUnit === 'fahrenheit' ? (
                      <>
                        <span>Temperature:</span> {observation.physical.feverSeverity} &#8457;
                      </>
                    ) : (
                      <>
                        <span>Temperature:</span> {observation.physical.feverSeverity} &#8451;
                      </>
                    )}
                  </RedFont>
                </Grid>
              </Grid>
            </ExpansionPanelSummary>
            <ExpansionPanelDetails className={classes.detailed}>
              <Grid container alignItems="center" justify="center" spacing={2}>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Cough:</span> {observation.physical.coughSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Chills:</span> {observation.physical.chillsSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Shortness Of Breath:</span> {observation.physical.shortnessOfBreathSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Sore Throat:</span> {observation.physical.soreThroatSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Fatigue:</span> {observation.physical.fatigueSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Bluishness:</span> {observation.physical.bluishnessSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Gastrointestinnal Issues: </span>
                    {observation.physical.giIssueSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Headache: </span>
                    {observation.physical.headacheSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Loss of Smell:</span> {observation.physical.lostSmellSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12} sm={6}>
                  <WhiteFont>
                    <span>Loss of Taste:</span> {observation.physical.lostTasteSeverity}
                  </WhiteFont>
                </Grid>
                <Grid item xs={12}>
                  <WhiteFont>
                    <span>Comments:</span>{' '}
                    {observation.nonPhysical.openComment ? observation.nonPhysical.openComment : 'N/A'}
                  </WhiteFont>
                </Grid>
              </Grid>
            </ExpansionPanelDetails>
          </ExpansionPanel>
        ))}
      <Grid container justify="center">
        <TablePagination
          rowsPerPageOptions={[2, 4, 8, 12]}
          component="div"
          count={observations.length}
          rowsPerPage={rowsPerPage}
          page={page}
          onChangePage={handleChangePage}
          onChangeRowsPerPage={handleChangeRowsPerPage}
        />
      </Grid>
    </div>
  );
}