@mui/material#Select JavaScript Examples
The following examples show how to use
@mui/material#Select.
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: TopSellingTable.jsx From matx-react with MIT License | 5 votes |
TopSellingTable = () => {
const { palette } = useTheme();
const bgError = palette.error.main;
const bgPrimary = palette.primary.main;
const bgSecondary = palette.secondary.main;
return (
<Card elevation={3} sx={{ pt: '20px', mb: 3 }}>
<CardHeader>
<Title>top selling products</Title>
<Select size="small" defaultValue="this_month">
<MenuItem value="this_month">This Month</MenuItem>
<MenuItem value="last_month">Last Month</MenuItem>
</Select>
</CardHeader>
<Box overflow="auto">
<ProductTable>
<TableHead>
<TableRow>
<TableCell sx={{ px: 3 }} colSpan={4}>
Name
</TableCell>
<TableCell sx={{ px: 0 }} colSpan={2}>
Revenue
</TableCell>
<TableCell sx={{ px: 0 }} colSpan={2}>
Stock Status
</TableCell>
<TableCell sx={{ px: 0 }} colSpan={1}>
Action
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{productList.map((product, index) => (
<TableRow key={index} hover>
<TableCell colSpan={4} align="left" sx={{ px: 0, textTransform: 'capitalize' }}>
<Box display="flex" alignItems="center">
<Avatar src={product.imgUrl} />
<Paragraph sx={{ m: 0, ml: 4 }}>{product.name}</Paragraph>
</Box>
</TableCell>
<TableCell align="left" colSpan={2} sx={{ px: 0, textTransform: 'capitalize' }}>
${product.price > 999 ? (product.price / 1000).toFixed(1) + 'k' : product.price}
</TableCell>
<TableCell sx={{ px: 0 }} align="left" colSpan={2}>
{product.available ? (
product.available < 20 ? (
<Small bgcolor={bgSecondary}>{product.available} available</Small>
) : (
<Small bgcolor={bgPrimary}>in stock</Small>
)
) : (
<Small bgcolor={bgError}>out of stock</Small>
)}
</TableCell>
<TableCell sx={{ px: 0 }} colSpan={1}>
<IconButton>
<Icon color="primary">edit</Icon>
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</ProductTable>
</Box>
</Card>
);
}
Example #2
Source File: CreateSavedFilter.jsx From Edlib with GNU General Public License v3.0 | 4 votes |
CreateSavedFilter = ({
show,
onClose,
savedFilterData,
filters,
onDone,
filterUtils,
}) => {
const { classes } = useStyles();
const { t } = useTranslation();
const { edlibApi } = useConfigurationContext();
const [selected, setSelected] = React.useState('new');
const [newFilterName, setNewFilterName] = React.useState('My filter');
const request = useRequestWithToken();
return (
<Dialog open={show} onClose={() => onClose()} maxWidth="sm" fullWidth>
<DialogTitle>{_.capitalize(t('edit_filter'))}</DialogTitle>
<DialogContent>
<Box pt={1}>
<FormControl
variant="outlined"
fullWidth
className={classes.formControl}
>
<InputLabel>
{_.capitalize(t('choose_filter'))}
</InputLabel>
<Select
value={selected}
onChange={(e) => setSelected(e.target.value)}
label={_.capitalize(t('choose_filter'))}
>
<MenuItem value="new">
<em>{_.capitalize(t('create_new'))}</em>
</MenuItem>
{savedFilterData.map((savedFilter) => (
<MenuItem
key={savedFilter.id}
value={savedFilter.id}
>
{savedFilter.name}
</MenuItem>
))}
</Select>
</FormControl>
{selected === 'new' && (
<TextField
required
label={_.capitalize(t('name'))}
variant="outlined"
className={classes.formControl}
fullWidth
value={newFilterName}
onChange={(e) => setNewFilterName(e.target.value)}
/>
)}
<div className={classes.formControl}>
<FilterChips
chips={filterUtils.getChipsFromFilters(false)}
/>
</div>
</Box>
</DialogContent>
<DialogActions>
<Button
color="primary"
variant="outlined"
onClick={() => onClose()}
>
{t('cancel')}
</Button>
<Button
color="primary"
variant="contained"
style={{ marginLeft: 5 }}
onClick={() => {
let url = edlibApi(`/common/saved-filters`);
if (selected !== 'new') {
url += `/` + selected;
}
request(url, 'POST', {
body: {
name: newFilterName,
choices: [
filters.contentTypes.value.map(
(contentType) => ({
group: 'contentType',
value: contentType.value,
})
),
filters.licenses.value.map(
(contentType) => ({
group: 'license',
value: contentType.value,
})
),
].flat(),
},
}).then((data) => onDone(data));
}}
>
{t('save')}
</Button>
</DialogActions>
</Dialog>
);
}
Example #3
Source File: DeleteSavedFilter.jsx From Edlib with GNU General Public License v3.0 | 4 votes |
DeleteSavedFilter = ({
show,
onClose,
savedFilterData,
onDeleted,
filterUtils,
}) => {
const { classes } = useStyles();
const { t } = useTranslation();
const request = useRequestWithToken();
const { edlibApi } = useConfigurationContext();
const [selected, setSelected] = React.useState(null);
const selectedSavedFilter = React.useMemo(() => {
if (!selected) {
return null;
}
return savedFilterData.find((sfd) => sfd.id === selected);
}, [selected]);
return (
<Dialog open={show} onClose={() => onClose()} maxWidth="sm" fullWidth>
<DialogTitle>{_.capitalize(t('delete_filter'))}</DialogTitle>
<DialogContent>
<Box pt={1}>
<FormControl
variant="outlined"
fullWidth
className={classes.formControl}
>
<InputLabel>
{_.capitalize(t('choose_filter'))}
</InputLabel>
<Select
value={selected}
onChange={(e) => setSelected(e.target.value)}
label={_.capitalize(t('choose_filter'))}
>
{savedFilterData.map((savedFilter) => (
<MenuItem
key={savedFilter.id}
value={savedFilter.id}
>
{savedFilter.name}
</MenuItem>
))}
</Select>
</FormControl>
<div className={classes.formControl}>
<FilterChips
chips={filterUtils.getChipsFromChoices(
selectedSavedFilter
? selectedSavedFilter.choices
: []
)}
color="default"
/>
</div>
</Box>
</DialogContent>
<DialogActions>
<Button
color="primary"
variant="outlined"
onClick={() => onClose()}
>
{t('cancel')}
</Button>
<Button
color="primary"
variant="contained"
style={{ marginLeft: 5 }}
disabled={!selected}
onClick={() => {
if (!selected) {
return;
}
let url = edlibApi(`/common/saved-filters/${selected}`);
request(url, 'DELETE', {
json: false,
}).then(() => onDeleted(selected));
}}
>
{t('delete')}
</Button>
</DialogActions>
</Dialog>
);
}
Example #4
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 #5
Source File: index.js From fireact with MIT License | 4 votes |
AddUser = () => {
const title = 'Add User';
const mountedRef = useRef(true);
const history = useHistory();
const { userData } = useContext(AuthContext);
const { setBreadcrumb } = useContext(BreadcrumbContext);
const [emailAddress, setEmailAddress] = useState({
hasError: false,
error: null,
value: null
});
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
const [inSubmit, setInSubmit] = useState(false);
const [selectedRole, setSelectedRole] = useState('user');
const [inviteDialog, setInviteDialog] = useState(false);
useEffect(() => {
setBreadcrumb([
{
to: "/",
text: "Home",
active: false
},
{
to: "/account/"+userData.currentAccount.id+"/",
text: userData.currentAccount.name,
active: false
},
{
to: "/account/"+userData.currentAccount.id+"/users",
text: 'Manage Users',
active: false
},
{
to: null,
text: title,
active: true
}
]);
}, [userData, setBreadcrumb, title]);
useEffect(() => {
return () => {
mountedRef.current = false
}
},[]);
return (
<>
<Paper>
<Box p={2}>
{success?(
<>
{inviteDialog?(
<Alert severity="success">The invite is sent to the email address.</Alert>
):(
<Alert severity="success">The user is added to the account.</Alert>
)}
<Stack direction="row" spacing={1} mt={2}>
<Button variant="contained" color="primary" onClick={() => history.push("/account/"+userData.currentAccount.id+"/users")} >Back to User List</Button>
</Stack>
</>
):(
<>
{error !== null &&
<div style={{marginBottom: '20px'}}><Alert severity="error">{error}</Alert></div>
}
{inviteDialog?(
<>
<Alert severity="info">The email is not registered by any existing user. Do you want to send an invite to the user?</Alert>
<Stack direction="row" spacing={1} mt={2}>
<Button variant="contained" color="primary" disabled={inSubmit} onClick={e => {
e.preventDefault();
setInSubmit(true);
const inviteEmailToAccount = CloudFunctions.httpsCallable('inviteEmailToAccount');
inviteEmailToAccount({
accountId: userData.currentAccount.id,
email: emailAddress.value,
role: selectedRole
}).then(res => {
if (!mountedRef.current) return null
setInSubmit(false);
setSuccess(true);
}).catch(err => {
if (!mountedRef.current) return null
setError(err.message);
});
}}>{inSubmit && <Loader />}
Yes, send an invite</Button>
<Button variant="contained" color="secondary" disabled={inSubmit} onClick={() => {
history.push("/account/"+userData.currentAccount.id+"/users");
}}>No</Button>
</Stack>
</>
):(
<Form handleSubmit={e => {
e.preventDefault();
setError(null);
setSuccess(false);
setInSubmit(true);
const addUserToAccount = CloudFunctions.httpsCallable('addUserToAccount');
addUserToAccount({
accountId: userData.currentAccount.id,
email: emailAddress.value,
role: selectedRole
}).then(res => {
if (!mountedRef.current) return null
setInSubmit(false);
setSuccess(true);
}).catch(err => {
if (!mountedRef.current) return null
setInSubmit(false);
if(err.details && err.details.code === 'auth/user-not-found'){
setInviteDialog(true);
setInSubmit(false);
}else{
setError(err.message);
}
});
}}
disabled={emailAddress.hasError || emailAddress.value===null || selectedRole===null || inSubmit}
submitBtnStyle={(selectedRole!=='remove')?"primary":"danger"}
inSubmit={inSubmit}
enableDefaultButtons={true}
backToUrl={"/account/"+userData.currentAccount.id+"/users"}
>
<Input label="Email Address" type="email" name="email-address" hasError={emailAddress.hasError} error={emailAddress.error} minLen={5} maxLen={50} required={true} validRegex="^[a-zA-Z0-9-_+\.]*@[a-zA-Z0-9-_\.]*\.[a-zA-Z0-9-_\.]*$" changeHandler={setEmailAddress} fullWidth />
<FormControl fullWidth>
<InputLabel>Role</InputLabel>
<Select label="Role" value={selectedRole} onChange={e => {
setSelectedRole(e.target.value);
}}>
<MenuItem value="user">user</MenuItem>
<MenuItem value="admin">admin</MenuItem>
</Select>
</FormControl>
</Form>
)}
</>
)}
</Box>
</Paper>
</>
)
}
Example #6
Source File: index.js From fireact with MIT License | 4 votes |
UserRole = () => {
const title = 'Change User Role';
const history = useHistory();
const { userData } = useContext(AuthContext);
const { userId } = useParams();
const mountedRef = useRef(true);
const { setBreadcrumb } = useContext(BreadcrumbContext);
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
const [inSubmit, setInSubmit] = useState(false);
const [selectedRole, setSelectedRole] = useState(null);
useEffect(() => {
setBreadcrumb([
{
to: "/",
text: "Home",
active: false
},
{
to: "/account/"+userData.currentAccount.id+"/",
text: userData.currentAccount.name,
active: false
},
{
to: "/account/"+userData.currentAccount.id+"/users",
text: 'Manage Users',
active: false
},
{
to: null,
text: title,
active: true
}
]);
setError(null);
const getAccountUser = CloudFunctions.httpsCallable('getAccountUser');
getAccountUser({
accountId: userData.currentAccount.id,
userId: userId
}).then(res => {
if (!mountedRef.current) return null
res.data.lastLoginTime = new Date(res.data.lastLoginTime);
setUser(res.data);
}).catch(err => {
if (!mountedRef.current) return null
setError(err.message);
});
},[userData, userId, setBreadcrumb]);
useEffect(() => {
return () => {
mountedRef.current = false
}
},[]);
return (
<Paper>
<Box p={2}>
{(userId !== userData.currentAccount.owner)?(
success?(
<>
<Alert severity="success" onClose={() => setSuccess(false)}>User role is successfully updated.</Alert>
<Stack direction="row" spacing={1} mt={2}>
<Button variant="contained" color="primary" onClick={() => history.push("/account/"+userData.currentAccount.id+"/users")} >Back to User List</Button>
</Stack>
</>
):(
<Stack spacing={3}>
{error !== null &&
<Alert severity="error">{error}</Alert>
}
{user === null ? (
<Loader text="Loading user details" />
):(
<Form handleSubmit={e => {
e.preventDefault();
setError(null);
setSuccess(false);
setInSubmit(true);
const updateAccountUserRole = CloudFunctions.httpsCallable('updateAccountUserRole');
updateAccountUserRole({
accountId: userData.currentAccount.id,
userId: userId,
role: selectedRole
}).then(res => {
setInSubmit(false);
setSuccess(true);
}).catch(err => {
setInSubmit(false);
setError(err.message);
});
}}
disabled={selectedRole===null || selectedRole===user.role || inSubmit}
submitBtnStyle={(selectedRole!=='remove')?"primary":"error"}
inSubmit={inSubmit}
enableDefaultButtons={true}
backToUrl={"/account/"+userData.currentAccount.id+"/users"}
>
<Stack spacing={1} mb={5} style={{display: 'inline-block', textAlign: 'center'}}>
<Avatar alt={user.displayName} src={user.photoUrl} sx={{width: 100, height:100, margin: 'auto'}} />
<Typography><strong style={{fontSize: '1.3rem'}}>{user.displayName}</strong></Typography>
<Typography>
Last Login:<br /> {user.lastLoginTime.toLocaleString()}
</Typography>
</Stack>
<FormControl fullWidth>
<InputLabel>Role</InputLabel>
<Select label="Role" defaultValue={user.role} onChange={e => {
setSelectedRole(e.target.value);
}}>
<MenuItem value="user">user</MenuItem>
<MenuItem value="admin">admin</MenuItem>
<MenuItem value="remove"><em>-- Remove Access --</em></MenuItem>
</Select>
</FormControl>
</Form>
)}
</Stack>
)
):(
<>
<Alert severity="error">Cannot change account owner role.</Alert>
<Stack direction="row" spacing={1} mt={2}>
<Button variant="contained" color="primary" onClick={() => history.push("/account/"+userData.currentAccount.id+"/users")} >Back to User List</Button>
</Stack>
</>
)}
</Box>
</Paper>
)
}
Example #7
Source File: Settings1.js From react-saas-template with MIT License | 4 votes |
function Settings1(props) {
const { classes, pushMessageToSnackbar } = props;
const [isSaveLoading, setIsSaveLoading] = useState(false);
const [isDefaultLoading, setIsDefaultLoading] = useState(false);
const [option1, setOption1] = useState("None");
const [option2, setOption2] = useState("None");
const [option3, setOption3] = useState("None");
const [option4, setOption4] = useState("None");
const [option5, setOption5] = useState("2 Days");
const [option6, setOption6] = useState(7500);
const handleChange = useCallback(
(event) => {
const { name, value } = event.target;
if (name === "option6") {
if (value > 7500 || value < 1000) {
return;
}
}
switch (name) {
case "option1": {
setOption1(value);
break;
}
case "option2": {
setOption2(value);
break;
}
case "option3": {
setOption3(value);
break;
}
case "option4": {
setOption4(value);
break;
}
case "option5": {
setOption5(value);
break;
}
case "option6": {
setOption6(value);
break;
}
default:
throw new Error("No branch selected in switch statement.");
}
},
[setOption1, setOption2, setOption3, setOption4, setOption5, setOption6]
);
const resetState = useCallback(() => {
setIsSaveLoading(false);
setIsDefaultLoading(false);
setOption1("None");
setOption2("None");
setOption3("None");
setOption4("None");
setOption5("2 Days");
setOption6(7500);
}, [
setIsSaveLoading,
setIsDefaultLoading,
setOption1,
setOption2,
setOption3,
setOption4,
setOption5,
setOption6,
]);
const onSetDefault = useCallback(() => {
setIsDefaultLoading(true);
setTimeout(() => {
pushMessageToSnackbar({
text: "Your settings have been reset to default",
});
resetState();
}, 1500);
}, [pushMessageToSnackbar, resetState]);
const onSubmit = useCallback(() => {
setIsSaveLoading(true);
setTimeout(() => {
pushMessageToSnackbar({
text: "Your settings have been saved",
});
setIsSaveLoading(false);
}, 1500);
}, [setIsSaveLoading, pushMessageToSnackbar]);
const inputs = [
{
state: option1,
label: "Option 1",
stateName: "option1",
},
{
state: option2,
label: "Option 2",
stateName: "option2",
},
{
state: option3,
label: "Option 3",
stateName: "option3",
},
{
state: option4,
label: "Option 4",
stateName: "option4",
},
];
return (
<Accordion>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>Settings 1</Typography>
</AccordionSummary>
<AccordionDetails className={classes.dBlock}>
<List disablePadding>
<Bordered disableVerticalPadding disableBorderRadius>
{inputs.map((element, index) => (
<ListItem
className="listItemLeftPadding"
disableGutters
divider
key={index}
>
<ListItemText>
<Typography variant="body2">{element.label}</Typography>
</ListItemText>
<FormControl variant="outlined">
<ListItemSecondaryAction
className={classes.ListItemSecondaryAction}
>
<Select
value={element.state}
onChange={handleChange}
input={
<OutlinedInput
name={element.stateName}
labelWidth={0}
className={classes.numberInput}
classes={{ input: classes.numberInputInput }}
/>
}
MenuProps={{ disableScrollLock: true }}
>
{inputOptions.map((innerElement) => (
<MenuItem value={innerElement} key={innerElement}>
{innerElement}
</MenuItem>
))}
</Select>
</ListItemSecondaryAction>
</FormControl>
</ListItem>
))}
<ListItem className="listItemLeftPadding" disableGutters divider>
<ListItemText>
<Typography variant="body2">Option 5</Typography>
</ListItemText>
<FormControl variant="outlined">
<ListItemSecondaryAction
className={classes.ListItemSecondaryAction}
>
<Select
value={option5}
onChange={handleChange}
input={
<OutlinedInput
name="option5"
labelWidth={0}
className={classes.numberInput}
classes={{ input: classes.numberInputInput }}
/>
}
MenuProps={{ disableScrollLock: true }}
>
{[
"Always",
"6 Hours",
"12 Hours",
"1 Day",
"2 Days",
"3 Days",
"1 Week",
].map((element) => (
<MenuItem value={element} key={element}>
{element}
</MenuItem>
))}
</Select>
</ListItemSecondaryAction>
</FormControl>
</ListItem>
<ListItem className="listItemLeftPadding" disableGutters>
<ListItemText>
<Typography variant="body2">Option 6</Typography>
</ListItemText>
<FormControl variant="outlined">
<ListItemSecondaryAction
className={classes.ListItemSecondaryAction}
>
<OutlinedInput
labelWidth={0}
name="option6"
value={option6}
type="number"
onChange={handleChange}
className={classes.numberInput}
classes={{ input: classes.numberInputInput }}
inputProps={{ step: 20 }}
/>
</ListItemSecondaryAction>
</FormControl>
</ListItem>
</Bordered>
</List>
</AccordionDetails>
<AccordionDetails className={classes.accordionDetails}>
<Box mr={1}>
<Button
onClick={onSetDefault}
disabled={isSaveLoading || isDefaultLoading}
>
Default {isDefaultLoading && <ButtonCircularProgress />}
</Button>
</Box>
<Button
variant="contained"
color="secondary"
disabled={isSaveLoading || isDefaultLoading}
onClick={onSubmit}
>
Save {isSaveLoading && <ButtonCircularProgress />}
</Button>
</AccordionDetails>
</Accordion>
);
}
Example #8
Source File: Settings2.js From react-saas-template with MIT License | 4 votes |
function Settings2(props) {
const { pushMessageToSnackbar, classes } = props;
const [isDefaultLoading, setIsDefaultLoading] = useState(false);
const [isSaveLoading, setIsSaveLoading] = useState(false);
const [option1, setOption1] = useState(false);
const [option2, setOption2] = useState(false);
const [option3, setOption3] = useState(false);
const [option4, setOption4] = useState(false);
const [option5, setOption5] = useState(false);
const [option6, setOption6] = useState("Both");
const [option7, setOption7] = useState("2 weeks");
const resetState = useCallback(() => {
setIsDefaultLoading(false);
setIsSaveLoading(false);
setOption1(false);
setOption2(false);
setOption3(false);
setOption4(false);
setOption5(false);
setOption6("Both");
setOption7("2 weeks");
}, [
setOption1,
setOption2,
setOption3,
setOption4,
setOption5,
setOption6,
setOption7,
]);
const onSubmit = useCallback(() => {
setIsSaveLoading(true);
setTimeout(() => {
pushMessageToSnackbar({
text: "Your settings have been saved",
});
setIsSaveLoading(false);
}, 1500);
}, [pushMessageToSnackbar, setIsSaveLoading]);
const onSetDefault = useCallback(() => {
setIsDefaultLoading(true);
setTimeout(() => {
pushMessageToSnackbar({
text: "Your settings have been reset to default",
});
resetState();
}, 1500);
}, [pushMessageToSnackbar, resetState, setIsDefaultLoading]);
const handleInputChange = useCallback(
(event) => {
const { name, value } = event.target;
switch (name) {
case "option6": {
setOption6(value);
break;
}
case "option7": {
setOption7(value);
break;
}
default:
throw new Error("No branch selected in switch statement");
}
},
[setOption6, setOption7]
);
const handleCheckboxChange = (name) => (event) => {
switch (name) {
case "option1":
setOption1(event.target.checked);
break;
case "option2":
setOption2(event.target.checked);
break;
case "option3":
setOption3(event.target.checked);
break;
case "option4":
setOption4(event.target.checked);
break;
case "option5":
setOption5(event.target.checked);
break;
default:
throw new Error("No branch selected in switch statement.");
}
};
const inputs = [
{
title: "Option 1",
secondaryAction: (
<Checkbox
value="option1"
color="primary"
checked={option1}
onChange={handleCheckboxChange("option1")}
/>
),
},
{
title: "Option 2",
secondaryAction: (
<Checkbox
value="option2"
color="primary"
checked={option2}
onChange={handleCheckboxChange("option2")}
/>
),
},
{
title: "Option 3",
secondaryAction: (
<Checkbox
value="option3"
color="primary"
checked={option3}
onChange={handleCheckboxChange("option3")}
/>
),
helpText: "You can add some further explanation here.",
},
{
title: "Option 4",
secondaryAction: (
<Checkbox
value="option4"
color="primary"
checked={option4}
onChange={handleCheckboxChange("option4")}
/>
),
},
{
title: "Option 5",
secondaryAction: (
<Checkbox
value="option5"
color="primary"
checked={option5}
onChange={handleCheckboxChange("option5")}
/>
),
},
{
title: "Option 6",
secondaryAction: (
<Select
value={option6}
input={
<OutlinedInput
onChange={handleInputChange}
labelWidth={0}
className={classes.numberInput}
classes={{ input: classes.numberInputInput }}
name="option6"
/>
}
>
<MenuItem value="Both">Both</MenuItem>
<MenuItem value="Male+">Male+</MenuItem>
<MenuItem value="Female+">Female+</MenuItem>
<MenuItem value="Only male">Only male</MenuItem>
<MenuItem value="Only female">Only female</MenuItem>
</Select>
),
helpText: "You can add some further explanation here.",
},
{
title: "Option 7",
secondaryAction: (
<Select
value={option7}
input={
<OutlinedInput
onChange={handleInputChange}
labelWidth={0}
className={classes.numberInput}
classes={{ input: classes.numberInputInput }}
name="option7"
/>
}
>
<MenuItem value="None">None</MenuItem>
<MenuItem value="6 hours">6 hours</MenuItem>
<MenuItem value="12 hours">12 hours</MenuItem>
<MenuItem value="1 day">1 day</MenuItem>
<MenuItem value="3 days">3 days</MenuItem>
<MenuItem value="1 week">1 week</MenuItem>
<MenuItem value="2 weeks">2 weeks</MenuItem>
<MenuItem value="1 month">1 month</MenuItem>
<MenuItem value="3 months">3 months</MenuItem>
<MenuItem value="6 months">6 months</MenuItem>
</Select>
),
helpText: "You can add some further explanation here.",
},
];
return (
<Accordion>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>Settings 2</Typography>
</AccordionSummary>
<AccordionDetails className={classes.dBlock}>
<List disablePadding>
<Bordered disableVerticalPadding disableBorderRadius>
{inputs.map((element, index) => (
<ListItem
key={index}
divider={index !== inputs.length - 1}
className="listItemLeftPadding"
>
<ListItemText>
<Typography variant="body2">
{element.title}
{element.helpText && <HelpIcon title={element.helpText} />}
</Typography>
</ListItemText>
<ListItemSecondaryAction>
<FormControl variant="outlined">
{element.secondaryAction}
</FormControl>
</ListItemSecondaryAction>
</ListItem>
))}
</Bordered>
</List>
</AccordionDetails>
<AccordionDetails className={classes.AccordionDetails}>
<Box mr={1}>
<Button
onClick={onSetDefault}
disabled={isSaveLoading || isDefaultLoading}
>
Default {isDefaultLoading && <ButtonCircularProgress />}
</Button>
</Box>
<Button
variant="contained"
color="secondary"
onClick={onSubmit}
disabled={isSaveLoading || isDefaultLoading}
>
Save {isSaveLoading && <ButtonCircularProgress />}
</Button>
</AccordionDetails>
</Accordion>
);
}
Example #9
Source File: AddPostOptions.js From react-saas-template with MIT License | 4 votes |
function AddPostOptions(props) {
const {
Dropzone,
classes,
files,
deleteItem,
onDrop,
EmojiTextArea,
ImageCropper,
DateTimePicker,
cropperFile,
onCrop,
onCropperClose,
uploadAt,
onChangeUploadAt,
} = props;
const [option1, setOption1] = useState("None");
const [option2, setOption2] = useState("None");
const [option3, setOption3] = useState("None");
const [option4, setOption4] = useState("None");
const handleChange = useCallback(
(event) => {
const { name, value } = event.target;
switch (name) {
case "option1":
setOption1(value);
break;
case "option2":
setOption2(value);
break;
case "option3":
setOption3(value);
break;
case "option4":
setOption4(value);
break;
default:
throw new Error("No branch selected in switch-statement.");
}
},
[setOption1, setOption2, setOption3, setOption4]
);
const printFile = useCallback(() => {
if (files[0]) {
return (
<div className={classes.imgWrapper}>
<img
alt="uploaded item"
src={files[0].preview}
className={classes.img}
style={{ height: 148 }}
/>
<div className={classes.floatButtonWrapper}>
<IconButton onClick={deleteItem} size="large">
<CloseIcon />
</IconButton>
</div>
</div>
);
}
return (
<Dropzone accept="image/png, image/jpeg" onDrop={onDrop} fullHeight>
<span className={classes.uploadText}>
Click / Drop file <br /> here
</span>
</Dropzone>
);
}, [onDrop, files, classes, deleteItem]);
const inputs =
[
{
state: option1,
label: "Option 1",
stateName: "option1",
},
{
state: option2,
label: "Option 2",
stateName: "option2",
},
{
state: option3,
label: "Option 3",
stateName: "option3",
},
{
state: option4,
label: "Option 4",
stateName: "option4",
},
];
return (
<Fragment>
{ImageCropper && (
<ImageCropperDialog
open={cropperFile ? true : false}
ImageCropper={ImageCropper}
src={cropperFile ? cropperFile.preview : ""}
onCrop={onCrop}
onClose={onCropperClose}
aspectRatio={4 / 3}
/>
)}
<Typography paragraph variant="h6">
Upload Image
</Typography>
<Box mb={2}>
{EmojiTextArea && (
<EmojiTextArea
inputClassName={classes.emojiTextArea}
maxCharacters={2200}
rightContent={printFile()}
emojiSet="google"
/>
)}
</Box>
<Typography paragraph variant="h6">
Options
</Typography>
<List disablePadding>
<Bordered disableVerticalPadding disableBorderRadius>
<ListItem divider disableGutters className="listItemLeftPadding">
<ListItemText>
<Typography variant="body2">Upload at</Typography>
</ListItemText>
<ListItemSecondaryAction>
{DateTimePicker && (
<DateTimePicker
value={uploadAt}
format="yyyy/MM/dd hh:mm a"
onChange={onChangeUploadAt}
disablePast
/>
)}
</ListItemSecondaryAction>
</ListItem>
{inputs.map((element, index) => (
<ListItem
className="listItemLeftPadding"
disableGutters
divider={index !== inputs.length - 1}
key={index}
>
<ListItemText>
<Typography variant="body2">{element.label}</Typography>
</ListItemText>
<FormControl variant="outlined">
<ListItemSecondaryAction>
<Select
value={element.state}
onChange={handleChange}
input={
<OutlinedInput
name={element.stateName}
labelWidth={0}
className={classes.numberInput}
classes={{ input: classes.numberInputInput }}
/>
}
MenuProps={{ disableScrollLock: true }}
>
{inputOptions.map((innerElement) => (
<MenuItem value={innerElement} key={innerElement}>
{innerElement}
</MenuItem>
))}
</Select>
</ListItemSecondaryAction>
</FormControl>
</ListItem>
))}
</Bordered>
</List>
</Fragment>
);
}
Example #10
Source File: FolderPermissions.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, open, onCancel, owners, domain, folderID } = this.props;
const { permissions, selected, adding, deleting } = this.state;
return (
<Dialog
onClose={onCancel}
open={open}
maxWidth="sm"
fullWidth
TransitionProps={{
onEnter: this.handleEnter,
}}
>
<DialogTitle>{t('Permissions')}</DialogTitle>
<DialogContent style={{ minWidth: 400 }}>
{owners.length > 0 ? <List className={classes.list}>
{owners.map((user, idx) => <Fragment key={idx}>
<ListItem disablePadding>
<ListItemButton
selected={user.memberID === selected?.memberID}
component="a"
onClick={this.handleUserSelect(user)}
>
<ListItemText primary={user.username}/>
</ListItemButton>
</ListItem>
<Divider />
</Fragment>)}
</List> : <div className={classes.noOwnersContainer}>
<em>{t('No owners')}</em>
</div>}
<div className={classes.addUserRow}>
<Button
onClick={this.handleAdd}
variant="contained"
color="primary"
style={{ marginRight: 8 }}
>
{t('Add')}
</Button>
<Button
onClick={this.handleDelete}
color="secondary"
>
{t('Remove')}
</Button>
</div>
<FormControl fullWidth style={{ marginBottom: 4 }}>
<InputLabel>{t('Profile')}</InputLabel>
<Select
labelId="demo-simple-select-label"
value={permissionProfiles.findIndex(profile => profile.value === permissions) === -1 ? "" : permissions}
label={t('Profile')}
onChange={this.handleProfileSelect}
>
{permissionProfiles.map((profile, idx) =>
<MenuItem key={idx} value={profile.value}>
{profile.name}
</MenuItem>
)}
</Select>
</FormControl>
<Grid container>
<Grid item xs={6}>
<FormControl className={classes.form}>
<FormLabel>Read</FormLabel>
<RadioGroup defaultValue={0} value={permissions & 1} onChange={this.handlePermissions}>
<FormControlLabel
value={0x0}
control={<Radio size="small" className={classes.radio}/>}
label="None"
/>
<FormControlLabel
value={0x1}
control={<Radio size="small" className={classes.radio}/>}
label="Full Details"
/>
</RadioGroup>
</FormControl>
</Grid>
<Grid item xs={6}>
<FormControl className={classes.form}>
<FormLabel>Write</FormLabel>
<FormControlLabel
control={
<Checkbox
value={0x2}
checked={Boolean(permissions & 0x2)}
onChange={this.handlePermissions}
className={classes.radio}
color="primary"
/>
}
label={t('Create items')}
/>
<FormControlLabel
control={
<Checkbox
value={0x80}
checked={Boolean(permissions & 0x80)}
className={classes.radio}
onChange={this.handlePermissions}
color="primary"
/>
}
label={t('Create subfolders')}
/>
<FormControlLabel
control={
<Checkbox
checked={Boolean(permissions & 0x8)}
value={0x8}
className={classes.radio}
onChange={this.handlePermissions}
color="primary"
/>
}
label={t('Edit own')}
/>
<FormControlLabel
control={
<Checkbox
className={classes.radio}
checked={Boolean(permissions & 0x20)}
value={0x20}
onChange={this.handlePermissions}
color="primary"
/>
}
label={t('Edit all')}
/>
</FormControl>
</Grid>
</Grid>
<Grid container style={{ marginTop: 16 }}>
<Grid item xs={6}>
<FormControl className={classes.form}>
<FormLabel>Delete items</FormLabel>
<RadioGroup
value={(permissions & 0x50) || true /* This is a bit janky */}
defaultValue={true}
onChange={this.handleRadioPermissions}
>
<FormControlLabel
value={(permissions & 0x50) === 0} // Has explicit handling
control={<Radio size="small" className={classes.radio}/>}
label="None" />
<FormControlLabel
value={0x10}
control={<Radio size="small" className={classes.radio}/>}
label="Own"
/>
<FormControlLabel
value={0x50}
control={<Radio size="small" className={classes.radio}/>}
label="All"
/>
</RadioGroup>
</FormControl>
</Grid>
<Grid item xs={6}>
<FormControl className={classes.form}>
<FormLabel>Other</FormLabel>
<FormControlLabel
control={
<Checkbox
className={classes.radio}
checked={Boolean(permissions & 0x100)}
value={0x100}
onChange={this.handlePermissions}
color="primary"
/>
}
label={t('Folder owner')}
/>
<FormControlLabel
control={
<Checkbox
className={classes.radio}
checked={Boolean(permissions & 0x200)}
onChange={this.handlePermissions}
color="primary"
value={0x200}
/>
}
label={t('Folder contact')}
/>
<FormControlLabel
control={
<Checkbox
className={classes.radio}
checked={Boolean(permissions & 0x400)}
onChange={this.handlePermissions}
color="primary"
value={0x400}
/>
}
label={t('Folder visible')}
/>
</FormControl>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button
onClick={onCancel}
color="secondary"
>
{t('Close')}
</Button>
<Button
onClick={this.handleSave}
variant="contained"
color="primary"
disabled={owners.length === 0 || !selected}
>
{t('Save')}
</Button>
</DialogActions>
<AddOwner
open={adding}
onSuccess={this.handleAddingSuccess}
onError={this.handleAddingError}
onCancel={this.handleAddingCancel}
domain={domain}
folderID={folderID}
/>
{selected && <RemoveOwner
open={deleting}
onSuccess={this.handleDeleteSuccess}
onError={this.handleDeleteError}
onClose={this.handleDeleteClose}
ownerName={selected.username}
domainID={domain.ID}
folderID={folderID}
memberID={selected.memberID}
/>}
</Dialog>
);
}
Example #11
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 #12
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 #13
Source File: Defaults.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t } = this.props;
const { createParams, sizeUnits, snackbar, langs } = this.state;
const { maxUser, prohibitsendquota, prohibitreceivequota, storagequotalimit,
lang, privChat, privArchive, privFiles, privVideo,
// eslint-disable-next-line camelcase
smtp, changePassword, pop3_imap, chatTeam, chatUser } = createParams;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<ViewWrapper
topbarTitle={t('Defaults')}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Paper className={classes.paper} elevation={1}>
<Grid container>
<Typography
color="primary"
variant="h5"
>
{t('editHeadline', { item: 'Defaults' })}
</Typography>
</Grid>
<FormControl className={classes.form}>
<Typography
color="primary"
variant="h6"
className={classes.subheader}
>
{t('Domain create parameters')}
</Typography>
<TextField
style={{ marginBottom: 16 }}
label={t("Max users")}
onChange={this.handleInput('maxUser')}
fullWidth
value={maxUser || ''}
autoFocus
/>
<Grid container className={classes.input}>
<FormControlLabel
control={
<Checkbox
checked={chatTeam || false }
onChange={this.handleCheckbox('chatTeam')}
color="primary"
/>
}
label={t('Create chat team')}
/>
</Grid>
<Typography
color="primary"
variant="h6"
className={classes.subheader}
>
{t('User create parameters')}
</Typography>
<TextField
select
className={classes.input}
label={t("Language")}
fullWidth
value={lang || ''}
onChange={this.handleInput('lang')}
>
{langs.map((l) => (
<MenuItem key={l.code} value={l.code}>
{l.code + ": " + l.name}
</MenuItem>
))}
</TextField>
<Grid container style={{ marginTop: 8 }}>
<TextField
className={classes.flexInput}
label={
<div className={classes.labelContainer}>
{t("Send quota limit")}
<div style={{ width: 6, height: 6, backgroundColor: yellow['500'], marginLeft: 4 }}></div>
</div>
}
value={prohibitsendquota !== undefined ? prohibitsendquota : ''}
onChange={this.handleInput('prohibitsendquota')}
InputProps={{
endAdornment:
<FormControl className={classes.adornment}>
<Select
onChange={this.handleUnitChange('prohibitsendquota')}
value={sizeUnits.prohibitsendquota}
className={classes.select}
variant="standard"
>
<MenuItem value={1}>MB</MenuItem>
<MenuItem value={2}>GB</MenuItem>
<MenuItem value={3}>TB</MenuItem>
</Select>
</FormControl>,
}}
/>
<TextField
className={classes.flexInput}
label={
<div className={classes.labelContainer}>
{t("Receive quota limit")}
<div style={{ width: 6, height: 6, backgroundColor: red['500'], marginLeft: 4 }}></div>
</div>
}
value={prohibitreceivequota !== undefined ? prohibitreceivequota : ''}
onChange={this.handleInput('prohibitreceivequota')}
InputProps={{
endAdornment:
<FormControl className={classes.adornment}>
<Select
onChange={this.handleUnitChange('prohibitreceivequota')}
value={sizeUnits.prohibitreceivequota}
className={classes.select}
variant="standard"
>
<MenuItem value={1}>MB</MenuItem>
<MenuItem value={2}>GB</MenuItem>
<MenuItem value={3}>TB</MenuItem>
</Select>
</FormControl>,
}}
/>
<TextField
className={classes.flexInput}
style={{ marginRight: 0 }}
label={
<div className={classes.labelContainer}>
{t("Storage quota limit")}
<div style={{ width: 6, height: 6, backgroundColor: '#ddd', marginLeft: 4 }}></div>
</div>
}
value={storagequotalimit !== undefined ? storagequotalimit : ''}
onChange={this.handleInput('storagequotalimit')}
InputProps={{
endAdornment:
<FormControl className={classes.adornment}>
<Select
onChange={this.handleUnitChange('storagequotalimit')}
value={sizeUnits.storagequotalimit}
className={classes.select}
variant="standard"
>
<MenuItem value={1}>MB</MenuItem>
<MenuItem value={2}>GB</MenuItem>
<MenuItem value={3}>TB</MenuItem>
</Select>
</FormControl>,
}}
/>
</Grid>
<Grid container className={classes.checkboxes}>
<FormControlLabel
control={
<Checkbox
checked={smtp || false }
onChange={this.handleCheckbox('smtp')}
color="primary"
/>
}
label={t('Allow SMTP sending (used by POP3/IMAP clients)')}
/>
<FormControlLabel
control={
<Checkbox
checked={changePassword || false }
onChange={this.handleCheckbox('changePassword')}
color="primary"
/>
}
label={t('Allow password changes')}
/>
<FormControlLabel
control={
<Checkbox
checked={pop3_imap || false /*eslint-disable-line*/}
onChange={this.handleCheckbox('pop3_imap')}
color="primary"
/>
}
label={t('Allow POP3/IMAP logins')}
/>
</Grid>
<Grid container className={classes.checkboxes}>
<FormControlLabel
control={
<Checkbox
checked={privChat || false }
onChange={this.handleCheckbox('privChat')}
color="primary"
/>
}
label={t('Allow Chat')}
/>
<FormControlLabel
control={
<Checkbox
checked={privVideo || false }
onChange={this.handleCheckbox('privVideo')}
color="primary"
/>
}
label={t('Allow Video')}
/>
<FormControlLabel
control={
<Checkbox
checked={privFiles || false }
onChange={this.handleCheckbox('privFiles')}
color="primary"
/>
}
label={t('Allow Files')}
/>
<FormControlLabel
control={
<Checkbox
checked={privArchive || false }
onChange={this.handleCheckbox('privArchive')}
color="primary"
/>
}
label={t('Allow Archive')}
/>
</Grid>
<Grid container className={classes.checkboxes}>
<FormControlLabel
control={
<Checkbox
checked={chatUser || false }
onChange={this.handleCheckbox('chatUser')}
color="primary"
/>
}
label={t('Create chat user')}
/>
</Grid>
</FormControl>
<Grid container className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={this.handleEdit}
disabled={!writable}
>
{t('Save')}
</Button>
</Grid>
</Paper>
</ViewWrapper>
);
}
Example #14
Source File: DomainMenu.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, domain, t, capabilities } = this.props;
const { snackbar, deleting, sizeUnits, langs, createParams } = this.state;
const { prohibitsendquota, prohibitreceivequota, storagequotalimit,
lang, privChat, privArchive, privFiles, privVideo,
// eslint-disable-next-line camelcase
smtp, changePassword, pop3_imap } = createParams;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
const editable = capabilities.includes(ORG_ADMIN);
return (
<TableViewContainer
headline={t("Domain overview")}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Paper className={classes.paper} elevation={1}>
<Grid container direction="column" className={classes.container}>
<Grid item className={classes.firstRow}>
<Typography variant="h6">
<span className={classes.description}>{t('Domain name')}:</span>
{domain.domainname}
</Typography>
{editable && <div className={classes.editButtonContainer}>
<Button
onClick={this.handleNav}
variant="contained"
color="primary"
style={{ marginRight: 8 }}
>
{t('editHeadline', { item: 'domain' })}
</Button>
<Button
onClick={this.handleDelete}
variant="contained"
color="secondary"
>
{t('Delete domain')}
</Button>
</div>}
</Grid>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Title')}:</span>
{domain.title}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Address')}:</span>
{domain.address}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Admin')}:</span>
{domain.adminName}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Users')}:</span>
{`${domain.activeUsers} active, ${domain.inactiveUsers} inactive, ${domain.maxUser} maximum`}
</Typography>
<Typography variant="h6" className={classes.data}>
<span className={classes.description}>{t('Telephone')}:</span>
{domain.tel}
</Typography>
</Grid>
<div className={classes.defaultsContainer}>
<FormControl className={classes.form}>
<Typography
color="primary"
variant="h6"
className={classes.subheader}
>
{t('Default user parameters')}
</Typography>
<TextField
select
className={classes.input}
label={t("Language")}
fullWidth
value={lang || ''}
onChange={this.handleInput('lang')}
>
{langs.map((l) => (
<MenuItem key={l.code} value={l.code}>
{l.code + ": " + l.name}
</MenuItem>
))}
</TextField>
<Grid container className={classes.input}>
<TextField
className={classes.flexInput}
label={
<div className={classes.labelContainer}>
{t("Send quota limit")}
<div style={{ width: 6, height: 6, backgroundColor: yellow['500'], marginLeft: 4 }}></div>
</div>
}
value={prohibitsendquota !== undefined ? prohibitsendquota : ''}
onChange={this.handleInput('prohibitsendquota')}
InputProps={{
endAdornment:
<FormControl className={classes.adornment}>
<Select
onChange={this.handleUnitChange('prohibitsendquota')}
value={sizeUnits.prohibitsendquota}
className={classes.select}
variant="standard"
>
<MenuItem value={1}>MB</MenuItem>
<MenuItem value={2}>GB</MenuItem>
<MenuItem value={3}>TB</MenuItem>
</Select>
</FormControl>,
}}
/>
<TextField
className={classes.flexInput}
label={
<div className={classes.labelContainer}>
{t("Receive quota limit")}
<div style={{ width: 6, height: 6, backgroundColor: red['500'], marginLeft: 4 }}></div>
</div>
}
value={prohibitreceivequota !== undefined ? prohibitreceivequota : ''}
onChange={this.handleInput('prohibitreceivequota')}
InputProps={{
endAdornment:
<FormControl className={classes.adornment}>
<Select
onChange={this.handleUnitChange('prohibitreceivequota')}
value={sizeUnits.prohibitreceivequota}
className={classes.select}
variant="standard"
>
<MenuItem value={1}>MB</MenuItem>
<MenuItem value={2}>GB</MenuItem>
<MenuItem value={3}>TB</MenuItem>
</Select>
</FormControl>,
}}
/>
<TextField
className={classes.flexInput}
style={{ marginRight: 0 }}
label={
<div className={classes.labelContainer}>
{t("Storage quota limit")}
<div style={{ width: 6, height: 6, backgroundColor: '#ddd', marginLeft: 4 }}></div>
</div>
}
value={storagequotalimit !== undefined ? storagequotalimit : ''}
onChange={this.handleInput('storagequotalimit')}
InputProps={{
endAdornment:
<FormControl className={classes.adornment}>
<Select
onChange={this.handleUnitChange('storagequotalimit')}
value={sizeUnits.storagequotalimit}
className={classes.select}
variant="standard"
>
<MenuItem value={1}>MB</MenuItem>
<MenuItem value={2}>GB</MenuItem>
<MenuItem value={3}>TB</MenuItem>
</Select>
</FormControl>,
}}
/>
</Grid>
<Grid container className={classes.input}>
<FormControlLabel
control={
<Checkbox
checked={smtp || false }
onChange={this.handleCheckbox('smtp')}
color="primary"
/>
}
label={t('Allow SMTP sending (used by POP3/IMAP clients)')}
/>
<FormControlLabel
control={
<Checkbox
checked={changePassword || false }
onChange={this.handleCheckbox('changePassword')}
color="primary"
/>
}
label={t('Allow password changes')}
/>
<FormControlLabel
control={
<Checkbox
checked={pop3_imap || false /*eslint-disable-line*/}
onChange={this.handleCheckbox('pop3_imap')}
color="primary"
/>
}
label={t('Allow POP3/IMAP logins')}
/>
</Grid>
<Grid container className={classes.input}>
<FormControlLabel
control={
<Checkbox
checked={privChat || false }
onChange={this.handleCheckbox('privChat')}
color="primary"
/>
}
label={t('Allow Chat')}
/>
<FormControlLabel
control={
<Checkbox
checked={privVideo || false }
onChange={this.handleCheckbox('privVideo')}
color="primary"
/>
}
label={t('Allow Video')}
/>
<FormControlLabel
control={
<Checkbox
checked={privFiles || false }
onChange={this.handleCheckbox('privFiles')}
color="primary"
/>
}
label={t('Allow Files')}
/>
<FormControlLabel
control={
<Checkbox
checked={privArchive || false }
onChange={this.handleCheckbox('privArchive')}
color="primary"
/>
}
label={t('Allow Archive')}
/>
</Grid>
</FormControl>
</div>
<Grid container className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={this.handleEdit}
disabled={!writable}
>
{t('Save')}
</Button>
</Grid>
</Paper>
<DeleteDomain
open={deleting}
delete={this.props.delete}
onSuccess={this.handleDeleteSuccess}
onError={this.handleDeleteError}
onClose={this.handleDeleteClose}
item={domain.domainname}
id={domain.ID}
/>
</TableViewContainer>
);
}
Example #15
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>
);
}