@mui/material#MenuItem JavaScript Examples

The following examples show how to use @mui/material#MenuItem. 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: SimpleMenu.jsx    From matx-react with MIT License 6 votes vote down vote up
function SimpleMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  function handleClick(event) {
    setAnchorEl(event.currentTarget);
  }

  function handleClose() {
    setAnchorEl(null);
  }

  return (
    <Box>
      <Button
        variant="outlined"
        aria-haspopup="true"
        onClick={handleClick}
        aria-owns={anchorEl ? "simple-menu" : undefined}
      >
        Open Menu
      </Button>

      <Menu id="simple-menu" anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose}>
        <MenuItem onClick={handleClose}>Profile</MenuItem>
        <MenuItem onClick={handleClose}>My account</MenuItem>
        <MenuItem onClick={handleClose}>Logout</MenuItem>
      </Menu>
    </Box>
  );
}
Example #2
Source File: UserMoreMenu.js    From Django-REST-Framework-React-BoilerPlate with MIT License 6 votes vote down vote up
// ----------------------------------------------------------------------

export default function UserMoreMenu() {
  const ref = useRef(null);
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <IconButton ref={ref} onClick={() => setIsOpen(true)}>
        <Iconify icon="eva:more-vertical-fill" width={20} height={20} />
      </IconButton>

      <Menu
        open={isOpen}
        anchorEl={ref.current}
        onClose={() => setIsOpen(false)}
        PaperProps={{
          sx: { width: 200, maxWidth: '100%' },
        }}
        anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
        transformOrigin={{ vertical: 'top', horizontal: 'right' }}
      >
        <MenuItem sx={{ color: 'text.secondary' }}>
          <ListItemIcon>
            <Iconify icon="eva:trash-2-outline" width={24} height={24} />
          </ListItemIcon>
          <ListItemText primary="Delete" primaryTypographyProps={{ variant: 'body2' }} />
        </MenuItem>

        <MenuItem component={RouterLink} to="#" sx={{ color: 'text.secondary' }}>
          <ListItemIcon>
            <Iconify icon="eva:edit-fill" width={24} height={24} />
          </ListItemIcon>
          <ListItemText primary="Edit" primaryTypographyProps={{ variant: 'body2' }} />
        </MenuItem>
      </Menu>
    </>
  );
}
Example #3
Source File: MaxHeightMenu.jsx    From matx-react with MIT License 6 votes vote down vote up
function MaxHeightMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const open = Boolean(anchorEl);

  function handleClick(event) {
    setAnchorEl(event.currentTarget);
  }

  function handleClose() {
    setAnchorEl(null);
  }

  return (
    <Box>
      <IconButton
        aria-label="More"
        aria-owns={open ? "long-menu" : undefined}
        aria-haspopup="true"
        onClick={handleClick}
      >
        <Icon>more_vert</Icon>
      </IconButton>

      <Menu
        open={open}
        id="long-menu"
        anchorEl={anchorEl}
        onClose={handleClose}
        PaperProps={{ style: { maxHeight: ITEM_HEIGHT * 4.5, width: 200 } }}
      >
        {options.map((option) => (
          <MenuItem key={option} selected={option === "Pyxis"} onClick={handleClose}>
            {option}
          </MenuItem>
        ))}
      </Menu>
    </Box>
  );
}
Example #4
Source File: Layout1Topbar.jsx    From matx-react with MIT License 6 votes vote down vote up
StyledItem = styled(MenuItem)(({ theme }) => ({
  display: 'flex',
  alignItems: 'center',
  minWidth: 185,
  '& a': {
    width: '100%',
    display: 'flex',
    alignItems: 'center',
    textDecoration: 'none',
  },
  '& span': { marginRight: '10px', color: theme.palette.text.primary },
}))
Example #5
Source File: AddFolder.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, open, onClose, Users } = this.props;
    const { displayname, owners, container, comment, loading, autocompleteInput } = this.state;

    return (
      <Dialog
        onClose={onClose}
        open={open}
        maxWidth="sm"
        fullWidth
      >
        <DialogTitle>{t('addHeadline', { item: 'Folder' })}</DialogTitle>
        <DialogContent style={{ minWidth: 400 }}>
          <FormControl className={classes.form}>
            <TextField 
              label={t("Folder name")}
              value={displayname}
              onChange={this.handleInput('displayname')}
              className={classes.input}
              autoFocus
              required
            />
            <TextField
              select
              className={classes.input}
              label={t("Container")}
              fullWidth
              value={container || ''}
              onChange={this.handleInput('container')}
            >
              {this.types.map((type, key) => (
                <MenuItem key={key} value={type.ID}>
                  {type.name}
                </MenuItem>
              ))}
            </TextField>
            <TextField 
              className={classes.input} 
              label={t("Comment")} 
              fullWidth
              multiline
              rows={4}
              value={comment}
              variant="outlined"
              onChange={this.handleInput('comment')}
            />
            <MagnitudeAutocomplete
              multiple
              value={owners || []}
              filterAttribute={'username'}
              inputValue={autocompleteInput}
              onChange={this.handleAutocomplete('owners')}
              className={classes.input} 
              options={Users || []}
              onInputChange={this.handleInput('autocompleteInput')}
              label={t('Owners')}
              placeholder={t("Search domains")  + "..."}
            />
          </FormControl>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={onClose}
            color="secondary"
          >
            Cancel
          </Button>
          <Button
            onClick={this.handleAdd}
            variant="contained"
            color="primary"
            disabled={!displayname || loading}
          >
            {loading ? <CircularProgress size={24}/> : 'Add'}
          </Button>
        </DialogActions>
      </Dialog>
    );
  }
Example #6
Source File: VertOptions.js    From react-saas-template with MIT License 5 votes vote down vote up
function VertOptions(props) {
  const { items, classes, color } = props;
  const anchorEl = useRef();
  const [isOpen, setIsOpen] = useState(false);

  const handleClose = useCallback(() => {
    setIsOpen(false);
  }, [setIsOpen]);

  const handleOpen = useCallback(() => {
    setIsOpen(true);
  }, [setIsOpen]);

  const id = isOpen ? "scroll-playground" : null;
  return (
    <Fragment>
      <IconButton
        onClick={handleOpen}
        buttonRef={anchorEl}
        style={{ color: color ? color : null }}
        aria-describedby={id}
        aria-label="More Options"
        size="large">
        <MoreVertIcon style={{ color: color ? color : null }} />
      </IconButton>
      <Popover
        id={id}
        open={isOpen}
        anchorEl={anchorEl.current}
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "center",
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "center",
        }}
        onClose={handleClose}
        disableScrollLock
      >
        <MenuList dense>
          {items.map((item) => (
            <MenuItem
              key={item.name}
              onClick={() => {
                handleClose();
                item.onClick();
              }}
            >
              <ListItemIcon>{item.icon}</ListItemIcon>
              <ListItemText className={classes.listItemtext}>
                {item.name}
              </ListItemText>
            </MenuItem>
          ))}
        </MenuList>
      </Popover>
    </Fragment>
  );
}
Example #7
Source File: CreateDbconfFile.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, open, onClose, commands } = this.props;
    const { service, data, loading } = this.state;

    return (
      <Dialog
        onClose={onClose}
        open={open}
        maxWidth="md"
        fullWidth
      >
        <DialogTitle>Configure grommunio-dbconf</DialogTitle>
        <DialogContent style={{ minWidth: 400 }}>
          <FormControl className={classes.form}>
            <TextField 
              className={classes.input} 
              label={t("Service name")} 
              fullWidth 
              value={service || ''}
              onChange={this.handleInput('service')}
              autoFocus
              required
            />
            <Typography variant="h6">Data</Typography>
            {data.map((pair, idx) => <Grid key={idx} container alignItems="flex-end">
              <Typography className={classes.gridTypo}>
                {pair.key}
              </Typography>
              <TextField
                label="value"
                value={pair.value}
                onChange={this.handleDataInput(idx)}
                className={classes.flexTextfield}
                select
              >
                {commands[this.commandKeys[idx]].map((command, idx) =>
                  <MenuItem key={idx} value={command}>
                    {command}
                  </MenuItem>
                )}
              </TextField>
            </Grid>
            )}
          </FormControl>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={onClose}
            color="secondary"
          >
            {t('Cancel')}
          </Button>
          <Button
            onClick={this.handleUpload}
            variant="contained"
            color="primary"
            disabled={loading || !service}
          >
            {loading ? <CircularProgress size={24}/> : t('Add')}
          </Button>
        </DialogActions>
      </Dialog>
    );
  }
Example #8
Source File: Smtp.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, user, aliases, forward, forwardError, handleForwardInput, handleAliasEdit, handleRemoveAlias,
      handleAddAlias } = this.props;
    return (
      <FormControl className={classes.form}>
        <div className={classes.flexRow}>
          <Typography variant="h6">{t('E-Mail Addresses')}</Typography>
          {user?.ldapID && <Tooltip title={t("Warning") + ": " + t("Changes will be overwritten with next LDAP sync")}>
            <Warning color="warning" fontSize="inherit" style={{ fontSize: 32 }}/>  
          </Tooltip>}
        </div>
        <List className={classes.list}>
          {(aliases || []).map((alias, idx) => <ListItem key={idx} className={classes.listItem}>
            <TextField
              className={classes.listTextfield}
              value={alias}
              label={'Alias ' + (idx + 1)}
              onChange={handleAliasEdit(idx)}
            />
            <IconButton onClick={handleRemoveAlias(idx)} size="large">
              <Delete color="error" />
            </IconButton>
          </ListItem>
          )}
        </List>
        <Grid container justifyContent="center">
          <Button variant="contained" onClick={handleAddAlias}>{t('addHeadline', { item: 'E-Mail' })}</Button>
        </Grid>
        <Typography variant="h6" className={classes.headline}>{t('E-Mail forward')}</Typography>
        <Grid container className={classes.bottom} >
          <TextField
            className={classes.select}
            value={forward.forwardType === undefined ? '' : forward.forwardType}
            label={t('Forward type')}
            onChange={handleForwardInput('forwardType')}
            select
          >
            <MenuItem value={0}>{t('CC')}</MenuItem>
            <MenuItem value={1}>{t('Redirect')}</MenuItem>
          </TextField>
          <TextField
            error={forwardError}
            className={classes.listTextfield}
            value={forward.destination || ''}
            label={t('Destination')}
            onChange={handleForwardInput('destination')}
          />
        </Grid>
      </FormControl>
    );
  }
Example #9
Source File: Settings.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, settings } = this.props;
    const { snackbar } = this.state;
    return (
      <TableViewContainer
        headline={t("Settings")}
        subtitle={t('settings_sub')}
        href="https://docs.grommunio.com/admin/administration.html#settings"
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <FormControl className={classes.form}>
            <TextField
              select
              className={classes.input}
              label={t("Language")}
              fullWidth
              value={settings.language || 'en-US'}
              onChange={this.handleLangChange}
            >
              {this.langs.map((lang, key) => (
                <MenuItem key={key} value={lang.ID}>
                  {lang.name}
                </MenuItem>
              ))}
            </TextField>
            <FormControl className={classes.formControl}>
              <FormLabel component="legend">{t('Darkmode')}</FormLabel>
              <Switch
                checked={(window.localStorage.getItem('darkMode') === 'true')}
                onChange={this.handleDarkModeChange}
                color="primary"
              />
            </FormControl>
          </FormControl>
        </Paper>
      </TableViewContainer>
    );
  }
Example #10
Source File: Status.js    From admin-web with GNU Affero General Public License v3.0 5 votes vote down vote up
render() {
    const { classes, t, vhosts } = this.props;
    const { snackbar, data, interval, vhost } = this.state;
    const { connections, serverZones, filterZones } = data;
    return (
      <TableViewContainer
        headline={t("Live Status")  + (data.hostName ? ' - ' + data.hostName : '')}
        subtitle={t('livestatus_sub')}
        href="https://docs.grommunio.com/admin/administration.html#live-status"
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <TextField
          select
          value={vhost}
          label="Vhost"
          className={classes.tf}
          onChange={this.handleChange('vhost')}
        >
          {vhosts.map((host, key) =>
            <MenuItem value={host} key={key}>{host}</MenuItem>
          )}
        </TextField>
        <TextField
          select
          value={interval}
          label={t("Update interval")}
          className={classes.tf}
          onChange={this.handleIntervalChange}
        >
          <MenuItem value={1000}>1 {t("second")}</MenuItem>
          <MenuItem value={2000}>2 {t("seconds")}</MenuItem>
          <MenuItem value={3000}>3 {t("seconds")}</MenuItem>
          <MenuItem value={5000}>5 {t("seconds")}</MenuItem>
          <MenuItem value={10000}>10 {t("seconds")}</MenuItem>
        </TextField>
        <Typography variant="h2" className={classes.pageTitle}>
          {t("Connections")}
        </Typography>
        <Typography variant="caption" className={classes.subtitle}>
          Current active connections being processed
        </Typography>
        <Connections data={connections || {}} />
        <Typography variant="h2" className={classes.pageTitle}>
          {t("Requests")}
        </Typography>
        <Typography variant="caption" className={classes.subtitle}>
          All processed requests by the services
        </Typography>
        <Requests data={connections || {}} />
        <div className={classes.logViewer}>
          <TableContainer component={Paper} className={classes.paper}>
            <div style={{ marginBottom: 8 }}>
              <Typography variant="h5">
                {t("Host details")}
              </Typography>
              <Typography variant="caption">
                Detailed and summarized overview over all requests
              </Typography>
            </div>
            <ServerZones serverZones={this.toSortedArray(serverZones || {})} />
            <FilterZones filterZones={filterZones || {}} />
          </TableContainer>
        </div>
      </TableViewContainer>
    );
  }
Example #11
Source File: index.js    From fireact with MIT License 5 votes vote down vote up
UserMenu = () => {
    const [anchorEl, setAnchorEl] = useState(null);
    const open = Boolean(anchorEl);
    const handleMenu = (event) => {
        setAnchorEl(event.currentTarget);
    };
    const handleClose = () => {
        setAnchorEl(null);
    };
    const history = useHistory();

    return (
        <>
        <AuthContext.Consumer>
            {(context) => (
                <>
                <IconButton 
                    ria-label="account of current user"
                    aria-controls="menu-appbar"
                    aria-haspopup="true"
                    onClick={handleMenu}
                    color="inherit"
                >
                    <Avatar alt={context.authUser.user.displayName} src={context.authUser.user.photoURL} />
                </IconButton>
                <Menu
                    id="menu-appbar"
                    anchorEl={anchorEl}
                    anchorOrigin={{
                        vertical: 'top',
                        horizontal: 'right',
                    }}
                    keepMounted
                    transformOrigin={{
                        vertical: 'top',
                        horizontal: 'right',
                    }}
                    open={open}
                    onClose={handleClose}
                >
                    <MenuItem onClick={(e)=>{
                        e.preventDefault();
                        handleClose();
                        history.push("/user/profile");
                    }}>
                        <AccountBoxIcon style={{marginRight: '10px'}} />
                        Profile
                    </MenuItem>
                    <MenuItem onClick={(e)=>{
                        e.preventDefault();
                        handleClose();
                        history.push("/user/log");
                        }}>
                        <ListAltIcon style={{marginRight: '10px'}} />
                        Activity Logs
                    </MenuItem>
                    <Divider />
                    <MenuItem onClick={() => userSignOut()}>
                        <ExitToAppIcon style={{marginRight: '10px'}} />
                        Sign Out
                    </MenuItem>
                </Menu>
                </>
            )}
        </AuthContext.Consumer>
        </>
    )
}
Example #12
Source File: TopSellingTable.jsx    From matx-react with MIT License 5 votes vote down vote up
TopSellingTable = () => {
  const { palette } = useTheme();
  const bgError = palette.error.main;
  const bgPrimary = palette.primary.main;
  const bgSecondary = palette.secondary.main;

  return (
    <Card elevation={3} sx={{ pt: '20px', mb: 3 }}>
      <CardHeader>
        <Title>top selling products</Title>
        <Select size="small" defaultValue="this_month">
          <MenuItem value="this_month">This Month</MenuItem>
          <MenuItem value="last_month">Last Month</MenuItem>
        </Select>
      </CardHeader>

      <Box overflow="auto">
        <ProductTable>
          <TableHead>
            <TableRow>
              <TableCell sx={{ px: 3 }} colSpan={4}>
                Name
              </TableCell>
              <TableCell sx={{ px: 0 }} colSpan={2}>
                Revenue
              </TableCell>
              <TableCell sx={{ px: 0 }} colSpan={2}>
                Stock Status
              </TableCell>
              <TableCell sx={{ px: 0 }} colSpan={1}>
                Action
              </TableCell>
            </TableRow>
          </TableHead>

          <TableBody>
            {productList.map((product, index) => (
              <TableRow key={index} hover>
                <TableCell colSpan={4} align="left" sx={{ px: 0, textTransform: 'capitalize' }}>
                  <Box display="flex" alignItems="center">
                    <Avatar src={product.imgUrl} />
                    <Paragraph sx={{ m: 0, ml: 4 }}>{product.name}</Paragraph>
                  </Box>
                </TableCell>

                <TableCell align="left" colSpan={2} sx={{ px: 0, textTransform: 'capitalize' }}>
                  ${product.price > 999 ? (product.price / 1000).toFixed(1) + 'k' : product.price}
                </TableCell>

                <TableCell sx={{ px: 0 }} align="left" colSpan={2}>
                  {product.available ? (
                    product.available < 20 ? (
                      <Small bgcolor={bgSecondary}>{product.available} available</Small>
                    ) : (
                      <Small bgcolor={bgPrimary}>in stock</Small>
                    )
                  ) : (
                    <Small bgcolor={bgError}>out of stock</Small>
                  )}
                </TableCell>

                <TableCell sx={{ px: 0 }} colSpan={1}>
                  <IconButton>
                    <Icon color="primary">edit</Icon>
                  </IconButton>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </ProductTable>
      </Box>
    </Card>
  );
}
Example #13
Source File: SelectedMenu.jsx    From matx-react with MIT License 5 votes vote down vote up
export default function SelectedMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const [selectedIndex, setSelectedIndex] = React.useState(1);

  function handleClickListItem(event) {
    setAnchorEl(event.currentTarget);
  }
  function handleMenuItemClick(event, index) {
    setSelectedIndex(index);
    setAnchorEl(null);
  }
  function handleClose() {
    setAnchorEl(null);
  }

  return (
    <MenuRoot>
      <List component="nav" aria-label="Device settings">
        <ListItem
          button
          aria-haspopup="true"
          aria-controls="lock-menu"
          aria-label="When device is locked"
          onClick={handleClickListItem}
        >
          <ListItemText primary="When device is locked" secondary={options[selectedIndex]} />
        </ListItem>
      </List>

      <Menu
        id="lock-menu"
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        {options.map((option, index) => (
          <MenuItem
            key={option}
            disabled={index === 0}
            selected={index === selectedIndex}
            onClick={(event) => handleMenuItemClick(event, index)}
          >
            {option}
          </MenuItem>
        ))}
      </Menu>
    </MenuRoot>
  );
}
Example #14
Source File: EditFetchmail.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, open, onClose, username } = this.props;
    const { active, srcServer, srcUser, srcPassword, srcFolder, srcAuth, fetchall, keep, protocol,
      useSSL, sslCertCheck, sslCertPath, sslFingerprint, extraOptions } = this.state;
    const disabled = [srcServer, srcUser, srcPassword, protocol].includes('');

    return (
      <Dialog
        onClose={onClose}
        open={open}
        maxWidth="md"
        fullWidth
        TransitionProps={{
          onEnter: this.handleEnter,
        }}>
        <DialogTitle>{t('editEntry', { username: username })}</DialogTitle>
        <DialogContent style={{ minWidth: 400 }}>
          <FormControl className={classes.form} noValidate autoComplete="off">
            <TextField 
              className={classes.input}
              label={t("Source server")} 
              fullWidth 
              value={srcServer || ''}
              onChange={this.handleInput('srcServer')}
              required
              autoFocus
            />
            <TextField 
              className={classes.input} 
              label={t("Source user")} 
              fullWidth 
              value={srcUser || ''}
              onChange={this.handleInput('srcUser')}
              required
            />
            <form autoComplete="off" noValidate>
              <TextField
                className={classes.input} 
                label={t("Source password")} 
                fullWidth 
                value={srcPassword || ''}
                onChange={this.handleInput('srcPassword')}
                type="password"
                required
                id="new-password"
                name='new-password'
                autoComplete="new-password"
              />
            </form>
            <TextField 
              className={classes.input} 
              label={t("Source folder")} 
              fullWidth 
              value={srcFolder || ''}
              onChange={this.handleInput('srcFolder')}
            />
            <TextField 
              className={classes.input} 
              label={t("Source auth")} 
              fullWidth 
              value={srcAuth || ''}
              onChange={this.handleInput('srcAuth')}
              select
            >
              {this.authTypes.map(t =>
                <MenuItem key={t} value={t}>{t}</MenuItem>  
              )}
            </TextField>
            <TextField 
              className={classes.input} 
              label={t("Protocol")} 
              fullWidth 
              value={protocol || ''}
              onChange={this.handleInput('protocol')}
              select
              required
            >
              {this.protocols.map(p =>
                <MenuItem key={p} value={p}>{p}</MenuItem>  
              )}
            </TextField>
            <TextField 
              className={classes.input} 
              label={t("SSL certificate path")} 
              fullWidth 
              value={sslCertPath || ''}
              onChange={this.handleInput('sslCertPath')}
              disabled={!useSSL}
            />
            <TextField 
              className={classes.input} 
              label={t("SSL fingerprint")} 
              fullWidth 
              value={sslFingerprint || ''}
              onChange={this.handleInput('sslFingerprint')}
              disabled={!useSSL}
            />
            <TextField 
              className={classes.input} 
              label={t("Extra options")} 
              fullWidth 
              value={extraOptions || ''}
              onChange={this.handleInput('extraOptions')}
            />
            <Grid container>
              <FormControlLabel
                control={
                  <Checkbox
                    checked={active}
                    onChange={this.handleCheckbox('active')}
                    color="primary"
                  />
                }
                label="Active"
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={useSSL}
                    onChange={this.handleCheckbox('useSSL')}
                    color="primary"
                  />
                }
                label="Use SSL"
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={fetchall}
                    onChange={this.handleCheckbox('fetchall')}
                    color="primary"
                  />
                }
                label="Fetch all"
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={keep}
                    onChange={this.handleCheckbox('keep')}
                    color="primary"
                  />
                }
                label="Keep"
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={sslCertCheck}
                    onChange={this.handleCheckbox('sslCertCheck')}
                    color="primary"
                    disabled={!useSSL}
                  />
                }
                label="SSL certificate check"
              />
            </Grid>
          </FormControl>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={onClose}
            color="secondary"
          >
            {t('Cancel')}
          </Button>
          <Button
            onClick={this.handleAdd}
            variant="contained"
            color="primary"
            disabled={disabled}
          >
            {t('Confirm')}
          </Button>
        </DialogActions>
      </Dialog>
    );
  }
Example #15
Source File: ClassDetails.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, domain, _classes } = this.props;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const { _class, autocompleteInput, snackbar, stack } = this.state;
    const { classname, parentClasses, members, filters, children } = _class;
    return (
      <ViewWrapper
        topbarTitle={t('Groups')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <Grid container>
            <Typography
              color="primary"
              variant="h5"
            >
              {t('editHeadline', { item: 'Group' })}
            </Typography>
          </Grid>
          <FormControl className={classes.form}>
            <Breadcrumbs className={classes.breadcrumbs}>
              {stack.map((_class, idx) =>
                <Link
                  className={classes.breadcrumb}
                  key={_class.ID}
                  color="inherit"
                  onClick={this.handleBreadcrumb(_class.ID, idx)}
                >
                  {_class.classname}
                </Link>
              )}
            </Breadcrumbs>
            <TextField 
              className={classes.input} 
              label={t("Groupname")} 
              fullWidth 
              value={classname || ''}
              onChange={this.handleInput('classname')}
              autoFocus
              required
            />
            <MagnitudeAutocomplete
              value={parentClasses || []}
              filterAttribute={'classname'}
              inputValue={autocompleteInput}
              onChange={this.handleAutocomplete('parentClasses')}
              className={classes.input} 
              options={_classes || []}
              onInputChange={this.handleAutocompleteInput}
              label={t("Parent groups")}
              placeholder={t("Search groups") + "..."}
              multiple
              autoSelect
            />
            <TextField 
              className={classes.input} 
              label={t("Members (separate by comma)")} 
              fullWidth 
              value={members || ''}
              onChange={this.handleMemberInput}
            />
          </FormControl>
          <div>
            <Typography variant="body1">{t('Filters (All must be true)')}</Typography>
            {filters && filters.map((ANDFilter, ANDidx) =>
              <Accordion
                className={classes.panel}
                elevation={2 /* 1 has global overwrite */}
                key={ANDidx}
                defaultExpanded
              >
                <AccordionSummary>
                  <Grid container justifyContent="space-between">
                    <Typography body="body1">{t('Filter (One must be true)')}</Typography>
                    <IconButton onClick={this.handleRemoveAND(ANDidx)} size="large">
                      <Delete fontSize="small" color="error"/>
                    </IconButton>
                  </Grid>
                </AccordionSummary>
                <AccordionDetails>
                  <Grid container>
                    {ANDFilter.map((ORFilter, ORidx) =>  
                      <Grid item xs={12} key={ORidx} className={classes.grid}>
                        <Autocomplete
                          value={ORFilter.prop || ''}
                          inputValue={ORFilter.prop || ''}
                          onChange={this.handleAutocomplete(ANDidx, ORidx, 'prop')}
                          onInputChange={this.handleFilterInput(ANDidx, ORidx, 'prop')}
                          freeSolo
                          className={classes.flexTextfield} 
                          options={this.columns}
                          renderInput={(params) => (
                            <TextField
                              {...params}
                              label={t("Name of property to match")}
                            />
                          )}
                        />
                        <TextField
                          className={classes.flexTextfield} 
                          label={t("Comparison operator")}
                          value={ORFilter.op || ''}
                          onChange={this.handleFilterInput(ANDidx, ORidx, 'op')}
                          select
                        >
                          {this.operators.map(op =>
                            <MenuItem value={op.value} key={op.label}>{op.label}</MenuItem>
                          )}
                        </TextField>
                        <TextField
                          className={classes.flexTextfield} 
                          label={t("Compare value (binary operators)")}
                          value={ORFilter.val || ''}
                          onChange={this.handleFilterInput(ANDidx, ORidx, 'val')}
                        />
                        {filters[ANDidx].length > 1 &&
                        <IconButton onClick={this.handleRemoveOR(ANDidx, ORidx)} size="large">
                          <Delete fontSize="small" color="error"/>
                        </IconButton>}
                      </Grid>
                    )}
                    <Grid container justifyContent="center">
                      <Button variant="outlined" onClick={this.handleAddOR(ANDidx)}>{t('Add or-statement')}</Button>
                    </Grid>
                  </Grid>
                </AccordionDetails>
              </Accordion>
            )}
            <Grid container justifyContent="center">
              <Button variant="outlined" onClick={this.handleAddAND}>{t('Add and-statement')}</Button>
            </Grid>
          </div>
          <Typography variant="h6">{t('Children')}</Typography>
          <List>
            {children && children.map(child =>
              <ListItem
                key={child.ID}
                button
                onClick={this.handleChildClicked(child)}
              >
                <ListItemText primary={child.classname} />
              </ListItem>
            )}
          </List>
          <Button
            variant="text"
            color="secondary"
            onClick={this.handleNavigation(domain.ID + '/classes')}
            style={{ marginRight: 8 }}
          >
            {t('Back')}
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={this.handleEdit}
            disabled={!writable}
          >
            {t('Save')}
          </Button>
        </Paper>
      </ViewWrapper>
    );
  }
Example #16
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 #17
Source File: Defaults.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t } = this.props;
    const { createParams, sizeUnits, snackbar, langs } = this.state;
    const { maxUser, prohibitsendquota, prohibitreceivequota, storagequotalimit,
      lang, privChat, privArchive, privFiles, privVideo,
      // eslint-disable-next-line camelcase
      smtp, changePassword, pop3_imap, chatTeam, chatUser } = createParams;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);

    return (
      <ViewWrapper
        topbarTitle={t('Defaults')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <Grid container>
            <Typography
              color="primary"
              variant="h5"
            >
              {t('editHeadline', { item: 'Defaults' })}
            </Typography>
          </Grid>
          <FormControl className={classes.form}>
            <Typography
              color="primary"
              variant="h6"
              className={classes.subheader}
            >
              {t('Domain create parameters')}
            </Typography>
            <TextField 
              style={{ marginBottom: 16 }}
              label={t("Max users")}
              onChange={this.handleInput('maxUser')}
              fullWidth 
              value={maxUser || ''}
              autoFocus
            />
            <Grid container className={classes.input}>
              <FormControlLabel
                control={
                  <Checkbox
                    checked={chatTeam || false }
                    onChange={this.handleCheckbox('chatTeam')}
                    color="primary"
                  />
                }
                label={t('Create chat team')}
              />
            </Grid>
            <Typography
              color="primary"
              variant="h6"
              className={classes.subheader}
            >
              {t('User create parameters')}
            </Typography>
            <TextField
              select
              className={classes.input}
              label={t("Language")}
              fullWidth
              value={lang || ''}
              onChange={this.handleInput('lang')}
            >
              {langs.map((l) => (
                <MenuItem key={l.code} value={l.code}>
                  {l.code + ": " + l.name}
                </MenuItem>
              ))}
            </TextField>
            <Grid container style={{ marginTop: 8 }}>
              <TextField 
                className={classes.flexInput}
                label={
                  <div className={classes.labelContainer}>
                    {t("Send quota limit")}
                    <div style={{ width: 6, height: 6, backgroundColor: yellow['500'], marginLeft: 4 }}></div>
                  </div>
                }
                value={prohibitsendquota !== undefined ? prohibitsendquota : ''}
                onChange={this.handleInput('prohibitsendquota')}
                InputProps={{
                  endAdornment:
                    <FormControl className={classes.adornment}>
                      <Select
                        onChange={this.handleUnitChange('prohibitsendquota')}
                        value={sizeUnits.prohibitsendquota}
                        className={classes.select}
                        variant="standard"
                      >
                        <MenuItem value={1}>MB</MenuItem>
                        <MenuItem value={2}>GB</MenuItem>
                        <MenuItem value={3}>TB</MenuItem>
                      </Select>
                    </FormControl>,
                }}
              />
              <TextField 
                className={classes.flexInput}
                label={
                  <div className={classes.labelContainer}>
                    {t("Receive quota limit")}
                    <div style={{ width: 6, height: 6, backgroundColor: red['500'], marginLeft: 4 }}></div>
                  </div>
                }
                value={prohibitreceivequota !== undefined ? prohibitreceivequota : ''}
                onChange={this.handleInput('prohibitreceivequota')}
                InputProps={{
                  endAdornment:
                    <FormControl className={classes.adornment}>
                      <Select
                        onChange={this.handleUnitChange('prohibitreceivequota')}
                        value={sizeUnits.prohibitreceivequota}
                        className={classes.select}
                        variant="standard"
                      >
                        <MenuItem value={1}>MB</MenuItem>
                        <MenuItem value={2}>GB</MenuItem>
                        <MenuItem value={3}>TB</MenuItem>
                      </Select>
                    </FormControl>,
                }}
              />
              <TextField 
                className={classes.flexInput}
                style={{ marginRight: 0 }}
                label={
                  <div className={classes.labelContainer}>
                    {t("Storage quota limit")}
                    <div style={{ width: 6, height: 6, backgroundColor: '#ddd', marginLeft: 4 }}></div>
                  </div>
                }
                value={storagequotalimit !== undefined ? storagequotalimit : ''}
                onChange={this.handleInput('storagequotalimit')}
                InputProps={{
                  endAdornment:
                    <FormControl className={classes.adornment}>
                      <Select
                        onChange={this.handleUnitChange('storagequotalimit')}
                        value={sizeUnits.storagequotalimit}
                        className={classes.select}
                        variant="standard"
                      >
                        <MenuItem value={1}>MB</MenuItem>
                        <MenuItem value={2}>GB</MenuItem>
                        <MenuItem value={3}>TB</MenuItem>
                      </Select>
                    </FormControl>,
                }}
              />
            </Grid>
            <Grid container className={classes.checkboxes}>
              <FormControlLabel
                control={
                  <Checkbox
                    checked={smtp || false }
                    onChange={this.handleCheckbox('smtp')}
                    color="primary"
                  />
                }
                label={t('Allow SMTP sending (used by POP3/IMAP clients)')}
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={changePassword || false }
                    onChange={this.handleCheckbox('changePassword')}
                    color="primary"
                  />
                }
                label={t('Allow password changes')}
              />
              <FormControlLabel
                control={
                  <Checkbox
                checked={pop3_imap || false /*eslint-disable-line*/}
                    onChange={this.handleCheckbox('pop3_imap')}
                    color="primary"
                  />
                }
                label={t('Allow POP3/IMAP logins')}
              />
            </Grid>
            <Grid container className={classes.checkboxes}>
              <FormControlLabel
                control={
                  <Checkbox
                    checked={privChat || false }
                    onChange={this.handleCheckbox('privChat')}
                    color="primary"
                  />
                }
                label={t('Allow Chat')}
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={privVideo || false }
                    onChange={this.handleCheckbox('privVideo')}
                    color="primary"
                  />
                }
                label={t('Allow Video')}
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={privFiles || false }
                    onChange={this.handleCheckbox('privFiles')}
                    color="primary"
                  />
                }
                label={t('Allow Files')}
              />
              <FormControlLabel
                control={
                  <Checkbox
                    checked={privArchive || false }
                    onChange={this.handleCheckbox('privArchive')}
                    color="primary"
                  />
                }
                label={t('Allow Archive')}
              />
            </Grid>
            <Grid container className={classes.checkboxes}>
              <FormControlLabel
                control={
                  <Checkbox
                    checked={chatUser || false }
                    onChange={this.handleCheckbox('chatUser')}
                    color="primary"
                  />
                }
                label={t('Create chat user')}
              />
            </Grid>
          </FormControl>
          <Grid container className={classes.buttonGrid}>
            <Button
              variant="contained"
              color="primary"
              onClick={this.handleEdit}
              disabled={!writable}
            >
              {t('Save')}
            </Button>
          </Grid>
        </Paper>
      </ViewWrapper>
    );
  }
Example #18
Source File: DomainDetails.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, orgs, capabilities, servers } = this.props;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
    const { domainname, domainStatus, orgID, maxUser, title, address, adminName,
      tel, syncPolicy, checkPw, newPw, changingPw, snackbar, tab, defaultPolicy,
      chat, homeserver, autocompleteInput } = this.state;
    
    return (
      <ViewWrapper
        topbarTitle={t('Domains')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <Grid container>
            <Typography
              color="primary"
              variant="h5"
            >
              {t('editHeadline', { item: 'Domain' })}
            </Typography>
          </Grid>
          <Tabs className={classes.tabs} indicatorColor="primary" onChange={this.handleTab} value={tab}>
            <Tab value={0} label={t('Domain')} />
            <Tab value={1} label={t('Sync policies')} />
          </Tabs>
          {tab === 0 && <FormControl className={classes.form}>
            <Grid container className={classes.input}>
              <TextField
                label={t("Domain")} 
                style={{ flex: 1, marginRight: 8 }} 
                value={domainname || ''}
                autoFocus
                disabled
              />
            </Grid>
            <TextField
              select
              className={classes.input}
              label={t("Status")}
              fullWidth
              value={domainStatus || 0}
              onChange={this.handleInput('domainStatus')}
            >
              {this.statuses.map((status, key) => (
                <MenuItem key={key} value={status.ID}>
                  {status.name}
                </MenuItem>
              ))}
            </TextField>
            {capabilities.includes(SYSTEM_ADMIN_READ) && <MagnitudeAutocomplete
              value={orgID}
              filterAttribute={'name'}
              onChange={this.handleAutocomplete('orgID')}
              className={classes.input} 
              options={orgs}
              inputValue={autocompleteInput}
              onInputChange={this.handleInput('autocompleteInput')}
              label={t('Organization')}
            />}
            <TextField 
              className={classes.input} 
              label={t("Maximum users")} 
              fullWidth 
              value={maxUser || ''}
              onChange={this.handleInput('maxUser')}
            />
            <TextField 
              className={classes.input} 
              label={t("Title")} 
              fullWidth 
              value={title || ''}
              onChange={this.handleInput('title')}
            />
            <TextField 
              className={classes.input} 
              label={t("Address")} 
              fullWidth 
              value={address || ''}
              onChange={this.handleInput('address')}
            />
            <TextField 
              className={classes.input} 
              label={t("Administrator")} 
              fullWidth 
              value={adminName || ''}
              onChange={this.handleInput('adminName')}
            />
            <TextField 
              className={classes.input} 
              label={t("Telephone")} 
              fullWidth 
              value={tel || ''}
              onChange={this.handleInput('tel')}
            />
            <MagnitudeAutocomplete
              value={homeserver}
              filterAttribute={'hostname'}
              onChange={this.handleServer}
              className={classes.input} 
              options={servers}
              label={t('Homeserver')}
            />
            <FormControlLabel
              control={
                <Checkbox
                  checked={chat || false}
                  onChange={this.handleCheckbox('chat')}
                  color="primary"
                />
              }
              className={classes.input} 
              label={t('grommunio-chat Team')}
            />
          </FormControl>}
          {tab === 1 && <SlimSyncPolicies
            syncPolicy={syncPolicy}
            defaultPolicy={defaultPolicy}
            handleChange={this.handleSyncChange}
            handleCheckbox={this.handleSyncCheckboxChange}
            handleSlider={this.handleSlider}
          />}
          <Button
            color="secondary"
            onClick={this.handleBack}
            style={{ marginRight: 8 }}
          >
            {t('Back')}
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={this.handleEdit}
            disabled={!writable}
          >
            {t('Save')}
          </Button>
        </Paper>
        <Dialog open={!!changingPw} onClose={() => this.setState({ changingPw: false })}>
          <DialogTitle>{t('Change password')}</DialogTitle>
          <DialogContent>
            <TextField 
              className={classes.input} 
              label={t("New password")} 
              fullWidth
              type="password"
              value={newPw}
              onChange={event => this.setState({ newPw: event.target.value })}
              autoFocus
              onKeyPress={this.handleKeyPress}
            />
            <TextField 
              className={classes.input} 
              label={t("Repeat new password")} 
              fullWidth
              type="password"
              value={checkPw}
              onChange={event => this.setState({ checkPw: event.target.value })}
              onKeyPress={this.handleKeyPress}
            />
          </DialogContent>
          <DialogActions>
            <Button
              color="secondary"
              onClick={() => this.setState({ changingPw: false })}>
              {t('Cancel')}
            </Button>
            <Button
              variant="contained"
              color="primary"
              onClick={this.handlePasswordChange}
              disabled={checkPw !== newPw}
            >
              {t('Save')}
            </Button>
          </DialogActions>
        </Dialog>
      </ViewWrapper>
    );
  }
Example #19
Source File: Account.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, user, domain, sizeUnits, handleStatusInput, handlePropertyChange,
      handleIntPropertyChange, handleCheckbox, handleUnitChange, langs,
      handlePasswordChange, handleQuotaDelete, handleChatUser, handleServer,
      servers } = this.props;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const { username, status, properties, smtp, pop3_imap, changePassword, lang, //eslint-disable-line
      ldapID, chat, chatAdmin, privChat, privVideo, privFiles, privArchive, homeserver } = user;
    const { creationtime, displaytypeex, storagequotalimit, prohibitreceivequota,
      prohibitsendquota } = properties;

    return (
      <FormControl className={classes.form}>
        <Grid container className={classes.input}>
          <TextField
            label={t("Username")}
            value={username || ''}
            autoFocus
            style={{ flex: 1, marginRight: 8 }}
            InputProps={{
              endAdornment: <div>@{domain.domainname}</div>,
            }}
            disabled
          />
          {writable && status !== 4 && ldapID === null && <Button
            variant="contained"
            color="primary"
            onClick={handlePasswordChange}
            size="small"
          >
            {t('Change password')}
          </Button>}
        </Grid>
        {ldapID && <TextField 
          label={t("LDAP ID")}
          className={classes.input}
          value={ldapID || ''}
          disabled
          style={{ flex: 1, marginRight: 8 }}
        />}
        <TextField
          select
          className={classes.input}
          label={t("Mode")}
          fullWidth
          value={status || 0}
          onChange={handleStatusInput}
        >
          {this.statuses.map((status, key) => (
            <MenuItem key={key} value={status.ID}>
              {status.name}
            </MenuItem>
          ))}
        </TextField>
        <TextField
          select
          className={classes.input}
          label={t("Type")}
          fullWidth
          disabled={displaytypeex === 1}
          value={displaytypeex || 0}
          onChange={handlePropertyChange('displaytypeex')}
        >
          {this.types.map((type, key) => (
            <MenuItem key={key} value={type.ID}>
              {type.name}
            </MenuItem>
          ))}
        </TextField>
        {this.context.includes(SYSTEM_ADMIN_READ) && <MagnitudeAutocomplete
          value={homeserver || ''}
          filterAttribute={'hostname'}
          onChange={handleServer}
          className={classes.input} 
          options={servers}
          label={t('Homeserver')}
          disabled={!this.context.includes(SYSTEM_ADMIN_WRITE)}
        />}
        <TextField
          select
          className={classes.input}
          label={t("Language")}
          fullWidth
          value={lang || 'en_US'}
          disabled
        >
          {langs.map((l) => (
            <MenuItem key={l.code} value={l.code}>
              {l.code + ": " + l.name}
            </MenuItem>
          ))}
        </TextField>
        <div className={classes.quota}>
          <Typography color="textPrimary" className={classes.quotaHeadline}>{t('Used space')}</Typography>
          <Grid container style={{ marginTop: 8 }}>
            <TextField 
              className={classes.flexInput}
              label={
                <div className={classes.labelContainer}>
                  {t("Send quota limit")}
                  <div style={{ width: 6, height: 6, backgroundColor: yellow['500'], marginLeft: 4 }}></div>
                </div>
              }
              value={prohibitsendquota !== undefined ? prohibitsendquota : ''}
              onChange={handleIntPropertyChange('prohibitsendquota')}
              InputProps={{
                endAdornment:
                  <FormControl className={classes.adornment}>
                    <Select
                      onChange={handleUnitChange('prohibitsendquota')}
                      value={sizeUnits.prohibitsendquota}
                      className={classes.select}
                      variant="standard"
                    >
                      <MenuItem value={1}>MB</MenuItem>
                      <MenuItem value={2}>GB</MenuItem>
                      <MenuItem value={3}>TB</MenuItem>
                    </Select>
                    <Tooltip title={('Delete quota')} placement="top">
                      <IconButton size="small" onClick={handleQuotaDelete('prohibitsendquota')}>
                        <Delete color="error" fontSize="small" />
                      </IconButton>
                    </Tooltip>
                  </FormControl>,
              }}
            />
            <TextField 
              className={classes.flexInput}
              label={
                <div className={classes.labelContainer}>
                  {t("Receive quota limit")}
                  <div style={{ width: 6, height: 6, backgroundColor: red['500'], marginLeft: 4 }}></div>
                </div>
              }
              value={prohibitreceivequota !== undefined ? prohibitreceivequota : ''}
              onChange={handleIntPropertyChange('prohibitreceivequota')}
              InputProps={{
                endAdornment:
                  <FormControl className={classes.adornment}>
                    <Select
                      onChange={handleUnitChange('prohibitreceivequota')}
                      value={sizeUnits.prohibitreceivequota}
                      className={classes.select}
                      variant="standard"
                    >
                      <MenuItem value={1}>MB</MenuItem>
                      <MenuItem value={2}>GB</MenuItem>
                      <MenuItem value={3}>TB</MenuItem>
                    </Select>
                    <Tooltip title={('Delete quota')} placement="top">
                      <IconButton size="small" onClick={handleQuotaDelete('prohibitreceivequota')}>
                        <Delete color="error" fontSize="small" />
                      </IconButton>
                    </Tooltip>
                  </FormControl>,
              }}
            />
            <TextField 
              className={classes.flexInput}
              label={
                <div className={classes.labelContainer}>
                  {t("Storage quota limit")}
                  <div style={{ width: 6, height: 6, backgroundColor: '#ddd', marginLeft: 4 }}></div>
                </div>
              }
              value={storagequotalimit !== undefined ? storagequotalimit : ''}
              onChange={handleIntPropertyChange('storagequotalimit')}
              InputProps={{
                endAdornment:
                  <FormControl className={classes.adornment}>
                    <Select
                      onChange={handleUnitChange('storagequotalimit')}
                      value={sizeUnits.storagequotalimit}
                      className={classes.select}
                      variant="standard"
                    >
                      <MenuItem value={1}>MB</MenuItem>
                      <MenuItem value={2}>GB</MenuItem>
                      <MenuItem value={3}>TB</MenuItem>
                    </Select>
                    <Tooltip title={('Delete quota')} placement="top">
                      <IconButton size="small" onClick={handleQuotaDelete('storagequotalimit')}>
                        <Delete color="error" fontSize="small" />
                      </IconButton>
                    </Tooltip>
                  </FormControl>,
              }}
            />
            <div className={classes.graphContainer}>
              {this.calculateGraph()}
            </div>
          </Grid>
        </div>
        <TextField
          className={classes.input}
          label={t("Creation time")}
          fullWidth
          value={creationtime || ''}
          onChange={handlePropertyChange('creationtime')}
          disabled
        />
        {status !== 4 && <Tooltip
          placement="top-start"
          title={!domain.chat ? "This domain doesn't have a grommunio-chat team" : ''}
        >
          <Grid container className={classes.input}>
            <FormControlLabel
              control={
                <Checkbox
                  checked={chat || false}
                  onChange={handleChatUser}
                  color="primary"
                />
              }
              label={t('Create grommunio-chat User')}
              disabled={!domain.chat}
            />
            <FormControlLabel
              control={
                <Checkbox
                  checked={chatAdmin || false}
                  onChange={handleCheckbox('chatAdmin')}
                  color="primary"
                />
              }
              disabled={!chat || !domain.chat}
              label={t('grommunio-chat admin permissions')}
            />
          </Grid>
        </Tooltip>}
        {status !== 4 && <Grid container className={classes.input}>
          <FormControlLabel
            control={
              <Checkbox
                checked={smtp || false }
                onChange={handleCheckbox('smtp')}
                color="primary"
              />
            }
            label={t('Allow SMTP sending (used by POP3/IMAP clients)')}
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={changePassword || false }
                onChange={handleCheckbox('changePassword')}
                color="primary"
              />
            }
            label={t('Allow password changes')}
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={pop3_imap || false /*eslint-disable-line*/}
                onChange={handleCheckbox('pop3_imap')}
                color="primary"
              />
            }
            label={t('Allow POP3/IMAP logins')}
          />
        </Grid>}
        {status !== 4 && <Grid container className={classes.input}>
          <FormControlLabel
            control={
              <Checkbox
                checked={privChat || false }
                onChange={handleCheckbox('privChat')}
                color="primary"
              />
            }
            disabled={!chat}
            label={t('Allow Chat')}
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={privVideo || false }
                onChange={handleCheckbox('privVideo')}
                color="primary"
              />
            }
            label={t('Allow Video')}
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={privFiles || false }
                onChange={handleCheckbox('privFiles')}
                color="primary"
              />
            }
            label={t('Allow Files')}
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={privArchive || false }
                onChange={handleCheckbox('privArchive')}
                color="primary"
              />
            }
            label={t('Allow Archive')}
          />
        </Grid>}
      </FormControl>
    );
  }
Example #20
Source File: DomainMenu.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, domain, t, capabilities } = this.props;
    const { snackbar, deleting, sizeUnits, langs, createParams } = this.state;
    const { prohibitsendquota, prohibitreceivequota, storagequotalimit,
      lang, privChat, privArchive, privFiles, privVideo,
      // eslint-disable-next-line camelcase
      smtp, changePassword, pop3_imap } = createParams;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const editable = capabilities.includes(ORG_ADMIN);

    return (
      <TableViewContainer
        headline={t("Domain overview")}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <Grid container direction="column" className={classes.container}>
            <Grid item className={classes.firstRow}>
              <Typography variant="h6">
                <span className={classes.description}>{t('Domain name')}:</span>
                {domain.domainname}
              </Typography>
              {editable && <div className={classes.editButtonContainer}>
                <Button
                  onClick={this.handleNav}
                  variant="contained"
                  color="primary"
                  style={{ marginRight: 8 }}
                >
                  {t('editHeadline', { item: 'domain' })}
                </Button>
                <Button
                  onClick={this.handleDelete}
                  variant="contained"
                  color="secondary"
                >
                  {t('Delete domain')}
                </Button>
              </div>}
            </Grid>
            <Typography variant="h6" className={classes.data}>
              <span className={classes.description}>{t('Title')}:</span>
              {domain.title}
            </Typography>
            <Typography variant="h6" className={classes.data}>
              <span className={classes.description}>{t('Address')}:</span>
              {domain.address}
            </Typography>
            <Typography variant="h6" className={classes.data}>
              <span className={classes.description}>{t('Admin')}:</span>
              {domain.adminName}
            </Typography>
            <Typography variant="h6" className={classes.data}>
              <span className={classes.description}>{t('Users')}:</span>
              {`${domain.activeUsers} active, ${domain.inactiveUsers} inactive, ${domain.maxUser} maximum`}
            </Typography>
            <Typography variant="h6" className={classes.data}>
              <span className={classes.description}>{t('Telephone')}:</span>
              {domain.tel}
            </Typography>
          </Grid>
          <div className={classes.defaultsContainer}>
            <FormControl className={classes.form}>
              <Typography
                color="primary"
                variant="h6"
                className={classes.subheader}
              >
                {t('Default user parameters')}
              </Typography>
              <TextField
                select
                className={classes.input}
                label={t("Language")}
                fullWidth
                value={lang || ''}
                onChange={this.handleInput('lang')}
              >
                {langs.map((l) => (
                  <MenuItem key={l.code} value={l.code}>
                    {l.code + ": " + l.name}
                  </MenuItem>
                ))}
              </TextField>
              <Grid container className={classes.input}>
                <TextField 
                  className={classes.flexInput}
                  label={
                    <div className={classes.labelContainer}>
                      {t("Send quota limit")}
                      <div style={{ width: 6, height: 6, backgroundColor: yellow['500'], marginLeft: 4 }}></div>
                    </div>
                  }
                  value={prohibitsendquota !== undefined ? prohibitsendquota : ''}
                  onChange={this.handleInput('prohibitsendquota')}
                  InputProps={{
                    endAdornment:
                      <FormControl className={classes.adornment}>
                        <Select
                          onChange={this.handleUnitChange('prohibitsendquota')}
                          value={sizeUnits.prohibitsendquota}
                          className={classes.select}
                          variant="standard"
                        >
                          <MenuItem value={1}>MB</MenuItem>
                          <MenuItem value={2}>GB</MenuItem>
                          <MenuItem value={3}>TB</MenuItem>
                        </Select>
                      </FormControl>,
                  }}
                />
                <TextField 
                  className={classes.flexInput}
                  label={
                    <div className={classes.labelContainer}>
                      {t("Receive quota limit")}
                      <div style={{ width: 6, height: 6, backgroundColor: red['500'], marginLeft: 4 }}></div>
                    </div>
                  }
                  value={prohibitreceivequota !== undefined ? prohibitreceivequota : ''}
                  onChange={this.handleInput('prohibitreceivequota')}
                  InputProps={{
                    endAdornment:
                      <FormControl className={classes.adornment}>
                        <Select
                          onChange={this.handleUnitChange('prohibitreceivequota')}
                          value={sizeUnits.prohibitreceivequota}
                          className={classes.select}
                          variant="standard"
                        >
                          <MenuItem value={1}>MB</MenuItem>
                          <MenuItem value={2}>GB</MenuItem>
                          <MenuItem value={3}>TB</MenuItem>
                        </Select>
                      </FormControl>,
                  }}
                />
                <TextField 
                  className={classes.flexInput}
                  style={{ marginRight: 0 }}
                  label={
                    <div className={classes.labelContainer}>
                      {t("Storage quota limit")}
                      <div style={{ width: 6, height: 6, backgroundColor: '#ddd', marginLeft: 4 }}></div>
                    </div>
                  }
                  value={storagequotalimit !== undefined ? storagequotalimit : ''}
                  onChange={this.handleInput('storagequotalimit')}
                  InputProps={{
                    endAdornment:
                      <FormControl className={classes.adornment}>
                        <Select
                          onChange={this.handleUnitChange('storagequotalimit')}
                          value={sizeUnits.storagequotalimit}
                          className={classes.select}
                          variant="standard"
                        >
                          <MenuItem value={1}>MB</MenuItem>
                          <MenuItem value={2}>GB</MenuItem>
                          <MenuItem value={3}>TB</MenuItem>
                        </Select>
                      </FormControl>,
                  }}
                />
              </Grid>
              <Grid container className={classes.input}>
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={smtp || false }
                      onChange={this.handleCheckbox('smtp')}
                      color="primary"
                    />
                  }
                  label={t('Allow SMTP sending (used by POP3/IMAP clients)')}
                />
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={changePassword || false }
                      onChange={this.handleCheckbox('changePassword')}
                      color="primary"
                    />
                  }
                  label={t('Allow password changes')}
                />
                <FormControlLabel
                  control={
                    <Checkbox
                  checked={pop3_imap || false /*eslint-disable-line*/}
                      onChange={this.handleCheckbox('pop3_imap')}
                      color="primary"
                    />
                  }
                  label={t('Allow POP3/IMAP logins')}
                />
              </Grid>
              <Grid container className={classes.input}>
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={privChat || false }
                      onChange={this.handleCheckbox('privChat')}
                      color="primary"
                    />
                  }
                  label={t('Allow Chat')}
                />
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={privVideo || false }
                      onChange={this.handleCheckbox('privVideo')}
                      color="primary"
                    />
                  }
                  label={t('Allow Video')}
                />
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={privFiles || false }
                      onChange={this.handleCheckbox('privFiles')}
                      color="primary"
                    />
                  }
                  label={t('Allow Files')}
                />
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={privArchive || false }
                      onChange={this.handleCheckbox('privArchive')}
                      color="primary"
                    />
                  }
                  label={t('Allow Archive')}
                />
              </Grid>
            </FormControl>
          </div>
          <Grid container className={classes.buttonGrid}>
            <Button
              variant="contained"
              color="primary"
              onClick={this.handleEdit}
              disabled={!writable}
            >
              {t('Save')}
            </Button>
          </Grid>
        </Paper>
        <DeleteDomain
          open={deleting}
          delete={this.props.delete}
          onSuccess={this.handleDeleteSuccess}
          onError={this.handleDeleteError}
          onClose={this.handleDeleteClose}
          item={domain.domainname}
          id={domain.ID}
        />
      </TableViewContainer>
    );
  }
Example #21
Source File: FolderDetails.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, domain } = this.props;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const { folder, adding, snackbar, readonly } = this.state;

    return (
      <ViewWrapper
        topbarTitle={t('Folders')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <Grid container>
            <Typography
              color="primary"
              variant="h5"
            >
              {t('Folder details')}
            </Typography>
          </Grid>
          <FormControl className={classes.form}>
            <TextField 
              className={classes.input} 
              label={t("Folder name")} 
              fullWidth 
              value={folder.displayname || ''}
              autoFocus
              onChange={this.handleInput('displayname')}
              disabled={readonly}
            />
            <TextField
              select
              className={classes.input}
              label={t("Container")}
              fullWidth
              value={folder.container || 'IPF.Note'}
              onChange={this.handleInput('container')}
              disabled={readonly}
            >
              {this.types.map((type, key) => (
                <MenuItem key={key} value={type.ID}>
                  {type.name}
                </MenuItem>
              ))}
            </TextField>
            <TextField 
              className={classes.input} 
              label={t("Comment")} 
              fullWidth
              multiline
              variant="outlined"
              rows={4}
              value={folder.comment || ''}
              onChange={this.handleInput('comment')}
              disabled={readonly}
            />
          </FormControl>
          <Grid container className={classes.grid}>
            <Button
              onClick={this.handleAdd}
              disabled={!writable}
              size="large"
              variant='outlined'
            >
              {t('Open permissions')}
            </Button>
          </Grid>
          <Grid container>
            <Button
              color="secondary"
              onClick={this.props.history.goBack}
              style={{ marginRight: 8 }}
            >
              {t('Back')}
            </Button>
            <Button
              variant="contained"
              color="primary"
              onClick={this.handleEdit}
              style={{ marginRight: 8 }}
              disabled={!writable || readonly}
            >
              {t('Save')}
            </Button>
          </Grid>
        </Paper>
        {folder.folderid && <FolderPermissions
          open={adding}
          onSuccess={this.handlePermissionsSuccess}
          onError={this.handlePermissionsError}
          onCancel={this.handlePermissionsCancel}
          domain={domain}
          folderID={folder.folderid}
        />}
      </ViewWrapper>
    );
  }
Example #22
Source File: LdapConfig.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t } = this.props;
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
    const { available, force, deleting, snackbar, server, bindUser, bindPass, starttls, baseDn, objectID, disabled,
      username, filter, templates, attributes, defaultQuota, displayName, searchAttributes,
      authBackendSelection, aliases, taskMessage, taskID } = this.state;
    return (
      <div className={classes.root}>
        <TopBar />
        <div className={classes.toolbar}></div>
        <form className={classes.base} onSubmit={this.handleSave}>
          <Typography variant="h2" className={classes.pageTitle}>
            {t("Directory")}
            <Tooltip
              className={classes.tooltip}
              title={t("ldap_settingsHelp")}
              placement="top"
            >
              <IconButton
                size="small"
                href="https://docs.grommunio.com/admin/administration.html#ldap"
                target="_blank"
              >
                <Help fontSize="small"/>
              </IconButton>
            </Tooltip>
          </Typography>
          <Typography variant="caption" className={classes.subtitle}>
            {t('ldap_sub')}
          </Typography>
          <Grid container className={classes.category}>
            <FormControlLabel
              control={
                <Switch
                  checked={!disabled}
                  onChange={this.handleActive}
                  name="disabled"
                  color="primary"
                />
              }
              label={<span>
                {t('LDAP enabled')}
                <Tooltip
                  className={classes.tooltip}
                  title={t("Enable LDAP service")}
                  placement="top"
                >
                  <IconButton size="small">
                    <Help fontSize="small"/>
                  </IconButton>
                </Tooltip>
              </span>}
            />
            <div className={classes.flexContainer}>
              <Tooltip placement="top" title={t("Synchronize already imported users")}>
                <Button
                  variant="contained"
                  color="primary"
                  style={{ marginRight: 16 }}
                  onClick={this.handleSync(false)}
                >
                  {t("Sync users")}
                </Button>
              </Tooltip>
              <Tooltip
                placement="top"
                title={t("ldap_import_tooltip")}
              >
                <Button
                  variant="contained"
                  color="primary"
                  style={{ marginRight: 16 }}
                  onClick={this.handleSync(true)}
                >
                  {t("Import users")}
                </Button>
              </Tooltip>
            </div>
          </Grid>
          <Typography
            color="inherit"
            variant="caption"
            style={{
              marginLeft: 16,
              color: available ? green['500'] : red['500'],
            }}
          >
            {!disabled && (available ? t('LDAP connectivity check passed') : t('LDAP connectivity check failed'))}
          </Typography>
          <Paper elevation={1} className={classes.paper}>
            <Typography variant="h6" className={classes.category}>{t('LDAP Server')}</Typography>
            <FormControl className={classes.formControl}>
              <div className={classes.flexRow}>
                <LdapTextfield
                  flex
                  label='LDAP Server'
                  autoFocus
                  placeholder="ldap://[::1]:389/"
                  onChange={this.handleInput('server')}
                  value={server || ''}
                  desc={t("ldap_server_desc")}
                  id="url"
                  name="url"
                  autoComplete="url"
                  InputLabelProps={{
                    shrink: true,
                  }}
                />
                <LdapTextfield
                  flex
                  label="LDAP Bind DN"
                  onChange={this.handleInput('bindUser')}
                  value={bindUser || ''}
                  desc={t("Distinguished Name used for binding")}
                  id="username"
                  name="username"
                  autoComplete="username"
                />
                <LdapTextfield
                  flex
                  label={t('LDAP Bind Password')}
                  onChange={this.handleInput('bindPass')}
                  value={bindPass || ''}
                  desc={t("ldap_password_desc")}
                  id="password"
                  name="password"
                  type="password"
                  autoComplete="current-password"
                />
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={starttls || false}
                      onChange={this.handleCheckbox('starttls')}
                      name="starttls"
                      inputProps={{
                        autoComplete: 'starttls',
                        name: 'starttls',
                        id: 'starttls',
                      }}
                      color="primary"
                    />
                  }
                  label={<span>
                    {'STARTTLS'}
                    <Tooltip
                      className={classes.tooltip}
                      title="Whether to issue a StartTLS extended operation"
                      placement="top"
                    >
                      <IconButton size="small">
                        <Help fontSize="small"/>
                      </IconButton>
                    </Tooltip>
                  </span>}
                />
              </div>
              <LdapTextfield
                label='LDAP Base DN'
                onChange={this.handleInput('baseDn')}
                value={baseDn || ''}
                desc={t("Base DN to use for searches")}
                id="baseDn"
                name="baseDn"
                autoComplete="baseDn"
              />
            </FormControl>
          </Paper>
          <Paper elevation={1} className={classes.paper}>
            <Typography variant="h6" className={classes.category}>
              {t('User authentication mechanism')}
            </Typography>
            <FormControl className={classes.formControl}>
              <RadioGroup
                name="authBackendSelection"
                value={authBackendSelection}
                onChange={this.handleInput("authBackendSelection")}
                row
                className={classes.radioGroup}
                color="primary"
              >
                <FormControlLabel
                  value="externid"
                  control={<Radio color="primary"/>}
                  label={t("Automatic")}
                />
                <FormControlLabel value="always_mysql" control={<Radio color="primary"/>} label={t("Only MySQL")} />
                <FormControlLabel value="always_ldap" control={<Radio color="primary"/>} label={t("Only LDAP")} />
              </RadioGroup>
            </FormControl>
          </Paper>
          <Paper className={classes.paper} elevation={1}>
            <FormControl className={classes.formControl}>
              <Typography variant="h6" className={classes.category}>{t('Attribute Configuration')}</Typography>
              <LdapTextfield
                label={t('LDAP Template')}
                onChange={this.handleTemplate}
                value={templates}
                select
                desc={t("Mapping templates to use")}
                id="templates"
                name="templates"
                autoComplete="templates"
              >
                <MenuItem value='none'>{t('No template')}</MenuItem>
                <MenuItem value="OpenLDAP">OpenLDAP</MenuItem>
                <MenuItem value="ActiveDirectory">ActiveDirectory</MenuItem>
              </LdapTextfield>
              <LdapTextfield
                label={t('LDAP Filter')}
                onChange={this.handleInput('filter')}
                value={filter || ''}
                desc={t("LDAP search filter to apply to user lookup")}
                id="filter"
                name="filter"
                autoComplete="filter"
              />
              <LdapTextfield
                label={t('Unique Identifier Attribute')}
                onChange={this.handleInput('objectID')}
                value={objectID || ''}
                desc={t("ldap_oID_desc")}
                id="objectID"
                name="objectID"
                autoComplete="objectID"
              />
              <LdapTextfield
                label={t('LDAP Username Attribute')}
                onChange={this.handleInput('username')}
                value={username || ''}
                desc={t("ldap_username_desc")}
                id="username"
                name="username"
                autoComplete="username"
              />
              <LdapTextfield
                label={t('LDAP Display Name Attribute')}
                onChange={this.handleInput('displayName')}
                value={displayName || ''}
                desc={t("Name of the attribute that contains the name")}
                id="displayName"
                name="displayName"
                autoComplete="displayName"
              />
              <LdapTextfield
                label={t('LDAP Default Quota')}
                onChange={this.handleInput('defaultQuota')}
                value={defaultQuota}
                desc={t("ldap_defaultQuota_desc")}
                id="defaultQuota"
                name="defaultQuota"
                autoComplete="defaultQuota"
              />
              <LdapTextfield
                label={t('LDAP Aliases')}
                onChange={this.handleInput('aliases')}
                value={aliases}
                desc={t("LDAP alias mapping")}
                id="aliasMapping"
                name="aliasMapping"
                autoComplete="aliasMapping"
              />
            </FormControl>
          </Paper>
          <Paper elevation={1} className={classes.paper}>
            <Typography variant="h6" className={classes.category}>{t('LDAP Search Attributes')}</Typography>
            <Typography variant="caption" className={classes.category}>
              {t('ldap_attribute_desc')}
            </Typography>
            <Autocomplete
              value={searchAttributes || []}
              onChange={this.handleAutocomplete('searchAttributes')}
              className={classes.textfield}
              options={adminConfig.searchAttributes}
              multiple
              renderInput={(params) => (
                <TextField
                  {...params}
                />
              )}
            />
          </Paper>
          <Paper elevation={1} className={classes.paper}>
            <Typography variant="h6" className={classes.category}>
              {t('Custom Mapping')}
              <Tooltip
                className={classes.tooltip}
                title={t('ldap_mapping_desc')}
                placement="top"
              >
                <IconButton size="small">
                  <Help fontSize="small"/>
                </IconButton>
              </Tooltip>
            </Typography>
            {attributes.map((mapping, idx) =>
              <Grid className={classes.attribute} container alignItems="center" key={idx}>
                <LdapTextfield
                  label={t('Name')}
                  flex
                  onChange={this.handleAttributeInput('key', idx)}
                  value={mapping.key || ''}
                  desc={t("LDAP attribute to map")}
                />
                <Typography className={classes.spacer}>:</Typography>
                <LdapTextfield
                  label={t('Value')}
                  flex
                  onChange={this.handleAttributeInput('value', idx)}
                  value={mapping.value || ''}
                  desc={t("Name of the user property to map to")}
                />
                <IconButton
                  onClick={this.removeRow(idx)}
                  className={classes.removeButton}
                  size="large">
                  <Delete color="error" />
                </IconButton>
              </Grid>
            )}
            <Grid container justifyContent="center" className={classes.addButton}>
              <Button size="small" onClick={this.handleNewRow}>
                <Add color="primary" />
              </Button>
            </Grid>
          </Paper>
          <div className={classes.bottomRow}>
            <Button
              variant="contained"
              color="secondary"
              onClick={this.handleDelete}
              className={classes.deleteButton}
            >
              {t('Delete config')}
            </Button>
            <Button
              variant="contained"
              color="primary"
              type="submit"
              onClick={this.handleSave}
              disabled={!writable}
            >
              {t('Save')}
            </Button>
            <FormControlLabel
              className={classes.attribute}
              control={
                <Checkbox
                  checked={force || false}
                  onChange={this.handleCheckbox('force')}
                  name="disabled"
                  color="primary"
                />
              }
              label={<span>
                {t('Force config save')}
                <Tooltip
                  className={classes.tooltip}
                  title={t("Save LDAP configuration even if it's faulty")}
                  placement="top"
                >
                  <IconButton size="small">
                    <Help fontSize="small"/>
                  </IconButton>
                </Tooltip>
              </span>}
            />
          </div>
        </form>
        <DeleteConfig
          open={deleting}
          onSuccess={this.handleDeleteSuccess}
          onError={this.handleDeleteError}
          onClose={this.handleDeleteClose}
        />
        <TaskCreated
          message={taskMessage}
          taskID={taskID}
          onClose={this.handleTaskClose}
        />
        <Feedback
          snackbar={snackbar}
          onClose={() => this.setState({ snackbar: '' })}
        />
      </div>
    );
  }
Example #23
Source File: MListDetails.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, domain, _classes } = this.props;
    const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
    const { snackbar, listname, listType, listPrivilege, associations, specifieds, class: _class,
      autocompleteInput } = this.state;

    return (
      <ViewWrapper
        topbarTitle={t('Mail lists')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <Grid container>
            <Typography
              color="primary"
              variant="h5"
            >
              {t('editHeadline', { item: 'Mail list' })}
            </Typography>
          </Grid>
          <FormControl className={classes.form}>
            <TextField 
              className={classes.input} 
              label={t("Mail list name")} 
              fullWidth 
              value={listname}
              autoFocus
              required
              inputProps={{
                disabled: true,
              }}
            />
            <TextField
              select
              className={classes.input}
              label={t("Type")}
              fullWidth
              value={listType}
              inputProps={{
                disabled: true,
              }}
            >
              {this.listTypes.map((status, key) => (
                <MenuItem key={key} value={status.ID}>
                  {status.name}
                </MenuItem>
              ))}
            </TextField>
            <TextField
              select
              className={classes.input}
              label={t("Privilege")}
              fullWidth
              value={listPrivilege}
              onChange={this.handlePrivilegeChange}
            >
              {this.listPrivileges.map((status, key) => (
                <MenuItem key={key} value={status.ID}>
                  {status.name}
                </MenuItem>
              ))}
            </TextField>
            {listType === 0 && <TextField 
              className={classes.input} 
              label={t("Recipients") + " separated by comma (,)"} 
              fullWidth 
              value={associations || ''}
              onChange={this.handleInput('associations')}
            />}
            {listPrivilege === 3 && <TextField 
              className={classes.input} 
              label={t("Senders") + " separated by comma (,)"} 
              fullWidth 
              value={specifieds || ''}
              onChange={this.handleInput('specifieds')}
            />}
            {listType === 3 && <MagnitudeAutocomplete
              value={_class}
              inputValue={autocompleteInput}
              onChange={this.handleAutocomplete('class')}
              filterAttribute={'classname'}
              className={classes.input} 
              options={_classes}
              label={t('Group')}
              onInputChange={this.handleInput('autocompleteInput')}
            />}
          </FormControl>
          <Button
            color="secondary"
            onClick={this.handleNavigation(domain.ID + '/mailLists')}
            style={{ marginRight: 8 }}
          >
            {t('Back')}
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={this.handleEdit}
            disabled={!writable}
          >
            {t('Save')}
          </Button>
        </Paper>
        <Feedback
          snackbar={snackbar}
          onClose={() => this.setState({ snackbar: '' })}
        />
      </ViewWrapper>
    );
  }
Example #24
Source File: RoleDetails.js    From admin-web with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { classes, t, Users, Permissions, Domains, Orgs } = this.props;
    const { snackbar, role, autocompleteInput } = this.state;
    const { name, description, users, permissions } = role;
    const domains = [{ ID: '*', domainname: 'All'}].concat(Domains);
    const orgs = [{ ID: '*', name: 'All'}].concat(Orgs);
    const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
    return (
      <ViewWrapper
        topbarTitle={t('Role')}
        snackbar={snackbar}
        onSnackbarClose={() => this.setState({ snackbar: '' })}
      >
        <Paper className={classes.paper} elevation={1}>
          <Grid container>
            <Typography
              color="primary"
              variant="h5"
            >
              {t('editHeadline', { item: 'Role' })}
            </Typography>
          </Grid>
          <FormControl className={classes.form}>
            <TextField 
              className={classes.input} 
              label={t("Name")} 
              fullWidth
              autoFocus
              value={name || ''}
              onChange={this.handleRoleInput('name')}
            />
            <TextField 
              className={classes.input} 
              label={t("Description")} 
              fullWidth
              multiline
              variant="outlined"
              rows={4}
              value={description || ''}
              onChange={this.handleRoleInput('description')}
            />
            <MagnitudeAutocomplete
              multiple
              inputValue={autocompleteInput}
              value={users || []}
              filterAttribute={'username'}
              onChange={this.handleAutocomplete('users')}
              onInputChange={this.handleACInput}
              className={classes.input} 
              options={Users || []}
              label={t('Users')}
              placeholder={t("Search users") + "..."}
            />
            {(permissions || []).map((permission, idx) =>
              <div key={idx} className={classes.row}>
                <TextField
                  select
                  label={t("Permission")}
                  value={permission.permission || ''}
                  onChange={this.handleSelectPermission(idx)}
                  fullWidth
                  variant="standard"
                >
                  {Permissions.map((name) => (
                    <MenuItem key={name} value={name}>
                      {name}
                    </MenuItem>
                  ))}
                </TextField>
                {permission.permission.includes('DomainAdmin') /*Read and Write*/ && <MagnitudeAutocomplete
                  value={permission.params}
                  getOptionLabel={(domainID) => domainID.domainname ||
                    (domains || []).find(d => d.ID === domainID)?.domainname || ''}
                  filterAttribute={'domainname'}
                  onChange={this.handleSetParams(idx, "domainname")}
                  inputValue={permission.autocompleteInput}
                  onInputChange={this.handleAutocompleteInput(idx)}
                  className={classes.rowTextfield} 
                  options={domains || []}
                  label={t('Params')}
                  placeholder={t("Search domains") + "..."}
                  variant="standard"
                  fullWidth
                  autoSelect
                />}
                {permission.permission === ORG_ADMIN && <MagnitudeAutocomplete
                  value={permission.params}
                  getOptionLabel={(orgID) => orgID.name ||
                    (orgs || []).find(o => o.ID === orgID)?.name || ''} // Because only ID is received
                  filterAttribute={'name'}
                  onChange={this.handleSetParams(idx, "name")}
                  inputValue={permission.autocompleteInput}
                  onInputChange={this.handleAutocompleteInput(idx)}
                  className={classes.rowTextfield} 
                  options={orgs || []}
                  label={t('Params')}
                  placeholder={t("Search organizations") + "..."}
                  variant="standard"
                  fullWidth
                  autoSelect
                />}
                <IconButton size="small" onClick={this.removeRow(idx)}>
                  <Delete fontSize="small" color="error" />
                </IconButton>
              </div>
            )}
            <Grid container justifyContent="center" className={classes.addButton}>
              <Button size="small" onClick={this.handleNewRow}>
                <Add color="primary" />
              </Button>
            </Grid>
          </FormControl>
          <Button
            color="secondary"
            onClick={() => this.props.history.push('/roles')}
            style={{ marginRight: 8 }}
          >
            {t('Back')}
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={this.handleEdit}
            disabled={!writable}
          >
            {t('Save')}
          </Button>
        </Paper>
      </ViewWrapper>
    );
  }
Example #25
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 #26
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 #27
Source File: CardChart.js    From react-saas-template with MIT License 4 votes vote down vote up
function CardChart(props) {
  const { color, data, title, classes, theme, height } = props;
  const [anchorEl, setAnchorEl] = useState(null);
  const [selectedOption, setSelectedOption] = useState("1 Month");

  const handleClick = useCallback(
    (event) => {
      setAnchorEl(event.currentTarget);
    },
    [setAnchorEl]
  );

  const formatter = useCallback(
    (value) => {
      return [value, title];
    },
    [title]
  );

  const getSubtitle = useCallback(() => {
    switch (selectedOption) {
      case "1 Week":
        return "Last week";
      case "1 Month":
        return "Last month";
      case "6 Months":
        return "Last 6 months";
      default:
        throw new Error("No branch selected in switch-statement");
    }
  }, [selectedOption]);

  const processData = useCallback(() => {
    let seconds;
    switch (selectedOption) {
      case "1 Week":
        seconds = 60 * 60 * 24 * 7;
        break;
      case "1 Month":
        seconds = 60 * 60 * 24 * 31;
        break;
      case "6 Months":
        seconds = 60 * 60 * 24 * 31 * 6;
        break;
      default:
        throw new Error("No branch selected in switch-statement");
    }
    const minSeconds = new Date() / 1000 - seconds;
    const arr = [];
    for (let i = 0; i < data.length; i += 1) {
      if (minSeconds < data[i].timestamp) {
        arr.unshift(data[i]);
      }
    }
    return arr;
  }, [data, selectedOption]);

  const handleClose = useCallback(() => {
    setAnchorEl(null);
  }, [setAnchorEl]);

  const selectOption = useCallback(
    (selectedOption) => {
      setSelectedOption(selectedOption);
      handleClose();
    },
    [setSelectedOption, handleClose]
  );

  const isOpen = Boolean(anchorEl);
  return (
    <Card>
      <Box pt={2} px={2} pb={4}>
        <Box display="flex" justifyContent="space-between">
          <div>
            <Typography variant="subtitle1">{title}</Typography>
            <Typography variant="body2" color="textSecondary">
              {getSubtitle()}
            </Typography>
          </div>
          <div>
            <IconButton
              aria-label="More"
              aria-owns={isOpen ? "long-menu" : undefined}
              aria-haspopup="true"
              onClick={handleClick}
              size="large">
              <MoreVertIcon />
            </IconButton>
            <Menu
              id="long-menu"
              anchorEl={anchorEl}
              open={isOpen}
              onClose={handleClose}
              PaperProps={{
                style: {
                  maxHeight: itemHeight,
                  width: 200,
                },
              }}
              disableScrollLock
            >
              {options.map((option) => (
                <MenuItem
                  key={option}
                  selected={option === selectedOption}
                  onClick={() => {
                    selectOption(option);
                  }}
                  name={option}
                >
                  {option}
                </MenuItem>
              ))}
            </Menu>
          </div>
        </Box>
      </Box>
      <CardContent>
        <Box className={classes.cardContentInner} height={height}>
          <ResponsiveContainer width="100%" height="100%">
            <AreaChart data={processData()} type="number">
              <XAxis
                dataKey="timestamp"
                type="number"
                domain={["dataMin", "dataMax"]}
                hide
              />
              <YAxis
                domain={[calculateMin(data, "value", 0.05), "dataMax"]}
                hide
              />
              <Area
                type="monotone"
                dataKey="value"
                stroke={color}
                fill={color}
              />
              <Tooltip
                labelFormatter={labelFormatter}
                formatter={formatter}
                cursor={false}
                contentStyle={{
                  border: "none",
                  padding: theme.spacing(1),
                  borderRadius: theme.shape.borderRadius,
                  boxShadow: theme.shadows[1],
                }}
                labelStyle={theme.typography.body1}
                itemStyle={{
                  fontSize: theme.typography.body1.fontSize,
                  letterSpacing: theme.typography.body1.letterSpacing,
                  fontFamily: theme.typography.body1.fontFamily,
                  lineHeight: theme.typography.body1.lineHeight,
                  fontWeight: theme.typography.body1.fontWeight,
                }}
              />
            </AreaChart>
          </ResponsiveContainer>
        </Box>
      </CardContent>
    </Card>
  );
}
Example #28
Source File: index.jsx    From Edlib with GNU General Public License v3.0 4 votes vote down vote up
ContentExplorerHeader = ({ onClose, getUrl }) => {
    const { t } = useTranslation();
    const { classes } = useStyles();
    const location = useLocation();
    const history = useHistory();
    const { enableDoku, inMaintenanceMode } = useConfigurationContext();
    const { getUserConfig } = useEdlibComponentsContext();

    const isActive = (path) => {
        let paths = [path];

        if (Array.isArray(path)) {
            paths = [...path];
        }

        return paths.some((path) =>
            matchPath(location.pathname, {
                path,
                exact: false,
            })
        );
    };

    const enabledTypes =
        getUserConfig('enabledResourceTypes') || Object.values(resourceEditors);

    const isEditorEnabled = (type) => enabledTypes.indexOf(type) !== -1;

    const editorMapping = {
        [resourceEditors.H5P]: {
            link: getUrl('/resources/new/contentauthor?group=h5p'),
            label: t('Interaktivitet'),
        },
        [resourceEditors.QUESTION_SET]: {
            link: getUrl('/resources/new/contentauthor?group=questionset'),
            label: t('Spørsmål'),
        },
        // [resourceEditors.ARTICLE]: {
        //     link: getUrl('/resources/new/contentauthor?group=article'),
        //     label: t('Tekst'),
        // },
        // [resourceEditors.EMBED]: {
        //     link: '/resources/new/url',
        //     label: 'Link',
        // },
        [resourceEditors.DOKU]: {
            link: getUrl('/resources/new/doku'),
            label: 'EdStep',
        },
    };

    const activatedEditorsList = Object.entries(editorMapping)
        .filter(([type]) => isEditorEnabled(type))
        .filter(([type]) => {
            switch (type) {
                case resourceEditors.DOKU:
                    return enableDoku;
                default:
                    return true;
            }
        });
    //******************************************************************************
    //************ New Component ***************************************************
    //******************************************************************************
    const [anchorEl, setAnchorEl] = React.useState(null);
    const open = Boolean(anchorEl);

    const handleMenu = (event) => {
        setAnchorEl(event.currentTarget);
    };

    const handleClose = () => {
        setAnchorEl(null);
    };

    const buttonClasses = (active) =>
        cn(classes.headerButton, {
            [classes.selectedButton]: active,
        });

    return (
        <AppBar position="static" className={classes.appBar}>
            <Toolbar className={classes.toolbar}>
                <div>
                    <img
                        className={classes.logo}
                        src={logoUrl}
                        alt="edlib logo"
                    />
                </div>
                {!inMaintenanceMode && (
                    <div className={classes.links}>
                        {activatedEditorsList.length > 1 && (
                            <div>
                                <Button
                                    aria-controls="menu-appbar"
                                    aria-haspopup="true"
                                    onClick={handleMenu}
                                    color="inherit"
                                    startIcon={<AddCircleRounded />}
                                    sx={{
                                        color: isActive([
                                            getUrl('/resources/new'),
                                            getUrl('/link-author'),
                                            getUrl('/doku-author'),
                                        ])
                                            ? 'secondary.main'
                                            : 'default',
                                    }}
                                    className={classes.headerButton}
                                >
                                    {t('Opprett innhold')}
                                </Button>
                                <Menu
                                    id="menu-appbar"
                                    anchorEl={anchorEl}
                                    keepMounted
                                    getContentAnchorEl={null}
                                    anchorOrigin={{
                                        vertical: 'bottom',
                                        horizontal: 'center',
                                    }}
                                    transformOrigin={{
                                        vertical: 'top',
                                        horizontal: 'center',
                                    }}
                                    open={open}
                                    onClose={handleClose}
                                >
                                    {activatedEditorsList.map(
                                        ([type, { link, label }]) => (
                                            <MenuItem
                                                onClick={() => {
                                                    history.push(link);
                                                    handleClose();
                                                }}
                                                key={type}
                                            >
                                                {label}
                                            </MenuItem>
                                        )
                                    )}
                                </Menu>
                            </div>
                        )}
                        {activatedEditorsList.length === 1 && (
                            <div>
                                <Button
                                    onClick={() => {
                                        history.push(
                                            activatedEditorsList[0][1].link
                                        );
                                        handleClose();
                                    }}
                                    color="inherit"
                                    startIcon={<AddCircleRounded />}
                                    sx={{
                                        color: isActive(
                                            activatedEditorsList[0][1].link
                                        )
                                            ? 'secondary.main'
                                            : 'default',
                                    }}
                                    className={classes.headerButton}
                                >
                                    {t('Opprett innhold')}
                                </Button>
                            </div>
                        )}
                        <div>
                            <Button
                                onClick={() => {
                                    history.push(getUrl('/shared-content'));
                                    handleClose();
                                }}
                                color="inherit"
                                startIcon={<ShoppingCart />}
                                sx={{
                                    color: isActive(getUrl('/shared-content'))
                                        ? 'secondary.main'
                                        : 'default',
                                }}
                                className={classes.headerButton}
                            >
                                {t('Delt innhold')}
                            </Button>
                        </div>
                        <div>
                            <Button
                                onClick={() => {
                                    history.push(getUrl('/my-content'));
                                    handleClose();
                                }}
                                color="inherit"
                                startIcon={<Home />}
                                sx={{
                                    color: isActive(getUrl('/my-content'))
                                        ? 'secondary.main'
                                        : 'default',
                                }}
                                className={classes.headerButton}
                            >
                                {t('Mitt innhold')}
                            </Button>
                        </div>
                    </div>
                )}
                {onClose ? (
                    <div className={classes.close}>
                        <Close onClick={onClose} />
                    </div>
                ) : (
                    <div>&nbsp</div>
                )}
            </Toolbar>
        </AppBar>
    );
}
Example #29
Source File: CreateSavedFilter.jsx    From Edlib with GNU General Public License v3.0 4 votes vote down vote up
CreateSavedFilter = ({
    show,
    onClose,
    savedFilterData,
    filters,
    onDone,
    filterUtils,
}) => {
    const { classes } = useStyles();
    const { t } = useTranslation();
    const { edlibApi } = useConfigurationContext();
    const [selected, setSelected] = React.useState('new');
    const [newFilterName, setNewFilterName] = React.useState('My filter');

    const request = useRequestWithToken();

    return (
        <Dialog open={show} onClose={() => onClose()} maxWidth="sm" fullWidth>
            <DialogTitle>{_.capitalize(t('edit_filter'))}</DialogTitle>
            <DialogContent>
                <Box pt={1}>
                    <FormControl
                        variant="outlined"
                        fullWidth
                        className={classes.formControl}
                    >
                        <InputLabel>
                            {_.capitalize(t('choose_filter'))}
                        </InputLabel>
                        <Select
                            value={selected}
                            onChange={(e) => setSelected(e.target.value)}
                            label={_.capitalize(t('choose_filter'))}
                        >
                            <MenuItem value="new">
                                <em>{_.capitalize(t('create_new'))}</em>
                            </MenuItem>
                            {savedFilterData.map((savedFilter) => (
                                <MenuItem
                                    key={savedFilter.id}
                                    value={savedFilter.id}
                                >
                                    {savedFilter.name}
                                </MenuItem>
                            ))}
                        </Select>
                    </FormControl>
                    {selected === 'new' && (
                        <TextField
                            required
                            label={_.capitalize(t('name'))}
                            variant="outlined"
                            className={classes.formControl}
                            fullWidth
                            value={newFilterName}
                            onChange={(e) => setNewFilterName(e.target.value)}
                        />
                    )}
                    <div className={classes.formControl}>
                        <FilterChips
                            chips={filterUtils.getChipsFromFilters(false)}
                        />
                    </div>
                </Box>
            </DialogContent>
            <DialogActions>
                <Button
                    color="primary"
                    variant="outlined"
                    onClick={() => onClose()}
                >
                    {t('cancel')}
                </Button>
                <Button
                    color="primary"
                    variant="contained"
                    style={{ marginLeft: 5 }}
                    onClick={() => {
                        let url = edlibApi(`/common/saved-filters`);

                        if (selected !== 'new') {
                            url += `/` + selected;
                        }

                        request(url, 'POST', {
                            body: {
                                name: newFilterName,
                                choices: [
                                    filters.contentTypes.value.map(
                                        (contentType) => ({
                                            group: 'contentType',
                                            value: contentType.value,
                                        })
                                    ),
                                    filters.licenses.value.map(
                                        (contentType) => ({
                                            group: 'license',
                                            value: contentType.value,
                                        })
                                    ),
                                ].flat(),
                            },
                        }).then((data) => onDone(data));
                    }}
                >
                    {t('save')}
                </Button>
            </DialogActions>
        </Dialog>
    );
}