@mui/material#TableSortLabel JavaScript Examples

The following examples show how to use @mui/material#TableSortLabel. 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: ClickableHeader.jsx    From Edlib with GNU General Public License v3.0 6 votes vote down vote up
ClickableHeader = ({
    style,
    sortingOrder,
    setSortingOrder,
    children,
    name,
}) => {
    const ascName = name + '(asc)';
    const descName = name + '(desc)';
    const active = [ascName, descName].indexOf(sortingOrder) !== -1;

    return (
        <div>
            <div>
                <TableSortLabel
                    style={style}
                    active={active}
                    direction={sortingOrder === ascName ? 'asc' : 'desc'}
                    onClick={() =>
                        setSortingOrder(
                            sortingOrder === descName ? ascName : descName
                        )
                    }
                >
                    {children}
                </TableSortLabel>
            </div>
        </div>
    );
}
Example #2
Source File: EnhancedTableHead.js    From react-saas-template with MIT License 5 votes vote down vote up
function EnhancedTableHead(props) {
  const { order, orderBy, rows, onRequestSort, classes } = props;

  const createSortHandler = useCallback(
    property => event => {
      onRequestSort(event, property);
    },
    [onRequestSort]
  );

  return (
    <TableHead>
      <TableRow>
        {rows.map((row, index) => (
          <TableCell
            key={index}
            align={row.numeric ? "right" : "inherit"}
            padding="normal"
            sortDirection={orderBy === row.name ? order : false}
            className={index === 0 ? classes.paddingFix : null}
          >
            {onRequestSort ? (
              <Tooltip
                title="Sort"
                placement={row.numeric ? "bottom-end" : "bottom-start"}
                enterDelay={300}
              >
                <TableSortLabel
                  active={orderBy === row.id}
                  direction={order}
                  onClick={createSortHandler(row.id)}
                >
                  <Typography variant="body2">{row.label}</Typography>
                </TableSortLabel>
              </Tooltip>
            ) : (
              <TableSortLabel
                className={classNames(classes.tableSortLabel, classes.noIcon)}
              >
                <Typography variant="body2" className={classes.label}>
                  {row.label}
                </Typography>
              </TableSortLabel>
            )}
          </TableCell>
        ))}
      </TableRow>
    </TableHead>
  );
}
Example #3
Source File: UserListHead.js    From Django-REST-Framework-React-BoilerPlate with MIT License 5 votes vote down vote up
export default function UserListHead({
  order,
  orderBy,
  rowCount,
  headLabel,
  numSelected,
  onRequestSort,
  onSelectAllClick,
}) {
  const createSortHandler = (property) => (event) => {
    onRequestSort(event, property);
  };

  return (
    <TableHead>
      <TableRow>
        <TableCell padding="checkbox">
          <Checkbox
            indeterminate={numSelected > 0 && numSelected < rowCount}
            checked={rowCount > 0 && numSelected === rowCount}
            onChange={onSelectAllClick}
          />
        </TableCell>
        {headLabel.map((headCell) => (
          <TableCell
            key={headCell.id}
            align={headCell.alignRight ? 'right' : 'left'}
            sortDirection={orderBy === headCell.id ? order : false}
          >
            <TableSortLabel
              hideSortIcon
              active={orderBy === headCell.id}
              direction={orderBy === headCell.id ? order : 'asc'}
              onClick={createSortHandler(headCell.id)}
            >
              {headCell.label}
              {orderBy === headCell.id ? (
                <Box sx={{ ...visuallyHidden }}>{order === 'desc' ? 'sorted descending' : 'sorted ascending'}</Box>
              ) : null}
            </TableSortLabel>
          </TableCell>
        ))}
      </TableRow>
    </TableHead>
  );
}
Example #4
Source File: Sync.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, sync } = this.props;
    const { sortedDevices, order, orderBy, wipingID, snackbar } = this.state;

    return (
      <FormControl className={classes.form}>
        <Grid container alignItems="center"  className={classes.headline}>
          <Typography variant="h6">{t('Mobile devices')}</Typography>
        </Grid>
        <Table size="small">
          <TableHead>
            <TableRow>
              {this.columns.map((column, key) =>
                <TableCell
                  key={key}
                  padding={column.padding || 'normal'}
                >
                  <TableSortLabel
                    active={orderBy === column.value}
                    align="left" 
                    direction={order}
                    onClick={this.handleSort(column.value, column.type, true)}
                  >
                    {t(column.label)}
                  </TableSortLabel>
                </TableCell>
              )}
              <TableCell padding="checkbox">{t('Actions')}</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {(sortedDevices || sync).map((obj, idx) =>
              <TableRow key={idx}>
                <TableCell>{obj.deviceid || ''}</TableCell>
                <TableCell>{obj.deviceuser || ''}</TableCell>
                <TableCell>{(obj.devicetype || '') + ' / ' + (obj.useragent || '')}</TableCell>
                <TableCell>{obj.firstsynctime ? parseUnixtime(obj.firstsynctime) : ''}</TableCell>
                <TableCell>{obj.lastupdatetime ? parseUnixtime(obj.lastupdatetime) : ''}</TableCell>
                <TableCell>{obj.asversion || ''}</TableCell>
                <TableCell>{(obj.foldersSynced || '') + '/' + (obj.foldersSyncable || '')}</TableCell>
                <TableCell>{this.getWipeStatus(obj.wipeStatus)}</TableCell>
                <TableCell style={{ display: 'flex' }}>
                  {obj.wipeStatus >= 2 && <Tooltip title="Cancel remote wipe" placement="top">
                    <IconButton onClick={this.handleRemoteWipeCancel(obj.deviceid)}>
                      <DoNotDisturbOn color="secondary"/>
                    </IconButton>
                  </Tooltip>}
                  {obj.wipeStatus < 2 && <Tooltip title="Remote wipe" placement="top">
                    <IconButton onClick={this.handlePasswordDialog(obj.deviceid)}>
                      <CleaningServices color="error" />
                    </IconButton>
                  </Tooltip>}
                  <Tooltip title="Resync" placement='top'>
                    <IconButton onClick={this.handleResync(obj.deviceid)}>
                      <SyncIcon color="primary"/>
                    </IconButton>
                  </Tooltip>
                  <Tooltip title="Delete device" placement='top'>
                    <IconButton onClick={this.handleRemoteDelete(obj.deviceid)}>
                      <Delete color="error"/>
                    </IconButton>
                  </Tooltip>
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
        <PasswordSafetyDialog
          open={Boolean(wipingID)}
          deviceID={wipingID}
          onClose={this.handlePasswordDialog('')}
          onConfirm={this.handleRemoteWipeConfirm}
        />
        <Feedback
          snackbar={snackbar || ''}
          onClose={() => this.setState({ snackbar: '' })}
        />
      </FormControl>
    );
  }
Example #5
Source File: Menu.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, domains } = this.props;
    const { orderBy, order, sortedDomains } = this.state;
    return (
      <div className={classes.root}>
        <TopBar onAdd={this.handleAdd} title="Dashboard"/>
        <div className={classes.toolbar}></div>
        <Typography variant="h2" className={classes.pageTitle}>
          {t("Dashboard")}
        </Typography>
        <div className={classes.base}>
          <Paper elevation={1}>
            <Table size="small">
              <TableHead>
                <TableRow>
                  {this.columns.map((column) => (
                    <TableCell key={column.value}>
                      <TableSortLabel
                        active={orderBy === column.value}
                        align="left"
                        direction={orderBy === column.value ? order : "asc"}
                        onClick={this.handleSort(column.value)}
                      >
                        {t(column.label)}
                      </TableSortLabel>
                    </TableCell>
                  ))}
                </TableRow>
              </TableHead>
              <TableBody>
                {(sortedDomains.length > 0 ? sortedDomains : domains).map((obj, idx) => 
                  <TableRow key={idx} hover onClick={this.handleNavigation(obj.ID)}>
                    <TableCell>
                      {obj.domainname}{" "}
                      {obj.domainStatus === 3 ? `[${t("Deactivated")}]` : ""}
                    </TableCell>
                    <TableCell>{obj.address}</TableCell>
                    <TableCell>{obj.title}</TableCell>
                    <TableCell>{obj.maxUser}</TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </Paper>
        </div>
      </div>
    );
  }
Example #6
Source File: Classes.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, _classes, domain, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { order, orderBy, match, snackbar, adding, deleting } = tableState;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const { tab, root } = this.state;

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={t("Groups")}
        subtitle={t("groups_sub")}
        href="https://docs.grommunio.com/admin/administration.html#groups"
        snackbar={snackbar || this.state.snackbar}
        onSnackbarClose={this.handleSnackbarClose}
        baseRef={tc => (this.treeContainer = tc)}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            className={classes.newButton}
            disabled={!writable}
          >
            {t('New group')}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Tabs
          indicatorColor="primary"
          textColor="primary"
          className={classes.tabs}
          onChange={this.handleTab}
          value={tab}
        >
          <Tab value={0} label={t("List")} />
          <Tab value={1} label={t("Tree")} />
        </Tabs>
        {!tab && <Typography className={classes.count} color="textPrimary">
          {t("showingGroups", { count: _classes.Classes.length })}
        </Typography>}
        {!tab ? <Paper className={classes.tablePaper} elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {this.columns.map(column =>
                  <TableCell key={column.value}>
                    <TableSortLabel
                      active={orderBy === column.value}
                      align="left" 
                      direction={orderBy === column.value ? order : 'asc'}
                      onClick={handleRequestSort(column.value)}
                    >
                      {t(column.label)}
                    </TableSortLabel>
                  </TableCell>
                )}
                <TableCell></TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {_classes.Classes.map((obj, idx) =>
                <TableRow key={idx} hover onClick={handleEdit('/' + domain.ID + '/classes/' + obj.ID)}>
                  <TableCell>{obj.classname}</TableCell>
                  <TableCell>{obj.listname}</TableCell>
                  <TableCell align="right">
                    {writable && <IconButton onClick={handleDelete(obj)} size="large">
                      <Delete color="error"/>
                    </IconButton>}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
          {(_classes.Classes.length < _classes.count) && <Grid container justifyContent="center">
            <CircularProgress color="primary" className={classes.circularProgress}/>
          </Grid>}
        </Paper> :
          <>
            <FormControl className={classes.select}>
              <InputLabel variant="standard">{t("Root group")}</InputLabel>
              <Select
                fullWidth
                value={root > -1 ? root : ''}
                onChange={this.handleRootSelect}
                input={<Input />}
                placeholder={t('Select root group')}
              >
                {_classes.Trees.map((tree, idx) => (
                  <MenuItem key={idx} value={idx}>
                    {tree.name}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
            <div className={classes.treeContainer}>
              {root !== -1 &&
                  <Paper style={{ flex: 1 }}>
                    <Tree
                      data={_classes.Trees[root]}
                      orientation="vertical"
                      renderCustomNodeElement={this.renderNode}
                      depthFactor={50}
                      pathFunc="step"
                      translate={this.getOffset()}
                      scaleExtent={{
                        min: 0.1,
                        max: 2,
                      }}
                      separation={{
                        siblings: 1,
                        nonSiblings: 2,
                      }}
                      onNodeClick={this.handleNodeClicked}
                      collapsible={false}
                    />
                  </Paper>}
            </div>
          </>
        }
        <AddClass
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          domain={domain}
          onClose={handleAddingClose}
        />
        <DomainDataDelete
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={handleDeleteSuccess}
          onError={handleDeleteError}
          onClose={handleDeleteClose}
          item={deleting.name}
          id={deleting.ID}
          domainID={domain.ID}
        />
      </TableViewContainer>
    );
  }
Example #7
Source File: Domains.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, domains, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { showDeleted } = this.state;
    const { order, orderBy, match, snackbar, adding, deleting } = tableState;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
    const filteredDomains = domains.Domains.filter(d => d.domainStatus !== 3 || showDeleted);

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={t("Domains")}
        subtitle={t('domains_sub')}
        snackbar={snackbar}
        href="https://docs.grommunio.com/admin/administration.html#domains"
        onSnackbarClose={clearSnackbar}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            disabled={!writable}
          >
            {t("New domain")}
          </Button>
          <div className={classes.actions}>
            <FormControlLabel
              label={t("Show deactivated")}
              control={
                <Checkbox
                  checked={showDeleted || false}
                  onChange={this.handleCheckbox("showDeleted")}
                />
              }
            />
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search")}
              variant={"outlined"}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Typography className={classes.count} color="textPrimary">
          {t("showingDomains", { count: filteredDomains.length })}
        </Typography>
        <Paper elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {this.columns.map((column) => (
                  <TableCell key={column.value}>
                    <TableSortLabel
                      active={orderBy === column.value}
                      align="left"
                      direction={orderBy === column.value ? order : "asc"}
                      onClick={handleRequestSort(column.value)}
                      disabled={column.value === 'activeUsers'}
                    >
                      {t(column.label)}
                    </TableSortLabel>
                  </TableCell>
                ))}
                <TableCell padding="checkbox" />
              </TableRow>
            </TableHead>
            <TableBody>
              {filteredDomains.map((obj, idx) =>
                <TableRow key={idx} hover onClick={handleEdit("/domains/" + obj.ID)}>
                  <TableCell>
                    {obj.domainname}{obj.domainname !== obj.displayname ? ` (${obj.displayname}) ` : " "}
                    {obj.domainStatus === 3 ? `[${t("Deactivated")}]` : ""}
                  </TableCell>
                  <TableCell>{obj.address}</TableCell>
                  <TableCell>{obj.title}</TableCell>
                  <TableCell>{obj.activeUsers}</TableCell>
                  <TableCell>{obj.maxUser}</TableCell>
                  <TableCell align="right">
                    {writable && <IconButton onClick={handleDelete(obj)} size="large">
                      <Delete color="error" />
                    </IconButton>}
                  </TableCell>
                </TableRow>)
              }
            </TableBody>
          </Table>
          {domains.Domains.length < domains.count && (
            <Grid container justifyContent="center">
              <CircularProgress
                color="primary"
                className={classes.circularProgress}
              />
            </Grid>
          )}
        </Paper>
        <AddDomain
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          onClose={handleAddingClose}
        />
        <DeleteDomain
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={handleDeleteSuccess}
          onError={handleDeleteError}
          onClose={handleDeleteClose}
          item={deleting.domainname}
          id={deleting.ID}
        />
      </TableViewContainer>
    );
  }
Example #8
Source File: GlobalUsers.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, users, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { order, orderBy, match, snackbar, adding, deleting } = tableState;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
    const { checking } = this.state;
    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={t("Users")}
        subtitle={t("globalusers_sub")}
        href="https://docs.grommunio.com/admin/administration.html#users"
        snackbar={snackbar}
        onSnackbarClose={clearSnackbar}
      > 
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            className={classes.newButton}
            disabled={!writable}
          >
            {t('New user')}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Typography className={classes.count} color="textPrimary">
          {t("showingUser", { count: users.Users.length })}
        </Typography>
        <Paper className={classes.tablePaper} elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell>
                  <TableSortLabel
                    active={orderBy === 'username'}
                    align="left" 
                    direction={orderBy === 'username' ? order : 'asc'}
                    onClick={handleRequestSort('username')}
                  >
                    {t('Username')}
                  </TableSortLabel>
                </TableCell>
                {this.columns.map(column =>
                  <TableCell key={column.value}>
                    {t(column.label)}
                  </TableCell>
                )}
                <TableCell padding="checkbox"></TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {users.Users.map((obj, idx) => {
                return (
                  <TableRow key={idx} hover onClick={handleEdit('/' + obj.domainID + '/users/' + obj.ID)}>
                    <TableCell>{obj.username}</TableCell>
                    <TableCell>{obj.ldapID || ''}</TableCell>
                    <TableCell align="right">
                      {writable && <IconButton onClick={handleDelete(obj)} size="large">
                        <Delete color="error"/>
                      </IconButton>}
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
          {(users.Users.length < users.count) && <Grid container justifyContent="center">
            <CircularProgress color="primary" className={classes.circularProgress}/>
          </Grid>}
        </Paper>
        <AddGlobalUser
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          onClose={handleAddingClose}
        />
        <DeleteUser
          open={!!deleting}
          onSuccess={handleDeleteSuccess}
          onClose={handleDeleteClose}
          onError={handleDeleteError}
          user={deleting}
          domainID={deleting.domainID || -1}
        />
        <CheckLdapDialog
          open={checking}
          onClose={this.handleCheckClose}
          onError={handleDeleteError}
        />
      </TableViewContainer>
    );
  }
Example #9
Source File: MLists.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, mLists, domain, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { order, orderBy, match, snackbar, adding, deleting } = tableState;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={t("Mail lists")}
        subtitle={t('mlists_sub')}
        href="https://docs.grommunio.com/admin/administration.html#mail-lists"
        snackbar={snackbar}
        onSnackbarClose={clearSnackbar}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            className={classes.newButton}
            disabled={!writable}
          >
            {t('New mail list')}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Typography className={classes.count} color="textPrimary">
          {t("showingMLists", { count: mLists.MLists.length })}
        </Typography>
        <Paper className={classes.tablePaper} elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {this.columns.map(column =>
                  <TableCell key={column.value}>
                    <TableSortLabel
                      active={orderBy === column.value}
                      align="left" 
                      direction={orderBy === column.value ? order : 'asc'}
                      onClick={handleRequestSort(column.value)}
                    >
                      {t(column.label)}
                    </TableSortLabel>
                  </TableCell>
                )}
                <TableCell></TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {mLists.MLists.map((obj, idx) =>
                <TableRow key={idx} hover onClick={handleEdit('/' + domain.ID + '/mailLists/' + obj.ID)}>
                  <TableCell>{obj.listname}</TableCell>
                  <TableCell>{this.listTypes[obj.listType]}</TableCell>
                  <TableCell>{this.listPrivileges[obj.listPrivilege]}</TableCell>
                  <TableCell align="right">
                    {writable && <IconButton onClick={handleDelete(obj)} size="large">
                      <Delete color="error"/>
                    </IconButton>}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
          {(mLists.MLists.length < mLists.count) && <Grid container justifyContent="center">
            <CircularProgress color="primary" className={classes.circularProgress}/>
          </Grid>}
        </Paper>
        <AddMList
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          domain={domain}
          onClose={handleAddingClose}
        />
        <DomainDataDelete
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={handleDeleteSuccess}
          onError={handleDeleteError}
          onClose={handleDeleteClose}
          item={deleting.listname}
          id={deleting.ID}
          domainID={domain.ID}
        />
      </TableViewContainer>
    );
  }
Example #10
Source File: Orgs.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, orgs, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { order, orderBy, match, snackbar, adding, deleting } = tableState;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={t("Organizations")}
        href="https://docs.grommunio.com/admin/administration.html#organizations"
        subtitle={t("orgs_sub")}
        snackbar={snackbar}
        onSnackbarClose={clearSnackbar}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            disabled={!writable}
          >
            {t("New organization")}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search organizations")}
              variant={"outlined"}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Typography className={classes.count} color="textPrimary">
          {t("showingOrgs", { count: orgs.Orgs.length })}
        </Typography>
        <Paper elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {this.columns.map((column) => (
                  <TableCell key={column.value}>
                    <TableSortLabel
                      active={orderBy === column.value}
                      align="left"
                      direction={orderBy === column.value ? order : "asc"}
                      onClick={handleRequestSort(column.value)}
                    >
                      {t(column.label)}
                    </TableSortLabel>
                  </TableCell>
                ))}
                <TableCell padding="checkbox" />
              </TableRow>
            </TableHead>
            <TableBody>
              {orgs.Orgs.map((obj, idx) => 
                <TableRow key={idx} hover onClick={handleEdit('/orgs/' + obj.ID)}>
                  <TableCell>{obj.name}</TableCell>
                  <TableCell>{obj.description}</TableCell>
                  <TableCell align="right">
                    {writable && <IconButton onClick={handleDelete(obj)} size="large">
                      <Delete color="error" />
                    </IconButton>}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
          {orgs.Orgs.length < orgs.count && (
            <Grid container justifyContent="center">
              <CircularProgress
                color="primary"
                className={classes.circularProgress}
              />
            </Grid>
          )}
        </Paper>
        <AddOrg
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          onClose={handleAddingClose}
        />
        <GeneralDelete
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={handleDeleteSuccess}
          onError={handleDeleteError}
          onClose={handleDeleteClose}
          item={deleting.name}
          id={deleting.ID}
        />
      </TableViewContainer>
    );
  }
Example #11
Source File: Roles.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, roles, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { order, match, adding, snackbar, deleting } = tableState;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={<span>
          {t("Roles")}
          <IconButton
            size="small"
            href="https://docs.grommunio.com/admin/administration.html#id1"
            target="_blank"
          >
            <HelpOutline fontSize="small"/>
          </IconButton>
        </span>
        }
        subtitle={t('roles_sub')}
        snackbar={snackbar}
        onSnackbarClose={clearSnackbar}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            disabled={!writable}
          >
            {t("New role")}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Typography className={classes.count} color="textPrimary">
          {t("showingRoles", { count: roles.Roles.length })}
        </Typography>
        <Paper elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell>
                  <TableSortLabel
                    active
                    align="left" 
                    direction={order}
                    onClick={handleRequestSort('name')}
                  >
                    {t('Name')}
                  </TableSortLabel>
                </TableCell>
                <TableCell>{t('Description')}</TableCell>
                <TableCell>{t('Permissions')}</TableCell>
                <TableCell padding="checkbox"></TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {roles.Roles.map((obj, idx) =>
                <TableRow key={idx} hover onClick={handleEdit('/roles/' + obj.ID)}>
                  <TableCell>{obj.name}</TableCell>
                  <TableCell>{obj.description}</TableCell>
                  <TableCell>{obj.permissions.map(perm => perm.permission).toString()}</TableCell>
                  <TableCell align="right">
                    {writable && <IconButton onClick={handleDelete(obj)} size="large">
                      <Delete color="error"/>
                    </IconButton>}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
          {(roles.Roles.length < roles.count) && <Grid container justifyContent="center">
            <CircularProgress color="primary" className={classes.circularProgress}/>
          </Grid>}
        </Paper>
        <AddRoles
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          onClose={handleAddingClose}
        />
        <GeneralDelete
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={handleDeleteSuccess}
          onError={handleDeleteError}
          onClose={handleDeleteClose}
          item={deleting.name}
          id={deleting.ID}
        />
      </TableViewContainer>
    );
  }
Example #12
Source File: Servers.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, servers, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { order, orderBy, match, adding, snackbar, deleting } = tableState;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={<span>
          {t("Servers")}
          <IconButton
            size="small"
            href="https://docs.grommunio.com/admin/administration.html#id1"
            target="_blank"
          >
            <HelpOutline fontSize="small"/>
          </IconButton>
        </span>
        }
        snackbar={snackbar || this.state.snackbar}
        onSnackbarClose={this.handleSnackbarClose}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            disabled={!writable}
          >
            {t("New server")}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <div>
          <TextField
            value={servers.policy || 'round-robin'}
            onChange={this.handlePolicyChange}
            select
            label="Selection policy"
            className={classes.policy}
          >
            <MenuItem value={"round-robin"}>round-robin</MenuItem>
            <MenuItem value={"balanced"}>balanced</MenuItem>
            <MenuItem value={"first"}>first</MenuItem>
            <MenuItem value={"last"}>last</MenuItem>
            <MenuItem value={"random"}>random</MenuItem>
          </TextField>
        </div>
        <Typography className={classes.count} color="textPrimary">
          {t("showingServers", { count: servers.Servers.length })}
        </Typography>
        <Paper elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {this.columns.map((column) => (
                  <TableCell key={column.value}>
                    <TableSortLabel
                      active={orderBy === column.value}
                      align="left"
                      direction={orderBy === column.value ? order : "asc"}
                      onClick={handleRequestSort(column.value)}
                    >
                      {t(column.label)}
                    </TableSortLabel>
                  </TableCell>
                ))}
                <TableCell padding="checkbox" />
              </TableRow>
            </TableHead>
            <TableBody>
              {servers.Servers.map((obj, idx) =>
                <TableRow key={idx} hover onClick={handleEdit('/servers/' + obj.ID)}>
                  <TableCell>{obj.hostname}</TableCell>
                  <TableCell>{obj.extname}</TableCell>
                  <TableCell align="right">
                    {writable && <IconButton onClick={handleDelete(obj)} size="large">
                      <Delete color="error"/>
                    </IconButton>}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
          {(servers.Servers.length < servers.count) && <Grid container justifyContent="center">
            <CircularProgress color="primary" className={classes.circularProgress}/>
          </Grid>}
        </Paper>
        <AddServer
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          onClose={handleAddingClose}
        />
        <GeneralDelete
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={handleDeleteSuccess}
          onError={handleDeleteError}
          onClose={handleDeleteClose}
          item={deleting.hostname}
          id={deleting.ID}
        />
      </TableViewContainer>
    );
  }
Example #13
Source File: Sync.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, sync } = this.props;
    const { snackbar, sortedDevices, order, orderBy, match, showPush, onlyActive,
      filterEnded, filterUpdated } = this.state;

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={<>
          {t("Mobile devices")}
          <IconButton
            size="small"
            href="https://docs.grommunio.com/admin/administration.html#mobile-devices"
            target="_blank"
          >
            <HelpOutline fontSize="small"/>
          </IconButton>
        </>
        }
        subtitle={t('sync_sub')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <FormControlLabel
            control={
              <Checkbox
                checked={showPush}
                onChange={this.handleCheckbox('showPush')}
                color="primary"
              />
            }
            label={t('Show push connections')}
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={onlyActive}
                onChange={this.handleCheckbox('onlyActive')}
                color="primary"
              />
            }
            label={t('Only show active connections')}
          />
          <TextField
            value={filterUpdated}
            onChange={this.handleInput('filterUpdated')}
            label={t("Last updated (seconds)")}
            className={classes.select}
            select
            color="primary"
            fullWidth
          >
            <MenuItem value={60}>10</MenuItem>
            <MenuItem value={60}>30</MenuItem>
            <MenuItem value={60}>60</MenuItem>
            <MenuItem value={120}>120</MenuItem>
          </TextField>
          <TextField
            value={filterEnded}
            onChange={this.handleInput('filterEnded')}
            label={t("Last ended (seconds)")}
            className={classes.select}
            select
            color="primary"
            fullWidth
          >
            <MenuItem value={20}>3</MenuItem>
            <MenuItem value={20}>5</MenuItem>
            <MenuItem value={20}>10</MenuItem>
            <MenuItem value={20}>20</MenuItem>
          </TextField>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={this.handleInput('match')}
              placeholder={t("Filter")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <SyncStatistics data={sync}/>
        <Paper elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {this.columns.map((column) => (
                  <TableCell
                    key={column.value}
                    padding={column.padding || 'normal'}
                  >
                    <TableSortLabel
                      active={orderBy === column.value}
                      align="left" 
                      direction={order}
                      onClick={this.handleSort(column.value, column.type, true)}
                    >
                      {t(column.label)}
                    </TableSortLabel>
                  </TableCell>
                ))}
                <TableCell padding="checkbox">
                  {t('Push')}
                </TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {(sortedDevices || sync).map((obj, idx) => {
                const timePast = getTimePast(obj.diff);
                const matches = this.getMatch(obj);
                return matches ? (
                  <Tooltip key={idx} placement="top" title={obj.devtype + ' / ' + obj.devagent}>
                    <TableRow hover className={this.getRowClass(obj, obj.diff)}>
                      <TableCell className={classes.cell} padding="checkbox">{obj.pid || ''}</TableCell>
                      <TableCell className={classes.cell} padding="checkbox">{obj.ip || ''}</TableCell>
                      <TableCell className={classes.cell}>{obj.user || ''}</TableCell>
                      <TableCell className={classes.cell}>{getStringFromCommand(obj.command)}</TableCell>
                      <TableCell className={classes.cell}>{timePast}</TableCell>
                      <TableCell className={classes.cell}>{obj.devid || ''}</TableCell>
                      <TableCell className={classes.cell}>{obj.addinfo || ''}</TableCell>
                      <TableCell className={classes.cell} padding="checkbox">
                        {obj.push ? <CheckCircleOutlined /> : <HighlightOffOutlined />}
                      </TableCell>
                    </TableRow>
                  </Tooltip>
                ) : null;
              })}
            </TableBody>
          </Table>
        </Paper>
      </TableViewContainer>
    );
  }
Example #14
Source File: TaskQ.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, taskq, tableState, handleMatch, handleRequestSort,
      handleEdit } = this.props;
    const { order, orderBy, match, snackbar } = tableState;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);

    return (
      <TableViewContainer
        headline={t("Task queue")}
        href="https://docs.grommunio.com/admin/administration.html#taskq"
        // subtitle={t("taskq_sub")}
        snackbar={snackbar || this.state.snackbar}
        onSnackbarClose={this.handleSnackbarClose}
      >
        <Grid container alignItems="flex-end" className={classes.chipGrid}>
          <Chip
            className={classes.chip}
            label={t(taskq.running ? "Running" : "Not running")}
            color={taskq.running ? "success" : "secondary"}
          />
          <Chip
            className={classes.chip}
            label={"Queued: " + taskq.queued}
            color={"primary"}
          />
          <Chip
            className={classes.chip}
            label={"Workers: " + taskq.workers}
            color={"primary"}
          />
        </Grid>
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={this.handleStart}
            disabled={!writable || taskq.running}
          >
            {t("Start server")}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search tasks")}
              variant={"outlined"}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Typography className={classes.count} color="textPrimary">
          {t("showingTaskq", { count: taskq.Tasks.length })}
        </Typography>
        <Paper elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {this.columns.map((column) => (
                  <TableCell key={column.value}>
                    <TableSortLabel
                      active={orderBy === column.value}
                      align="left"
                      direction={orderBy === column.value ? order : "asc"}
                      onClick={handleRequestSort(column.value)}
                    >
                      {t(column.label)}
                    </TableSortLabel>
                  </TableCell>
                ))}
              </TableRow>
            </TableHead>
            <TableBody>
              {taskq.Tasks.map((obj, idx) => 
                <TableRow key={idx} hover onClick={handleEdit('/taskq/' + obj.ID)}>
                  <TableCell>{obj.command}</TableCell>
                  <TableCell>{t(this.getTaskState(obj.state))}</TableCell>
                  <TableCell>{obj.message}</TableCell>
                  <TableCell>{obj.created ? setDateTimeString(obj.created) : ''}</TableCell>
                  <TableCell>{obj.updated ? setDateTimeString(obj.updated) : ''}</TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
          {taskq.Tasks.length < taskq.count && (
            <Grid container justifyContent="center">
              <CircularProgress
                color="primary"
                className={classes.circularProgress}
              />
            </Grid>
          )}
        </Paper>
      </TableViewContainer>
    );
  }
Example #15
Source File: Users.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, users, domain, tableState, handleMatch, handleRequestSort,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { order, orderBy, match, snackbar, adding, deleting } = tableState;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const { checking, taskMessage, taskID } = this.state;
    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={t("Users")}
        subtitle={t('users_sub')}
        href="https://docs.grommunio.com/admin/administration.html#users"
        snackbar={snackbar || this.state.snackbar}
        onSnackbarClose={this.handleSnackbarClose}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            className={classes.newButton}
            disabled={!writable}
          >
            {t('New user')}
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={this.handleNavigation(domain.ID + '/ldap')}
            className={classes.newButton}
            disabled={!writable}
          >
            {t('Search in LDAP')}
          </Button>
          <Tooltip placement="top" title="Synchronize imported users for this domain">
            <Button
              variant="contained"
              color="primary"
              className={classes.newButton}
              onClick={this.handleUserSync(false)}
              disabled={!writable}
            >
              {t('Sync LDAP users')}
            </Button>
          </Tooltip>
          <Tooltip
            placement="top"
            title="Import new users from LDAP for this domain and synchronize previously imported ones"
          >
            <Button
              variant="contained"
              color="primary"
              className={classes.newButton}
              onClick={this.handleUserSync(true)}
              disabled={!writable}
            >
              {t('Import LDAP users')}
            </Button>
          </Tooltip>
          <Tooltip
            placement="top"
            title="Check status of imported users of this domain"
          >
            <Button
              variant="contained"
              color="primary"
              onClick={this.checkUsers}
              disabled={!writable}
            >
              {t('Check LDAP users')}
            </Button>
          </Tooltip>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={handleMatch}
              placeholder={t("Search")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Typography className={classes.count} color="textPrimary">
          {t("showingUser", { count: users.Users.length })}
        </Typography>
        <Paper className={classes.tablePaper} elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell>
                  <TableSortLabel
                    active={orderBy === 'username'}
                    align="left" 
                    direction={orderBy === 'username' ? order : 'asc'}
                    onClick={handleRequestSort('username')}
                    color="primary"
                    sx={{
                      color: 'text.primary',
                    }}
                  >
                    {t('Username')}
                  </TableSortLabel>
                </TableCell>
                {this.columns.map(column =>
                  <TableCell key={column.value}>
                    {t(column.label)}
                  </TableCell>
                )}
                <TableCell padding="checkbox"></TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {users.Users.map((obj, idx) => {
                const properties = obj.properties || {};
                return (
                  <TableRow key={idx} hover onClick={handleEdit('/' + domain.ID + '/users/' + obj.ID)}>
                    <TableCell>{obj.username}</TableCell>
                    <TableCell>{properties.displayname}</TableCell>
                    <TableCell>{this.getStatus(obj.status)}</TableCell>
                    <TableCell>{this.getType(properties.displaytypeex)}</TableCell>
                    <TableCell>{obj.ldapID || ''}</TableCell>
                    <TableCell>{this.getMaxSizeFormatting(properties.storagequotalimit)}</TableCell>
                    <TableCell align="right">
                      {writable && <IconButton onClick={handleDelete(obj)} size="large">
                        <Delete color="error"/>
                      </IconButton>}
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
          {(users.Users.length < users.count) && <Grid container justifyContent="center">
            <CircularProgress color="primary" className={classes.circularProgress}/>
          </Grid>}
        </Paper>
        <AddUser
          open={adding}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          domain={domain}
          onClose={handleAddingClose}
        />
        <DeleteUser
          open={!!deleting}
          onSuccess={handleDeleteSuccess}
          onClose={handleDeleteClose}
          onError={handleDeleteError}
          domainID={domain.ID}
          user={deleting}
        />
        <CheckLdapDialog
          open={checking}
          onClose={this.handleCheckClose}
          onError={handleDeleteError}
        />
        <TaskCreated
          message={taskMessage}
          taskID={taskID}
          onClose={this.handleTaskClose}
        />
      </TableViewContainer>
    );
  }