@mui/material#Tooltip JavaScript Examples
The following examples show how to use
@mui/material#Tooltip.
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: index.js From zoomkoding-gatsby-blog with BSD Zero Clause License | 6 votes |
function IconButtonBar({ links = {} }) {
const IconPicker = useCallback((icon) => {
const props = { className: 'icon' };
switch (icon) {
case 'post':
return <DescriptionIcon {...props} />;
case 'demo':
return <PlayIcon {...props} />;
case 'github':
return <GitHubIcon {...props} />;
case 'googlePlay':
return <AndroidIcon {...props} />;
case 'appStore':
return <AppleIcon {...props} />;
case 'email':
return <EmailIcon {...props} />;
case 'linkedIn':
return <LinkedInIcon {...props} />;
default:
return <></>;
}
}, []);
return (
<>
{Object.keys(links).map((link, index) => {
return (
links[link] && (
<Tooltip key={index} title={link} arrow className="icon-tooltip">
<IconButton size="small" href={`${link === 'email' ? `mailto:` : ``}${links[link]}`}>
{IconPicker(link)}
</IconButton>
</Tooltip>
)
);
})}
</>
);
}
Example #2
Source File: HelpIcon.js From react-saas-template with MIT License | 6 votes |
function HelpIcon(props) {
const { classes, title } = props;
const [isHovered, setIsHovered] = useState(false);
const onMouseOver = useCallback(() => {
setIsHovered(true);
}, []);
const onMouseLeave = useCallback(() => {
setIsHovered(false);
}, []);
return (
<Tooltip
title={
<Typography variant="body2" className={classes.tooltipTypo}>
{title}
</Typography>
}
className={classes.tooltip}
enterTouchDelay={300}
>
<HelpIconOutline
/**
* We have to use onMouseOver and not onMouseEnter, because if we have overlapping
* tooltips, the onMouseEnter wont fire when the old tooltip is fading
* */
onMouseOver={onMouseOver}
onFocus={onMouseOver}
onBlur={onMouseLeave}
onMouseLeave={onMouseLeave}
color={isHovered ? "primary" : "inherit"}
className={classes.helpIcon}
style={{ cursor: isHovered ? "pointer" : "auto" }}
/>
</Tooltip>
);
}
Example #3
Source File: CustomizedSlider.jsx From matx-react with MIT License | 6 votes |
function ValueLabelComponent(props) {
const { children, open, value } = props;
const popperRef = React.useRef(null);
React.useEffect(() => {
if (popperRef.current) {
popperRef.current.update();
}
});
return (
<Tooltip
open={open}
title={value}
placement="top"
enterTouchDelay={0}
PopperProps={{ popperRef }}
>
{children}
</Tooltip>
);
}
Example #4
Source File: AppIcon.jsx From matx-react with MIT License | 6 votes |
AppIcon = () => {
return (
<Container>
<Box className="breadcrumb">
<Breadcrumb routeSegments={[{ name: "Material", path: "/material" }, { name: "Icons" }]} />
</Box>
<SimpleCard title="icons">
<Box display="flex" flexWrap="wrap" gap={3}>
{IconList.map((icon, key) => (
<Tooltip title={icon} key={key}>
<Icon fontSize="large">{icon}</Icon>
</Tooltip>
))}
</Box>
</SimpleCard>
</Container>
);
}
Example #5
Source File: StatCards.jsx From matx-react with MIT License | 6 votes |
StatCards = () => {
const cardList = [
{ name: 'New Leads', amount: 3050, icon: 'group' },
{ name: 'This week Sales', amount: '$80,500', icon: 'attach_money' },
{ name: 'Inventory Status', amount: '8.5% Stock Surplus', icon: 'store' },
{ name: 'Orders to deliver', amount: '305 Orders', icon: 'shopping_cart' },
];
return (
<Grid container spacing={3} sx={{ mb: '24px' }}>
{cardList.map((item, index) => (
<Grid item xs={12} md={6} key={index}>
<StyledCard elevation={6}>
<ContentBox>
<Icon className="icon">{item.icon}</Icon>
<Box ml="12px">
<Small>{item.name}</Small>
<Heading>{item.amount}</Heading>
</Box>
</ContentBox>
<Tooltip title="View Details" placement="top">
<IconButton>
<Icon>arrow_right_alt</Icon>
</IconButton>
</Tooltip>
</StyledCard>
</Grid>
))}
</Grid>
);
}
Example #6
Source File: EnhancedTableHead.js From react-saas-template with MIT License | 5 votes |
function EnhancedTableHead(props) {
const { order, orderBy, rows, onRequestSort, classes } = props;
const createSortHandler = useCallback(
property => event => {
onRequestSort(event, property);
},
[onRequestSort]
);
return (
<TableHead>
<TableRow>
{rows.map((row, index) => (
<TableCell
key={index}
align={row.numeric ? "right" : "inherit"}
padding="normal"
sortDirection={orderBy === row.name ? order : false}
className={index === 0 ? classes.paddingFix : null}
>
{onRequestSort ? (
<Tooltip
title="Sort"
placement={row.numeric ? "bottom-end" : "bottom-start"}
enterDelay={300}
>
<TableSortLabel
active={orderBy === row.id}
direction={order}
onClick={createSortHandler(row.id)}
>
<Typography variant="body2">{row.label}</Typography>
</TableSortLabel>
</Tooltip>
) : (
<TableSortLabel
className={classNames(classes.tableSortLabel, classes.noIcon)}
>
<Typography variant="body2" className={classes.label}>
{row.label}
</Typography>
</TableSortLabel>
)}
</TableCell>
))}
</TableRow>
</TableHead>
);
}
Example #7
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 #8
Source File: index.js From neutron with Mozilla Public License 2.0 | 5 votes |
SectionNeverSaved = () => {
const passwordsNeverSaveDomains = useSelector(
(state) => state.preferences.passwordsNeverSaveDomains,
);
return (
<List disablePadding dense>
{passwordsNeverSaveDomains.length < 1 ? (
<ListItem disabled>
<ListItemText primary="Empty." />
</ListItem>
) : (
<ListItem>
<Table size="small" aria-label="Never Saved">
<TableBody>
{passwordsNeverSaveDomains.map((domain) => (
<TableRow key={domain}>
<TableCell component="th" scope="row">
{domain}
</TableCell>
<TableCell align="right">
<Tooltip title="Remove">
<IconButton
aria-label="Remove"
size="small"
onClick={() => {
requestSetPreference(
'passwordsNeverSaveDomains',
passwordsNeverSaveDomains.filter(((item) => item !== domain)),
);
}}
>
<ClearIcon />
</IconButton>
</Tooltip>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</ListItem>
)}
</List>
);
}
Example #9
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 #10
Source File: Sync.js From admin-web with GNU Affero General Public License v3.0 | 5 votes |
render() {
const { classes, t, sync } = this.props;
const { sortedDevices, order, orderBy, wipingID, snackbar } = this.state;
return (
<FormControl className={classes.form}>
<Grid container alignItems="center" className={classes.headline}>
<Typography variant="h6">{t('Mobile devices')}</Typography>
</Grid>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column, key) =>
<TableCell
key={key}
padding={column.padding || 'normal'}
>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={order}
onClick={this.handleSort(column.value, column.type, true)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
)}
<TableCell padding="checkbox">{t('Actions')}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{(sortedDevices || sync).map((obj, idx) =>
<TableRow key={idx}>
<TableCell>{obj.deviceid || ''}</TableCell>
<TableCell>{obj.deviceuser || ''}</TableCell>
<TableCell>{(obj.devicetype || '') + ' / ' + (obj.useragent || '')}</TableCell>
<TableCell>{obj.firstsynctime ? parseUnixtime(obj.firstsynctime) : ''}</TableCell>
<TableCell>{obj.lastupdatetime ? parseUnixtime(obj.lastupdatetime) : ''}</TableCell>
<TableCell>{obj.asversion || ''}</TableCell>
<TableCell>{(obj.foldersSynced || '') + '/' + (obj.foldersSyncable || '')}</TableCell>
<TableCell>{this.getWipeStatus(obj.wipeStatus)}</TableCell>
<TableCell style={{ display: 'flex' }}>
{obj.wipeStatus >= 2 && <Tooltip title="Cancel remote wipe" placement="top">
<IconButton onClick={this.handleRemoteWipeCancel(obj.deviceid)}>
<DoNotDisturbOn color="secondary"/>
</IconButton>
</Tooltip>}
{obj.wipeStatus < 2 && <Tooltip title="Remote wipe" placement="top">
<IconButton onClick={this.handlePasswordDialog(obj.deviceid)}>
<CleaningServices color="error" />
</IconButton>
</Tooltip>}
<Tooltip title="Resync" placement='top'>
<IconButton onClick={this.handleResync(obj.deviceid)}>
<SyncIcon color="primary"/>
</IconButton>
</Tooltip>
<Tooltip title="Delete device" placement='top'>
<IconButton onClick={this.handleRemoteDelete(obj.deviceid)}>
<Delete color="error"/>
</IconButton>
</Tooltip>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<PasswordSafetyDialog
open={Boolean(wipingID)}
deviceID={wipingID}
onClose={this.handlePasswordDialog('')}
onConfirm={this.handleRemoteWipeConfirm}
/>
<Feedback
snackbar={snackbar || ''}
onClose={() => this.setState({ snackbar: '' })}
/>
</FormControl>
);
}
Example #11
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 #12
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 #13
Source File: MatxCustomizer.jsx From matx-react with MIT License | 4 votes |
MatxCustomizer = () => {
const theme = useTheme();
const [open, setOpen] = useState(false);
const [tabIndex, setTabIndex] = useState(0);
const { settings, updateSettings } = useSettings();
const secondary = theme.palette.text.secondary;
const tooglePanel = () => setOpen(!open);
const handleTabChange = (index) => setTabIndex(index);
let activeTheme = { ...settings.themes[settings.activeTheme] };
return (
<Fragment>
<Tooltip title="Theme Settings" placement="left">
<Label className="open" onClick={tooglePanel}>
DEMOS
</Label>
</Tooltip>
<ThemeProvider theme={activeTheme}>
<Drawer
open={open}
anchor="right"
variant="temporary"
onClose={tooglePanel}
ModalProps={{ keepMounted: true }}
>
<MaxCustomaizer>
<Controller>
<Box display="flex">
<Icon className="icon" color="primary">
settings
</Icon>
<H5 sx={{ ml: 1, fontSize: '1rem' }}>Theme Settings</H5>
</Box>
<IconButton onClick={tooglePanel}>
<Icon className="icon">close</Icon>
</IconButton>
</Controller>
<Box px={3} mb={2} display="flex">
<Button
variant="outlined"
onClick={() => handleTabChange(0)}
color={tabIndex === 0 ? 'secondary' : 'primary'}
sx={{ mr: 2 }}
>
Demos
</Button>
<Button
variant="outlined"
onClick={() => handleTabChange(1)}
color={tabIndex === 1 ? 'secondary' : 'primary'}
>
Settings
</Button>
</Box>
<StyledScrollBar options={{ suppressScrollX: true }}>
{tabIndex === 0 && (
<Box sx={{ mb: 4, mx: 3 }}>
<Box sx={{ color: secondary }}>Layouts</Box>
<Box display="flex" flexDirection="column">
{demoLayouts.map((layout) => (
<LayoutBox
key={layout.name}
color="secondary"
badgeContent={'Pro'}
invisible={!layout.isPro}
>
<Card
elevation={4}
sx={{ position: 'relative' }}
onClick={() => updateSettings(layout.options)}
>
<Box sx={{ overflow: 'hidden' }} className="layout-name">
<Button variant="contained" color="secondary">
{layout.name}
</Button>
</Box>
<IMG src={layout.thumbnail} alt={layout.name} />
</Card>
</LayoutBox>
))}
</Box>
</Box>
)}
{/* END LAYOUT */}
{tabIndex === 1 && (
<div>
<div className="helpText">
We used React context API to control layout. Check out the{' '}
<Link href="http://demos.ui-lib.com/matx-react-doc/layout.html" target="_blank">
Documentation
</Link>
</div>
</div>
)}
</StyledScrollBar>
</MaxCustomaizer>
</Drawer>
</ThemeProvider>
</Fragment>
);
}
Example #14
Source File: Layout1Customizer.jsx From matx-react with MIT License | 4 votes |
Layout1Customizer = ({ settings, handleChange, handleControlChange }) => {
return (
<Fragment>
<Box mb="16px" mx="12px">
<ThemeName>Sidebar theme</ThemeName>
<ToolbarContainer>
{mainSidebarThemes.map((color, i) => (
<Tooltip key={i} title={color} placement="top">
<ToolbarContent
color={color}
onClick={() => handleChange('layout1Settings.leftSidebar.theme', color)}
>
{settings.layout1Settings.leftSidebar.theme === color && <Icon>done</Icon>}
<div className={settings.themes[color].palette.type}></div>
</ToolbarContent>
</Tooltip>
))}
</ToolbarContainer>
</Box>
<Box mb="32px" mx="12px">
<ThemeName>Sidebar theme</ThemeName>
<ToolbarContainer>
{topbarThemes.map((color, i) => (
<Tooltip key={i} title={color} placement="top">
<ToolbarContent
color={color}
onClick={() => handleChange('layout1Settings.topbar.theme', color)}
>
{settings.layout1Settings.topbar.theme === color && <Icon>done</Icon>}
<div className={settings.themes[color].palette.type}></div>
</ToolbarContent>
</Tooltip>
))}
</ToolbarContainer>
</Box>
<Box mb="18px" mx="12px">
<FormControl component="fieldset">
<FormLabel component="legend">Sidebar mode</FormLabel>
<RadioGroup
aria-label="Sidebar"
name="leftSidebar"
value={settings.layout1Settings.leftSidebar.mode}
onChange={handleControlChange('layout1Settings.leftSidebar.mode')}
>
<FormControlLabel value="full" control={<Radio />} label="Full" />
<FormControlLabel value="close" control={<Radio />} label="Close" />
<FormControlLabel value="compact" control={<Radio />} label="Compact" />
</RadioGroup>
</FormControl>
</Box>
<Box mb="32px" mx="12px">
<ThemeName sx={{ mb: 4 }}>Sidebar background image</ThemeName>
<div>
<Grid container spacing={3}>
{sidebarBG.map((bg, i) => (
<Grid item xs={4} key={i}>
<BadgeSelected
color="primary"
badgeContent={<Icon>done</Icon>}
invisible={settings.layout1Settings.leftSidebar.bgImgURL !== bg}
sx={{ width: '100%', height: '100%', cursor: 'pointer' }}
>
<Paper onClick={() => handleChange('layout1Settings.leftSidebar.bgImgURL', bg)}>
<IMG src={bg} alt="" />
</Paper>
</BadgeSelected>
</Grid>
))}
</Grid>
</div>
</Box>
<Box mb="24px" mx="12px">
<FormControl component="fieldset">
<FormLabel component="legend">Topbar</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Switch
checked={get(settings.layout1Settings.topbar, 'show')}
onChange={handleControlChange('layout1Settings.topbar.show')}
/>
}
label="Show"
/>
<FormControlLabel
control={
<Switch
checked={get(settings.layout1Settings.topbar, 'fixed')}
onChange={handleControlChange('layout1Settings.topbar.fixed')}
/>
}
label="Fixed"
/>
</FormGroup>
</FormControl>
</Box>
</Fragment>
);
}
Example #15
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 #16
Source File: UserDetails.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, domain, history } = this.props;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
const sysAdminReadPermissions = this.context.includes(SYSTEM_ADMIN_READ);
const { user, changingPw, snackbar, tab, sizeUnits, detachLoading, defaultPolicy, langs,
detaching, adding, editing, dump, rawData, syncPolicy, domainDetails, forwardError } = this.state;
const { ID, username, properties, roles, aliases, fetchmail, ldapID, forward } = user; //eslint-disable-line
return (
<ViewWrapper
topbarTitle={t('Users')}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Paper className={classes.paper} elevation={1}>
<Grid container className={classes.header}>
<Typography
color="primary"
variant="h5"
>
{t('editHeadline', { item: 'User' })} {properties.displayname ? ` - ${properties.displayname}` : ''}
</Typography>
</Grid>
{ldapID && <Grid container className={classes.syncButtons}>
<Tooltip title="Detach user from LDAP object" placement="top">
<Button
variant="contained"
color="secondary"
style={{ marginRight: 8 }}
onClick={this.handleDetachDialog(true)}
size="small"
>
<Detach fontSize="small" className={classes.leftIcon} /> Detach
</Button>
</Tooltip>
<Tooltip title="Synchronize data from LDAP" placement="top">
<Button
size="small"
onClick={this.handleSync}
variant="contained"
color="primary"
style={{ marginRight: 8 }}
>
<Sync fontSize="small" className={classes.leftIcon}/> Sync
</Button>
</Tooltip>
<Tooltip title="Show raw data" placement="top">
<Button
size="small"
onClick={this.handleDump}
variant="contained"
color="primary"
>
<Dump fontSize="small" className={classes.leftIcon}/> Dump
</Button>
</Tooltip>
</Grid>}
<div className={classes.tabsContainer}>
<Tabs
indicatorColor="primary"
value={tab}
onChange={this.handleTabChange}
variant="scrollable"
scrollButtons="auto"
classes={{
scroller: classes.scroller,
}}
>
<Tab label={t("Account")} />
<Tab label={t("User")} disabled={!ID}/>
<Tab label={t("Contact")} disabled={!ID}/>
<Tab label={t("Roles")} disabled={!ID || !sysAdminReadPermissions}/>
<Tab label={t("SMTP")} disabled={!ID}/>
<Tab label={t("Permissions")} disabled={!ID}/>
<Tab label={t("FetchMail")} disabled={!ID}/>
<Tab label={t("Mobile devices")} disabled={!ID}/>
<Tab label={t("Sync policy")} disabled={!ID}/>
</Tabs>
</div>
{tab === 0 && <Account
domain={domainDetails.ID ? domainDetails : domain}
user={user}
sizeUnits={sizeUnits}
langs={langs}
handleInput={this.handleInput}
handleStatusInput={this.handleStatusInput}
handlePropertyChange={this.handlePropertyChange}
handleIntPropertyChange={this.handleIntPropertyChange}
handleCheckbox={this.handleCheckbox}
handleUnitChange={this.handleUnitChange}
handlePasswordChange={this.handlePasswordDialogToggle(true)}
rawData={rawData}
handleQuotaDelete={this.handleQuotaDelete}
handleChatUser={this.handleChatUser}
handleServer={this.handleServer}
/>}
{tab === 1 && <User
user={user}
handlePropertyChange={this.handlePropertyChange}
/>}
{tab === 2 && <Contact
user={user}
handlePropertyChange={this.handlePropertyChange}
/>}
{tab === 3 && sysAdminReadPermissions && <Roles
roles={roles}
handleAutocomplete={this.handleAutocomplete}
/>}
{tab === 4 && <Smtp
user={user}
aliases={aliases}
forward={forward || {}}
forwardError={forwardError}
handleForwardInput={this.handleForwardInput}
handleAliasEdit={this.handleAliasEdit}
handleAddAlias={this.handleAddAlias}
handleRemoveAlias={this.handleRemoveAlias}
/>}
{tab === 5 && <Delegates
domainID={domain.ID}
userID={user.ID}
disabled={!writable}
/>}
{tab === 6 && <FetchMail
fetchmail={fetchmail}
handleAdd={this.handleFetchmailDialog(true)}
handleEdit={this.handleFetchmailEditDialog}
handleDelete={this.handleFetchmailDelete}
/>}
{tab === 7 && <SyncTab
domainID={domain.ID}
userID={user.ID}
/>}
{tab === 8 && <SlimSyncPolicies
syncPolicy={syncPolicy}
defaultPolicy={defaultPolicy}
handleChange={this.handleSyncChange}
handleCheckbox={this.handleSyncCheckboxChange}
handleSlider={this.handleSlider}
/>}
{tab !== 5 && <Grid container className={classes.buttonGrid}>
<Button
onClick={history.goBack}
style={{ marginRight: 8 }}
color="secondary"
>
{t('Back')}
</Button>
<Button
variant="contained"
color="primary"
onClick={tab === 3 ? this.handleSaveRoles : this.handleEdit}
disabled={!writable || forwardError}
>
{t('Save')}
</Button>
</Grid>}
</Paper>
<DetachDialog
open={detaching}
loading={detachLoading}
onClose={this.handleDetachDialog(false)}
onDetach={this.handleDetach}
/>
<AddFetchmail
open={adding}
add={this.addFetchmail}
onClose={this.handleFetchmailDialog(false)}
username={username + '@' + domain.domainname}
/>
<EditFetchmail
open={editing !== null}
entry={editing !== null ? fetchmail[editing] : editing}
edit={this.editFetchmail}
onClose={this.handleFetchmailEditDialog(null)}
username={username + '@' + domain.domainname}
/>
<ChangeUserPassword
onClose={this.handlePasswordDialogToggle(false)}
onError={this.handleError}
onSuccess={this.handleSuccess}
changingPw={changingPw}
domain={domain}
user={user}
/>
<DumpDialog onClose={this.handleCloseDump} open={!!dump} dump={dump} />
</ViewWrapper>
);
}
Example #17
Source File: TaskDetails.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t } = this.props;
const { snackbar, ID, command, state, created, updated, message, params } = this.state;
return (
<ViewWrapper
topbarTitle={t('Task queue')}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Paper className={classes.paper} elevation={1}>
<Grid container direction="column" className={classes.container}>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Task ID')}:</span>
{ID || t('Unknown')}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Command')}:</span>
{command || t('Unknown')}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('State')}:</span>
{this.getTaskState(state) || t('Unknown')}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Message')}:</span>
{message || t('Unknown')}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Created')}:</span>
{setDateTimeString(created) || t('Unknown')}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Updated')}:</span>
{setDateTimeString(updated) || t('Unknown')}
</Typography>
<Divider />
<Typography variant="h6" className={classes.params}>
{t('Params')}
</Typography>
{Object.entries(params).map(([param, value], key) => {
const displayValue = JSON.stringify(value);
return param !== 'result' ? <Typography className={classes.param} key={key}>
<span className={classes.description}>{param}:</span>
{displayValue || t('Unknown')}
</Typography> :
<div className={classes.flexRow} key={key}>
<div className={classes.description}>{param}</div>
<div>
{(value || []).map(({username, code, message}, idx) =>
<Tooltip key={idx} placement='right' title={message || ''}>
<Typography className={classes.resultParam}>
<span
style={{
marginRight: 8,
backgroundColor: code - 300 < 0 /* code 2xx */ ? green['500'] : red['500'],
borderRadius: 4,
padding: '2px 4px',
}}
>
{code}
</span>
{username}
</Typography>
</Tooltip>
)}
</div>
</div>;
})}
</Grid>
<Button
color="secondary"
onClick={this.handleNavigation('taskq')}
>
{t('Back')}
</Button>
</Paper>
<Feedback
snackbar={snackbar}
onClose={() => this.setState({ snackbar: '' })}
/>
</ViewWrapper>
);
}
Example #18
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 #19
Source File: User.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, user, handlePropertyChange } = this.props;
const { properties, ldapID } = user;
const { title, displayname, nickname, primarytelephonenumber, streetaddress,
departmentname, companyname, officelocation, givenname, surname, initials,
assistant, country, locality, stateorprovince, postalcode } = properties;
return (
<FormControl className={classes.form}>
<div className={classes.flexRow}>
<Typography variant="h6">{t('Name')}</Typography>
{ldapID && <Tooltip title={t("Warning") + ": " + t("Changes will be overwritten with next LDAP sync")}>
<Warning color="warning" fontSize="inherit" style={{ fontSize: 32 }}/>
</Tooltip>}
</div>
<Grid container>
<Grid item xs={12} className={classes.gridItem}>
<div className={classes.grid}>
<TextField
className={classes.flexTextfield}
label={t("First name")}
value={givenname || ''}
onChange={handlePropertyChange('givenname')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
//className={classes.flexTextfield}
label={t("Initials")}
value={initials || ''}
onChange={handlePropertyChange('initials')}
variant={ldapID ? "filled" : 'outlined'}
/>
</div>
<TextField
className={classes.propertyInput}
label={t("Surname")}
fullWidth
value={surname || ''}
onChange={handlePropertyChange('surname')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.propertyInput}
label={t("Display name")}
fullWidth
value={displayname || ''}
onChange={handlePropertyChange('displayname')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.propertyInput}
label={t("Nickname")}
fullWidth
value={nickname || ''}
onChange={handlePropertyChange('nickname')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
</Grid>
<Divider className={classes.divider} />
<Grid container>
<Grid item xs={6} style={{ display: 'flex' }}>
<TextField
className={classes.address}
label={t("Address")}
value={streetaddress || ''}
onChange={handlePropertyChange('streetaddress')}
multiline
rows={3}
variant={ldapID ? "filled" : 'outlined'}
inputProps={{
style: {
height: 95,
},
}}
/>
</Grid>
<Grid item xs={6} style={{ paddingRight: 16 }}>
<TextField
className={classes.input}
label={t("Position")}
fullWidth
value={title || ''}
onChange={handlePropertyChange('title')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.input}
label={t("Company")}
fullWidth
value={companyname || ''}
onChange={handlePropertyChange('companyname')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
</Grid>
<Grid container>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.propertyInput}
label={t("Locality")}
fullWidth
value={locality || ''}
onChange={handlePropertyChange('locality')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.propertyInput}
label={t("Department")}
fullWidth
value={departmentname || ''}
onChange={handlePropertyChange('departmentname')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.propertyInput}
label={t("State")}
fullWidth
value={stateorprovince || ''}
onChange={handlePropertyChange('stateorprovince')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.propertyInput}
label={t("Office")}
fullWidth
value={officelocation || ''}
onChange={handlePropertyChange('officelocation')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.propertyInput}
label={t("Postal Code")}
fullWidth
value={postalcode || ''}
onChange={handlePropertyChange('postalcode')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.propertyInput}
label={t("Assistant")}
fullWidth
value={assistant || ''}
onChange={handlePropertyChange('assistant')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
<Grid item xs={12} className={classes.gridItem}>
<FormControl className={classes.countrySelect}>
<InputLabel variant="standard">{t("Country")}</InputLabel>
<NativeSelect
value={country || "Germany"}
onChange={handlePropertyChange('country')}
fullWidth
>
{world.map(country =>
<option key={country.id} value={country.name}>
{country.name}
</option>
)}
</NativeSelect>
</FormControl>
<TextField
className={classes.propertyInput}
label={t("Telephone")}
fullWidth
value={primarytelephonenumber || ''}
onChange={handlePropertyChange('primarytelephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
</Grid>
</FormControl>
);
}
Example #20
Source File: Contact.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, user, handlePropertyChange } = this.props;
const { properties, ldapID } = user;
const { mobiletelephonenumber, comment, hometelephonenumber, home2telephonenumber, businesstelephonenumber,
business2telephonenumber, pagertelephonenumber, primaryfaxnumber, assistanttelephonenumber } = properties;
return (
<FormControl className={classes.form}>
<div className={classes.flexRow}>
<Typography variant="h6">{t('Telephone')}</Typography>
{ldapID && <Tooltip title={t("Warning") + ": " + t("Changes will be overwritten with next LDAP sync")}>
<Warning color="warning" fontSize="inherit" style={{ fontSize: 32 }}/>
</Tooltip>}
</div>
<Grid container>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.input}
label={t("Business 1")}
fullWidth
value={businesstelephonenumber || ''}
onChange={handlePropertyChange('businesstelephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.input}
label={t("Privat 1")}
fullWidth
value={hometelephonenumber || ''}
onChange={handlePropertyChange('hometelephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.input}
label={t("Business 2")}
fullWidth
value={business2telephonenumber || ''}
onChange={handlePropertyChange('business2telephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.input}
label={t("Privat 2")}
fullWidth
value={home2telephonenumber || ''}
onChange={handlePropertyChange('home2telephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.input}
label={t("Fax")}
fullWidth
value={primaryfaxnumber || ''}
onChange={handlePropertyChange('primaryfaxnumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.input}
label={t("Mobile")}
fullWidth
value={mobiletelephonenumber || ''}
onChange={handlePropertyChange('mobiletelephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
<Grid item xs={12} className={classes.gridItem}>
<TextField
className={classes.input}
label={t("Assistant")}
fullWidth
value={assistanttelephonenumber || ''}
onChange={handlePropertyChange('assistanttelephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
<TextField
className={classes.input}
label={t("Pager")}
fullWidth
value={pagertelephonenumber || ''}
onChange={handlePropertyChange('pagertelephonenumber')}
variant={ldapID ? "filled" : 'outlined'}
/>
</Grid>
</Grid>
<Divider className={classes.divider}/>
<div className={classes.flexRow}>
<Typography variant="h6">{t('Annotation')}</Typography>
{ldapID && <Tooltip title={t("Warning") + ": " + t("Changes will be overwritten with next LDAP sync")}>
<Warning color="warning" fontSize="inherit" style={{ fontSize: 32 }}/>
</Tooltip>}
</div>
<TextField
className={classes.input}
fullWidth
value={comment || ''}
onChange={handlePropertyChange('comment')}
multiline
rows={4}
variant={ldapID ? "filled" : 'outlined'}
/>
</FormControl>
);
}
Example #21
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 #22
Source File: TopBar.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, profile, title, onAdd, fetching, settings, license } = this.props;
const { menuAnchorEl } = this.state;
const licenseVisible = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<AppBar position="fixed" className={classes.root}>
<Toolbar className={classes.root}>
<Hidden lgUp>
<IconButton color="inherit" onClick={this.handleMenuToggle} size="large">
<Burger />
</IconButton>
</Hidden>
{this.links.map((link, idx) =>
<Tooltip
placement="bottom"
title={t(link.title) + (!config[link.key] ? ` (${t("Not configured")})` : '')} key={idx}
>
<span>
<IconButton
href={config[link.key]}
disabled={!config[link.key]}
target="_blank"
className={classes.iconButton}
size="large">
<link.icon />
</IconButton>
</span>
</Tooltip>
)}
{title && <Typography className={classes.title} variant="h6">{title}</Typography>}
<div className={classes.flexEndContainer}>
<Box className={classes.profileButton} onClick={this.handleMenuOpen('menuAnchorEl')}>
<Typography className={classes.username}>{profile.Profile.user.username}</Typography>
<AccountCircleIcon className={classes.profileIcon}></AccountCircleIcon>
</Box>
{licenseVisible && <LicenseIcon
activated={license.product && license.product !== "Community"}
handleNavigation={this.handleNavigation}
/>}
<img
src={settings.language === 'en-US' ? german : english}
alt=""
width={35}
height={44}
className={classes.flag}
onClick={this.handleLangChange}
/>
<Menu
id="simple-menu"
anchorEl={menuAnchorEl}
keepMounted
open={Boolean(menuAnchorEl)}
onClose={this.handleMenuClose('menuAnchorEl')}
>
<MenuItem onClick={this.handleNavigation('settings')}>
{t('Settings')}
</MenuItem>
<MenuItem onClick={this.handleNavigation('changePassword')}>
{t('Change password')}
</MenuItem>
<MenuItem onClick={this.handleLogout}>
{t('Logout')}
</MenuItem>
</Menu>
</div>
{onAdd && <div className={classes.divider}></div>}
{onAdd && <Button onClick={onAdd} color="inherit" className={classes.add}>
<Add />{t('Add')}
</Button>}
</Toolbar>
<Fade
in={fetching}
style={{
transitionDelay: '500ms',
}}
>
<LinearProgress variant="indeterminate" color="primary"/>
</Fade>
</AppBar>
);
}
Example #23
Source File: ServicesChart.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, Services, t } = this.props;
const { starting, restarting, stoping, snackbar, service, action } = this.state;
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>
{"Service"}
</TableCell>
<TableCell align="center" style={{ width: 124 }}>
{"State | Autostart"}
</TableCell>
<TableCell align="center" style={{ width: 132 }}>
{"Actions"}
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{Services.map((service, idx) => (
<TableRow key={idx} hover style={{cursor: "default"}}>
<TableCell>
<Tooltip
title={service.description ? <>
<Typography>{service.description}</Typography>
<Typography variant="caption">
{service.since ? `${t('since')} ${setDateTimeString(service.since)}` : ''}
</Typography>
</> : ''}
placement="top"
>
<Typography className={classes.serviceName}>
{service.name}
</Typography>
</Tooltip>
</TableCell>
<TableCell>
<Grid container justifyContent="center">
<div
style={{ marginRight: 4 }}
className={classes.label + " " + this.getChipColor(service.state)}
>
{service.state}
</div>
<div className={classes.label + " " +
this.getChipColor(service.autostart === "enabled" ? "active" : "error")}>
{service.autostart || 'error'}
</div>
</Grid>
</TableCell>
<TableCell align="right">
<Tooltip title={t("Enable/Disable")} placement="top">
<IconButton
onClick={this.handleServiceAction(service, service.autostart === "enabled" ?
"disable" : "enable")}
className={classes.chipIcon}
size="large">
<Enable className={classes.iconButton} fontSize="small" />
</IconButton>
</Tooltip>
{stoping !== service.name ? (
<Tooltip title={t("Stop")} placement="top">
<IconButton
onClick={this.handleDialog(service, "stop")}
className={classes.chipIcon}
size="large">
<Stop className={classes.iconButton} fontSize="small" />
</IconButton>
</Tooltip>
) : (
<IconButton className={classes.chipIcon} size="large">
<CircularProgress size={18} />
</IconButton>
)}
{restarting !== service.name ? (
<Tooltip title={t("Restart")}placement="top">
<IconButton
onClick={this.handleDialog(service, "restart")}
className={classes.chipIcon}
size="large">
<Restart
className={classes.iconButton}
fontSize="small"
/>
</IconButton>
</Tooltip>
) : (
<IconButton className={classes.chipIcon} size="large">
<CircularProgress size={18} />
</IconButton>
)}
{starting !== service.name ? (
<Tooltip title={t("Start")} placement="top">
<IconButton
onClick={this.handleServiceAction(service, "start")}
className={classes.chipIcon}
size="large">
<Start className={classes.iconButton} fontSize="small" />
</IconButton>
</Tooltip>
) : (
<IconButton className={classes.chipIcon} size="large">
<CircularProgress size={18} />
</IconButton>
)}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
<ConfirmRestartStop
open={!!service}
handleConfirm={this.handleServiceAction(service, action)}
onClose={this.handleCloseDialog}
service={service}
action={action}
/>
<Feedback
snackbar={snackbar}
onClose={() => this.setState({ snackbar: "" })}
/>
</div>
);
}
Example #24
Source File: NavBar.js From react-saas-template with MIT License | 4 votes |
function NavBar(props) {
const { selectedTab, messages, classes, openAddBalanceDialog, theme } = props;
// Will be use to make website more accessible by screen readers
const links = useRef([]);
const [isMobileOpen, setIsMobileOpen] = useState(false);
const [isSideDrawerOpen, setIsSideDrawerOpen] = useState(false);
const isWidthUpSm = useMediaQuery(theme.breakpoints.up("sm"));
const openMobileDrawer = useCallback(() => {
setIsMobileOpen(true);
}, [setIsMobileOpen]);
const closeMobileDrawer = useCallback(() => {
setIsMobileOpen(false);
}, [setIsMobileOpen]);
const openDrawer = useCallback(() => {
setIsSideDrawerOpen(true);
}, [setIsSideDrawerOpen]);
const closeDrawer = useCallback(() => {
setIsSideDrawerOpen(false);
}, [setIsSideDrawerOpen]);
const menuItems = [
{
link: "/c/dashboard",
name: "Dashboard",
onClick: closeMobileDrawer,
icon: {
desktop: (
<DashboardIcon
className={
selectedTab === "Dashboard" ? classes.textPrimary : "text-white"
}
fontSize="small"
/>
),
mobile: <DashboardIcon className="text-white" />,
},
},
{
link: "/c/posts",
name: "Posts",
onClick: closeMobileDrawer,
icon: {
desktop: (
<ImageIcon
className={
selectedTab === "Posts" ? classes.textPrimary : "text-white"
}
fontSize="small"
/>
),
mobile: <ImageIcon className="text-white" />,
},
},
{
link: "/c/subscription",
name: "Subscription",
onClick: closeMobileDrawer,
icon: {
desktop: (
<AccountBalanceIcon
className={
selectedTab === "Subscription"
? classes.textPrimary
: "text-white"
}
fontSize="small"
/>
),
mobile: <AccountBalanceIcon className="text-white" />,
},
},
{
link: "/",
name: "Logout",
icon: {
desktop: (
<PowerSettingsNewIcon className="text-white" fontSize="small" />
),
mobile: <PowerSettingsNewIcon className="text-white" />,
},
},
];
return (
<Fragment>
<AppBar position="sticky" className={classes.appBar}>
<Toolbar className={classes.appBarToolbar}>
<Box display="flex" alignItems="center">
<Hidden smUp>
<Box mr={1}>
<IconButton
aria-label="Open Navigation"
onClick={openMobileDrawer}
color="primary"
size="large"
>
<MenuIcon />
</IconButton>
</Box>
</Hidden>
<Hidden smDown>
<Typography
variant="h4"
className={classes.brandText}
display="inline"
color="primary"
>
Wa
</Typography>
<Typography
variant="h4"
className={classes.brandText}
display="inline"
color="secondary"
>
Ver
</Typography>
</Hidden>
</Box>
<Box
display="flex"
justifyContent="flex-end"
alignItems="center"
width="100%"
>
{isWidthUpSm && (
<Box mr={3}>
<Balance
balance={2573}
openAddBalanceDialog={openAddBalanceDialog}
/>
</Box>
)}
<MessagePopperButton messages={messages} />
<ListItem
disableGutters
className={classNames(classes.iconListItem, classes.smBordered)}
>
<Avatar
alt="profile picture"
src={`${process.env.PUBLIC_URL}/images/logged_in/profilePicture.jpg`}
className={classNames(classes.accountAvatar)}
/>
{isWidthUpSm && (
<ListItemText
className={classes.username}
primary={
<Typography color="textPrimary">Username</Typography>
}
/>
)}
</ListItem>
</Box>
<IconButton
onClick={openDrawer}
color="primary"
aria-label="Open Sidedrawer"
size="large"
>
<SupervisorAccountIcon />
</IconButton>
<SideDrawer open={isSideDrawerOpen} onClose={closeDrawer} />
</Toolbar>
</AppBar>
<Hidden smDown>
<Drawer // both drawers can be combined into one for performance
variant="permanent"
classes={{
paper: classes.drawerPaper,
}}
open={false}
>
<List>
{menuItems.map((element, index) => (
<Link
to={element.link}
className={classes.menuLink}
onClick={element.onClick}
key={index}
ref={(node) => {
links.current[index] = node;
}}
>
<Tooltip
title={element.name}
placement="right"
key={element.name}
>
<ListItem
selected={selectedTab === element.name}
button
divider={index !== menuItems.length - 1}
className={classes.permanentDrawerListItem}
onClick={() => {
links.current[index].click();
}}
aria-label={
element.name === "Logout"
? "Logout"
: `Go to ${element.name}`
}
>
<ListItemIcon className={classes.justifyCenter}>
{element.icon.desktop}
</ListItemIcon>
</ListItem>
</Tooltip>
</Link>
))}
</List>
</Drawer>
</Hidden>
<NavigationDrawer
menuItems={menuItems.map((element) => ({
link: element.link,
name: element.name,
icon: element.icon.mobile,
onClick: element.onClick,
}))}
anchor="left"
open={isMobileOpen}
selectedItem={selectedTab}
onClose={closeMobileDrawer}
/>
</Fragment>
);
}
Example #25
Source File: index.js From mui-image with ISC License | 3 votes |
export default function Demo() {
const [currentPhoto, setCurrentPhoto] = React.useState(DEFAULT_IMAGE);
const [showPhoto, setShowPhoto] = React.useState(true);
const [showLoading, setShowLoading] = React.useState(SHOW_LOADING);
const [errorIcon, setErrorIcon] = React.useState(ERROR_ICON);
const [height, setHeight] = React.useState(HEIGHT);
const [width, setWidth] = React.useState(WIDTH);
const [shift, setShift] = React.useState(SHIFT);
const [distance, setDistance] = React.useState(DISTANCE);
const [shiftDuration, setShiftDuration] = React.useState(SHIFT_DURATION);
const [duration, setDuration] = React.useState(DURATION);
const [easing, setEasing] = React.useState(EASING);
const [fit, setFit] = React.useState(FIT);
const [bgColor, setBgColor] = React.useState(BG_COLOR);
function getNewPhoto() {
if (mobileOpen) setMobileOpen(false);
const newPhoto = Math.floor(Math.random() * 1051);
setShowPhoto(false);
setCurrentPhoto(newPhoto);
setTimeout(() => {
setShowPhoto(true);
}, 100);
}
function refreshPhoto() {
if (mobileOpen) setMobileOpen(false);
setShowPhoto(false);
setTimeout(() => {
setShowPhoto(true);
}, 100);
}
function resetDefaults() {
setShowLoading(SHOW_LOADING);
setErrorIcon(ERROR_ICON);
setHeight(HEIGHT);
setWidth(WIDTH);
setShift(SHIFT);
setDistance(DISTANCE);
setShiftDuration(SHIFT_DURATION);
setDuration(DURATION);
setEasing(EASING);
setFit(FIT);
setBgColor(BG_COLOR);
}
const [mobileOpen, setMobileOpen] = React.useState(false);
const mobile = useMediaQuery('@media (max-width: 900px)');
function handleDrawerToggle() {
setMobileOpen(!mobileOpen);
}
return (
<Box sx={{ display: 'flex', height: '100vh' }}>
<CssBaseline />
<AppBar
elevation={0}
position="fixed"
sx={{ zIndex: (theme) => theme.zIndex.drawer + 1 }}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
sx={{ mr: 2, display: { md: 'none' } }}
>
{mobileOpen ? <CodeOffIcon /> : <CodeIcon />}
</IconButton>
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: { xs: 'none', md: 'inline-block' } }}
>
<TypeIt
getBeforeInit={(instance) => {
instance
.pause(3500)
.type('npm install mui-image')
.pause(1500)
.delete()
.type("import Image from 'mui-image'");
return instance;
}}
options={{ speed: 120, cursor: false }}
/>
</Typography>
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: { xs: 'inline-block', md: 'none' } }}
>
mui-image
</Typography>
<Box display="flex">
<IconButton
onClick={() =>
window.open('https://yarnpkg.com/package/mui-image')
}
color="inherit"
>
<YarnIcon
viewBox="0 0 256 256"
fontSize="large"
color="inherit"
/>
</IconButton>
<IconButton
onClick={() => window.open('https://npmjs.com/package/mui-image')}
color="inherit"
>
<NpmIcon fontSize="large" color="inherit" />
</IconButton>
<IconButton
onClick={() =>
window.open('https://github.com/benmneb/mui-image')
}
color="inherit"
>
<GitHubIcon fontSize="large" color="inherit" />
</IconButton>
</Box>
</Toolbar>
</AppBar>
<Drawer
variant={mobile ? 'temporary' : 'permanent'}
open={mobile ? mobileOpen : true}
onClose={handleDrawerToggle}
ModalProps={{
keepMounted: true,
}}
sx={{
width: DRAWER_WIDTH,
maxWidth: '100vw',
flexShrink: 0,
'& .MuiDrawer-paper': {
width: DRAWER_WIDTH,
maxWidth: '100vw',
boxSizing: 'border-box',
},
}}
>
<Toolbar />
<Stack
spacing={2}
component="section"
padding={2}
sx={{ minWidth: '100%' }}
>
<Box component="div" variant="h6">
{'<Image'}
</Box>
<Stack spacing={1} sx={{ pl: 2 }}>
<Line component="div">
src="https://picsum.photos/id/{currentPhoto}/2000"
</Line>
<Tooltip title="Any valid CSS `height` property" placement="right">
<Line component="div">
height="
<TextField
variant="standard"
value={height}
onChange={(e) => setHeight(e.target.value)}
/>
"
</Line>
</Tooltip>
<Tooltip title="Any valid CSS `width` property" placement="right">
<Line component="div">
width="
<TextField
variant="standard"
value={width}
onChange={(e) => setWidth(e.target.value)}
/>
"
</Line>
</Tooltip>
<Tooltip
title="Any valid CSS `object-fit` property"
placement="right"
>
<Line component="div">
fit=
<Select
variant="standard"
value={fit}
onChange={(e) => setFit(e.target.value)}
sx={{ minWidth: 100 }}
>
<MenuItem value="fill">"fill"</MenuItem>
<MenuItem value="contain">"contain"</MenuItem>
<MenuItem value="cover">"cover"</MenuItem>
<MenuItem value="none">"none"</MenuItem>
<MenuItem value="scale-down">"scale-down"</MenuItem>
</Select>
</Line>
</Tooltip>
<Tooltip
title="Number of milliseconds the image takes to transition in"
placement="right"
>
<Line component="div">
duration={'{'}
<TextField
variant="standard"
value={duration}
onChange={(e) => setDuration(e.target.value)}
/>
{'}'}
</Line>
</Tooltip>
<Tooltip
title="Any valid CSS `transition-timing-function` property"
placement="right"
>
<Line component="div">
easing=
<Select
variant="standard"
value={easing}
onChange={(e) => setEasing(e.target.value)}
sx={{ minWidth: 100 }}
>
<MenuItem value="cubic-bezier(0.7, 0, 0.6, 1)">
"cubic-bezier(0.7, 0, 0.6, 1)"
</MenuItem>
<MenuItem value="ease">"ease"</MenuItem>
<MenuItem value="ease-in">"ease-in"</MenuItem>
<MenuItem value="ease-out">"ease-out"</MenuItem>
<MenuItem value="ease-in-out">"ease-in-out"</MenuItem>
<MenuItem value="linear">"linear"</MenuItem>
</Select>
</Line>
</Tooltip>
<Tooltip
title="Once installed you can add a custom loading indicator"
placement="right"
>
<Line component="div">
showLoading=
<FormControlLabel
sx={{ ml: 0 }}
control={
<Switch
checked={showLoading}
onChange={(e) => setShowLoading(e.target.checked)}
/>
}
label={`{ ${showLoading} }`}
labelPlacement="start"
/>
</Line>
</Tooltip>
<Tooltip
title="Once installed you can add a custom error icon"
placement="right"
>
<Line component="div">
errorIcon=
<FormControlLabel
sx={{ ml: 0 }}
control={
<Switch
checked={errorIcon}
onChange={(e) => setErrorIcon(e.target.checked)}
/>
}
label={`{ ${errorIcon} }`}
labelPlacement="start"
/>
</Line>
</Tooltip>
<Tooltip
title="Direction to shift image as it appears"
placement="right"
>
<Line component="div">
shift=
<Select
variant="standard"
value={shift || 'null'}
onChange={(e) => setShift(e.target.value)}
sx={{ minWidth: 100 }}
>
<MenuItem value={'null'}>{'{ null }'}</MenuItem>
<MenuItem value="top">"top"</MenuItem>
<MenuItem value="right">"right"</MenuItem>
<MenuItem value="bottom">"bottom"</MenuItem>
<MenuItem value="left">"left"</MenuItem>
</Select>
</Line>
</Tooltip>
<Tooltip
title="Distance to shift the image as it appears. Any valid CSS `length` property"
placement="right"
>
<Line component="div">
distance="
<TextField
variant="standard"
value={distance}
onChange={(e) => setDistance(e.target.value)}
/>
"
</Line>
</Tooltip>
<Tooltip
title="Number of milliseconds the shift takes"
placement="right"
>
<Line component="div">
shiftDuration={'{'}
<TextField
variant="standard"
value={shiftDuration || duration * 0.3}
onChange={(e) => setShiftDuration(e.target.value)}
/>
{'}'}
</Line>
</Tooltip>
<Tooltip
title="Color the image transitions in from. Any valid CSS `background-color` property"
placement="right"
>
<Line component="div">
bgColor="
<TextField
variant="standard"
value={bgColor}
onChange={(e) => setBgColor(e.target.value)}
/>
"
</Line>
</Tooltip>
</Stack>
<Box component="div" variant="h6">
{'/>'}
</Box>
<Button
disabled={showPhoto === 'refresh'}
variant="contained"
onClick={refreshPhoto}
disableElevation
>
Refresh photo
</Button>
<Button
disabled={showPhoto === 'new'}
variant="outlined"
onClick={getNewPhoto}
>
Random photo
</Button>
<Button onClick={resetDefaults}>Reset defaults</Button>
</Stack>
</Drawer>
<Box component="section" sx={{ flexGrow: 1, backgroundColor: bgColor }}>
<Toolbar />
<ImageOutput
sx={{
maxHeight: { xs: 'calc(100vh - 56px)', sm: 'calc(100vh - 64px)' },
}}
>
{showPhoto && (
<Image
src={`https://picsum.photos/id/${currentPhoto}/2000`}
width={width}
height={height}
duration={duration}
showLoading={showLoading}
errorIcon={errorIcon}
shift={shift}
distance={distance}
shiftDuration={shiftDuration}
easing={easing}
fit={fit}
bgColor={bgColor}
/>
)}
</ImageOutput>
</Box>
</Box>
);
}