@mui/material#InputAdornment JavaScript Examples
The following examples show how to use
@mui/material#InputAdornment.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: VisibilityPasswordTextField.js From react-saas-template with MIT License | 6 votes |
function VisibilityPasswordTextField(props) {
const { isVisible, onVisibilityChange, ...rest } = props;
return (
<TextField
{...rest}
type={isVisible ? "text" : "password"}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="Toggle password visibility"
onClick={() => {
onVisibilityChange(!isVisible);
}}
onMouseDown={(event) => {
event.preventDefault();
}}
size="large">
{isVisible ? <VisibilityIcon /> : <VisibilityOffIcon />}
</IconButton>
</InputAdornment>
),
}}
></TextField>
);
}
Example #2
Source File: StripeCardForm.js From react-saas-template with MIT License | 5 votes |
function StripeCardForm(props) {
const {
stripeError,
setStripeError,
amount,
amountError,
onAmountChange,
name,
setName
} = props;
return (
<Grid container spacing={2} justifyContent="space-between">
<Grid item xs={8}>
<TextField
variant="outlined"
margin="none"
required
label="Your Name"
value={name}
onChange={event => {
setName(event.target.value);
}}
fullWidth
autoFocus
autoComplete="off"
type="text"
/>
</Grid>
<Grid item xs={4}>
<TextField
required
value={amount}
onChange={event => {
onAmountChange(parseInt(event.target.value));
}}
error={amountError ? true : false}
helperText={amountError}
variant="outlined"
fullWidth
type="number"
margin="none"
label="Amount"
InputProps={{
startAdornment: <InputAdornment position="start">$</InputAdornment>
}}
/>
</Grid>
<Grid item xs={12}>
<StripeTextField
margin="none"
fullWidth
label="Credit Card"
error={stripeError ? true : false}
helperText={stripeError}
variant="outlined"
required
StripeElement={CardElement}
onChange={() => {
if (stripeError) {
setStripeError("");
}
}}
></StripeTextField>
</Grid>
</Grid>
);
}
Example #3
Source File: Searchbar.js From Django-REST-Framework-React-BoilerPlate with MIT License | 5 votes |
// ----------------------------------------------------------------------
export default function Searchbar() {
const [isOpen, setOpen] = useState(false);
const handleOpen = () => {
setOpen((prev) => !prev);
};
const handleClose = () => {
setOpen(false);
};
return (
<ClickAwayListener onClickAway={handleClose}>
<div>
{!isOpen && (
<IconButton onClick={handleOpen}>
<Iconify icon="eva:search-fill" width={20} height={20} />
</IconButton>
)}
<Slide direction="down" in={isOpen} mountOnEnter unmountOnExit>
<SearchbarStyle>
<Input
autoFocus
fullWidth
disableUnderline
placeholder="Search…"
startAdornment={
<InputAdornment position="start">
<Iconify icon="eva:search-fill" sx={{ color: 'text.disabled', width: 20, height: 20 }} />
</InputAdornment>
}
sx={{ mr: 1, fontWeight: 'fontWeightBold' }}
/>
<Button variant="contained" onClick={handleClose}>
Search
</Button>
</SearchbarStyle>
</Slide>
</div>
</ClickAwayListener>
);
}
Example #4
Source File: UserListToolbar.js From Django-REST-Framework-React-BoilerPlate with MIT License | 5 votes |
export default function UserListToolbar({ numSelected, filterName, onFilterName }) {
return (
<RootStyle
sx={{
...(numSelected > 0 && {
color: 'primary.main',
bgcolor: 'primary.lighter',
}),
}}
>
{numSelected > 0 ? (
<Typography component="div" variant="subtitle1">
{numSelected} selected
</Typography>
) : (
<SearchStyle
value={filterName}
onChange={onFilterName}
placeholder="Search user..."
startAdornment={
<InputAdornment position="start">
<Iconify icon="eva:search-fill" sx={{ color: 'text.disabled', width: 20, height: 20 }} />
</InputAdornment>
}
/>
)}
{numSelected > 0 ? (
<Tooltip title="Delete">
<IconButton>
<Iconify icon="eva:trash-2-fill" />
</IconButton>
</Tooltip>
) : (
<Tooltip title="Filter list">
<IconButton>
<Iconify icon="ic:round-filter-list" />
</IconButton>
</Tooltip>
)}
</RootStyle>
);
}
Example #5
Source File: Ldap.js From admin-web with GNU Affero General Public License v3.0 | 5 votes |
render() {
const { classes, t, domain, ldapUsers } = this.props;
const { loading, snackbar, confirming } = this.state;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
return (
<ViewWrapper
topbarTitle={domain.domainname}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Typography variant="h2" className={classes.pageTitle}>
<BackIcon onClick={this.handleNavigation(domain.ID + '/users')} className={classes.backIcon} />
<span className={classes.pageTitleSecondary}>| </span>
{t("LDAP")}
</Typography>
<Grid container justifyContent="center">
<TextField
autoFocus
placeholder={t("Search LDAP")}
onChange={this.handleLdapSearch}
variant="outlined"
color="primary"
fullWidth
className={classes.searchTf}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="primary"/>
</InputAdornment>
),
}}
/>
</Grid>
{ldapUsers.length > 0 && <Paper elevation={1}>
<List>
{ldapUsers.map((user, idx) => <React.Fragment key={idx}>
<ListItem >
<ListItemText
primary={user.name}
primaryTypographyProps={{ color: 'primary' }}
secondary={user.email}
/>
{writable && <IconButton onClick={this.handleImport(user)} size="large">
<Import />
</IconButton>}
</ListItem>
<Divider />
</React.Fragment>
)}
</List>
</Paper>}
<Grid container justifyContent="center" className={classes.loaderContainer}>
<Grow
in={loading}
timeout={{
appear: 500,
enter: 10,
exit: 10,
}}
>
<CircularProgress color="primary" size={40}/>
</Grow>
</Grid>
<ImportDialog
open={!!confirming}
user={confirming || {}}
onSuccess={this.handleSuccess}
onClose={this.handleClose}
onError={this.handleError}
/>
</ViewWrapper>
);
}
Example #6
Source File: index.js From neutron with Mozilla Public License 2.0 | 4 votes |
SectionSavedPassword = () => {
const [credentials, setCredentials] = useState([]);
const [revealPasswords, setRevealPasswords] = useState({});
const reloadCredentials = useCallback(() => {
getAllCredentialsAsync()
.then((_credentials) => {
setCredentials(_credentials);
})
.catch((err) => {
// eslint-disable-next-line no-console
console.log(err);
});
}, [setCredentials]);
useEffect(() => {
reloadCredentials();
}, [reloadCredentials]);
useEffect(() => {
ipcRenderer.removeAllListeners('password-credentials-added');
ipcRenderer.on('password-credentials-added', () => {
reloadCredentials();
});
return () => {
ipcRenderer.removeAllListeners('password-credentials-added');
};
}, [reloadCredentials]);
return (
<List disablePadding dense>
{credentials.length < 1 ? (
<ListItem disabled>
<ListItemText primary="Saved passwords will appear here." />
</ListItem>
) : (
<>
<ListItem>
<Table size="small" aria-label="Saved Passwords">
<TableHead>
<TableRow>
<TableCell>Website</TableCell>
<TableCell align="right">Username</TableCell>
<TableCell align="right">Password</TableCell>
<TableCell align="right" />
</TableRow>
</TableHead>
<TableBody>
{credentials.map((row) => {
const key = `${row.domain}-${row.username}`;
return (
<TableRow key={key}>
<TableCell component="th" scope="row">
{row.domain}
</TableCell>
<TableCell align="right">
<TextField
value={row.username}
margin="dense"
fullWidth
variant="outlined"
inputProps={{ 'aria-label': 'Username' }}
disabled
/>
</TableCell>
<TableCell align="right">
<FormControl variant="outlined">
<OutlinedInput
id="outlined-adornment-password"
type={revealPasswords[key] ? 'text' : 'password'}
defaultValue={row.password}
margin="dense"
endAdornment={(
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={() => {
setRevealPasswords({
...revealPasswords,
[key]: !revealPasswords[key],
});
}}
edge="end"
size="large"
>
{revealPasswords[key]
? <VisibilityIcon /> : <VisibilityOffIcon />}
</IconButton>
</InputAdornment>
)}
inputProps={{ 'aria-label': 'Password' }}
fullWidth
onChange={(e) => {
const newPassword = e.target.value;
saveCredentialAsync(row.domain, row.username, newPassword, row.id)
.then(() => reloadCredentials())
.catch((err) => {
// eslint-disable-next-line no-console
console.log(err);
});
}}
/>
</FormControl>
</TableCell>
<TableCell align="right">
<Tooltip title="Remove">
<IconButton
aria-label="Remove"
size="small"
onClick={() => {
deleteCredentialAsync(row.id)
.then(() => reloadCredentials())
.catch((err) => {
// eslint-disable-next-line no-console
console.log(err);
});
}}
>
<ClearIcon />
</IconButton>
</Tooltip>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</ListItem>
<ListItem disabled>
<ListItemText primary={`Passwords are stored encrypted locally on disk with the master key stored securely in ${getKeytarVaultName()}.`} />
</ListItem>
</>
)}
</List>
);
}
Example #7
Source File: ResourcePage.jsx From Edlib with GNU General Public License v3.0 | 4 votes |
ResourcePage = ({ filters, showDeleteButton = false }) => {
const { t } = useTranslation();
const theme = useTheme();
const forceGridView = useMediaQuery(theme.breakpoints.down(1400));
const [filtersExpanded, setFiltersExpanded] = React.useState(false);
const [sortingOrder, setSortingOrder] = React.useState(useDefaultOrder());
const [page, setPage] = React.useState(0);
const [pageSize, setPageSize] = React.useState(40);
const [_isGridView, setIsGridView] = React.useState(false);
const filterUtils = FilterUtils(filters);
const isGridView = forceGridView || _isGridView;
const { error, loading, resources, pagination, refetch, filterCount } =
useGetResources(
React.useMemo(
() => ({
limit: pageSize,
offset: page * pageSize,
resourceCapabilities: ['view'],
orderBy: sortingOrder,
...(filters && filters.requestData),
}),
[page, sortingOrder, filters && filters.requestData, pageSize]
)
);
React.useEffect(() => {
setPage(0);
}, [sortingOrder, filters.requestData]);
const setSearch = React.useCallback(
(searchText) => {
filters.setSearchInput(searchText);
if (sortingOrder !== resourceOrders.RELEVANT_DESC) {
setSortingOrder(resourceOrders.RELEVANT_DESC);
}
},
[filters, sortingOrder, setSortingOrder]
);
const sortOrderDropDown = (
<FormControl variant="outlined">
<InputLabel>{t('Sortering')}</InputLabel>
<Select
MenuProps={{
style: { zIndex: 2051 },
anchorOrigin: {
vertical: 'bottom',
horizontal: 'center',
},
transformOrigin: {
vertical: 'top',
horizontal: 'center',
},
}}
value={sortingOrder}
onChange={(e) => setSortingOrder(e.target.value)}
label={getOrderText(t, sortingOrder)}
>
{[
resourceOrders.RELEVANT_DESC,
resourceOrders.VIEWS_DESC,
resourceOrders.VIEWS_ASC,
resourceOrders.UPDATED_AT_DESC,
resourceOrders.UPDATED_AT_ASC,
].map((value, index) => (
<MenuItem key={index} value={value}>
{getOrderText(t, value)}
</MenuItem>
))}
</Select>
</FormControl>
);
return (
<StyledResourcePage>
<Box
sx={[
{
backgroundColor: 'white',
boxShadow: '5px 0 5px 0 rgba(0, 0, 0, 0.16)',
overflowY: 'auto',
position: {
xs: 'absolute',
md: 'initial',
},
right: {
xs: '110%',
md: 'initial',
},
zIndex: {
xs: 2,
md: 'initial',
},
},
filtersExpanded && {
width: '100vw',
right: 'unset',
left: 0,
},
]}
>
<ResourceFilters filters={filters} filterCount={filterCount} />
</Box>
<Box
onClick={() => setFiltersExpanded(false)}
sx={[
{
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
zIndex: 1,
cursor: 'pointer',
},
filtersExpanded && {
display: {
xs: 'block',
md: 'none',
},
},
!filtersExpanded && {
display: 'none',
},
]}
/>
<div className="pageContent">
<div className="contentOptions">
<Box display="flex" paddingRight={1}>
<Box
paddingRight={1}
style={{
width: 400,
}}
>
<TextField
fullWidth
label={t('Søk')}
variant="outlined"
value={filters.searchInput}
onChange={(e) => setSearch(e.target.value)}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<Icon>
<SearchIcon />
</Icon>
</InputAdornment>
),
}}
/>
</Box>
<div
style={{
width: 200,
}}
>
<LanguageDropdown
language={
filters.languages.length !== 0
? filters.languages[0]
: null
}
setLanguage={(value) =>
filters.languages.setValue(
value ? [value] : []
)
}
/>
</div>
</Box>
<div>{sortOrderDropDown}</div>
</div>
<Box
pt={1}
sx={{
display: {
xs: 'block',
md: 'none',
},
}}
>
<Button
color="primary"
variant="contained"
onClick={() => setFiltersExpanded(!filtersExpanded)}
startIcon={<TuneIcon />}
>
{t('filter', { count: 2 })}
</Button>
</Box>
<Box
display="flex"
flexDirection="row"
justifyContent="space-between"
pt={1}
>
<Box>
<FilterChips
chips={filterUtils.getChipsFromFilters()}
/>
</Box>
<Box>
{!forceGridView && (
<IconButton
onClick={() => setIsGridView(!isGridView)}
size="large"
>
{isGridView ? <ListIcon /> : <ViewModuleIcon />}
</IconButton>
)}
</Box>
</Box>
<Content>
<div style={{ marginTop: 20 }}>
{loading && <Spinner />}
{error && <div>{t('Noe skjedde')}</div>}
{!loading && !error && resources && !isGridView && (
<ResourceTable
totalCount={pagination.totalCount}
resources={resources}
refetch={refetch}
showDeleteButton={showDeleteButton}
sortingOrder={sortingOrder}
setSortingOrder={setSortingOrder}
/>
)}
{!loading && !error && resources && isGridView && (
<CardView
totalCount={pagination.totalCount}
resources={resources}
refetch={refetch}
showDeleteButton={showDeleteButton}
/>
)}
</div>
{pagination && (
<PaginationWrapper>
<TablePagination
component="div"
count={pagination.totalCount}
page={page}
onPageChange={(e, page) => {
setPage(page);
}}
rowsPerPage={pageSize}
onRowsPerPageChange={(e, pageSize) => {
setPageSize(pageSize);
setPage(0);
}}
rowsPerPageOptions={[40]}
/>
</PaginationWrapper>
)}
</Content>
</div>
</StyledResourcePage>
);
}
Example #8
Source File: Users.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, users, domain, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, snackbar, adding, deleting } = tableState;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
const { checking, taskMessage, taskID } = this.state;
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Users")}
subtitle={t('users_sub')}
href="https://docs.grommunio.com/admin/administration.html#users"
snackbar={snackbar || this.state.snackbar}
onSnackbarClose={this.handleSnackbarClose}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
className={classes.newButton}
disabled={!writable}
>
{t('New user')}
</Button>
<Button
variant="contained"
color="primary"
onClick={this.handleNavigation(domain.ID + '/ldap')}
className={classes.newButton}
disabled={!writable}
>
{t('Search in LDAP')}
</Button>
<Tooltip placement="top" title="Synchronize imported users for this domain">
<Button
variant="contained"
color="primary"
className={classes.newButton}
onClick={this.handleUserSync(false)}
disabled={!writable}
>
{t('Sync LDAP users')}
</Button>
</Tooltip>
<Tooltip
placement="top"
title="Import new users from LDAP for this domain and synchronize previously imported ones"
>
<Button
variant="contained"
color="primary"
className={classes.newButton}
onClick={this.handleUserSync(true)}
disabled={!writable}
>
{t('Import LDAP users')}
</Button>
</Tooltip>
<Tooltip
placement="top"
title="Check status of imported users of this domain"
>
<Button
variant="contained"
color="primary"
onClick={this.checkUsers}
disabled={!writable}
>
{t('Check LDAP users')}
</Button>
</Tooltip>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingUser", { count: users.Users.length })}
</Typography>
<Paper className={classes.tablePaper} elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>
<TableSortLabel
active={orderBy === 'username'}
align="left"
direction={orderBy === 'username' ? order : 'asc'}
onClick={handleRequestSort('username')}
color="primary"
sx={{
color: 'text.primary',
}}
>
{t('Username')}
</TableSortLabel>
</TableCell>
{this.columns.map(column =>
<TableCell key={column.value}>
{t(column.label)}
</TableCell>
)}
<TableCell padding="checkbox"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.Users.map((obj, idx) => {
const properties = obj.properties || {};
return (
<TableRow key={idx} hover onClick={handleEdit('/' + domain.ID + '/users/' + obj.ID)}>
<TableCell>{obj.username}</TableCell>
<TableCell>{properties.displayname}</TableCell>
<TableCell>{this.getStatus(obj.status)}</TableCell>
<TableCell>{this.getType(properties.displaytypeex)}</TableCell>
<TableCell>{obj.ldapID || ''}</TableCell>
<TableCell>{this.getMaxSizeFormatting(properties.storagequotalimit)}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
{(users.Users.length < users.count) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper>
<AddUser
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
domain={domain}
onClose={handleAddingClose}
/>
<DeleteUser
open={!!deleting}
onSuccess={handleDeleteSuccess}
onClose={handleDeleteClose}
onError={handleDeleteError}
domainID={domain.ID}
user={deleting}
/>
<CheckLdapDialog
open={checking}
onClose={this.handleCheckClose}
onError={handleDeleteError}
/>
<TaskCreated
message={taskMessage}
taskID={taskID}
onClose={this.handleTaskClose}
/>
</TableViewContainer>
);
}
Example #9
Source File: TaskQ.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, taskq, tableState, handleMatch, handleRequestSort,
handleEdit } = this.props;
const { order, orderBy, match, snackbar } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<TableViewContainer
headline={t("Task queue")}
href="https://docs.grommunio.com/admin/administration.html#taskq"
// subtitle={t("taskq_sub")}
snackbar={snackbar || this.state.snackbar}
onSnackbarClose={this.handleSnackbarClose}
>
<Grid container alignItems="flex-end" className={classes.chipGrid}>
<Chip
className={classes.chip}
label={t(taskq.running ? "Running" : "Not running")}
color={taskq.running ? "success" : "secondary"}
/>
<Chip
className={classes.chip}
label={"Queued: " + taskq.queued}
color={"primary"}
/>
<Chip
className={classes.chip}
label={"Workers: " + taskq.workers}
color={"primary"}
/>
</Grid>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={this.handleStart}
disabled={!writable || taskq.running}
>
{t("Start server")}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search tasks")}
variant={"outlined"}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingTaskq", { count: taskq.Tasks.length })}
</Typography>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column) => (
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : "asc"}
onClick={handleRequestSort(column.value)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{taskq.Tasks.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/taskq/' + obj.ID)}>
<TableCell>{obj.command}</TableCell>
<TableCell>{t(this.getTaskState(obj.state))}</TableCell>
<TableCell>{obj.message}</TableCell>
<TableCell>{obj.created ? setDateTimeString(obj.created) : ''}</TableCell>
<TableCell>{obj.updated ? setDateTimeString(obj.updated) : ''}</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{taskq.Tasks.length < taskq.count && (
<Grid container justifyContent="center">
<CircularProgress
color="primary"
className={classes.circularProgress}
/>
</Grid>
)}
</Paper>
</TableViewContainer>
);
}
Example #10
Source File: Sync.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, sync } = this.props;
const { snackbar, sortedDevices, order, orderBy, match, showPush, onlyActive,
filterEnded, filterUpdated } = this.state;
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={<>
{t("Mobile devices")}
<IconButton
size="small"
href="https://docs.grommunio.com/admin/administration.html#mobile-devices"
target="_blank"
>
<HelpOutline fontSize="small"/>
</IconButton>
</>
}
subtitle={t('sync_sub')}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<FormControlLabel
control={
<Checkbox
checked={showPush}
onChange={this.handleCheckbox('showPush')}
color="primary"
/>
}
label={t('Show push connections')}
/>
<FormControlLabel
control={
<Checkbox
checked={onlyActive}
onChange={this.handleCheckbox('onlyActive')}
color="primary"
/>
}
label={t('Only show active connections')}
/>
<TextField
value={filterUpdated}
onChange={this.handleInput('filterUpdated')}
label={t("Last updated (seconds)")}
className={classes.select}
select
color="primary"
fullWidth
>
<MenuItem value={60}>10</MenuItem>
<MenuItem value={60}>30</MenuItem>
<MenuItem value={60}>60</MenuItem>
<MenuItem value={120}>120</MenuItem>
</TextField>
<TextField
value={filterEnded}
onChange={this.handleInput('filterEnded')}
label={t("Last ended (seconds)")}
className={classes.select}
select
color="primary"
fullWidth
>
<MenuItem value={20}>3</MenuItem>
<MenuItem value={20}>5</MenuItem>
<MenuItem value={20}>10</MenuItem>
<MenuItem value={20}>20</MenuItem>
</TextField>
<div className={classes.actions}>
<TextField
value={match}
onChange={this.handleInput('match')}
placeholder={t("Filter")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<SyncStatistics data={sync}/>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column) => (
<TableCell
key={column.value}
padding={column.padding || 'normal'}
>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={order}
onClick={this.handleSort(column.value, column.type, true)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
))}
<TableCell padding="checkbox">
{t('Push')}
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{(sortedDevices || sync).map((obj, idx) => {
const timePast = getTimePast(obj.diff);
const matches = this.getMatch(obj);
return matches ? (
<Tooltip key={idx} placement="top" title={obj.devtype + ' / ' + obj.devagent}>
<TableRow hover className={this.getRowClass(obj, obj.diff)}>
<TableCell className={classes.cell} padding="checkbox">{obj.pid || ''}</TableCell>
<TableCell className={classes.cell} padding="checkbox">{obj.ip || ''}</TableCell>
<TableCell className={classes.cell}>{obj.user || ''}</TableCell>
<TableCell className={classes.cell}>{getStringFromCommand(obj.command)}</TableCell>
<TableCell className={classes.cell}>{timePast}</TableCell>
<TableCell className={classes.cell}>{obj.devid || ''}</TableCell>
<TableCell className={classes.cell}>{obj.addinfo || ''}</TableCell>
<TableCell className={classes.cell} padding="checkbox">
{obj.push ? <CheckCircleOutlined /> : <HighlightOffOutlined />}
</TableCell>
</TableRow>
</Tooltip>
) : null;
})}
</TableBody>
</Table>
</Paper>
</TableViewContainer>
);
}
Example #11
Source File: Servers.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, servers, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, adding, snackbar, deleting } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={<span>
{t("Servers")}
<IconButton
size="small"
href="https://docs.grommunio.com/admin/administration.html#id1"
target="_blank"
>
<HelpOutline fontSize="small"/>
</IconButton>
</span>
}
snackbar={snackbar || this.state.snackbar}
onSnackbarClose={this.handleSnackbarClose}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
disabled={!writable}
>
{t("New server")}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<div>
<TextField
value={servers.policy || 'round-robin'}
onChange={this.handlePolicyChange}
select
label="Selection policy"
className={classes.policy}
>
<MenuItem value={"round-robin"}>round-robin</MenuItem>
<MenuItem value={"balanced"}>balanced</MenuItem>
<MenuItem value={"first"}>first</MenuItem>
<MenuItem value={"last"}>last</MenuItem>
<MenuItem value={"random"}>random</MenuItem>
</TextField>
</div>
<Typography className={classes.count} color="textPrimary">
{t("showingServers", { count: servers.Servers.length })}
</Typography>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column) => (
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : "asc"}
onClick={handleRequestSort(column.value)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
))}
<TableCell padding="checkbox" />
</TableRow>
</TableHead>
<TableBody>
{servers.Servers.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/servers/' + obj.ID)}>
<TableCell>{obj.hostname}</TableCell>
<TableCell>{obj.extname}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{(servers.Servers.length < servers.count) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper>
<AddServer
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
onClose={handleAddingClose}
/>
<GeneralDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.hostname}
id={deleting.ID}
/>
</TableViewContainer>
);
}
Example #12
Source File: Roles.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, roles, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, match, adding, snackbar, deleting } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={<span>
{t("Roles")}
<IconButton
size="small"
href="https://docs.grommunio.com/admin/administration.html#id1"
target="_blank"
>
<HelpOutline fontSize="small"/>
</IconButton>
</span>
}
subtitle={t('roles_sub')}
snackbar={snackbar}
onSnackbarClose={clearSnackbar}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
disabled={!writable}
>
{t("New role")}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingRoles", { count: roles.Roles.length })}
</Typography>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>
<TableSortLabel
active
align="left"
direction={order}
onClick={handleRequestSort('name')}
>
{t('Name')}
</TableSortLabel>
</TableCell>
<TableCell>{t('Description')}</TableCell>
<TableCell>{t('Permissions')}</TableCell>
<TableCell padding="checkbox"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{roles.Roles.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/roles/' + obj.ID)}>
<TableCell>{obj.name}</TableCell>
<TableCell>{obj.description}</TableCell>
<TableCell>{obj.permissions.map(perm => perm.permission).toString()}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{(roles.Roles.length < roles.count) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper>
<AddRoles
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
onClose={handleAddingClose}
/>
<GeneralDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.name}
id={deleting.ID}
/>
</TableViewContainer>
);
}
Example #13
Source File: Orgs.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, orgs, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, snackbar, adding, deleting } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Organizations")}
href="https://docs.grommunio.com/admin/administration.html#organizations"
subtitle={t("orgs_sub")}
snackbar={snackbar}
onSnackbarClose={clearSnackbar}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
disabled={!writable}
>
{t("New organization")}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search organizations")}
variant={"outlined"}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingOrgs", { count: orgs.Orgs.length })}
</Typography>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column) => (
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : "asc"}
onClick={handleRequestSort(column.value)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
))}
<TableCell padding="checkbox" />
</TableRow>
</TableHead>
<TableBody>
{orgs.Orgs.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/orgs/' + obj.ID)}>
<TableCell>{obj.name}</TableCell>
<TableCell>{obj.description}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error" />
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{orgs.Orgs.length < orgs.count && (
<Grid container justifyContent="center">
<CircularProgress
color="primary"
className={classes.circularProgress}
/>
</Grid>
)}
</Paper>
<AddOrg
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
onClose={handleAddingClose}
/>
<GeneralDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.name}
id={deleting.ID}
/>
</TableViewContainer>
);
}
Example #14
Source File: MLists.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, mLists, domain, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, snackbar, adding, deleting } = tableState;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Mail lists")}
subtitle={t('mlists_sub')}
href="https://docs.grommunio.com/admin/administration.html#mail-lists"
snackbar={snackbar}
onSnackbarClose={clearSnackbar}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
className={classes.newButton}
disabled={!writable}
>
{t('New mail list')}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingMLists", { count: mLists.MLists.length })}
</Typography>
<Paper className={classes.tablePaper} elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map(column =>
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : 'asc'}
onClick={handleRequestSort(column.value)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
)}
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{mLists.MLists.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/' + domain.ID + '/mailLists/' + obj.ID)}>
<TableCell>{obj.listname}</TableCell>
<TableCell>{this.listTypes[obj.listType]}</TableCell>
<TableCell>{this.listPrivileges[obj.listPrivilege]}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{(mLists.MLists.length < mLists.count) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper>
<AddMList
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
domain={domain}
onClose={handleAddingClose}
/>
<DomainDataDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.listname}
id={deleting.ID}
domainID={domain.ID}
/>
</TableViewContainer>
);
}
Example #15
Source File: GlobalUsers.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, users, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, snackbar, adding, deleting } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
const { checking } = this.state;
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Users")}
subtitle={t("globalusers_sub")}
href="https://docs.grommunio.com/admin/administration.html#users"
snackbar={snackbar}
onSnackbarClose={clearSnackbar}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
className={classes.newButton}
disabled={!writable}
>
{t('New user')}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingUser", { count: users.Users.length })}
</Typography>
<Paper className={classes.tablePaper} elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>
<TableSortLabel
active={orderBy === 'username'}
align="left"
direction={orderBy === 'username' ? order : 'asc'}
onClick={handleRequestSort('username')}
>
{t('Username')}
</TableSortLabel>
</TableCell>
{this.columns.map(column =>
<TableCell key={column.value}>
{t(column.label)}
</TableCell>
)}
<TableCell padding="checkbox"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.Users.map((obj, idx) => {
return (
<TableRow key={idx} hover onClick={handleEdit('/' + obj.domainID + '/users/' + obj.ID)}>
<TableCell>{obj.username}</TableCell>
<TableCell>{obj.ldapID || ''}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
{(users.Users.length < users.count) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper>
<AddGlobalUser
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
onClose={handleAddingClose}
/>
<DeleteUser
open={!!deleting}
onSuccess={handleDeleteSuccess}
onClose={handleDeleteClose}
onError={handleDeleteError}
user={deleting}
domainID={deleting.domainID || -1}
/>
<CheckLdapDialog
open={checking}
onClose={this.handleCheckClose}
onError={handleDeleteError}
/>
</TableViewContainer>
);
}
Example #16
Source File: Folders.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, folders, domain, tableState, handleMatch,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { Folders, moreDataAvailable } = folders;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
const { match, snackbar, adding, deleting } = tableState;
const { hierarchy } = this.state;
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Folders")}
subtitle={t('folders_sub')}
href="https://docs.grommunio.com/admin/administration.html#folders"
snackbar={snackbar}
onSnackbarClose={clearSnackbar}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
disabled={!writable}
>
{t('New folder')}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingFolders", { count: Folders.length + (hierarchy.length === 1 ? 1 : 0) })}
</Typography>
<Breadcrumbs aria-label="breadcrumb" className={classes.breadcumbs}>
{hierarchy.map((folder, idx) =>
<Link
key={folder.folderid}
underline="hover"
color="primary"
onClick={this.handleBreadcrumb(folder, idx)}
className={classes.link}
>
{folder.displayname}
</Link>
)}
</Breadcrumbs>
<Paper className={classes.tablePaper} elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{['Folder name', 'Comment', 'Creation time', ''].map(headerName =>
<TableCell key={headerName}>{t(headerName)}</TableCell>
)}
</TableRow>
</TableHead>
<TableBody>
{hierarchy.length === 1 && <TableRow>
<TableCell>{IPM_SUBTREE_OBJECT.displayname}</TableCell>
<TableCell>{t(IPM_SUBTREE_OBJECT.comment)}</TableCell>
<TableCell></TableCell>
<TableCell align="right">
<IconButton onClick={handleEdit('/' + domain.ID + '/folders/' + IPM_SUBTREE_ID)} size="large">
<Edit color="primary"/>
</IconButton>
</TableCell>
</TableRow>}
{Folders.map((obj, idx) =>
<TableRow hover onClick={this.handleFetchChildren(obj)} key={idx}>
<TableCell>{obj.displayname}</TableCell>
<TableCell>{obj.comment}</TableCell>
<TableCell>{obj.creationtime}</TableCell>
<TableCell align="right">
<IconButton onClick={handleEdit('/' + domain.ID + '/folders/' + obj.folderid)} size="large">
<Edit color="primary"/>
</IconButton>
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{(moreDataAvailable) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper>
<AddFolder
open={adding}
onClose={handleAddingClose}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
domain={domain}
parentID={hierarchy[hierarchy.length - 1].folderid}
/>
<DeleteFolder
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.displayname}
id={deleting.folderid}
domainID={domain.ID}
/>
</TableViewContainer>
);
}
Example #17
Source File: Domains.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, domains, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { showDeleted } = this.state;
const { order, orderBy, match, snackbar, adding, deleting } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
const filteredDomains = domains.Domains.filter(d => d.domainStatus !== 3 || showDeleted);
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Domains")}
subtitle={t('domains_sub')}
snackbar={snackbar}
href="https://docs.grommunio.com/admin/administration.html#domains"
onSnackbarClose={clearSnackbar}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
disabled={!writable}
>
{t("New domain")}
</Button>
<div className={classes.actions}>
<FormControlLabel
label={t("Show deactivated")}
control={
<Checkbox
checked={showDeleted || false}
onChange={this.handleCheckbox("showDeleted")}
/>
}
/>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant={"outlined"}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingDomains", { count: filteredDomains.length })}
</Typography>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column) => (
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : "asc"}
onClick={handleRequestSort(column.value)}
disabled={column.value === 'activeUsers'}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
))}
<TableCell padding="checkbox" />
</TableRow>
</TableHead>
<TableBody>
{filteredDomains.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit("/domains/" + obj.ID)}>
<TableCell>
{obj.domainname}{obj.domainname !== obj.displayname ? ` (${obj.displayname}) ` : " "}
{obj.domainStatus === 3 ? `[${t("Deactivated")}]` : ""}
</TableCell>
<TableCell>{obj.address}</TableCell>
<TableCell>{obj.title}</TableCell>
<TableCell>{obj.activeUsers}</TableCell>
<TableCell>{obj.maxUser}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error" />
</IconButton>}
</TableCell>
</TableRow>)
}
</TableBody>
</Table>
{domains.Domains.length < domains.count && (
<Grid container justifyContent="center">
<CircularProgress
color="primary"
className={classes.circularProgress}
/>
</Grid>
)}
</Paper>
<AddDomain
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
onClose={handleAddingClose}
/>
<DeleteDomain
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.domainname}
id={deleting.ID}
/>
</TableViewContainer>
);
}
Example #18
Source File: DBConf.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, services, commands } = this.props;
const { adding, configuring, snackbar, match, tab, deleting } = this.state;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<TableViewContainer
headline={t("Configuration DB")}
href="https://docs.grommunio.com/admin/administration.html#db-configuration"
subtitle={t('dbconf_sub')}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={() => this.setState({ adding: true })}
disabled={!writable}
>
{t("Create file")}
</Button>
<Button
variant="contained"
color="primary"
onClick={() => this.setState({ configuring: true })}
className={classes.button}
disabled={!writable}
>
{t("Configure grommunio-dbconf")}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={this.handleMatch}
placeholder={t("search services")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Tabs
textColor="primary"
indicatorColor="primary"
value={tab}
onChange={this.handleTab}
>
<Tab value={0} label="Services" />
<Tab value={1} label="Commands" />
</Tabs>
</Grid>
{tab === 0 ? <Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>
{t('Name')}
</TableCell>
<TableCell padding="checkbox"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{services.filter(s => s.includes(match)).map((service, idx) =>
<TableRow onClick={this.handleNavigation('dbconf/' + service)} key={idx} hover>
<TableCell>{service}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={this.handleDelete(service)} size="large">
<Delete color="error" />
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</Paper> : <Paper className={classes.paper}>
<Typography variant="h6">Key</Typography>
{commands.key.length > 0 ? commands.key.map((key, idx) =>
<pre className={classes.pre} key={idx}>
<code key={idx}>{key}</code>
</pre>
) : <Typography><i>none</i></Typography>}
<Typography className={classes.title} variant="h6">File</Typography>
{commands.file.length > 0 ? commands.file.map((key, idx) =>
<pre className={classes.pre} key={idx}>
<code>{key}</code>
</pre>
) : <Typography><i>none</i></Typography>}
<Typography className={classes.title} variant="h6">Service</Typography>
{commands.service.length > 0 ? commands.service.map((key, idx) =>
<pre className={classes.pre} key={idx}>
<code>{key}</code>
</pre>
) : <Typography><i>none</i></Typography>}
</Paper>}
<GeneralDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={this.handleDeleteSuccess}
onError={this.handleDeleteError}
onClose={this.handleDeleteClose}
item={deleting}
id={deleting}
/>
<UploadServiceFile
open={adding}
onClose={this.handleAddingClose}
onError={this.handleAddingError}
onSuccess={this.handleAddingSuccess}
/>
<CreateDbconfFile
open={configuring}
onClose={this.handleAddingClose}
onError={this.handleAddingError}
onSuccess={this.handleAddingSuccess}
/>
</TableViewContainer>
);
}
Example #19
Source File: Classes.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, _classes, domain, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, snackbar, adding, deleting } = tableState;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
const { tab, root } = this.state;
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Groups")}
subtitle={t("groups_sub")}
href="https://docs.grommunio.com/admin/administration.html#groups"
snackbar={snackbar || this.state.snackbar}
onSnackbarClose={this.handleSnackbarClose}
baseRef={tc => (this.treeContainer = tc)}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
className={classes.newButton}
disabled={!writable}
>
{t('New group')}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Tabs
indicatorColor="primary"
textColor="primary"
className={classes.tabs}
onChange={this.handleTab}
value={tab}
>
<Tab value={0} label={t("List")} />
<Tab value={1} label={t("Tree")} />
</Tabs>
{!tab && <Typography className={classes.count} color="textPrimary">
{t("showingGroups", { count: _classes.Classes.length })}
</Typography>}
{!tab ? <Paper className={classes.tablePaper} elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map(column =>
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : 'asc'}
onClick={handleRequestSort(column.value)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
)}
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{_classes.Classes.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/' + domain.ID + '/classes/' + obj.ID)}>
<TableCell>{obj.classname}</TableCell>
<TableCell>{obj.listname}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{(_classes.Classes.length < _classes.count) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper> :
<>
<FormControl className={classes.select}>
<InputLabel variant="standard">{t("Root group")}</InputLabel>
<Select
fullWidth
value={root > -1 ? root : ''}
onChange={this.handleRootSelect}
input={<Input />}
placeholder={t('Select root group')}
>
{_classes.Trees.map((tree, idx) => (
<MenuItem key={idx} value={idx}>
{tree.name}
</MenuItem>
))}
</Select>
</FormControl>
<div className={classes.treeContainer}>
{root !== -1 &&
<Paper style={{ flex: 1 }}>
<Tree
data={_classes.Trees[root]}
orientation="vertical"
renderCustomNodeElement={this.renderNode}
depthFactor={50}
pathFunc="step"
translate={this.getOffset()}
scaleExtent={{
min: 0.1,
max: 2,
}}
separation={{
siblings: 1,
nonSiblings: 2,
}}
onNodeClick={this.handleNodeClicked}
collapsible={false}
/>
</Paper>}
</div>
</>
}
<AddClass
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
domain={domain}
onClose={handleAddingClose}
/>
<DomainDataDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.name}
id={deleting.ID}
domainID={domain.ID}
/>
</TableViewContainer>
);
}
Example #20
Source File: NavigationLinks.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, expandedDomain, location, domains, capabilities } = this.props;
const { filter, tab } = this.state;
const isSysAdmin = capabilities.includes(SYSTEM_ADMIN_READ);
const pathname = location.pathname;
return(
<React.Fragment>
<div className={classes.drawerHeader}>
<img
src={logo}
width="140"
height="32"
alt="grommunio"
onClick={this.handleNavigation('')}
className={classes.logo}
/>
</div>
{isSysAdmin && <Tabs
onChange={(event, tab) => this.setState({ tab: tab })}
value={tab}
className={classes.tabs}
indicatorColor="primary"
textColor="primary"
>
<Tab className={classes.tab} value={0} label={t('Admin')} />
<Tab className={classes.tab} value={1} label={t('Domains')} />
</Tabs>}
{(tab === 1 || !isSysAdmin) &&
<Grid container component="form" autoComplete="off">
<TextField
variant="outlined"
label={t('Search')}
value={filter}
onChange={this.handleTextInput}
InputLabelProps={{
classes: {
root: classes.input,
},
shrink: true,
}}
InputProps={{
classes: { root: classes.input },
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
className={classes.textfield}
/>
</Grid>}
<List className={classes.list}>
{(tab === 1 || !isSysAdmin) &&
domains.map(({ domainname: name, ID, domainStatus }) => {
return name.includes(filter) ?
<React.Fragment key={name}>
<ListItem
onClick={this.handleDrawer(ID)}
button
className={classes.li}
selected={expandedDomain === ID && pathname === '/' + ID}
>
<Grid container alignItems="center">
<Domains className={classes.icon} />
<ListItemText primary={name + (domainStatus === 3 ? ` [${t('Deactivated')}]` : '')} />
</Grid>
</ListItem>
<Collapse in={expandedDomain === ID} unmountOnExit>
<List component="div" disablePadding>
<ListItem
className={classes.li}
button
onClick={this.handleNavigation(ID + '/users')}
selected={expandedDomain === ID &&
pathname.startsWith('/' + ID + '/users')}
>
<Grid container alignItems="center">
<People className={classes.nestedIcon}/>
<ListItemText primary={t('Users')}/>
</Grid>
</ListItem>
<ListItem
className={classes.li}
button
onClick={this.handleNavigation(ID + '/folders')}
selected={expandedDomain === ID &&
pathname.startsWith('/' + ID + '/folders')}
>
<Grid container alignItems="center">
<Folder className={classes.nestedIcon}/>
<ListItemText primary={t('Public folders')}/>
</Grid>
</ListItem>
<ListItem
className={classes.li}
button
onClick={this.handleNavigation(ID + '/classes')}
selected={pathname.startsWith('/' + ID + '/classes')}
>
<Grid container alignItems="center">
<Classes className={classes.nestedIcon}/>
<ListItemText primary={t('Groups')}/>
</Grid>
</ListItem>
<ListItem
className={classes.li}
button
onClick={this.handleNavigation(ID + '/mailLists')}
selected={pathname.startsWith('/' + ID + '/mailLists')}
>
<Grid container alignItems="center">
<MLists className={classes.nestedIcon}/>
<ListItemText primary={t('Mail lists')}/>
</Grid>
</ListItem>
</List>
</Collapse>
</React.Fragment> : null;
})}
{(tab === 0 && !isSysAdmin) && <ListItem
button
onClick={this.handleNavigation('taskq')}
className={classes.li}
selected={pathname.startsWith('/taskq')}
>
<Grid container alignItems="center">
<TaskAlt className={classes.icon}/>
<ListItemText primary={t('Task queue')} />
</Grid>
</ListItem>}
{tab === 0 && isSysAdmin && <React.Fragment>
<Typography variant="inherit" className={classes.subheader}>{t('Overview')}</Typography>
<ListItem
button
onClick={this.handleNavigation('')}
className={classes.li}
selected={pathname === '/'}
>
<Grid container alignItems="center">
<Dashboard className={classes.icon} />
<ListItemText primary="Dashboard"/>
</Grid>
</ListItem>
<Typography variant="inherit" className={classes.subheader}>{t('Management')}</Typography>
<ListItem
className={classes.li}
button
onClick={this.handleNavigation('orgs')}
selected={pathname.startsWith('/orgs')}
>
<Grid container alignItems="center">
<Orgs className={classes.icon}/>
<ListItemText primary={t('Organizations')}/>
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('domains')}
className={classes.li}
selected={pathname.startsWith('/domains')}
>
<Grid container alignItems="center">
<Domains className={classes.icon}/>
<ListItemText primary={t('Domains')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('users')}
className={classes.li}
selected={pathname.startsWith('/users')}
>
<Grid container alignItems="center">
<People className={classes.icon}/>
<ListItemText primary={t('Users')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('roles')}
className={classes.li}
selected={pathname === '/roles'}
>
<Grid container alignItems="center">
<Roles className={classes.icon}/>
<ListItemText primary={t('Roles')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('defaults')}
className={classes.li}
selected={pathname === '/defaults'}
>
<Grid container alignItems="center">
<BackupTable className={classes.icon}/>
<ListItemText primary={t('Defaults')} />
</Grid>
</ListItem>
<Typography variant="inherit" className={classes.subheader}>{t('Configuration')}</Typography>
<ListItem
button
onClick={this.handleNavigation('directory')}
className={classes.li}
selected={pathname === '/directory'}
>
<Grid container alignItems="center">
<Ldap className={classes.icon}/>
<ListItemText primary={t('Directory')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('dbconf')}
className={classes.li}
selected={pathname.startsWith('/dbconf')}
>
<Grid container alignItems="center">
<Storage className={classes.icon}/>
<ListItemText primary={t('Configuration DB')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('servers')}
className={classes.li}
selected={pathname.startsWith('/servers')}
>
<Grid container alignItems="center">
<Dns className={classes.icon}/>
<ListItemText primary={t('Servers')} />
</Grid>
</ListItem>
<Typography variant="inherit" className={classes.subheader}>{t('Monitoring')}</Typography>
<ListItem
button
onClick={this.handleNavigation('logs')}
className={classes.li}
selected={pathname.startsWith('/logs')}
>
<Grid container alignItems="center">
<Logs className={classes.icon}/>
<ListItemText primary={t('Logs')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('mailq')}
className={classes.li}
selected={pathname.startsWith('/mailq')}
>
<Grid container alignItems="center">
<QueryBuilder className={classes.icon}/>
<ListItemText primary={t('Mail queue')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('taskq')}
className={classes.li}
selected={pathname.startsWith('/taskq')}
>
<Grid container alignItems="center">
<TaskAlt className={classes.icon}/>
<ListItemText primary={t('Task queue')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('sync')}
className={classes.li}
selected={pathname.startsWith('/sync')}
>
<Grid container alignItems="center">
<Sync className={classes.icon}/>
<ListItemText primary={t('Mobile devices')} />
</Grid>
</ListItem>
<ListItem
button
onClick={this.handleNavigation('status')}
className={classes.li}
selected={pathname.startsWith('/status')}
>
<Grid container alignItems="center">
<TableChart className={classes.icon}/>
<ListItemText primary={t('Live status')} />
</Grid>
</ListItem>
</React.Fragment>
}
</List>
<div className={classes.background} />
</React.Fragment>
);
}
Example #21
Source File: RegisterForm.js From Django-REST-Framework-React-BoilerPlate with MIT License | 4 votes |
// ----------------------------------------------------------------------
export default function RegisterForm() {
const dispatch = useDispatch();
const navigate = useNavigate();
const userLogin = useSelector((state) => state.userLogin);
const { userInfo } = userLogin;
const userRgister = useSelector((state) => state.userRgister);
const { error: registerError, loading: registerLoading } = userRgister;
const [showPassword, setShowPassword] = useState(false);
const RegisterSchema = Yup.object().shape({
firstName: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('First name required'),
lastName: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('Last name required'),
email: Yup.string().email('Email must be a valid email address').required('Email is required'),
password: Yup.string().required('Password is required'),
});
const formik = useFormik({
initialValues: {
firstName: '',
lastName: '',
email: '',
password: '',
},
validationSchema: RegisterSchema,
onSubmit: () => {
dispatch(register(values.firstName, values.lastName, values.email, values.password));
},
});
const { errors, touched, values, handleSubmit, isSubmitting, getFieldProps } = formik;
useEffect(() => {
if (userInfo) {
navigate('/dashboard/app', { replace: true });
}
}, [navigate, userInfo]);
return (
<FormikProvider value={formik}>
<Form autoComplete="off" noValidate onSubmit={handleSubmit}>
<Stack spacing={3}>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
<TextField
fullWidth
label="First name"
{...getFieldProps('firstName')}
error={Boolean(touched.firstName && errors.firstName)}
helperText={touched.firstName && errors.firstName}
/>
<TextField
fullWidth
label="Last name"
{...getFieldProps('lastName')}
error={Boolean(touched.lastName && errors.lastName)}
helperText={touched.lastName && errors.lastName}
/>
</Stack>
<TextField
fullWidth
autoComplete="username"
type="email"
label="Email address"
{...getFieldProps('email')}
error={Boolean(touched.email && errors.email)}
helperText={touched.email && errors.email}
/>
<TextField
fullWidth
autoComplete="current-password"
type={showPassword ? 'text' : 'password'}
label="Password"
{...getFieldProps('password')}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton edge="end" onClick={() => setShowPassword((prev) => !prev)}>
<Iconify icon={showPassword ? 'eva:eye-fill' : 'eva:eye-off-fill'} />
</IconButton>
</InputAdornment>
),
}}
error={Boolean(touched.password && errors.password)}
helperText={touched.password && errors.password}
/>
{registerError ? (
<Alert severity="error">
<AlertTitle>Register Error</AlertTitle>
{registerError}
</Alert>
) : null}
<LoadingButton
fullWidth
size="large"
type="submit"
variant="contained"
loading={registerLoading ? isSubmitting : null}
>
Register
</LoadingButton>
</Stack>
</Form>
</FormikProvider>
);
}
Example #22
Source File: LoginForm.js From Django-REST-Framework-React-BoilerPlate with MIT License | 4 votes |
// ----------------------------------------------------------------------
export default function LoginForm() {
const dispatch = useDispatch();
const navigate = useNavigate();
const userLogin = useSelector((state) => state.userLogin);
const { error: loginError, loading: loginLoading, userInfo } = userLogin;
const [showPassword, setShowPassword] = useState(false);
const LoginSchema = Yup.object().shape({
email: Yup.string().email('Email must be a valid email address').required('Email is required'),
password: Yup.string().required('Password is required'),
});
const formik = useFormik({
initialValues: {
email: '',
password: '',
},
validationSchema: LoginSchema,
onSubmit: () => {
dispatch(login(values.email, values.password));
},
});
const { errors, touched, values, isSubmitting, handleSubmit, getFieldProps } = formik;
const handleShowPassword = () => {
setShowPassword((show) => !show);
};
useEffect(() => {
if (userInfo) {
navigate('/dashboard/app', { replace: true });
}
}, [navigate, userInfo]);
return (
<FormikProvider value={formik}>
<Form autoComplete="off" noValidate onSubmit={handleSubmit}>
<Stack spacing={3}>
<TextField
fullWidth
autoComplete="username"
type="email"
label="Email address"
{...getFieldProps('email')}
error={Boolean(touched.email && errors.email)}
helperText={touched.email && errors.email}
/>
<TextField
fullWidth
autoComplete="current-password"
type={showPassword ? 'text' : 'password'}
label="Password"
{...getFieldProps('password')}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={handleShowPassword} edge="end">
<Iconify icon={showPassword ? 'eva:eye-fill' : 'eva:eye-off-fill'} />
</IconButton>
</InputAdornment>
),
}}
error={Boolean(touched.password && errors.password)}
helperText={touched.password && errors.password}
/>
</Stack>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ my: 2 }}>
<Link component={RouterLink} variant="subtitle2" to="#" underline="hover">
Forgot password?
</Link>
</Stack>
{loginError ? (
<Alert severity="error">
<AlertTitle>Login Error</AlertTitle>
{loginError}
</Alert>
) : null}
<LoadingButton
fullWidth
size="large"
type="submit"
variant="contained"
loading={loginLoading ? isSubmitting : null}
>
Login
</LoadingButton>
</Form>
</FormikProvider>
);
}
Example #23
Source File: StripeIBANForm.js From react-saas-template with MIT License | 4 votes |
function StripeIBANForm(props) {
const {
stripeError,
setStripeError,
amount,
amountError,
onAmountChange,
name,
setName,
email,
setEmail
} = props;
return (
<Grid container spacing={2} justifyContent="space-between">
<Grid item xs={8}>
<TextField
variant="outlined"
margin="none"
required
label="Your Name"
value={name}
onChange={event => {
setName(event.target.value);
}}
fullWidth
autoFocus
autoComplete="off"
type="text"
/>
</Grid>
<Grid item xs={4}>
<TextField
required
value={amount}
onChange={event => {
onAmountChange(parseInt(event.target.value));
}}
error={amountError ? true : false}
helperText={amountError}
variant="outlined"
fullWidth
type="number"
margin="none"
label="Amount"
InputProps={{
startAdornment: <InputAdornment position="start">$</InputAdornment>
}}
/>
</Grid>
<Grid item xs={12}>
<TextField
required
variant="outlined"
fullWidth
value={email}
onChange={event => {
setEmail(event.target.value);
}}
type="email"
margin="none"
label="Email"
/>
</Grid>
<Grid item xs={12}>
<StripeTextField
margin="none"
variant="outlined"
fullWidth
label="IBAN"
error={stripeError ? true : false}
helperText={stripeError}
required
StripeElement={IbanElement}
stripeOptions={{ supportedCountries: ["SEPA"] }}
onChange={() => {
if (stripeError) {
setStripeError("");
}
}}
></StripeTextField>
</Grid>
</Grid>
);
}