@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 |
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 |
// ----------------------------------------------------------------------
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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> </div>
)}
</Toolbar>
</AppBar>
);
}
Example #29
Source File: CreateSavedFilter.jsx From Edlib with GNU General Public License v3.0 | 4 votes |
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>
);
}