@mui/material#InputAdornment JavaScript Examples

The following examples show how to use @mui/material#InputAdornment. 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: VisibilityPasswordTextField.js    From react-saas-template with MIT License 6 votes vote down vote up
function VisibilityPasswordTextField(props) {
  const { isVisible, onVisibilityChange, ...rest } = props;
  return (
    <TextField
      {...rest}
      type={isVisible ? "text" : "password"}
      InputProps={{
        endAdornment: (
          <InputAdornment position="end">
            <IconButton
              aria-label="Toggle password visibility"
              onClick={() => {
                onVisibilityChange(!isVisible);
              }}
              onMouseDown={(event) => {
                event.preventDefault();
              }}
              size="large">
              {isVisible ? <VisibilityIcon /> : <VisibilityOffIcon />}
            </IconButton>
          </InputAdornment>
        ),
      }}
    ></TextField>
  );
}
Example #2
Source File: StripeCardForm.js    From react-saas-template with MIT License 5 votes vote down vote up
function StripeCardForm(props) {
  const {
    stripeError,
    setStripeError,
    amount,
    amountError,
    onAmountChange,
    name,
    setName
  } = props;
  return (
    <Grid container spacing={2} justifyContent="space-between">
      <Grid item xs={8}>
        <TextField
          variant="outlined"
          margin="none"
          required
          label="Your Name"
          value={name}
          onChange={event => {
            setName(event.target.value);
          }}
          fullWidth
          autoFocus
          autoComplete="off"
          type="text"
        />
      </Grid>
      <Grid item xs={4}>
        <TextField
          required
          value={amount}
          onChange={event => {
            onAmountChange(parseInt(event.target.value));
          }}
          error={amountError ? true : false}
          helperText={amountError}
          variant="outlined"
          fullWidth
          type="number"
          margin="none"
          label="Amount"
          InputProps={{
            startAdornment: <InputAdornment position="start">$</InputAdornment>
          }}
        />
      </Grid>
      <Grid item xs={12}>
        <StripeTextField
          margin="none"
          fullWidth
          label="Credit Card"
          error={stripeError ? true : false}
          helperText={stripeError}
          variant="outlined"
          required
          StripeElement={CardElement}
          onChange={() => {
            if (stripeError) {
              setStripeError("");
            }
          }}
        ></StripeTextField>
      </Grid>
    </Grid>
  );
}
Example #3
Source File: Searchbar.js    From Django-REST-Framework-React-BoilerPlate with MIT License 5 votes vote down vote up
// ----------------------------------------------------------------------

export default function Searchbar() {
  const [isOpen, setOpen] = useState(false);

  const handleOpen = () => {
    setOpen((prev) => !prev);
  };

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

  return (
    <ClickAwayListener onClickAway={handleClose}>
      <div>
        {!isOpen && (
          <IconButton onClick={handleOpen}>
            <Iconify icon="eva:search-fill" width={20} height={20} />
          </IconButton>
        )}

        <Slide direction="down" in={isOpen} mountOnEnter unmountOnExit>
          <SearchbarStyle>
            <Input
              autoFocus
              fullWidth
              disableUnderline
              placeholder="Search…"
              startAdornment={
                <InputAdornment position="start">
                  <Iconify icon="eva:search-fill" sx={{ color: 'text.disabled', width: 20, height: 20 }} />
                </InputAdornment>
              }
              sx={{ mr: 1, fontWeight: 'fontWeightBold' }}
            />
            <Button variant="contained" onClick={handleClose}>
              Search
            </Button>
          </SearchbarStyle>
        </Slide>
      </div>
    </ClickAwayListener>
  );
}
Example #4
Source File: UserListToolbar.js    From Django-REST-Framework-React-BoilerPlate with MIT License 5 votes vote down vote up
export default function UserListToolbar({ numSelected, filterName, onFilterName }) {
  return (
    <RootStyle
      sx={{
        ...(numSelected > 0 && {
          color: 'primary.main',
          bgcolor: 'primary.lighter',
        }),
      }}
    >
      {numSelected > 0 ? (
        <Typography component="div" variant="subtitle1">
          {numSelected} selected
        </Typography>
      ) : (
        <SearchStyle
          value={filterName}
          onChange={onFilterName}
          placeholder="Search user..."
          startAdornment={
            <InputAdornment position="start">
              <Iconify icon="eva:search-fill" sx={{ color: 'text.disabled', width: 20, height: 20 }} />
            </InputAdornment>
          }
        />
      )}

      {numSelected > 0 ? (
        <Tooltip title="Delete">
          <IconButton>
            <Iconify icon="eva:trash-2-fill" />
          </IconButton>
        </Tooltip>
      ) : (
        <Tooltip title="Filter list">
          <IconButton>
            <Iconify icon="ic:round-filter-list" />
          </IconButton>
        </Tooltip>
      )}
    </RootStyle>
  );
}
Example #5
Source File: Ldap.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, domain, ldapUsers } = this.props;
    const { loading, snackbar, confirming } = this.state;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    return (
      <ViewWrapper
        topbarTitle={domain.domainname}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Typography variant="h2" className={classes.pageTitle}>
          <BackIcon onClick={this.handleNavigation(domain.ID + '/users')} className={classes.backIcon} />
          <span className={classes.pageTitleSecondary}>| </span>
          {t("LDAP")}
        </Typography>
        <Grid container justifyContent="center">
          <TextField
            autoFocus
            placeholder={t("Search LDAP")}
            onChange={this.handleLdapSearch}
            variant="outlined"
            color="primary"
            fullWidth
            className={classes.searchTf}
            InputProps={{
              startAdornment: (
                <InputAdornment position="start">
                  <Search color="primary"/>
                </InputAdornment>
              ),
            }}
          />
        </Grid>
        {ldapUsers.length > 0 && <Paper elevation={1}>
          <List>
            {ldapUsers.map((user, idx) => <React.Fragment key={idx}>
              <ListItem >
                <ListItemText
                  primary={user.name}
                  primaryTypographyProps={{ color: 'primary' }}
                  secondary={user.email}
                />
                {writable && <IconButton onClick={this.handleImport(user)} size="large">
                  <Import />
                </IconButton>}
              </ListItem>
              <Divider />
            </React.Fragment>
            )}
          </List>
        </Paper>}
        <Grid container justifyContent="center" className={classes.loaderContainer}>
          <Grow
            in={loading}
            timeout={{
              appear: 500,
              enter: 10,
              exit: 10,
            }}
          >
            <CircularProgress color="primary" size={40}/>
          </Grow>
        </Grid>
        <ImportDialog
          open={!!confirming}
          user={confirming || {}}
          onSuccess={this.handleSuccess}
          onClose={this.handleClose}
          onError={this.handleError}
        />
      </ViewWrapper>
    );
  }
Example #6
Source File: index.js    From neutron with Mozilla Public License 2.0 4 votes vote down vote up
SectionSavedPassword = () => {
  const [credentials, setCredentials] = useState([]);
  const [revealPasswords, setRevealPasswords] = useState({});

  const reloadCredentials = useCallback(() => {
    getAllCredentialsAsync()
      .then((_credentials) => {
        setCredentials(_credentials);
      })
      .catch((err) => {
        // eslint-disable-next-line no-console
        console.log(err);
      });
  }, [setCredentials]);

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

  useEffect(() => {
    ipcRenderer.removeAllListeners('password-credentials-added');
    ipcRenderer.on('password-credentials-added', () => {
      reloadCredentials();
    });
    return () => {
      ipcRenderer.removeAllListeners('password-credentials-added');
    };
  }, [reloadCredentials]);

  return (
    <List disablePadding dense>
      {credentials.length < 1 ? (
        <ListItem disabled>
          <ListItemText primary="Saved passwords will appear here." />
        </ListItem>
      ) : (
        <>
          <ListItem>
            <Table size="small" aria-label="Saved Passwords">
              <TableHead>
                <TableRow>
                  <TableCell>Website</TableCell>
                  <TableCell align="right">Username</TableCell>
                  <TableCell align="right">Password</TableCell>
                  <TableCell align="right" />
                </TableRow>
              </TableHead>
              <TableBody>
                {credentials.map((row) => {
                  const key = `${row.domain}-${row.username}`;
                  return (
                    <TableRow key={key}>
                      <TableCell component="th" scope="row">
                        {row.domain}
                      </TableCell>
                      <TableCell align="right">
                        <TextField
                          value={row.username}
                          margin="dense"
                          fullWidth
                          variant="outlined"
                          inputProps={{ 'aria-label': 'Username' }}
                          disabled
                        />
                      </TableCell>
                      <TableCell align="right">
                        <FormControl variant="outlined">
                          <OutlinedInput
                            id="outlined-adornment-password"
                            type={revealPasswords[key] ? 'text' : 'password'}
                            defaultValue={row.password}
                            margin="dense"
                            endAdornment={(
                              <InputAdornment position="end">
                                <IconButton
                                  aria-label="toggle password visibility"
                                  onClick={() => {
                                    setRevealPasswords({
                                      ...revealPasswords,
                                      [key]: !revealPasswords[key],
                                    });
                                  }}
                                  edge="end"
                                  size="large"
                                >
                                  {revealPasswords[key]
                                    ? <VisibilityIcon /> : <VisibilityOffIcon />}
                                </IconButton>
                              </InputAdornment>
                            )}
                            inputProps={{ 'aria-label': 'Password' }}
                            fullWidth
                            onChange={(e) => {
                              const newPassword = e.target.value;
                              saveCredentialAsync(row.domain, row.username, newPassword, row.id)
                                .then(() => reloadCredentials())
                                .catch((err) => {
                                  // eslint-disable-next-line no-console
                                  console.log(err);
                                });
                            }}
                          />
                        </FormControl>
                      </TableCell>
                      <TableCell align="right">
                        <Tooltip title="Remove">
                          <IconButton
                            aria-label="Remove"
                            size="small"
                            onClick={() => {
                              deleteCredentialAsync(row.id)
                                .then(() => reloadCredentials())
                                .catch((err) => {
                                  // eslint-disable-next-line no-console
                                  console.log(err);
                                });
                            }}
                          >
                            <ClearIcon />
                          </IconButton>
                        </Tooltip>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </ListItem>
          <ListItem disabled>
            <ListItemText primary={`Passwords are stored encrypted locally on disk with the master key stored securely in ${getKeytarVaultName()}.`} />
          </ListItem>
        </>
      )}
    </List>
  );
}
Example #7
Source File: ResourcePage.jsx    From Edlib with GNU General Public License v3.0 4 votes vote down vote up
ResourcePage = ({ filters, showDeleteButton = false }) => {
    const { t } = useTranslation();
    const theme = useTheme();

    const forceGridView = useMediaQuery(theme.breakpoints.down(1400));
    const [filtersExpanded, setFiltersExpanded] = React.useState(false);
    const [sortingOrder, setSortingOrder] = React.useState(useDefaultOrder());
    const [page, setPage] = React.useState(0);
    const [pageSize, setPageSize] = React.useState(40);
    const [_isGridView, setIsGridView] = React.useState(false);
    const filterUtils = FilterUtils(filters);
    const isGridView = forceGridView || _isGridView;

    const { error, loading, resources, pagination, refetch, filterCount } =
        useGetResources(
            React.useMemo(
                () => ({
                    limit: pageSize,
                    offset: page * pageSize,
                    resourceCapabilities: ['view'],
                    orderBy: sortingOrder,
                    ...(filters && filters.requestData),
                }),
                [page, sortingOrder, filters && filters.requestData, pageSize]
            )
        );

    React.useEffect(() => {
        setPage(0);
    }, [sortingOrder, filters.requestData]);

    const setSearch = React.useCallback(
        (searchText) => {
            filters.setSearchInput(searchText);
            if (sortingOrder !== resourceOrders.RELEVANT_DESC) {
                setSortingOrder(resourceOrders.RELEVANT_DESC);
            }
        },
        [filters, sortingOrder, setSortingOrder]
    );

    const sortOrderDropDown = (
        <FormControl variant="outlined">
            <InputLabel>{t('Sortering')}</InputLabel>
            <Select
                MenuProps={{
                    style: { zIndex: 2051 },
                    anchorOrigin: {
                        vertical: 'bottom',
                        horizontal: 'center',
                    },
                    transformOrigin: {
                        vertical: 'top',
                        horizontal: 'center',
                    },
                }}
                value={sortingOrder}
                onChange={(e) => setSortingOrder(e.target.value)}
                label={getOrderText(t, sortingOrder)}
            >
                {[
                    resourceOrders.RELEVANT_DESC,
                    resourceOrders.VIEWS_DESC,
                    resourceOrders.VIEWS_ASC,
                    resourceOrders.UPDATED_AT_DESC,
                    resourceOrders.UPDATED_AT_ASC,
                ].map((value, index) => (
                    <MenuItem key={index} value={value}>
                        {getOrderText(t, value)}
                    </MenuItem>
                ))}
            </Select>
        </FormControl>
    );

    return (
        <StyledResourcePage>
            <Box
                sx={[
                    {
                        backgroundColor: 'white',
                        boxShadow: '5px 0 5px 0 rgba(0, 0, 0, 0.16)',
                        overflowY: 'auto',
                        position: {
                            xs: 'absolute',
                            md: 'initial',
                        },
                        right: {
                            xs: '110%',
                            md: 'initial',
                        },
                        zIndex: {
                            xs: 2,
                            md: 'initial',
                        },
                    },
                    filtersExpanded && {
                        width: '100vw',
                        right: 'unset',
                        left: 0,
                    },
                ]}
            >
                <ResourceFilters filters={filters} filterCount={filterCount} />
            </Box>
            <Box
                onClick={() => setFiltersExpanded(false)}
                sx={[
                    {
                        position: 'absolute',
                        top: 0,
                        bottom: 0,
                        left: 0,
                        right: 0,
                        backgroundColor: 'rgba(0, 0, 0, 0.5)',
                        zIndex: 1,
                        cursor: 'pointer',
                    },
                    filtersExpanded && {
                        display: {
                            xs: 'block',
                            md: 'none',
                        },
                    },
                    !filtersExpanded && {
                        display: 'none',
                    },
                ]}
            />
            <div className="pageContent">
                <div className="contentOptions">
                    <Box display="flex" paddingRight={1}>
                        <Box
                            paddingRight={1}
                            style={{
                                width: 400,
                            }}
                        >
                            <TextField
                                fullWidth
                                label={t('Søk')}
                                variant="outlined"
                                value={filters.searchInput}
                                onChange={(e) => setSearch(e.target.value)}
                                InputProps={{
                                    endAdornment: (
                                        <InputAdornment position="end">
                                            <Icon>
                                                <SearchIcon />
                                            </Icon>
                                        </InputAdornment>
                                    ),
                                }}
                            />
                        </Box>
                        <div
                            style={{
                                width: 200,
                            }}
                        >
                            <LanguageDropdown
                                language={
                                    filters.languages.length !== 0
                                        ? filters.languages[0]
                                        : null
                                }
                                setLanguage={(value) =>
                                    filters.languages.setValue(
                                        value ? [value] : []
                                    )
                                }
                            />
                        </div>
                    </Box>
                    <div>{sortOrderDropDown}</div>
                </div>
                <Box
                    pt={1}
                    sx={{
                        display: {
                            xs: 'block',
                            md: 'none',
                        },
                    }}
                >
                    <Button
                        color="primary"
                        variant="contained"
                        onClick={() => setFiltersExpanded(!filtersExpanded)}
                        startIcon={<TuneIcon />}
                    >
                        {t('filter', { count: 2 })}
                    </Button>
                </Box>
                <Box
                    display="flex"
                    flexDirection="row"
                    justifyContent="space-between"
                    pt={1}
                >
                    <Box>
                        <FilterChips
                            chips={filterUtils.getChipsFromFilters()}
                        />
                    </Box>
                    <Box>
                        {!forceGridView && (
                            <IconButton
                                onClick={() => setIsGridView(!isGridView)}
                                size="large"
                            >
                                {isGridView ? <ListIcon /> : <ViewModuleIcon />}
                            </IconButton>
                        )}
                    </Box>
                </Box>
                <Content>
                    <div style={{ marginTop: 20 }}>
                        {loading && <Spinner />}
                        {error && <div>{t('Noe skjedde')}</div>}
                        {!loading && !error && resources && !isGridView && (
                            <ResourceTable
                                totalCount={pagination.totalCount}
                                resources={resources}
                                refetch={refetch}
                                showDeleteButton={showDeleteButton}
                                sortingOrder={sortingOrder}
                                setSortingOrder={setSortingOrder}
                            />
                        )}
                        {!loading && !error && resources && isGridView && (
                            <CardView
                                totalCount={pagination.totalCount}
                                resources={resources}
                                refetch={refetch}
                                showDeleteButton={showDeleteButton}
                            />
                        )}
                    </div>
                    {pagination && (
                        <PaginationWrapper>
                            <TablePagination
                                component="div"
                                count={pagination.totalCount}
                                page={page}
                                onPageChange={(e, page) => {
                                    setPage(page);
                                }}
                                rowsPerPage={pageSize}
                                onRowsPerPageChange={(e, pageSize) => {
                                    setPageSize(pageSize);
                                    setPage(0);
                                }}
                                rowsPerPageOptions={[40]}
                            />
                        </PaginationWrapper>
                    )}
                </Content>
            </div>
        </StyledResourcePage>
    );
}
Example #8
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>
    );
  }
Example #9
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 #10
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 #11
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 #12
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 #13
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 #14
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 #15
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 #16
Source File: Folders.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, folders, domain, tableState, handleMatch,
      handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
      clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
      handleDeleteSuccess, handleEdit } = this.props;
    const { Folders, moreDataAvailable } = folders;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const { match, snackbar, adding, deleting } = tableState;
    const { hierarchy } = this.state;

    return (
      <TableViewContainer
        handleScroll={this.handleScroll}
        headline={t("Folders")}
        subtitle={t('folders_sub')}
        href="https://docs.grommunio.com/admin/administration.html#folders"
        snackbar={snackbar}
        onSnackbarClose={clearSnackbar}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleAdd}
            disabled={!writable}
          >
            {t('New folder')}
          </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("showingFolders", { count: Folders.length + (hierarchy.length === 1 ? 1 : 0) })}
        </Typography>
        <Breadcrumbs aria-label="breadcrumb" className={classes.breadcumbs}>
          {hierarchy.map((folder, idx) => 
            <Link
              key={folder.folderid}
              underline="hover"
              color="primary"
              onClick={this.handleBreadcrumb(folder, idx)}
              className={classes.link}
            >
              {folder.displayname}
            </Link>
          )}
        </Breadcrumbs>
        <Paper className={classes.tablePaper} elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                {['Folder name', 'Comment', 'Creation time', ''].map(headerName =>
                  <TableCell key={headerName}>{t(headerName)}</TableCell>
                )}
              </TableRow>
            </TableHead>
            <TableBody>
              {hierarchy.length === 1 && <TableRow>
                <TableCell>{IPM_SUBTREE_OBJECT.displayname}</TableCell>
                <TableCell>{t(IPM_SUBTREE_OBJECT.comment)}</TableCell>
                <TableCell></TableCell>
                <TableCell align="right">
                  <IconButton onClick={handleEdit('/' + domain.ID + '/folders/' + IPM_SUBTREE_ID)} size="large">
                    <Edit color="primary"/>
                  </IconButton>
                </TableCell>
              </TableRow>}
              {Folders.map((obj, idx) =>
                <TableRow hover onClick={this.handleFetchChildren(obj)} key={idx}>
                  <TableCell>{obj.displayname}</TableCell>
                  <TableCell>{obj.comment}</TableCell>
                  <TableCell>{obj.creationtime}</TableCell>
                  <TableCell align="right">
                    <IconButton onClick={handleEdit('/' + domain.ID + '/folders/' + obj.folderid)} size="large">
                      <Edit color="primary"/>
                    </IconButton>
                    {writable && <IconButton onClick={handleDelete(obj)} size="large">
                      <Delete color="error"/>
                    </IconButton>}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
          {(moreDataAvailable) && <Grid container justifyContent="center">
            <CircularProgress color="primary" className={classes.circularProgress}/>
          </Grid>}
        </Paper>
        <AddFolder
          open={adding}
          onClose={handleAddingClose}
          onSuccess={handleAddingSuccess}
          onError={handleAddingError}
          domain={domain}
          parentID={hierarchy[hierarchy.length - 1].folderid}
        />
        <DeleteFolder
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={handleDeleteSuccess}
          onError={handleDeleteError}
          onClose={handleDeleteClose}
          item={deleting.displayname}
          id={deleting.folderid}
          domainID={domain.ID}
        />
      </TableViewContainer>
    );
  }
Example #17
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 #18
Source File: DBConf.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, services, commands } = this.props;
    const { adding, configuring, snackbar, match, tab, deleting } = this.state;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
    return (
      <TableViewContainer
        headline={t("Configuration DB")}
        href="https://docs.grommunio.com/admin/administration.html#db-configuration"
        subtitle={t('dbconf_sub')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Button
            variant="contained"
            color="primary"
            onClick={() => this.setState({ adding: true })}
            disabled={!writable}
          >
            {t("Create file")}
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={() => this.setState({ configuring: true })}
            className={classes.button}
            disabled={!writable}
          >
            {t("Configure grommunio-dbconf")}
          </Button>
          <div className={classes.actions}>
            <TextField
              value={match}
              onChange={this.handleMatch}
              placeholder={t("search services")}
              variant="outlined"
              className={classes.textfield}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Search color="secondary" />
                  </InputAdornment>
                ),
              }}
              color="primary"
            />
          </div>
        </Grid>
        <Grid container alignItems="flex-end" className={classes.buttonGrid}>
          <Tabs
            textColor="primary" 
            indicatorColor="primary"
            value={tab}
            onChange={this.handleTab}
          >
            <Tab value={0} label="Services" />
            <Tab value={1} label="Commands" />
          </Tabs>
        </Grid>
        {tab === 0 ? <Paper elevation={1}>
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell>
                  {t('Name')}
                </TableCell>
                <TableCell padding="checkbox"></TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {services.filter(s => s.includes(match)).map((service, idx) =>
                <TableRow onClick={this.handleNavigation('dbconf/' + service)} key={idx} hover>
                  <TableCell>{service}</TableCell>
                  <TableCell align="right">
                    {writable && <IconButton onClick={this.handleDelete(service)} size="large">
                      <Delete color="error" />
                    </IconButton>}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </Paper> : <Paper className={classes.paper}>
          <Typography variant="h6">Key</Typography>
          {commands.key.length > 0 ? commands.key.map((key, idx) =>
            <pre className={classes.pre} key={idx}>
              <code key={idx}>{key}</code>
            </pre>
          ) : <Typography><i>none</i></Typography>}
          <Typography className={classes.title} variant="h6">File</Typography>
          {commands.file.length > 0 ? commands.file.map((key, idx) =>
            <pre className={classes.pre} key={idx}>
              <code>{key}</code>
            </pre>
          ) : <Typography><i>none</i></Typography>}
          <Typography className={classes.title} variant="h6">Service</Typography>
          {commands.service.length > 0 ? commands.service.map((key, idx) =>
            <pre className={classes.pre} key={idx}>
              <code>{key}</code>
            </pre>
          ) : <Typography><i>none</i></Typography>}
        </Paper>}
        <GeneralDelete
          open={!!deleting}
          delete={this.props.delete}
          onSuccess={this.handleDeleteSuccess}
          onError={this.handleDeleteError}
          onClose={this.handleDeleteClose}
          item={deleting}
          id={deleting}
        />
        <UploadServiceFile
          open={adding}
          onClose={this.handleAddingClose}
          onError={this.handleAddingError}
          onSuccess={this.handleAddingSuccess}
        />
        <CreateDbconfFile
          open={configuring}
          onClose={this.handleAddingClose}
          onError={this.handleAddingError}
          onSuccess={this.handleAddingSuccess}
        />
      </TableViewContainer>
    );
  }
Example #19
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 #20
Source File: NavigationLinks.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, expandedDomain, location, domains, capabilities } = this.props;
    const { filter, tab } = this.state;
    const isSysAdmin = capabilities.includes(SYSTEM_ADMIN_READ);
    const pathname = location.pathname;
    return(
      <React.Fragment>
        <div className={classes.drawerHeader}>
          <img
            src={logo}
            width="140"
            height="32"
            alt="grommunio"
            onClick={this.handleNavigation('')}
            className={classes.logo}
          />
        </div>
        {isSysAdmin && <Tabs
          onChange={(event, tab) => this.setState({ tab: tab })}
          value={tab}
          className={classes.tabs}
          indicatorColor="primary"
          textColor="primary"
        >
          <Tab className={classes.tab} value={0} label={t('Admin')} />
          <Tab className={classes.tab} value={1} label={t('Domains')} />
        </Tabs>}
        {(tab === 1 || !isSysAdmin) &&
            <Grid container component="form" autoComplete="off">
              <TextField
                variant="outlined"
                label={t('Search')}
                value={filter}
                onChange={this.handleTextInput}
                InputLabelProps={{
                  classes: {
                    root: classes.input,
                  },
                  shrink: true,
                }}
                InputProps={{
                  classes: { root: classes.input },
                  startAdornment: (
                    <InputAdornment position="start">
                      <Search color="secondary" />
                    </InputAdornment>
                  ),
                }}
                color="primary"
                className={classes.textfield}
              />
            </Grid>}
        <List className={classes.list}>
          {(tab === 1 || !isSysAdmin) &&
            domains.map(({ domainname: name, ID, domainStatus }) => {
              return name.includes(filter) ?
                <React.Fragment key={name}>
                  <ListItem
                    onClick={this.handleDrawer(ID)}
                    button
                    className={classes.li}
                    selected={expandedDomain === ID && pathname === '/' + ID}
                  >
                    <Grid container alignItems="center">
                      <Domains className={classes.icon} />
                      <ListItemText primary={name + (domainStatus === 3 ? ` [${t('Deactivated')}]` : '')} />
                    </Grid>
                  </ListItem>
                  <Collapse in={expandedDomain === ID} unmountOnExit>
                    <List component="div" disablePadding>
                      <ListItem
                        className={classes.li}
                        button
                        onClick={this.handleNavigation(ID + '/users')}
                        selected={expandedDomain === ID &&
                          pathname.startsWith('/' + ID + '/users')}
                      >
                        <Grid container alignItems="center">
                          <People className={classes.nestedIcon}/>
                          <ListItemText primary={t('Users')}/>
                        </Grid>
                      </ListItem>
                      <ListItem
                        className={classes.li}
                        button
                        onClick={this.handleNavigation(ID + '/folders')}
                        selected={expandedDomain === ID &&
                          pathname.startsWith('/' + ID + '/folders')}
                      >
                        <Grid container alignItems="center">
                          <Folder className={classes.nestedIcon}/>
                          <ListItemText primary={t('Public folders')}/>
                        </Grid>
                      </ListItem>
                      <ListItem
                        className={classes.li}
                        button
                        onClick={this.handleNavigation(ID + '/classes')}
                        selected={pathname.startsWith('/' + ID + '/classes')}
                      >
                        <Grid container alignItems="center">
                          <Classes className={classes.nestedIcon}/>
                          <ListItemText primary={t('Groups')}/>
                        </Grid>
                      </ListItem>
                      <ListItem
                        className={classes.li}
                        button
                        onClick={this.handleNavigation(ID + '/mailLists')}
                        selected={pathname.startsWith('/' + ID + '/mailLists')}
                      >
                        <Grid container alignItems="center">
                          <MLists className={classes.nestedIcon}/>
                          <ListItemText primary={t('Mail lists')}/>
                        </Grid>
                      </ListItem>
                    </List>
                  </Collapse>
                </React.Fragment> : null;
            })}
          {(tab === 0 && !isSysAdmin) && <ListItem
            button
            onClick={this.handleNavigation('taskq')}
            className={classes.li}
            selected={pathname.startsWith('/taskq')}
          >
            <Grid container alignItems="center">
              <TaskAlt className={classes.icon}/>
              <ListItemText primary={t('Task queue')} />
            </Grid>
          </ListItem>}
          {tab === 0 && isSysAdmin && <React.Fragment>
            <Typography variant="inherit" className={classes.subheader}>{t('Overview')}</Typography>
            <ListItem
              button
              onClick={this.handleNavigation('')}
              className={classes.li}
              selected={pathname === '/'}
            >
              <Grid container alignItems="center">
                <Dashboard className={classes.icon} />
                <ListItemText primary="Dashboard"/>
              </Grid>
            </ListItem>
            <Typography variant="inherit" className={classes.subheader}>{t('Management')}</Typography>
            <ListItem
              className={classes.li}
              button
              onClick={this.handleNavigation('orgs')}
              selected={pathname.startsWith('/orgs')}
            >
              <Grid container alignItems="center">
                <Orgs className={classes.icon}/>
                <ListItemText primary={t('Organizations')}/>
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('domains')}
              className={classes.li}
              selected={pathname.startsWith('/domains')}
            >
              <Grid container alignItems="center">
                <Domains className={classes.icon}/>
                <ListItemText primary={t('Domains')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('users')}
              className={classes.li}
              selected={pathname.startsWith('/users')}
            >
              <Grid container alignItems="center">
                <People className={classes.icon}/>
                <ListItemText primary={t('Users')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('roles')}
              className={classes.li}
              selected={pathname === '/roles'}
            >
              <Grid container alignItems="center">
                <Roles className={classes.icon}/>
                <ListItemText primary={t('Roles')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('defaults')}
              className={classes.li}
              selected={pathname === '/defaults'}
            >
              <Grid container alignItems="center">
                <BackupTable className={classes.icon}/>
                <ListItemText primary={t('Defaults')} />
              </Grid>
            </ListItem>
            <Typography variant="inherit" className={classes.subheader}>{t('Configuration')}</Typography>
            <ListItem
              button
              onClick={this.handleNavigation('directory')}
              className={classes.li}
              selected={pathname === '/directory'}
            >
              <Grid container alignItems="center">
                <Ldap className={classes.icon}/>
                <ListItemText primary={t('Directory')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('dbconf')}
              className={classes.li}
              selected={pathname.startsWith('/dbconf')}
            >
              <Grid container alignItems="center">
                <Storage className={classes.icon}/>
                <ListItemText primary={t('Configuration DB')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('servers')}
              className={classes.li}
              selected={pathname.startsWith('/servers')}
            >
              <Grid container alignItems="center">
                <Dns className={classes.icon}/>
                <ListItemText primary={t('Servers')} />
              </Grid>
            </ListItem>
            <Typography variant="inherit" className={classes.subheader}>{t('Monitoring')}</Typography>
            <ListItem
              button
              onClick={this.handleNavigation('logs')}
              className={classes.li}
              selected={pathname.startsWith('/logs')}
            >
              <Grid container alignItems="center">
                <Logs className={classes.icon}/>
                <ListItemText primary={t('Logs')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('mailq')}
              className={classes.li}
              selected={pathname.startsWith('/mailq')}
            >
              <Grid container alignItems="center">
                <QueryBuilder className={classes.icon}/>
                <ListItemText primary={t('Mail queue')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('taskq')}
              className={classes.li}
              selected={pathname.startsWith('/taskq')}
            >
              <Grid container alignItems="center">
                <TaskAlt className={classes.icon}/>
                <ListItemText primary={t('Task queue')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('sync')}
              className={classes.li}
              selected={pathname.startsWith('/sync')}
            >
              <Grid container alignItems="center">
                <Sync className={classes.icon}/>
                <ListItemText primary={t('Mobile devices')} />
              </Grid>
            </ListItem>
            <ListItem
              button
              onClick={this.handleNavigation('status')}
              className={classes.li}
              selected={pathname.startsWith('/status')}
            >
              <Grid container alignItems="center">
                <TableChart className={classes.icon}/>
                <ListItemText primary={t('Live status')} />
              </Grid>
            </ListItem>
          </React.Fragment>
          }
        </List>
        <div className={classes.background} />
      </React.Fragment>
    );
  }
Example #21
Source File: RegisterForm.js    From Django-REST-Framework-React-BoilerPlate with MIT License 4 votes vote down vote up
// ----------------------------------------------------------------------

export default function RegisterForm() {
  const dispatch = useDispatch();
  const navigate = useNavigate();

  const userLogin = useSelector((state) => state.userLogin);
  const { userInfo } = userLogin;

  const userRgister = useSelector((state) => state.userRgister);
  const { error: registerError, loading: registerLoading } = userRgister;

  const [showPassword, setShowPassword] = useState(false);

  const RegisterSchema = Yup.object().shape({
    firstName: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('First name required'),
    lastName: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('Last name required'),
    email: Yup.string().email('Email must be a valid email address').required('Email is required'),
    password: Yup.string().required('Password is required'),
  });

  const formik = useFormik({
    initialValues: {
      firstName: '',
      lastName: '',
      email: '',
      password: '',
    },
    validationSchema: RegisterSchema,
    onSubmit: () => {
      dispatch(register(values.firstName, values.lastName, values.email, values.password));
    },
  });

  const { errors, touched, values, handleSubmit, isSubmitting, getFieldProps } = formik;
  useEffect(() => {
    if (userInfo) {
      navigate('/dashboard/app', { replace: true });
    }
  }, [navigate, userInfo]);
  return (
    <FormikProvider value={formik}>
      <Form autoComplete="off" noValidate onSubmit={handleSubmit}>
        <Stack spacing={3}>
          <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
            <TextField
              fullWidth
              label="First name"
              {...getFieldProps('firstName')}
              error={Boolean(touched.firstName && errors.firstName)}
              helperText={touched.firstName && errors.firstName}
            />

            <TextField
              fullWidth
              label="Last name"
              {...getFieldProps('lastName')}
              error={Boolean(touched.lastName && errors.lastName)}
              helperText={touched.lastName && errors.lastName}
            />
          </Stack>

          <TextField
            fullWidth
            autoComplete="username"
            type="email"
            label="Email address"
            {...getFieldProps('email')}
            error={Boolean(touched.email && errors.email)}
            helperText={touched.email && errors.email}
          />

          <TextField
            fullWidth
            autoComplete="current-password"
            type={showPassword ? 'text' : 'password'}
            label="Password"
            {...getFieldProps('password')}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  <IconButton edge="end" onClick={() => setShowPassword((prev) => !prev)}>
                    <Iconify icon={showPassword ? 'eva:eye-fill' : 'eva:eye-off-fill'} />
                  </IconButton>
                </InputAdornment>
              ),
            }}
            error={Boolean(touched.password && errors.password)}
            helperText={touched.password && errors.password}
          />

          {registerError ? (
            <Alert severity="error">
              <AlertTitle>Register Error</AlertTitle>
              {registerError}
            </Alert>
          ) : null}

          <LoadingButton
            fullWidth
            size="large"
            type="submit"
            variant="contained"
            loading={registerLoading ? isSubmitting : null}
          >
            Register
          </LoadingButton>
        </Stack>
      </Form>
    </FormikProvider>
  );
}
Example #22
Source File: LoginForm.js    From Django-REST-Framework-React-BoilerPlate with MIT License 4 votes vote down vote up
// ----------------------------------------------------------------------

export default function LoginForm() {
  const dispatch = useDispatch();
  const navigate = useNavigate();

  const userLogin = useSelector((state) => state.userLogin);
  const { error: loginError, loading: loginLoading, userInfo } = userLogin;

  const [showPassword, setShowPassword] = useState(false);

  const LoginSchema = Yup.object().shape({
    email: Yup.string().email('Email must be a valid email address').required('Email is required'),
    password: Yup.string().required('Password is required'),
  });

  const formik = useFormik({
    initialValues: {
      email: '',
      password: '',
    },
    validationSchema: LoginSchema,
    onSubmit: () => {
      dispatch(login(values.email, values.password));
    },
  });

  const { errors, touched, values, isSubmitting, handleSubmit, getFieldProps } = formik;

  const handleShowPassword = () => {
    setShowPassword((show) => !show);
  };

  useEffect(() => {
    if (userInfo) {
      navigate('/dashboard/app', { replace: true });
    }
  }, [navigate, userInfo]);
  return (
    <FormikProvider value={formik}>
      <Form autoComplete="off" noValidate onSubmit={handleSubmit}>
        <Stack spacing={3}>
          <TextField
            fullWidth
            autoComplete="username"
            type="email"
            label="Email address"
            {...getFieldProps('email')}
            error={Boolean(touched.email && errors.email)}
            helperText={touched.email && errors.email}
          />

          <TextField
            fullWidth
            autoComplete="current-password"
            type={showPassword ? 'text' : 'password'}
            label="Password"
            {...getFieldProps('password')}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  <IconButton onClick={handleShowPassword} edge="end">
                    <Iconify icon={showPassword ? 'eva:eye-fill' : 'eva:eye-off-fill'} />
                  </IconButton>
                </InputAdornment>
              ),
            }}
            error={Boolean(touched.password && errors.password)}
            helperText={touched.password && errors.password}
          />
        </Stack>

        <Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ my: 2 }}>
          <Link component={RouterLink} variant="subtitle2" to="#" underline="hover">
            Forgot password?
          </Link>
        </Stack>
        {loginError ? (
          <Alert severity="error">
            <AlertTitle>Login Error</AlertTitle>
            {loginError}
          </Alert>
        ) : null}

        <LoadingButton
          fullWidth
          size="large"
          type="submit"
          variant="contained"
          loading={loginLoading ? isSubmitting : null}
        >
          Login
        </LoadingButton>
      </Form>
    </FormikProvider>
  );
}
Example #23
Source File: StripeIBANForm.js    From react-saas-template with MIT License 4 votes vote down vote up
function StripeIBANForm(props) {
  const {
    stripeError,
    setStripeError,
    amount,
    amountError,
    onAmountChange,
    name,
    setName,
    email,
    setEmail
  } = props;
  return (
    <Grid container spacing={2} justifyContent="space-between">
      <Grid item xs={8}>
        <TextField
          variant="outlined"
          margin="none"
          required
          label="Your Name"
          value={name}
          onChange={event => {
            setName(event.target.value);
          }}
          fullWidth
          autoFocus
          autoComplete="off"
          type="text"
        />
      </Grid>
      <Grid item xs={4}>
        <TextField
          required
          value={amount}
          onChange={event => {
            onAmountChange(parseInt(event.target.value));
          }}
          error={amountError ? true : false}
          helperText={amountError}
          variant="outlined"
          fullWidth
          type="number"
          margin="none"
          label="Amount"
          InputProps={{
            startAdornment: <InputAdornment position="start">$</InputAdornment>
          }}
        />
      </Grid>
      <Grid item xs={12}>
        <TextField
          required
          variant="outlined"
          fullWidth
          value={email}
          onChange={event => {
            setEmail(event.target.value);
          }}
          type="email"
          margin="none"
          label="Email"
        />
      </Grid>
      <Grid item xs={12}>
        <StripeTextField
          margin="none"
          variant="outlined"
          fullWidth
          label="IBAN"
          error={stripeError ? true : false}
          helperText={stripeError}
          required
          StripeElement={IbanElement}
          stripeOptions={{ supportedCountries: ["SEPA"] }}
          onChange={() => {
            if (stripeError) {
              setStripeError("");
            }
          }}
        ></StripeTextField>
      </Grid>
    </Grid>
  );
}